- Added support for the EFM32 ARM CortexM3 family with a demo for the Olimex EM32G880F128-STK board and Crossworks compiler

git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@23 5dc33758-31d5-4daf-9ae8-b24bf3d40d73
This commit is contained in:
Frank Voorburg 2012-03-02 17:46:26 +00:00
parent 26cd4f8bd6
commit a8ee802492
182 changed files with 99178 additions and 0 deletions

View File

@ -0,0 +1,790 @@
S02B0000443A2F7573722F6665617365722F736F6674776172652F4F70656E424C542F5461726765742F44657D
S113000094080020550100007D0200007D020000DC
S11300107D0200007D0200007D0200007D020000E0
S11300207D0200007D0200007D0200007D020000D0
S11300307D0200007D0200007D0200007D020000C0
S11300407D0200007D0200007D0200007D020000B0
S11300507D0200007D0200007D0200007D020000A0
S11300607D0200007D0200007D0200007D02000090
S11300707D0200007D0200007D0200007D02000080
S11300807D0200007D0200007D0200007D02000070
S11300907D0200007D0200007D0200007D02000060
S11300A07D0200007D0200007D0200007D02000050
S10B00B07D0200007D02000046
S11300B872B654485449016054498D4654495548C8
S11300C80A1A04D081F30988022282F31488524858
S11300D85249534A00F084F852485349534A00F0AD
S11300E87FF853485349544A00F07AF8534854491E
S11300F8544A00F075F854485449554A00F070F8C9
S113010854485549554A00F06BF85548554900225A
S113011800F071F854485549091A082903DB0022EC
S113012802600430016046484649884205D00268A6
S1130138043003B4904703BCF7E700208646EC4636
S113014800F01EFE00200021494A904772B62F494C
S11301588D462F492F480A1A04D081F309880222B0
S113016882F314882C482D492D4A00F039F82D487B
S11301782D492E4A00F034F82D482E492E4A00F015
S11301882FF82E482E492F4A00F02AF82E482F49D6
S11301982F4A00F025F82F482F49304A00F020F85C
S11301A82F483049002200F026F82F482F49091A11
S11301B8082903DB00220260043001602048214939
S11301C8884205D00268043003B4904703BCF7E7BB
S11301D800208646EC4600200021254A9047FEE789
S11301E8884207D0521A05D0037801300B700131C8
S11301F8013AF9D17047884202D002700130FAE717
S11302087047000008ED00E000000000940800209A
S113021894080020940800200431000014020020EF
S11302281C0200207C0200007C020000E42C000078
S1130238F02E00000000002014020020E42C00002E
S1130248E42C0000E42C0000E42C0000E42C000062
S1130258E42C0000E42C0000E42C0000F02E000044
S11302681C02002014070020140700209407002013
S1070278F11D000070
S113027C00B542F6E440C0F200004FF03C0140F6F9
S113028CFD33C0F2000398475DF804FB00B540F65B
S113029C6103C0F20003984778B140F66953C0F289
S11302AC000398474EF60853CEF200034FF48042F5
S11302BC1A6044F204031B6898475DF804FB00BF02
S11302CCF0B50F4692B28AB1064600F1010002F174
S11302DCFF3292B2851840F6AD54C0F2000417F800
S11302EC013B06F8013BA047AE42F8D1F0BD00BF7C
S11302FC00B540F25513C0F2000398475DF804FBB7
S113030CF0B5064642F67C55C0F200054FF00004E9
S113031C40F6AD57C0F20007B8472B68B3420DD86E
S113032C69685B189E4209D242F67C53C0F2000302
S113033C04EB440203EB8203187AF0BD04F10104CC
S113034C05F10C050E2CE7D14FF0FF00F0BD00BFFA
S113035CF0B5C7B242F67C54C0F200044FF000066C
S113036C40F6AD55C0F20005A847237ABB4208D12C
S113037C42F67C53C0F2000306EB460253F822000B
S113038CF0BD06F1010604F10C040E2EECD14FF075
S113039CFF30F0BD2DE9F04381B00546006840F212
S11303AC0D33C0F200039847FF2808BF002027D064
S11303BC4FF0000440F6AD58C0F2000840F2C509F5
S11303CCC2F200092E68A71904F10403EB58009338
S11303DCC047384669464FF00402C84758B9A25979
S11303EC009B9A420AD104F10404B4F5007FE9D1CC
S11303FC4FF0010004E04FF0010001E04FF0010068
S113040C01B0BDE8F08300BF00B54FEAC1534FEA19
S113041CD3537BB903688B4210D040F8041B4FF4C0
S113042C007240F2CD23C0F2000398474FF0010054
S113043C5DF804FB4FF000005DF804FB4FF0010085
S113044C5DF804FB30B504460D4640F21C23C2F2A1
S113045C0003984209D0B1F5804F0BD040F2A13380
S113046CC0F20003984748B913E040F22044C2F2AA
S113047C000403E040F21C24C2F200042046294686
S113048C40F21543C0F200039847002808BF00242B
S113049C01E04FF00004204630BD00BF2DE9F047C9
S11304AC05460C4616469FB24FEA51294FEA492994
S11304BC0368B3F1FF3F07D1494640F21543C0F23C
S11304CC00039847002838D02B684B4509D02846A0
S11304DC494640F25143C0F20003984705460028B0
S11304EC2FD02B68E41A04F104042C1906F101082A
S11304FC07F1FF37BFB2B84440F6AD57C0F200075E
S113050C40F2514AC0F2000AB84705F10403E31A59
S113051CB3F5007F07D309F500712846D04705468B
S113052C98B100F1040416F8013B04F8013B46456C
S113053CEAD14FF00100BDE8F0874FF00000BDE8B0
S113054CF0874FF00000BDE8F0874FF00000BDE8E5
S113055CF08700BF00B541F68D53C0F200039847F5
S113056C40F22043C2F200034FF0FF321A6040F213
S113057C1C23C2F200031A605DF804FB70B5044638
S113058C0D46164640F20D33C0F200039847FF287F
S113059C1ED004F1FF30401940F20D33C0F20003B9
S11305AC9847FF2817D04FEA5423202B07BF40F25B
S11305BC1C20C2F2000040F22040C2F20000ABB298
S11305CC2146324640F2A944C0F20004A04770BD53
S11305DC4FF0000070BD4FF0000070BD2DE9F047E6
S11305EC05460F4640F20D34C0F20004A0470646FF
S11305FC05F1FF35E819A04704468046FF2814BFCF
S113060C00230123FF2E08BF43F00103002B7CD1F0
S113061C864266D8012E68D90F286AD848F2FE1390
S113062CC0F6E07393F80090B9F1490F14BF00239E
S113063C0123B9F1470F08BF43F00103B9F1480F87
S113064C14BF4FF400694FF480590BB14FF4007987
S113065C304640F25D35C0F20005A84707462046F7
S113066CA847824642F67C54C0F200044FF00006C0
S113067C40F6AD55C0F20005A847237A434509D18D
S113068C42F67C53C0F2000306EB460203EB8203F2
S113069C5D6807E006F1010604F10C040E2EEBD1A3
S11306AC4FF00005C7EB0A0A5544B5FBF9F5ADB29A
S11306BC1DB34FF0000440F6AD56C0F2000640F2F4
S11306CC0108C2F20008B0473846C047C8B904F163
S11306DC0104A4B24F44A542F5D84FF00100BDE883
S11306ECF0874FF00000BDE8F0874FF00000BDE844
S11306FCF0874FF00000BDE8F0874FF00100BDE833
S113070CF0874FF00000BDE8F0874FF00000BDE823
S113071CF08700BF00B581B040F21C23C2F2000385
S113072C1B68B3F1FF3F08BF01201FD040F21C230C
S113073CC2F2000399685A688918DA6889181A6928
S113074C89185A6989189A698918DA698B18C3F156
S113075C000301AA42F8043D44F2B8004FF004012E
S113076C6A4640F28953C0F20003984701B000BDB9
S113077C44F2040318684FF480431B68C01844F215
S113078C08031B68C01844F20C031B68C01844F21D
S113079C10031B68C01844F214031B68C01844F2FD
S11307AC18031B68C01844F2B8031B68C018D0F1B6
S11307BC010038BF0020704700B540F21C23C2F280
S11307CC00031B68B3F1FF3F09D040F21C20C2F2B6
S11307DC000040F2A133C0F200039847D0B140F2BC
S11307EC2043C2F200031B68B3F1FF3F09D040F26F
S11307FC2040C2F2000040F2A133C0F2000398473B
S113080C60B141F6AD53C0F2000398474FF00100BC
S113081C5DF804FB4FF000005DF804FB4FF00000A2
S113082C5DF804FB00B540F26153C0F20003984735
S113083C5DF804FB00B540F28953C0F200039847FD
S113084C5DF804FB00B540F2E953C0F2000398478D
S113085C5DF804FB00B540F27D73C0F200039847C9
S113086C5DF804FB00B540F22173C0F20003984715
S113087C30B140F2C573C0F2000398475DF804FB35
S113088C4FF000005DF804FB4EF21003CEF20003AF
S113089C4FF000021A6070474EF21003CEF20003C0
S11308AC1B6813F4803F1FBF40F22463C2F20003A1
S11308BC1A88013218BF1A80704700BF40F22463B3
S11308CCC2F200031880704700B540F69503C0F2DD
S11308DC000398474EF21003CEF2000343F2AF62CA
S11308EC5A604FF0000098604FF005021A6040F611
S11308FCC903C0F2000398475DF804FB00B540F649
S113090CA503C0F20003984740F22463C2F200032B
S113091C18885DF804FB00BF10B504464FF48843F7
S113092CC4F20803DB6A13F0040F0CD04FF48840B4
S113093CC4F2080041F65D53C0F2000398472070DE
S113094C4FF0010010BD4FF0000010BD30B5C1B226
S113095C4FF48843C4F208039B6813F0100F1DD0A6
S113096C4FF48844C4F20804204641F66D53C0F297
S113097C00039847A36813F0100F12D140F6AD553D
S113098CC0F200054FF48844C4F20804A847A368D5
S113099C13F0100FFAD04FF0010030BD4FF00000EF
S11309AC30BD4FF0010030BD30B586B06C4642F618
S11309BC2465C0F200050FCD0FC495E8030084E84C
S11309CC03004FF44240C0F202004FF0010141F227
S11309DC7964C0F20004A0474FF002004FF0060106
S11309EC4FF004024FF0010341F68535C0F20005C7
S11309FCA8474FF002004FF007014FF001024FF0EF
S1130A0C0003A8474FF40C50C0F204004FF001014E
S1130A1CA0474FF00300C0F212004FF0020141F660
S1130A2C4123C0F2000398474FF4AA55C0F21605AF
S1130A3C28464FF0010141F27543C0F20003984778
S1130A4C28464FF00101A0474FF0000506A941F8D4
S1130A5C185D4FF48844C4F208042046694641F6F4
S1130A6CFD43C0F200039847204629464FF4165222
S1130A7C41F65D43C0F2000398474FF003036365EE
S1130A8C4FF00403636320464FF0050141F6C14364
S1130A9CC0F20003984706B030BD00BF2DE9F04307
S1130AAC0546CCB2402C0AD942F63C60C0F2000098
S1130ABC4FF0680140F6FD33C0F20003984720461E
S1130ACC40F65913C0F20003984701280AD042F6A5
S1130ADC3C60C0F200004FF06B0140F6FD33C0F2F5
S1130AEC000398472646FCB14FF0000440F6AD577E
S1130AFCC0F2000740F65918C0F2000842F63C69EF
S1130B0CB847285DC047012809D04846C0F2000008
S1130B1C4FF0730140F6FD33C0F20003984704F123
S1130B2C0104A3B2B342EBD3BDE8F08310B5044681
S1130B3C40F26D63C2F200031B78CBB940F228601B
S1130B4CC2F2000040F62513C0F2000398470128B6
S1130B5C42D140F26D63C2F200034FF001021A70ED
S1130B6C40F26C63C2F200034FF00000187010BD29
S1130B7C40F22863C2F2000340F26C62C2F200023B
S1130B8C107800F10100181840F62513C0F2000388
S1130B9C9847012823D140F26C63C2F200031A78FF
S1130BAC02F10102D2B21A7040F22863C2F20003BD
S1130BBC1B78934216D120460C4940F2CD23C0F247
S1130BCC0003984740F26D63C2F200034FF0000239
S1130BDC1A704FF0010010BD4FF0000010BD4FF023
S1130BEC000010BD4FF0000010BD00BF290600200E
S1130BFC00B540F27063C2F20003186040F27463F3
S1130C0CC2F20003196040F6AD54C0F20004A047D0
S1130C1CFDE700BF00B540F69953C0F200039847B6
S1130C2C01281ED040F27863C2F200031B78012B1A
S1130C3C17D140F60913C0F200039847312810D994
S1130C4C40F27863C2F200034FF000021A7040F6CF
S1130C5C9503C0F20003984740F29923C0F20003B5
S1130C6C98475DF804FB00BF00B540F27863C2F20C
S1130C7C00034FF001021A7040F6D503C0F20003D2
S1130C8C984740F62143C0F2000398475DF804FBF3
S1130C9C00B540F6A953C0F20003984740F67543DB
S1130CACC0F20003984740F63103C0F200039847A2
S1130CBC40F6F143C0F2000398475DF804FB00BF13
S1130CCC00B540F6AD53C0F20003984740F63953D3
S1130CDCC0F20003984740F62143C0F20003984742
S1130CEC5DF804FB00B581B04FF0FF038DF80030C4
S1130CFC4FF000038DF8013040F6DD53C0F20003D1
S1130D0C984740F6B513C0F20003984740F2796354
S1130D1CC2F200031B78012B05D1684640F625630B
S1130D2CC0F20003984701B000BD00BF00B540F20B
S1130D3C7C60C2F2000040F63933C0F200039847DD
S1130D4C012808D140F27C60C2F2000040F6256311
S1130D5CC0F2000398475DF804FB00BF704700BF66
S1130D6C00B5C9B240F6A923C0F20003984740F677
S1130D7C1163C0F2000398475DF804FB40F27963F9
S1130D8CC2F200034FF001021A70704700B540F62E
S1130D9CFD53C0F2000398475DF804FB704700BF95
S1130DAC704700BF40F2BC63C2F200034FF0000274
S1130DBC5A70704740F2BC63C2F200034FF0FE025B
S1130DCCDA7018714FF00202A3F84420704700BF88
S1130DDC40F2BC63C2F200034FF000021A709A6432
S1130DEC83F84320A3F844209A705A70704700BFCC
S1130DFC40F2BC63C2F200031878003018BF012023
S1130E0C704700BF40F2BC63C2F200034FF0000213
S1130E1C83F84320704700BF30B504460278FF2A9C
S1130E2C20D140F6B153C0F20003984740F2BC63A2
S1130E3CC2F200034FF001021A704FF0FF01D97097
S1130E4C4FF0100119714FF0000159714FF040002F
S1130E5C9871D87119725A729A724FF00802A3F8E9
S1130E6C4420DAE140F2BC63C2F200031B78012B8C
S1130E7C40F0F381A2F1C902352A00F2C781DFE800
S1130E8C12F00A01C501C501BD01C501C501AC01C2
S1130E9C31018C017601C501C501C501C501C5012E
S1130EACC501C501C501C501C501C501C501C50102
S1130EBCC501C501C501C501C501C501C501C501F2
S1130ECCC501C501C501C501C501C501C501C501E2
S1130EDCC501C501C5018E005A0036008000C5014C
S1130EECC501C501BE00C501DA00E200F600427876
S1130EFC3F2A07D94FF0220040F6C153C0F2000339
S1130F0C98478AE140F2BC65C2F2000505F1040081
S1130F1CA96C40F2CD23C0F2000398474FF0FF03B5
S1130F2CEB706278AB6CD318AB64637803F1010398
S1130F3CA5F8443071E143783F2B07D94FF02200D8
S1130F4C40F6C153C0F20003984766E1416840F291
S1130F5CBC65C2F20005A96405F10400627840F294
S1130F6CCD23C0F2000398474FF0FF03EB70627877
S1130F7CAB6CD318AB64637803F10103A5F844306C
S1130F8C4BE140F2BC63C2F200034FF0FF02DA7093
S1130F9C42689A644FF00102A3F844203DE140F208
S1130FACBC63C2F200034FF0FF02DA70996C436821
S1130FBC4FF000023BB14FF0000211F8010B121874
S1130FCCD2B2013BF9D140F2BC63C2F200034FF040
S1130FDC0001DA714FEA1220C0B218724FEA1240C3
S1130FECC0B258724FEA12629A724FF001021A712F
S1130FFC597199714FF00802A3F844200DE140F2A5
S113100CBC63C2F200034FF0FF02DA7042F6C8620E
S113101CC0F200029A644FF000021A715A719A716C
S113102C4FF00701D9711A725A729A724FF0080272
S113103CA3F84420F1E04FF0000040F6C153C0F295
S113104C00039847E9E040F2BC63C2F200034FF09E
S113105CFF02DA704FF000021A71597859719A71C3
S113106CDA711A724FF00602A3F84420D5E040F26C
S113107CBC64C2F200044FF00003237040F6B15379
S113108CC0F2000398474FF0FF03E3704FF00103E5
S113109CA4F84430C1E040F2BC63C2F20003986C83
S11310AC04F101024FF03F0140F64103C0F200038A
S11310BC984738B94FF0310040F6C153C0F20003E1
S11310CC9847AAE040F2BC63C2F200034FF0FF025F
S11310DCDA709A6C02F13F029A644FF00102A3F8A1
S11310EC44209AE043783E2B07D94FF0220040F677
S11310FCC153C0F2000398478FE040F2BC63C2F2C4
S113110C00034FF0FF02DA704FF00102A3F8442001
S113111C417871B940F67103C0F200039847002876
S113112C7BD14FF0310040F6C153C0F20003984715
S113113C73E040F2BC63C2F20003986C04F1020247
S113114C40F64103C0F20003984738B94FF0310020
S113115C40F6C153C0F2000398475EE040F2BC6312
S113116CC2F2000361789A6C8A189A6455E040F2D2
S113117CBC63C2F200034FF0FF02DA704FF00002BE
S113118C1A715A714FF040019971DA711A725A72CC
S113119C4FF00702A3F844203FE040F2BC63C2F2D4
S11311AC0003986C616840F65103C0F20003984741
S11311BC38B94FF0310040F6C153C0F200039847E0
S11311CC2BE040F2BC63C2F200034FF0FF02DA7072
S11311DC4FF00102A3F844201FE040F2FD23C0F2BB
S11311EC0003984740F2BC63C2F200034FF0FF02C5
S11311FCDA704FF00102A3F844200EE04FF03100F6
S113120C40F6C153C0F20003984706E04FF02000AB
S113121C40F6C153C0F20003984740F2BC63C2F2DB
S113122C000393F84330012B06D14FF0100040F625
S113123CC153C0F20003984740F2BC63C2F20003EE
S113124C4FF0010283F8432003F10300B3F8441078
S113125C40F66D53C0F20003984730BD4FF4004381
S113126CC4F20C03DB6A03F47053B3F5805F48D00B
S113127CB3F5005F03D0B3F5006F0CD105E040F279
S113128C1423C2F200031868704740F21823C2F208
S113129C0003186870474FF40043C4F20C03DB6876
S11312AC03F4E063B3F5007F19D004D80BB3B3F5A2
S11312BC807F23D118E0B3F5806F25D0B3F5A06FF0
S11312CC03D0B3F5407F19D104E04FF47C50C0F245
S11312DCAB10704749F68070C0F2D50070474DF6DC
S11312ECC000C0F2A70070474CF6C070C0F26A0090
S11312FC704744F24020C0F20F0070474FF00000DA
S113130C70474FF40040704746F64070C0F24010EE
S113131C704700BF00B541F26923C0F2000398473F
S113132C4FF40043C4F20C035B6803F00F0320FA80
S113133C03F040F20873C2F2000318605DF804FB7A
S113134C704700BF4FF40040704700BF40F21423B5
S113135CC2F20003186870474FF00003C4F20C0388
S113136C5B6803F00702032A0CD8DFE802F00202E0
S113137C070723F0070343F0010303E023F00703FB
S113138C43F003034FF00002C4F20C0253607047A5
S113139CB0FA80F0C0B2C0F11F0070474FF00003E8
S11313ACC4F20C035B684DF6FF32CFF60B72821855
S11313BC42F2FF31C0F2F4018A420BD803F0070267
S11313CCA2F10202012A23F0070394BF43F00303A2
S11313DC43F001034FF41052C0F2F402904209D8C6
S11313EC03F00702A2F10202012A23F0070398BFBB
S11313FC43F002034FF00002C4F20C025360704736
S113140C49F68070C0F2D500704700BF00B54FF4A8
S113141C0043C4F20C039B6A4FEA400023FA00F029
S113142C00F0030002280AD003280FD0012816D19B
S113143C41F25133C0F2000398475DF804FB41F2CA
S113144C5933C0F2000398475DF804FB41F2213391
S113145CC0F2000398474FEA50005DF804FB4FF0CC
S113146C00005DF804FB00BF10B50C46C0F3031379
S113147C03F1FF33032B00F2F780DFE803F00212D1
S113148C31A8084641F29D33C0F2000398474FF44B
S113149C0043C4F20C039A6822F00F0210439860C4
S11314AC10BD41F26533C0F200039847204641F267
S11314BC9D33C0F2000398474FF40043C4F20C036D
S11314CC5A6822F00F021043586041F22133C0F2E3
S11314DC0003984741F2A933C0F20003984710BDAA
S11314EC41F23043C0F20A0398422CD04FF030033F
S11314FCC0F20C03984247D04FF48663C0F2080341
S113150C984240F0B1804FF40043C4F20C035B6D7D
S113151C13F0010F07D14FF40042C4F20C02136D07
S113152C13F0040FFBD1204641F29D33C0F20003AB
S113153C98474FF40043C4F20C039A6E22F00F0246
S113154C1043986610BD4FF40043C4F20C035B6D5A
S113155C13F0010F07D14FF40042C4F20C02136DC7
S113156C13F0040FFBD1204641F29D33C0F200036B
S113157C98474FF40043C4F20C039A6E22F0F00225
S113158C42EA0010986610BD4FF40043C4F20C03F9
S113159C5B6D13F0010F07D14FF40042C4F20C023F
S11315AC136D13F0040FFBD1204641F29D33C0F2AE
S11315BC000398474FF40043C4F20C039A6EA0F155
S11315CC100022F4407242EA00229A6610BD4FF4D5
S11315DCA863C0F21403984206D04FF4AA53C0F285
S11315EC1603984240D11FE04FF40043C4F20C039D
S11315FC5B6D13F0010F07D14FF40042C4F20C02DF
S113160C136D13F0400FFBD1204641F29D33C0F211
S113161C000398474FF40043C4F20C031A6F22F0F2
S113162C03021043186710BD4FF40043C4F20C03BB
S113163C5B6D13F0010F07D14FF40042C4F20C029E
S113164C136D13F0400FFBD1204641F29D33C0F2D1
S113165C000398474FF40043C4F20C031A6F22F0B2
S113166C300242EA0010186710BD00BF30B4C9B292
S113167CC0F3032303F1FF33052B43D8DFE803F056
S113168C08363B1E250348F27802C4F20C0236E0FD
S113169CC0F3043048F20802C4F20C0206E04FF422
S11316AC0044C4F20C04236D1D42FCD102F10472FB
S11316BC00EBC2024FEA8202116023E04FF00105F5
S11316CC48F25802C4F20C0205E04FF0100548F23F
S11316DC6002C4F20C02C0F304304FF40043C4F2B1
S11316EC0C035B6D13F0010FE0D1D8E748F2440210
S11316FCC4F20C0203E048F24002C4F20C02C0F340
S113170C0430D3E730BC704700F00F0000F1FF3019
S113171C032842D8DFE800F0051B2E024FF0070027
S113172C70474FF40043C4F20C03D86A00F47050B1
S113173CB0F5805F34D0B0F5005F05D0B0F5006F24
S113174C0CBF0420052070474FF0020070474FF483
S113175C0043C4F20C03986A00F00300022822D060
S113176C032804D001280CBF0320012070474FF03C
S113177C060070474FF40043C4F20C03986A00F05F
S113178C0C00022812D0032804D001280CBF03201B
S113179C012070474FF0060070474FF0000070476F
S11317AC4FF0030070474FF0020070474FF00200F7
S11317BC704700BF00B500F47810B0F5402F7AD014
S11317CC14D8B0F5802F42D005D848B3B0F5003FFB
S11317DC40F0EF802BE0B0F5002F48D0B0F5202F6F
S11317EC57D0B0F5C02F40F0E48037E0B0F5A01F1F
S11317FC00F0958007D8B0F5602F6ED0B0F5901F2F
S113180C40F0D78082E0B0F5C01F00F0AC80B0F59A
S113181CD01F00F0C780B0F5B01F40F0CA8090E034
S113182C41F26923C0F2000398475DF804FB41F2CE
S113183C6923C0F2000398474FF40043C4F20C032D
S113184C9B6803F00F0320FA03F05DF804FB41F2EC
S113185C2133C0F2000398475DF804FB4FF00000FD
S113186C41F21943C0F2000398475DF804FB4FF0B2
S113187C000041F21943C0F2000398474FF40043AF
S113188CC4F20C039B6E03F00F0320FA03F05DF813
S113189C04FB4FF0000041F21943C0F200039847D7
S11318AC4FF40043C4F20C039B6EC3F3031320FAEE
S11318BC03F05DF804FB4FF0000041F21943C0F251
S11318CC000398474FF40043C4F20C039B6EC3F31C
S11318DC012320FA03F05DF804FB4FF0000041F201
S11318EC1943C0F2000398474FF40043C4F20C03AD
S11318FC9A6EC2F3012220FA02F0DB6F03F00703A5
S113190C03F10103B0FBF3F05DF804FB4FF00100AD
S113191C41F21943C0F2000398475DF804FB4FF001
S113192C010041F21943C0F2000398474FF40043FD
S113193CC4F20C031B6F03F0030320FA03F05DF8ED
S113194C04FB4FF0010041F21943C0F20003984725
S113195C4FF40043C4F20C031B6FC3F3011320FABE
S113196C03F05DF804FB4FF00400C0F2180041F2E0
S113197C1573C0F200039847072808D008280DD126
S113198C41F26923C0F2000398475DF804FB41F26D
S113199C0D43C0F2000398475DF804FB4FF00000C0
S11319AC5DF804FB41F20D43C0F2000398475DF867
S11319BC04FB4FF000005DF804FB00BF10B5C9B286
S11319CCD2B2042835D8DFE800F0120D1703080052
S11319DC4FF001044FF0020012E04FF010044FF0EE
S11319EC20000DE04FF040044FF0800008E04FF46D
S11319FC80744FF4007003E04FF004044FF00800BF
S1131A0C69B14FF40043C4F20C031C6262B14FF48D
S1131A1C0042C4F20C02D36A1842FCD004E04FF426
S1131A2C0043C4F20C03186241F65133C0F20003B4
S1131A3C984710BD10B500F00F00012804D0002801
S1131A4C7FD003287DD83BE0A1F10201032978D88B
S1131A5CDFE801F00210070B4FF000004FF0040414
S1131A6C0CE04FF00200044608E04FF003004FF086
S1131A7C010403E04FF001004FF003044FF00101A7
S1131A8C0A4641F6C913C0F20003984741F2653384
S1131A9CC0F2000398474FF40043C4F20C035C6299
S1131AAC41F65133C0F20003984741F22133C0F29E
S1131ABC0003984741F2A933C0F20003984710BDC4
S1131ACC022814BF0224002401F1FF31052938D85F
S1131ADCDFE801F026031037371C4FF000004FF0FD
S1131AEC01010A4641F6C913C0F2000398474FF0AE
S1131AFC020217E04FF001000146024641F6C913F9
S1131B0CC0F2000398474FF001020BE040F60803C3
S1131B1CC4F290334FF001021A604FF0030201E05B
S1131B2C4FF000024FF40043C4F20C03996A02FA1A
S1131B3C04F24FF0030000FA04F421EA0404144301
S1131B4C9C6210BD4FF40043C4F20C03DA6A40F2F9
S1131B5C0C73C2F200031A80704700BF4FF4C043E9
S1131B6CC4F2000300EBC0004FEA80001A5822F0C4
S1131B7C0302114319507047F0B4DAB16BB14FF052
S1131B8C010505FA01F500EBC0044FEA840404F1E5
S1131B9C804404F5C04425610CE04FF0010505FABE
S1131BAC01F500EBC0044FEA840404F1804404F50D
S1131BBCC0446561072915D800EBC0044FEA8404BE
S1131BCC04F1804404F5C04467684FEA81054FF082
S1131BDC0F0606FA05F627EA060602FA05F535435A
S1131BEC656016E000EBC0044FEA840404F1804401
S1131BFC04F5C044A7684FEA8105A5F120054FF010
S1131C0C0F0606FA05F627EA060602FA05F5354329
S1131C1CA560DAB96BB14FF0010303FA01F100EBE3
S1131C2CC0004FEA800000F1804000F5C040016123
S1131C3C0CE04FF0010303FA01F100EBC0004FEA92
S1131C4C800000F1804000F5C0404161F0BC704759
S1131C5C30B504461546D9B94FF48043C4F2080391
S1131C6C98420BD04FF48843C4F20803984204BF43
S1131C7C4FF4AA50C0F216001BD103E04FF4A86035
S1131C8CC0F2140041F2C173C0F20003984701463C
S1131C9C4FEA4111B1FBF5F5A5F120054FEAC50555
S1131CAC236C13F0010F03D1636C13F0040FFBD1FD
S1131CBCE56030BD6FEA010303F0050341EA43011B
S1131CCC036C13F0010F03D1436C13F0020FFBD11F
S1131CDC41607047C9B231B1436C002BFCD14FF059
S1131CEC0103036470474FF000030364704700BFA3
S1131CFC70B504460D46036C13F0010F03D1636CED
S1131D0C13F0020FFBD14FF00A03636020464FF02F
S1131D1C010141F6E146C0F20006B0472268296988
S1131D2CEB680B4369690B4322F01C0213432360D9
S1131D3C6968AA68204641F65D43C0F200039847DF
S1131D4C2B68636020464FF00001B04770BD00BFA4
S1131D5C836813F0200FFBD0C069C0B2704700BF7A
S1131D6CC9B2836813F0100FFBD0036C13F0010F8E
S1131D7C03D1436C13F0400FFBD18162704700BF59
S1131D8C4FF00003C4F20C039A6842F001029A600B
S1131D9C41F67132DA639A6822F001029A60704754
S1131DAC4FF00003C4F20C039A6842F001029A60EB
S1131DBC4FF00002DA639A6822F001029A607047CD
S1131DCC4FF6D073CEF20F031A6902F03F02027081
S1131DDC9A6902F0F002DB69C3F3031313434370F3
S1131DEC704700BF00B581B041F24D33C0F200031F
S1131DFC984748F2FC13C0F6E0731B681B0E14D111
S1131E0C4AF20C03C4F20C031A6822F070021A6032
S1131E1C46F22003C4F20C031A6822F060421A60E2
S1131E2C1A6862F060621A6001E0032B22D846F251
S1131E3C2003C4F20C031A6822F4FC521A6048F210
S1131E4C4002C4F20C024FF00003136048F2440247
S1131E5CC4F20C02136048F25802C4F20C02136070
S1131E6C48F26002C4F20C02136048F27802C4F225
S1131E7C0C021360684641F6CD53C0F20003984738
S1131E8C9DF80030012B17D19DF801303BB948F275
S1131E9C4003C4F20C031A6842F002021A609DF863
S1131EAC0130012B9FBF48F24403C4F20C031A689F
S1131EBC42F0010298BF1A6048F2F013C0F6E073C6
S1131ECC1A684BF6FF13C4F68A439A422FD848F289
S1131EDC4403C4F20C031A6842F490421A6048F2A8
S1131EECB412C0F6E0721168C1F3062110681568CB
S1131EFC146804F07F0405F4FE42224300F07F00D2
S1131F0C42EA004242EA016142F23402C4F20002A3
S1131F1C116048F2C812C0F6E072116844F22C0247
S1131F2CC4F2000211601A6822F490421A604FF055
S1131F3C00004FF001010A4641F6C913C0F2000338
S1131F4C98474FF40043C4F20C031A6C42F00F028E
S1131F5C1A645A6C6FEA12426FEA02425A644FF4E2
S1131F6C3340C0F206004FF0000141F27964C0F234
S1131F7C0004A0474FF44850C0F202004FF0000197
S1131F8CA0474FF47245C0F2020528464FF00001F9
S1131F9CA04728464FF00001A0474FF001004FF036
S1131FAC09014FF00502034641F68534C0F20004E2
S1131FBCA0474FF001004FF0020141F66933C0F223
S1131FCC0003984740F69D43C0F20003984740F63F
S1131FDCCD44C0F20004A047FDE700BF2DE9F04F4B
S1131FEC87B007460C4603924FF00003036042F699
S1131FFCD06BC0F2000B42F6E063C0F20003029314
S113200CC1E204F10104252904BF2346002603D0B0
S113201C384600F0A3FDB6E2194613F8010B1C4632
S113202CA0F12002102A1CD8DFE802F0091B1B0CBB
S113203C1B1B1B0F1B1B1B121B151B1B180046F019
S113204C4006E9E746F08006E6E746F40046E3E797
S113205C46F02006E0E746F01006DDE746F400768D
S113206CDAE72A2808D0A0F13002D2B2092A88BFB4
S113207C4FF0000A11D920E0039B03F104000390F4
S113208CD3F800A0BAF1000FBCBFCAF1000A46F0A5
S113209C1006487801F102040FE04FF0000A0AEB35
S11320AC8A0AA0F1300000EB4A0A13F8010B1C4613
S11320BCA0F13002D2B2092AF1D92AEAEA7A2E28FE
S11320CC18BF4FF000082DD120782A280AD004F12B
S11320DC0104A0F13003DBB2092B88BF4FF00008D8
S11320EC0AD91DE0039B03F104020392D3F8008088
S11320FC607804F1020410E023464FF0000808EB6A
S113210C8808A0F1300000EB480813F8010B1C46BA
S113211CA0F13002D2B2092AF1D9B8F1000F01DBD7
S113212C46F4807668280AD12078682803BF46F0E4
S113213C080660780234013418BF46F00406782887
S113214C7AD8DFE810F02E02790079007900790052
S113215C79007900790079007900790079007900A7
S113216C7900790079007900790079007900790097
S113217C7900790079007900790079007900790087
S113218C7900790079007900790079007900790077
S113219C8A00790079007900790079007900790056
S11321AC7900790079007900790079007900790057
S11321BC7900790079007900790079007900790047
S11321CC7900790079007900790079007900790037
S11321DC7900790079007900790079007900790027
S11321EC7900790079007900790079007900790017
S11321FC790079007900EE00790079007900790092
S113220C79007900790079007900790090001A013D
S113221C79007900790079001A0179007900790044
S113222C7900AB000201DB0079007900B70079007A
S113223C110179007900F00040F21073C2F200032E
S113224C1D68002D00F09F81CDF8008003AB019335
S113225C394632465346A84795E138464FF0250196
S113226C00F07CFC8FE1039B03F1040203921D78C4
S113227C0AF1FF3A304651463A4600F09DFC384686
S113228C294600F06BFC16F0100F00F07C814FF027
S113229C200051463A4600F07DFC74E116F0080F1C
S11322AC039B03F1040203921B683A6814BF1A706F
S11322BC1A6068E1039B03F104020392D3F80090C3
S11322CC484600F0C9FC05468045ACBF00230123F9
S11322DC03EA1623002B18BF4546C5EB0A0A304601
S11322EC51463A4600F068FC002DCCD019F8011B7D
S11322FC384600F033FC013DF8D1C4E7039B03F1ED
S113230C040203921B6806F08009B9F1000F14BF94
S113231C4FF023094FF0000946F480764FF008087B
S113232C69E046F4005643F2780343F258097828DE
S113233C08BF994616F0800F08BF4FF0000916F439
S113234C807F18BF26F400761EE006F08009B9F1F0
S113235C000F14BF4FF030094FF0000916F4807FC2
S113236C18BF26F400760FE016F4807F1CBF26F409
S113237C00764FF0000907D104E046F480464FF094
S113238C000901E04FF0000916F4804F1DD0039BA7
S113239C03F1040203921B6816F0040F18BF1BB25E
S11323AC03D116F0080F18BFDBB2002BBCBF5B4285
S11323BC4FF02D091ADB06F04002002A18BF4FF02B
S11323CC200916F0200F11D00EE0039B03F1040238
S11323DC03921B6816F0040F18BF9BB206D116F0BB
S11323EC080F18BFDBB201E04FF02B0916F4807F05
S11323FC04D026F4007616F4807F01D14FF0010846
S113240CA0F15800202870D8DFE800F0196F6F6F26
S113241C6F6F6F6F6F6F6F6F156F6F6F6F156F6F70
S113242C6F6F6F11196F6F6F6F156F6F19004FF01E
S113243C00050BBB5BE04FF0000553BB57E04FF0BE
S113244C0005002B53D04FF0000506F40052DDF8C4
S113245C08E032B103F00F011EF8010004A968541E
S113246C05E003F00F011BF8010004A9685405F101
S113247C01051B09EDD13AE04FF0000503F007010B
S113248C01F1300104AAA95405F10105DB08F5D1C9
S113249C2DE04FF0000506F4004C4CF6CD4ECCF676
S11324ACCC4E6246A446144654B105F00302032AEA
S11324BC01BF07A842192C2102F80C1C08BF0135D6
S11324CC07AA5119AEFB03024FEAD20202EB8200B7
S11324DCA3EB400303F1300301F80C3C05F10105B7
S11324EC1346002AE0D1644601E04FF00005C5EB29
S11324FC080828EAE878C8EB0A0AC5EB0A0AB9F115
S113250CFF0F88BF0AF1FF3AB9F1000F01D00AF1AD
S113251CFF3A16F4007F06D1304651463A4600F095
S113252C4BFB4FF0000AB9F1FF0F04D9C9F3072193
S113253C384600F013FBB9F1000F04D05FFA89F1AF
S113254C384600F00BFB304651463A4600F034FB5B
S113255C4FF0300041463A4600F01CFB012D09D4E3
S113256C0DF11008454415F8011D384600F0F6FA33
S113257C4545F8D116F0100F05D04FF02000514608
S113258C3A4600F007FB217800297FF43AADBB688A
S113259C2BB13A6879688A423CBF00219954386857
S11325AC01E04FF0FF3007B0BDE8F08F10B50446E2
S11325BC0B783BB1B0F1FF3F06D04B6803F1FF330E
S11325CC4B6001E08B689847204610BD2DE9F04F15
S11325DC82468B4617469846099E4FF0FF3900E019
S11325ECA94609F10105504600F0A4FA044600F08E
S11325FC27FB0028F4D12346B4F1FF3F08BF4FF06A
S113260CFF3500F09C8027F4C067002E4EDD17F0D8
S113261C800F0DD02B2C03D02D2C09D147F48067BF
S113262C09F10205504600F085FA044606F1FF361E
S113263C302C14BF00230123002ED4BF002303F03D
S113264C0103002B32D047F4007706F1FF3605F175
S113265C0109504600F06EFA0446002E20DD58287D
S113266C14BF00230123782808BF43F00103BBB136
S113267CB8F1100F14BF00230123B8F1000F08BFE9
S113268C43F0010363B127F4007706F1FF3605F13B
S113269C0209504600F04EFA04464FF0100851E07F
S11326ACB8F1000F08BF4FF008084BE0B8F1000F69
S11326BC08BF4FF00A08002ED8BF4FF000090EDCFB
S11326CC15E047F4007706F1FF3608FB090905F11C
S11326DC0105504600F02EFA044616B907E04FF0F7
S11326EC00092046414600F08DFA0028E9DA20461C
S11326FC5146FFF75BFF17F4007F08BF6FF001052D
S113270C1DD017F0010F1AD1DBF8003003F10402CD
S113271CCBF800201B6807F49062B2F5906F08BFE9
S113272CC9F1000917F0100F18BF83F8009006D1F7
S113273C17F0080F14BFA3F80090C3F800902846B4
S113274CBDE8F08F4D46B6E72DE9F04F85B001900A
S113275C8A4604924FF0000BCDF808B04CF6CC49E5
S113276CC0F6CC49544614F8015B002D00F0DE8110
S113277C252D3BD0284600F063FA08B918E02C4606
S113278C04F10105207800F05BFA0028F7D101E090
S113279C0BF1010B019800F0CDF9054600F050FA4D
S11327AC0028F5D128460199FFF700FFA246D9E786
S11327BC019800F0BFF90646A84203D10BF1010BB6
S11327CCA246CFE70199FFF7F1FE029AD2F1010379
S11327DC38BF0023B6F1FF3F14BF002603F00106F7
S11327EC002E18BF4FF0FF3202929FE19AF801308D
S11327FC2A2B06BF0AF102044FF001084FF000081F
S113280C4FF000050CE04D4500F3908105EB850578
S113281CA6F1300616EB450500F1888148F0200836
S113282C274604F101043E78A246304600F0E2F952
S113283C0028E8D1414608F02002002A08BF6FF0B6
S113284C00454C2E05D17E7807F1020A48F0440865
S113285C0EE0682E0CD17E78682E03BF48F0100869
S113286CBE7807F1030A07F1020A18BF41F0080801
S113287CA6F12506532E00F25981DFE816F0540018
S113288C5701570157015701570157015701570178
S113289C5701570157015701570157015701570168
S11328AC5701570157015701570157015701570158
S11328BC5701570157015701570157015701570148
S11328CC5701570157015701570157015701570138
S11328DC5701570157015701570157015701570128
S11328EC570157013301570157015701570157013C
S11328FC5701570157015701570170009F005701A9
S113290C570157015701AA005701570157015701A5
S113291CB500CD00D80057015701E3005701280139
S113292C570157013301019800F004F90446252896
S113293C02D10BF1010B15E70199FFF737FE029A4F
S113294C131C18BF0123B4F1FF3F0CBF1C4643F00A
S113295C0104002C08BF4FF0FF320292E6E008F0AD
S113296C2003002B08BF012518F0010401BF049BB0
S113297C1A1D04921E6818BF0026002D00F0D68084
S113298C002D13DD019800F0D5F8B0F1FF3F06D10E
S113299C029B002B08BF4FF0FF330293C6E00CB927
S11329AC06F8010B0BF1010B013DEBD1002C7FF46C
S11329BCD9AE029B03F101030293D3E648F08002E3
S11329CC0095019804A94FF00A03FFF7FFFD044694
S11329DC92E048F080020095019804A94FF000039E
S11329ECFFF7F4FD044687E018F0010F7FF4BAAE4C
S11329FC049B03F1040204921B6818F0100F18BF17
S1132A0C83F800B07FF4AEAE18F0080F14BFA3F82F
S1132A1C00B0C3F800B0A5E648F080020095019818
S1132A2C04A94FF00803FFF7D1FD044664E028F035
S1132A3C1E020095019804A94FF01003FFF7C6FD80
S1132A4C044659E04FF0FF3404F10104019800F0FE
S1132A5C71F8064600F0F4F80028F5D1B6F1FF3F02
S1132A6C08BF4FF0FF3447D018F0010701BF049B97
S1132A7C1A1D04921B680EBF039300220392002DAF
S1132A8C16DC1AE005F1FF351FB9039B03F8016B43
S1132A9C039304F10104019800F04CF80646431C1E
S1132AAC18BF0123002DD4BF002303F0010323B16D
S1132ABC304600F0C5F80028E4D030460199FFF701
S1132ACC75FDCFB94FF00002039B1A7014E048F067
S1132ADC80020095019804A94FF00A03FFF776FDD4
S1132AEC044609E048F080020095019804A94FF0CF
S1132AFC1003FFF76BFD0446002C0FDA029A131C2B
S1132B0C18BF0123B4F1FF3F0CBF1C4643F0010472
S1132B1C002C08BF4FF0FF32029207E018F0010FAF
S1132B2C02BF029B01330293A3441BE6029805B037
S1132B3CBDE8F08F00B5034602783AB142681078CC
S1132B4C40B102F101025A605DF804FB43689847F6
S1132B5C5DF804FB4FF0FF305DF804FB30B5044620
S1132B6CC8B2A16849B12368626803F101059542B2
S1132B7C08BF0020934238BFC854E3682BB12168C6
S1132B8C6268914201D221469847236803F10103FC
S1132B9C236030BDF0B5154601290BD40E464FF019
S1132BAC0004C7B228463946FFF7D8FF04F10104E4
S1132BBCB442F7D1F0BD00BF00B510F0100F07D12F
S1132BCC00F4007000280CBF20203020FFF7E2FF37
S1132BDC5DF804FBA0F1410019288CBF00200120F2
S1132BEC704700BFA0F1610019288CBF00200120A0
S1132BFC704700BFA0F1300009288CBF00200120D1
S1132C0C704700BF30B504460D46FFF7F3FF10B113
S1132C1CA4F130000FE02046FFF7E4FF10B1A4F15B
S1132C2C570008E02046FFF7D5FF10B1A4F1370098
S1132C3C01E04FF0FF30A842A8BF4FF0FF3030BD89
S1132C4CA0F10903202814BF00200120042B98BFF5
S1132C5C40F00100704700BF00F1010110F0030FB8
S1132C6C11D010F8012B002A23D010F0030F0AD036
S1132C7C10F8012B002A1CD010F0030F03D010F80D
S1132C8C012B002A15D02DE970004FF001324FF0C2
S1132C9C803350F8044BA4EB020525EA04051D40CF
S1132CAC00D1F6E7A0F1040070BC10F8012B002A47
S1132CBCFBD1A0EB0100704700B503B400F008F899
S1132CCC03BC02B4694609BE00F004F801BC00BDA3
S10B2CDC704700BF704700BF00
S1132CE4443A2F7573722F6665617365722F736F1F
S1132CF46674776172652F4F70656E424C542F541D
S1132D0461726765742F44656D6F2F41524D434D55
S1132D14335F45464D33325F4F6C696D65785F456B
S1132D244D3332473838304631323853544B5F438D
S1132D34726F7373776F726B732F426F6F742F6933
S1132D4464652F2E2E2F2E2E2F2E2E2F2E2E2F5304
S1132D546F757263652F41524D434D335F45464D44
S1132D6433322F43726F7373776F726B732F76657D
S1132D7463746F72732E630000400000002000002F
S1132D8402000000006000000020000003000000B6
S1132D9400800000002000000400000000A00000E7
S1132DA4002000000500000000C000000020000016
S1132DB40600000000E000000020000007000000FE
S1132DC400000100002000000800000000200100B1
S1132DD40020000009000000004001000020000061
S1132DE40A00000000600100002000000B00000045
S1132DF400800100002000000C00000000A001007D
S1132E04002000000D00000000C0010000200000AC
S1132E140E00000000E00100002000000F0000008C
S1132E2405000000000000008025000000000000F0
S1132E340000000000000000443A2F7573722F66EE
S1132E4465617365722F736F6674776172652F4F52
S1132E5470656E424C542F5461726765742F4465D7
S1132E646D6F2F41524D434D335F45464D33325FB1
S1132E744F6C696D65785F454D3332473838304659
S1132E8431323853544B5F43726F7373776F726B81
S1132E94732F426F6F742F6964652F2E2E2F2E2E7D
S1132EA42F2E2E2F2E2E2F536F757263652F4152A2
S1132EB44D434D335F45464D33322F756172742E45
S1132EC4630000004F70656E424C5400303132335D
S1132ED43435363738396162636465663031323388
S10F2EE434353637383941424344454602
S1132EF04FF00003C4F20C039A6842F001029A6096
S1132F0018614FF00102DA60DB6913F0040F0AD094
S1132F104FF00003C4F20C039A6822F001029A6095
S1132F204FF0FF3070474FF00003C4F20C03DB692D
S1132F3013F0020F0AD04FF00003C4F20C039A6896
S1132F4022F001029A606FF0010070474FF0000315
S1132F50C4F20C034FF00202DA60DB6913F0010FD4
S1132F601CD049F28063C0F298034FF00001C4F210
S1132F700C0103F1FF33CA6912F0010F02D0002BD8
S1132F80F7D100E053B94FF00003C4F20C039A6880
S1132F9022F001029A606FF0020070474FF00003C4
S1132FA0C4F20C039A6822F001029A604FF0000008
S1132FB0704700BF2DE9F0074FF00003C4F20C0383
S1132FC09C6844F001049C604FEAA207002F40F380
S1132FD08C8080464FF00003C4F20C0318614FF05C
S1132FE00102DA60DB6913F0040F21D14FF0000312
S1132FF0C4F20C03DB6913F0020F33D14FF0040465
S11330004FF0000A55465246C4F20C0249F280665B
S1133010C0F298064FF0080C4FF001091BE004EBD6
S113302008031361C2F80C90D36913F0040F0AD09B
S11330304FF00003C4F20C039A6822F001029A6074
S11330404FF0FF305BE0D36904F1040013F0020F8A
S113305008D1A2460446D36913F0080F08BF3346CB
S11330600BD01FE04FF00003C4F20C039A6822F067
S113307001029A606FF0010041E003F1FF33D0696F
S113308010F0080F02D1002BF7D100E053B94FF034
S11330900003C4F20C039A6822F001029A606FF0F4
S11330A002002CE051F80A309361C2F80CC0D369D5
S11330B013F0010F15D0334603F1FF33D06910F03C
S11330C0010F02D0002BF7D100E053B94FF00003F9
S11330D0C4F20C039A6822F001029A606FF00200B5
S11330E00DE005F10105BD4299D14FF00003C4F292
S11330F00C039A6822F001029A604FF00000BDE8C8
S1073100F007704719
S10B3104008000000048E8010E
S9030155A6

View File

@ -0,0 +1,108 @@
/****************************************************************************************
| Description: bootloader configuration header file
| File Name: config.h
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
#ifndef CONFIG_H
#define CONFIG_H
/****************************************************************************************
* C P U D R I V E R C O N F I G U R A T I O N
****************************************************************************************/
/* To properly initialize the baudrate clocks of the communication interface, typically
* the speed of the crystal oscillator and/or the speed at which the system runs is
* needed. Set these through configurables BOOT_CPU_XTAL_SPEED_KHZ and
* BOOT_CPU_SYSTEM_SPEED_KHZ, respectively. To enable data exchange with the host that is
* not dependent on the targets architecture, the byte ordering needs to be known.
* Setting BOOT_CPU_BYTE_ORDER_MOTOROLA to 1 selects little endian mode and 0 selects
* big endian mode.
*/
#define BOOT_CPU_XTAL_SPEED_KHZ (32000)
#define BOOT_CPU_SYSTEM_SPEED_KHZ (14000)
#define BOOT_CPU_BYTE_ORDER_MOTOROLA (0)
/****************************************************************************************
* C O M M U N I C A T I O N I N T E R F A C E C O N F I G U R A T I O N
****************************************************************************************/
/* The UART communication interface is selected by setting the BOOT_COM_UART_ENABLE
* configurable to 1. Configurable BOOT_COM_UART_BAUDRATE selects the communication speed
* in bits/second. The maximum amount of data bytes in a message for data transmission
* and reception is set through BOOT_COM_UART_TX_MAX_DATA and BOOT_COM_UART_RX_MAX_DATA,
* respectively. It is common for a microcontroller to have more than 1 UART interface
* on board. The zero-based BOOT_COM_UART_CHANNEL_INDEX selects the UART interface.
*
*/
#define BOOT_COM_UART_ENABLE (1)
#define BOOT_COM_UART_BAUDRATE (9600)
#define BOOT_COM_UART_TX_MAX_DATA (64)
#define BOOT_COM_UART_RX_MAX_DATA (64)
#define BOOT_COM_UART_CHANNEL_INDEX (1)
/****************************************************************************************
* B A C K D O O R E N T R Y C O N F I G U R A T I O N
****************************************************************************************/
/* It is possible to implement an application specific method to force the bootloader to
* stay active after a reset. Such a backdoor entry into the bootloader is desired in
* situations where the user program does not run properly and therefore cannot
* reactivate the bootloader. By enabling these hook functions, the application can
* implement the backdoor, which overrides the default backdoor entry that is programmed
* into the bootloader. When desired for security purposes, these hook functions can
* also be implemented in a way that disables the backdoor entry altogether.
*/
#define BOOT_BACKDOOR_HOOKS_ENABLE (0)
/****************************************************************************************
* N O N - V O L A T I L E M E M O R Y D R I V E R C O N F I G U R A T I O N
****************************************************************************************/
/* The NVM driver typically supports erase and program operations of the internal memory
* present on the microcontroller. Through these hook functions the NVM driver can be
* extended to support additional memory types such as external flash memory and serial
* eeproms. The size of the internal memory in kilobytes is specified with configurable
* BOOT_NVM_SIZE_KB.
*/
#define BOOT_NVM_HOOKS_ENABLE (0)
#define BOOT_NVM_SIZE_KB (128)
/****************************************************************************************
* W A T C H D O G D R I V E R C O N F I G U R A T I O N
****************************************************************************************/
/* The COP driver cannot be configured internally in the bootloader, because its use
* and configuration is application specific. The bootloader does need to service the
* watchdog in case it is used. When the application requires the use of a watchdog,
* set BOOT_COP_HOOKS_ENABLE to be able to initialize and service the watchdog through
* hook functions.
*/
#define BOOT_COP_HOOKS_ENABLE (0)
#endif /* CONFIG_H */
/*********************************** end of config.h ***********************************/

View File

@ -0,0 +1,179 @@
/****************************************************************************************
| Description: bootloader callback source file
| File Name: hooks.c
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "boot.h" /* bootloader generic header */
/****************************************************************************************
* B A C K D O O R E N T R Y H O O K F U N C T I O N S
****************************************************************************************/
#if (BOOT_BACKDOOR_HOOKS_ENABLE > 0)
/****************************************************************************************
** NAME: BackDoorInitHook
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Initializes the backdoor entry option.
**
****************************************************************************************/
void BackDoorInitHook(void)
{
} /*** end of BackDoorInitHook ***/
/****************************************************************************************
** NAME: BackDoorEntryHook
** PARAMETER: none
** RETURN VALUE: BLT_TRUE if the backdoor entry is requested, BLT_FALSE otherwise.
** DESCRIPTION: Checks if a backdoor entry is requested.
**
****************************************************************************************/
blt_bool BackDoorEntryHook(void)
{
/* default implementation always activates the bootloader after a reset */
return BLT_TRUE;
} /*** end of BackDoorEntryHook ***/
#endif /* BOOT_BACKDOOR_HOOKS_ENABLE > 0 */
/****************************************************************************************
* N O N - V O L A T I L E M E M O R Y D R I V E R H O O K F U N C T I O N S
****************************************************************************************/
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/****************************************************************************************
** NAME: NvmInitHook
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Callback that gets called at the start of the internal NVM driver
** initialization routine.
**
****************************************************************************************/
void NvmInitHook(void)
{
} /*** end of NvmInitHook ***/
/****************************************************************************************
** NAME: NvmWriteHook
** PARAMETER: addr start address
** len length in bytes
** data pointer to the data buffer.
** RETURN VALUE: BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
** not within the supported memory range, or BLT_NVM_ERROR is the write
** operation failed.
** DESCRIPTION: Callback that gets called at the start of the NVM driver write
** routine. It allows additional memory to be operated on. If the address
** is not within the range of the additional memory, then
** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the data hasn't
** been written yet.
**
**
****************************************************************************************/
blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data)
{
return BLT_NVM_NOT_IN_RANGE;
} /*** end of NvmWriteHook ***/
/****************************************************************************************
** NAME: NvmEraseHook
** PARAMETER: addr start address
** len length in bytes
** RETURN VALUE: BLT_NVM_OKAY if successful, BLT_NVM_NOT_IN_RANGE if the address is
** not within the supported memory range, or BLT_NVM_ERROR is the erase
** operation failed.
** DESCRIPTION: Callback that gets called at the start of the NVM driver erase
** routine. It allows additional memory to be operated on. If the address
** is not within the range of the additional memory, then
** BLT_NVM_NOT_IN_RANGE must be returned to indicate that the memory
** hasn't been erased yet.
**
****************************************************************************************/
blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len)
{
return BLT_NVM_NOT_IN_RANGE;
} /*** end of NvmEraseHook ***/
/****************************************************************************************
** NAME: NvmDoneHook
** PARAMETER: none
** RETURN VALUE: BLT_TRUE is successful, BLT_FALSE otherwise.
** DESCRIPTION: Callback that gets called at the end of the NVM programming session.
**
****************************************************************************************/
blt_bool NvmDoneHook(void)
{
return BLT_TRUE;
} /*** end of NvmDoneHook ***/
#endif /* BOOT_NVM_HOOKS_ENABLE > 0 */
/****************************************************************************************
* W A T C H D O G D R I V E R H O O K F U N C T I O N S
****************************************************************************************/
#if (BOOT_COP_HOOKS_ENABLE > 0)
/****************************************************************************************
** NAME: CopInitHook
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Callback that gets called at the end of the internal COP driver
** initialization routine. It can be used to configure and enable the
** watchdog.
**
****************************************************************************************/
void CopInitHook(void)
{
} /*** end of CopInitHook ***/
/****************************************************************************************
** NAME: CopServiceHook
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Callback that gets called at the end of the internal COP driver
** service routine. This gets called upon initialization and during
** potential long lasting loops and routine. It can be used to service
** the watchdog to prevent a watchdog reset.
**
****************************************************************************************/
void CopServiceHook(void)
{
} /*** end of CopServiceHook ***/
#endif /* BOOT_COP_HOOKS_ENABLE > 0 */
/*********************************** end of hooks.c ************************************/

View File

@ -0,0 +1,137 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="EFM32G880_crossworks" target="8" version="2">
<project Name="openbtl_olimex_efm32g880">
<configuration Name="Common" Target="EFM32G880F128" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_heap_size="128" arm_linker_process_stack_size="0" arm_linker_stack_size="128" arm_long_calls="Yes" arm_simulator_memory_simulation_filename="$(TargetsDir)/EFM32/EFM32SimulatorMemory.dll" arm_simulator_memory_simulation_parameter="EFM32G880F128;FLASH=0x00000000:0x20000;RAM=0x20000000:0x4000" arm_target_debug_interface_type="ADIv5" arm_target_interface_type="SWD" arm_target_loader_parameter="16000000" build_intermediate_directory="$(Configuration)/../../obj" build_output_directory="$(Configuration)/../../bin" c_preprocessor_definitions="USE_PROCESS_STACK" c_user_include_directories="$(ProjectDir)/..;$(ProjectDir)/../lib/CMSIS/CM3/CoreSupport;$(ProjectDir)/../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32;$(ProjectDir)/../lib/efm32lib/inc;$(ProjectDir)/../../../../Source;$(ProjectDir)/../../../../Source/ARMCM3_EFM32;$(ProjectDir)/../../../../Source/ARMCM3_EFM32/Crossworks" gcc_optimization_level="Level 1" link_include_startup_code="No" linker_additional_files="" linker_memory_map_file="$(TargetsDir)/EFM32/EFM32G880F128_MemoryMap.xml" linker_output_format="srec" oscillator_frequency="Other" project_directory="" project_type="Executable" property_groups_file_path="$(TargetsDir)/EFM32/EFM32_propertyGroups.xml"/>
<configuration Name="Flash" Placement="Flash" arm_target_flash_loader_file_path="$(TargetsDir)/EFM32/Release/Loader_rpc.elf" arm_target_flash_loader_type="LIBMEM RPC Loader" linker_section_placement_file="$(StudioDir)/targets/Cortex_M/flash_placement.xml" target_reset_script="FLASHReset()"/>
<configuration Name="RAM" Placement="RAM" linker_section_placement_file="$(StudioDir)/targets/Cortex_M/ram_placement.xml" target_reset_script="SRAMReset()"/>
<folder Name="Source Files">
<configuration Name="Common" filter="c;cpp;cxx;cc;h;s;asm;inc"/>
<folder Name="Source">
<folder Name="ARMCM3_EFM32">
<folder Name="Crossworks">
<file file_name="../../../../Source/ARMCM3_EFM32/Crossworks/cstart.s"/>
<file file_name="../../../../Source/ARMCM3_EFM32/Crossworks/vectors.c"/>
</folder>
<file file_name="../../../../Source/ARMCM3_EFM32/cpu.c"/>
<file file_name="../../../../Source/ARMCM3_EFM32/cpu.h"/>
<file file_name="../../../../Source/ARMCM3_EFM32/flash.c"/>
<file file_name="../../../../Source/ARMCM3_EFM32/flash.h"/>
<file file_name="../../../../Source/ARMCM3_EFM32/nvm.c"/>
<file file_name="../../../../Source/ARMCM3_EFM32/nvm.h"/>
<file file_name="../../../../Source/ARMCM3_EFM32/timer.c"/>
<file file_name="../../../../Source/ARMCM3_EFM32/timer.h"/>
<file file_name="../../../../Source/ARMCM3_EFM32/types.h"/>
<file file_name="../../../../Source/ARMCM3_EFM32/uart.c"/>
<file file_name="../../../../Source/ARMCM3_EFM32/uart.h"/>
</folder>
<file file_name="../../../../Source/assert.c"/>
<file file_name="../../../../Source/assert.h"/>
<file file_name="../../../../Source/backdoor.c"/>
<file file_name="../../../../Source/backdoor.h"/>
<file file_name="../../../../Source/boot.c"/>
<file file_name="../../../../Source/boot.h"/>
<file file_name="../../../../Source/com.c"/>
<file file_name="../../../../Source/com.h"/>
<file file_name="../../../../Source/cop.c"/>
<file file_name="../../../../Source/cop.h"/>
<file file_name="../../../../Source/plausibility.h"/>
<file file_name="../../../../Source/xcp.c"/>
<file file_name="../../../../Source/xcp.h"/>
</folder>
<folder Name="Demo">
<folder Name="Boot">
<folder Name="Lib">
<folder Name="Cmsis">
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cm3.c"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cm3.h"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cmFunc.h"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cmInstr.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32g880f128.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.h"/>
</folder>
<folder Name="Efm32lib">
<file file_name="../lib/efm32lib/inc/efm32_acmp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_adc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_aes.h"/>
<file file_name="../lib/efm32lib/inc/efm32_assert.h"/>
<file file_name="../lib/efm32lib/inc/efm32_bitband.h"/>
<file file_name="../lib/efm32lib/inc/efm32_chip.h"/>
<file file_name="../lib/efm32lib/inc/efm32_cmu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_common.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dac.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dbg.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dma.h"/>
<file file_name="../lib/efm32lib/inc/efm32_ebi.h"/>
<file file_name="../lib/efm32lib/inc/efm32_emu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_gpio.h"/>
<file file_name="../lib/efm32lib/inc/efm32_i2c.h"/>
<file file_name="../lib/efm32lib/inc/efm32_int.h"/>
<file file_name="../lib/efm32lib/inc/efm32_lcd.h"/>
<file file_name="../lib/efm32lib/inc/efm32_lesense.h"/>
<file file_name="../lib/efm32lib/inc/efm32_letimer.h"/>
<file file_name="../lib/efm32lib/inc/efm32_leuart.h"/>
<file file_name="../lib/efm32lib/inc/efm32_mpu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_msc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_opamp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_pcnt.h"/>
<file file_name="../lib/efm32lib/inc/efm32_prs.h"/>
<file file_name="../lib/efm32lib/inc/efm32_rmu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_rtc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_system.h"/>
<file file_name="../lib/efm32lib/inc/efm32_timer.h"/>
<file file_name="../lib/efm32lib/inc/efm32_usart.h"/>
<file file_name="../lib/efm32lib/inc/efm32_vcmp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_wdog.h"/>
<file file_name="../lib/efm32lib/src/efm32_acmp.c"/>
<file file_name="../lib/efm32lib/src/efm32_adc.c"/>
<file file_name="../lib/efm32lib/src/efm32_aes.c"/>
<file file_name="../lib/efm32lib/src/efm32_assert.c"/>
<file file_name="../lib/efm32lib/src/efm32_cmu.c"/>
<file file_name="../lib/efm32lib/src/efm32_dac.c"/>
<file file_name="../lib/efm32lib/src/efm32_dbg.c"/>
<file file_name="../lib/efm32lib/src/efm32_dma.c"/>
<file file_name="../lib/efm32lib/src/efm32_ebi.c"/>
<file file_name="../lib/efm32lib/src/efm32_emu.c"/>
<file file_name="../lib/efm32lib/src/efm32_gpio.c"/>
<file file_name="../lib/efm32lib/src/efm32_i2c.c"/>
<file file_name="../lib/efm32lib/src/efm32_int.c"/>
<file file_name="../lib/efm32lib/src/efm32_lcd.c"/>
<file file_name="../lib/efm32lib/src/efm32_lesense.c"/>
<file file_name="../lib/efm32lib/src/efm32_letimer.c"/>
<file file_name="../lib/efm32lib/src/efm32_leuart.c"/>
<file file_name="../lib/efm32lib/src/efm32_mpu.c"/>
<file file_name="../lib/efm32lib/src/efm32_msc.c"/>
<file file_name="../lib/efm32lib/src/efm32_opamp.c"/>
<file file_name="../lib/efm32lib/src/efm32_pcnt.c"/>
<file file_name="../lib/efm32lib/src/efm32_prs.c"/>
<file file_name="../lib/efm32lib/src/efm32_rmu.c"/>
<file file_name="../lib/efm32lib/src/efm32_rtc.c"/>
<file file_name="../lib/efm32lib/src/efm32_system.c"/>
<file file_name="../lib/efm32lib/src/efm32_timer.c"/>
<file file_name="../lib/efm32lib/src/efm32_usart.c"/>
<file file_name="../lib/efm32lib/src/efm32_vcmp.c"/>
<file file_name="../lib/efm32lib/src/efm32_wdog.c"/>
</folder>
</folder>
<file file_name="../config.h"/>
<file file_name="../hooks.c"/>
<file file_name="../main.c"/>
</folder>
</folder>
</folder>
<folder Name="System Files">
<file file_name="$(TargetsDir)/EFM32/EFM32_Target.js">
<configuration Name="Common" file_type="Reset Script"/>
</file>
<file file_name="../../../../Source/ARMCM3_EFM32/Crossworks/memory.x">
<configuration Name="Common" file_type="Linker Script"/>
</file>
</folder>
</project>
<configuration Name="THUMB Flash Debug" inherited_configurations="THUMB;Flash;Debug"/>
<configuration Name="THUMB" Platform="ARM" arm_instruction_set="THUMB" arm_library_instruction_set="THUMB" c_preprocessor_definitions="__THUMB" hidden="Yes"/>
<configuration Name="Flash" c_preprocessor_definitions="__FLASH_BUILD" hidden="Yes"/>
<configuration Name="Debug" build_debug_information="Yes" c_preprocessor_definitions="DEBUG" gcc_optimization_level="None" hidden="Yes" link_include_startup_code="No"/>
</solution>

View File

@ -0,0 +1,64 @@
<!DOCTYPE CrossStudio_for_ARM_Session_File>
<session>
<Bookmarks/>
<Breakpoints/>
<ETMWindow>
<ETMRegister number="0" value="800" />
<ETMRegister number="8" value="6f" />
<ETMRegister number="9" value="1000000" />
</ETMWindow>
<ExecutionCountWindow/>
<Memory1>
<MemoryWindow autoEvaluate="0" addressText="0x4000" numColumns="8" sizeText="128" dataSize="1" radix="16" addressSpace="" />
</Memory1>
<Memory2>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory2>
<Memory3>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory3>
<Memory4>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory4>
<Project>
<ProjectSessionItem path="EFM32G880_crossworks" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;openbtl_olimex_efm32g880" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;openbtl_olimex_efm32g880;Source Files" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;openbtl_olimex_efm32g880;Source Files;Source" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;openbtl_olimex_efm32g880;Source Files;Source;ARMCM3_EFM32" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;openbtl_olimex_efm32g880;Source Files;Source;ARMCM3_EFM32;Crossworks" name="unnamed" />
</Project>
<Register1>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register1>
<Register2>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register2>
<Register3>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register3>
<Register4>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register4>
<TargetWindow programAction="" uploadFileType="" programLoadAddress="" programSize="" uploadFileName="" uploadMemoryInterface="" programFileName="" uploadStartAddress="" programFileType="" uploadSize="" programMemoryInterface="" />
<TraceWindow>
<Trace enabled="Yes" />
</TraceWindow>
<Watch1>
<Watches active="1" update="Never" />
</Watch1>
<Watch2>
<Watches active="0" update="Never" />
</Watch2>
<Watch3>
<Watches active="0" update="Never" />
</Watch3>
<Watch4>
<Watches active="0" update="Never" />
</Watch4>
<Files>
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="D:\usr\feaser\software\OpenBLT\Target\Demo\ARMCM3_EFM32_Olimex_EM32G880F128STK_Crossworks\Boot\main.c" y="72" path="D:\usr\feaser\software\OpenBLT\Target\Demo\ARMCM3_EFM32_Olimex_EM32G880F128STK_Crossworks\Boot\main.c" left="0" selected="0" name="unnamed" top="36" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="D:\usr\feaser\software\OpenBLT\Target\Source\ARMCM3_EFM32\uart.c" y="37" path="D:\usr\feaser\software\OpenBLT\Target\Source\ARMCM3_EFM32\uart.c" left="0" selected="1" name="unnamed" top="15" />
</Files>
<ARMCrossStudioWindow activeProject="openbtl_olimex_efm32g880" autoConnectTarget="Olimex ARM-USB-TINY" debugSearchFileMap="" fileDialogInitialDirectory="D:\usr\feaser\software\OpenBLT\Target\Source\ARMCM3_EFM32\Crossworks" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
</session>

View File

@ -0,0 +1,4 @@
Integrated Development Environment
----------------------------------
Rowleys CrossWorks was used as the editor during the development of this software program. This directory contains
the CrossWorks project and solution files. More info is available at: http://www.rowley.co.uk/

View File

@ -0,0 +1,339 @@
/**************************************************************************//**
* @file core_cm3.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V2.00
* @date 13. September 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ########################## Core Instruction Access ######################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __CLREX(void)
{
clrex
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
/* ########################### Core Function Access ########################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_IPSR(void)
{
mrs r0, ipsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_APSR(void)
{
mrs r0, apsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_xPSR(void)
{
mrs r0, xpsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask Register.
\return Fault Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set the Fault Mask
This function assigns the given value to the Fault Mask Register.
\param [in] faultMask Fault Mask value value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif

View File

@ -0,0 +1,851 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H__
#define __CORE_CMFUNC_H__
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_CONTROL(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_CONTROL(uint32_t control);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_IPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_APSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_xPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PSP(uint32_t topOfProcStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_MSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_MSP(uint32_t topOfMainStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PRIMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PRIMASK(uint32_t priMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_BASEPRI(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_BASEPRI(uint32_t basePri);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_FAULTMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_FAULTMASK(uint32_t faultMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & 1);
}
#endif /* __ARMCC_VERSION */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
/* Energy Micro: Add support for new versions of IAR */
#if __VER__ >= 6020000
#include "cmsis_iar.h"
#else
/* Energy Micro: Fix end */
#include <intrinsics.h> /* IAR Intrinsics */
#pragma diag_suppress=Pe940
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_irq __enable_interrupt
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_irq __disable_interrupt
/* intrinsic unsigned long __get_CONTROL( void ); (see intrinsic.h) */
/* intrinsic void __set_CONTROL( unsigned long ); (see intrinsic.h) */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
static uint32_t __get_IPSR(void)
{
__ASM("mrs r0, ipsr");
}
/* Energy Micro: This function is present in new IAR versions */
#if __VER__ < 6010002
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
static uint32_t __get_APSR(void)
{
__ASM("mrs r0, apsr");
}
#endif
/* Energy Micro: Fix end */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
static uint32_t __get_xPSR(void)
{
__ASM("mrs r0, psr"); // assembler does not know "xpsr"
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
static uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
static void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
static uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
static void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
}
/* intrinsic unsigned long __get_PRIMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_PRIMASK( unsigned long ); (see intrinsic.h) */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __enable_fault_irq(void)
{
__ASM ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __disable_fault_irq(void)
{
__ASM ("cpsid f");
}
/* intrinsic unsigned long __get_BASEPRI( void ); (see intrinsic.h) */
/* intrinsic void __set_BASEPRI( unsigned long ); (see intrinsic.h) */
/* intrinsic unsigned long __get_FAULTMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_FAULTMASK(unsigned long); (see intrinsic.h) */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
__ASM("vmrs r0, fpscr");
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM("vmsr fpscr, r0");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#pragma diag_default=Pe940
#endif
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile ("MRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H__ */

View File

@ -0,0 +1,782 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H__
#define __CORE_CMINSTR_H__
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern uint32_t __REV16(uint32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern int32_t __REVSH(int32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
extern void __CLREX(void);
#else /* (__ARMCC_VERSION >= 400000) */
#define __CLREX __clrex
#endif /* __ARMCC_VERSION */
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
/* Energy Micro: Add support for new versions of IAR */
#if __VER__ >= 6020000
#include "cmsis_iar.h"
#else
/* Energy Micro: Adpaptation end */
#include <intrinsics.h> /* IAR Intrinsics */
#pragma diag_suppress=Pe940
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __no_operation
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
static __INLINE void __WFI(void)
{
__ASM ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
static __INLINE void __WFE(void)
{
__ASM ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
static __INLINE void __SEV(void)
{
__ASM ("sev");
}
/* intrinsic void __ISB(void) (see intrinsics.h) */
/* intrinsic void __DSB(void) (see intrinsics.h) */
/* intrinsic void __DMB(void) (see intrinsics.h) */
/* intrinsic uint32_t __REV(uint32_t value) (see intrinsics.h) */
/* intrinsic __SSAT (see intrinsics.h) */
/* intrinsic __USAT (see intrinsics.h) */
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __REV16(uint32_t value)
{
__ASM("rev16 r0, r0");
}
/* intrinsic uint32_t __REVSH(uint32_t value) (see intrinsics.h */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
static uint8_t __LDREXB(volatile uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
static uint16_t __LDREXH(volatile uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
/* intrinsic unsigned long __LDREX(unsigned long *) (see intrinsics.h) */
static uint32_t __LDREXW(volatile uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
/* intrinsic unsigned long __STREX(unsigned long, unsigned long) (see intrinsics.h )*/
static uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
static __INLINE void __CLREX(void)
{
__ASM ("clrex");
}
/* intrinsic unsigned char __CLZ( unsigned long ) (see intrinsics.h) */
#endif /* (__CORTEX_M >= 0x03) */
#pragma diag_default=Pe940
#endif
/* Energy Micro: Fix end */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H__ */

View File

@ -0,0 +1,526 @@
/**************************************************************************//**
* @file
* @brief CMSIS Cortex-M0/M3 Peripheral Access Layer for EFM32 device series
*
* This is a convenience header file for defining the EFM32 part number on the
* build command line, instead of specifying the part specific header file.
* @verbatim
* Example: Add "-DEFM32G890F128" to your build options, to define part
* Add "#include "efm32.h" to your source files
* @endverbatim
* @author Energy Micro AS
* @version 2.3.2
******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#ifndef __EFM32_H
#define __EFM32_H
#if defined(EFM32G200F16)
#include "efm32g200f16.h"
#elif defined(EFM32G200F32)
#include "efm32g200f32.h"
#elif defined(EFM32G200F64)
#include "efm32g200f64.h"
#elif defined(EFM32G210F128)
#include "efm32g210f128.h"
#elif defined(EFM32G222F128)
#include "efm32g222f128.h"
#elif defined(EFM32G222F32)
#include "efm32g222f32.h"
#elif defined(EFM32G222F64)
#include "efm32g222f64.h"
#elif defined(EFM32G230F128)
#include "efm32g230f128.h"
#elif defined(EFM32G230F32)
#include "efm32g230f32.h"
#elif defined(EFM32G230F64)
#include "efm32g230f64.h"
#elif defined(EFM32G232F128)
#include "efm32g232f128.h"
#elif defined(EFM32G232F32)
#include "efm32g232f32.h"
#elif defined(EFM32G232F64)
#include "efm32g232f64.h"
#elif defined(EFM32G280F128)
#include "efm32g280f128.h"
#elif defined(EFM32G280F32)
#include "efm32g280f32.h"
#elif defined(EFM32G280F64)
#include "efm32g280f64.h"
#elif defined(EFM32G290F128)
#include "efm32g290f128.h"
#elif defined(EFM32G290F32)
#include "efm32g290f32.h"
#elif defined(EFM32G290F64)
#include "efm32g290f64.h"
#elif defined(EFM32G840F128)
#include "efm32g840f128.h"
#elif defined(EFM32G840F32)
#include "efm32g840f32.h"
#elif defined(EFM32G840F64)
#include "efm32g840f64.h"
#elif defined(EFM32G842F128)
#include "efm32g842f128.h"
#elif defined(EFM32G842F32)
#include "efm32g842f32.h"
#elif defined(EFM32G842F64)
#include "efm32g842f64.h"
#elif defined(EFM32G880F128)
#include "efm32g880f128.h"
#elif defined(EFM32G880F32)
#include "efm32g880f32.h"
#elif defined(EFM32G880F64)
#include "efm32g880f64.h"
#elif defined(EFM32G890F128)
#include "efm32g890f128.h"
#elif defined(EFM32G890F32)
#include "efm32g890f32.h"
#elif defined(EFM32G890F64)
#include "efm32g890f64.h"
#elif defined(EFM32GG230F1024)
#include "efm32gg230f1024.h"
#elif defined(EFM32GG230F512)
#include "efm32gg230f512.h"
#elif defined(EFM32GG232F1024)
#include "efm32gg232f1024.h"
#elif defined(EFM32GG232F512)
#include "efm32gg232f512.h"
#elif defined(EFM32GG280F1024)
#include "efm32gg280f1024.h"
#elif defined(EFM32GG280F512)
#include "efm32gg280f512.h"
#elif defined(EFM32GG290F1024)
#include "efm32gg290f1024.h"
#elif defined(EFM32GG290F512)
#include "efm32gg290f512.h"
#elif defined(EFM32GG295F1024)
#include "efm32gg295f1024.h"
#elif defined(EFM32GG295F512)
#include "efm32gg295f512.h"
#elif defined(EFM32GG330F1024)
#include "efm32gg330f1024.h"
#elif defined(EFM32GG330F512)
#include "efm32gg330f512.h"
#elif defined(EFM32GG332F1024)
#include "efm32gg332f1024.h"
#elif defined(EFM32GG332F512)
#include "efm32gg332f512.h"
#elif defined(EFM32GG380F1024)
#include "efm32gg380f1024.h"
#elif defined(EFM32GG380F512)
#include "efm32gg380f512.h"
#elif defined(EFM32GG390F1024)
#include "efm32gg390f1024.h"
#elif defined(EFM32GG390F512)
#include "efm32gg390f512.h"
#elif defined(EFM32GG395F1024)
#include "efm32gg395f1024.h"
#elif defined(EFM32GG395F512)
#include "efm32gg395f512.h"
#elif defined(EFM32GG840F1024)
#include "efm32gg840f1024.h"
#elif defined(EFM32GG840F512)
#include "efm32gg840f512.h"
#elif defined(EFM32GG842F1024)
#include "efm32gg842f1024.h"
#elif defined(EFM32GG842F512)
#include "efm32gg842f512.h"
#elif defined(EFM32GG880F1024)
#include "efm32gg880f1024.h"
#elif defined(EFM32GG880F512)
#include "efm32gg880f512.h"
#elif defined(EFM32GG890F1024)
#include "efm32gg890f1024.h"
#elif defined(EFM32GG890F512)
#include "efm32gg890f512.h"
#elif defined(EFM32GG895F1024)
#include "efm32gg895f1024.h"
#elif defined(EFM32GG895F512)
#include "efm32gg895f512.h"
#elif defined(EFM32GG940F1024)
#include "efm32gg940f1024.h"
#elif defined(EFM32GG940F512)
#include "efm32gg940f512.h"
#elif defined(EFM32GG942F1024)
#include "efm32gg942f1024.h"
#elif defined(EFM32GG942F512)
#include "efm32gg942f512.h"
#elif defined(EFM32GG980F1024)
#include "efm32gg980f1024.h"
#elif defined(EFM32GG980F512)
#include "efm32gg980f512.h"
#elif defined(EFM32GG990F1024)
#include "efm32gg990f1024.h"
#elif defined(EFM32GG990F512)
#include "efm32gg990f512.h"
#elif defined(EFM32GG995F1024)
#include "efm32gg995f1024.h"
#elif defined(EFM32GG995F512)
#include "efm32gg995f512.h"
#elif defined(EFM32LG230F128)
#include "efm32lg230f128.h"
#elif defined(EFM32LG230F256)
#include "efm32lg230f256.h"
#elif defined(EFM32LG230F64)
#include "efm32lg230f64.h"
#elif defined(EFM32LG232F128)
#include "efm32lg232f128.h"
#elif defined(EFM32LG232F256)
#include "efm32lg232f256.h"
#elif defined(EFM32LG232F64)
#include "efm32lg232f64.h"
#elif defined(EFM32LG280F128)
#include "efm32lg280f128.h"
#elif defined(EFM32LG280F256)
#include "efm32lg280f256.h"
#elif defined(EFM32LG280F64)
#include "efm32lg280f64.h"
#elif defined(EFM32LG290F128)
#include "efm32lg290f128.h"
#elif defined(EFM32LG290F256)
#include "efm32lg290f256.h"
#elif defined(EFM32LG290F64)
#include "efm32lg290f64.h"
#elif defined(EFM32LG295F128)
#include "efm32lg295f128.h"
#elif defined(EFM32LG295F256)
#include "efm32lg295f256.h"
#elif defined(EFM32LG295F64)
#include "efm32lg295f64.h"
#elif defined(EFM32LG330F128)
#include "efm32lg330f128.h"
#elif defined(EFM32LG330F256)
#include "efm32lg330f256.h"
#elif defined(EFM32LG330F64)
#include "efm32lg330f64.h"
#elif defined(EFM32LG332F128)
#include "efm32lg332f128.h"
#elif defined(EFM32LG332F256)
#include "efm32lg332f256.h"
#elif defined(EFM32LG332F64)
#include "efm32lg332f64.h"
#elif defined(EFM32LG380F128)
#include "efm32lg380f128.h"
#elif defined(EFM32LG380F256)
#include "efm32lg380f256.h"
#elif defined(EFM32LG380F64)
#include "efm32lg380f64.h"
#elif defined(EFM32LG390F128)
#include "efm32lg390f128.h"
#elif defined(EFM32LG390F256)
#include "efm32lg390f256.h"
#elif defined(EFM32LG390F64)
#include "efm32lg390f64.h"
#elif defined(EFM32LG395F128)
#include "efm32lg395f128.h"
#elif defined(EFM32LG395F256)
#include "efm32lg395f256.h"
#elif defined(EFM32LG395F64)
#include "efm32lg395f64.h"
#elif defined(EFM32LG840F128)
#include "efm32lg840f128.h"
#elif defined(EFM32LG840F256)
#include "efm32lg840f256.h"
#elif defined(EFM32LG840F64)
#include "efm32lg840f64.h"
#elif defined(EFM32LG842F128)
#include "efm32lg842f128.h"
#elif defined(EFM32LG842F256)
#include "efm32lg842f256.h"
#elif defined(EFM32LG842F64)
#include "efm32lg842f64.h"
#elif defined(EFM32LG880F128)
#include "efm32lg880f128.h"
#elif defined(EFM32LG880F256)
#include "efm32lg880f256.h"
#elif defined(EFM32LG880F64)
#include "efm32lg880f64.h"
#elif defined(EFM32LG890F128)
#include "efm32lg890f128.h"
#elif defined(EFM32LG890F256)
#include "efm32lg890f256.h"
#elif defined(EFM32LG890F64)
#include "efm32lg890f64.h"
#elif defined(EFM32LG895F128)
#include "efm32lg895f128.h"
#elif defined(EFM32LG895F256)
#include "efm32lg895f256.h"
#elif defined(EFM32LG895F64)
#include "efm32lg895f64.h"
#elif defined(EFM32LG940F128)
#include "efm32lg940f128.h"
#elif defined(EFM32LG940F256)
#include "efm32lg940f256.h"
#elif defined(EFM32LG940F64)
#include "efm32lg940f64.h"
#elif defined(EFM32LG942F128)
#include "efm32lg942f128.h"
#elif defined(EFM32LG942F256)
#include "efm32lg942f256.h"
#elif defined(EFM32LG942F64)
#include "efm32lg942f64.h"
#elif defined(EFM32LG980F128)
#include "efm32lg980f128.h"
#elif defined(EFM32LG980F256)
#include "efm32lg980f256.h"
#elif defined(EFM32LG980F64)
#include "efm32lg980f64.h"
#elif defined(EFM32LG990F128)
#include "efm32lg990f128.h"
#elif defined(EFM32LG990F256)
#include "efm32lg990f256.h"
#elif defined(EFM32LG990F64)
#include "efm32lg990f64.h"
#elif defined(EFM32LG995F128)
#include "efm32lg995f128.h"
#elif defined(EFM32LG995F256)
#include "efm32lg995f256.h"
#elif defined(EFM32LG995F64)
#include "efm32lg995f64.h"
#elif defined(EFM32TG108F16)
#include "efm32tg108f16.h"
#elif defined(EFM32TG108F32)
#include "efm32tg108f32.h"
#elif defined(EFM32TG108F4)
#include "efm32tg108f4.h"
#elif defined(EFM32TG108F8)
#include "efm32tg108f8.h"
#elif defined(EFM32TG110F16)
#include "efm32tg110f16.h"
#elif defined(EFM32TG110F32)
#include "efm32tg110f32.h"
#elif defined(EFM32TG110F4)
#include "efm32tg110f4.h"
#elif defined(EFM32TG110F8)
#include "efm32tg110f8.h"
#elif defined(EFM32TG210F16)
#include "efm32tg210f16.h"
#elif defined(EFM32TG210F32)
#include "efm32tg210f32.h"
#elif defined(EFM32TG210F8)
#include "efm32tg210f8.h"
#elif defined(EFM32TG222F16)
#include "efm32tg222f16.h"
#elif defined(EFM32TG222F32)
#include "efm32tg222f32.h"
#elif defined(EFM32TG222F8)
#include "efm32tg222f8.h"
#elif defined(EFM32TG230F16)
#include "efm32tg230f16.h"
#elif defined(EFM32TG230F32)
#include "efm32tg230f32.h"
#elif defined(EFM32TG230F8)
#include "efm32tg230f8.h"
#elif defined(EFM32TG232F16)
#include "efm32tg232f16.h"
#elif defined(EFM32TG232F32)
#include "efm32tg232f32.h"
#elif defined(EFM32TG232F8)
#include "efm32tg232f8.h"
#elif defined(EFM32TG822F16)
#include "efm32tg822f16.h"
#elif defined(EFM32TG822F32)
#include "efm32tg822f32.h"
#elif defined(EFM32TG822F8)
#include "efm32tg822f8.h"
#elif defined(EFM32TG840F16)
#include "efm32tg840f16.h"
#elif defined(EFM32TG840F32)
#include "efm32tg840f32.h"
#elif defined(EFM32TG840F8)
#include "efm32tg840f8.h"
#elif defined(EFM32TG842F16)
#include "efm32tg842f16.h"
#elif defined(EFM32TG842F32)
#include "efm32tg842f32.h"
#elif defined(EFM32TG842F8)
#include "efm32tg842f8.h"
#else
#error "efm32.h: PART NUMBER undefined"
#endif
#endif

View File

@ -0,0 +1,369 @@
/***************************************************************************//**
* @file
* @brief CMSIS Cortex-M3 Peripheral Access Layer for EFM32 devices.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdint.h>
#include "efm32.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
/* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFXO_FREQ
#ifdef _EFM32_GIANT_FAMILY
#define EFM32_HFXO_FREQ (48000000UL)
#else
#define EFM32_HFXO_FREQ (32000000UL)
#endif
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
ret = SystemHFClockGet();
#if defined (_EFM32_GIANT_FAMILY)
/* Leopard/Giant Gecko has an additional divider */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)>>_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
/* Keep CMSIS variable up-to-date just in case */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
{
case CMU_STATUS_LFXOSEL:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_STATUS_LFRCOSEL:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_STATUS_HFXOSEL:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_STATUS_HFRCOSEL */
switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
{
case CMU_HFRCOCTRL_BAND_28MHZ:
ret = 28000000;
break;
case CMU_HFRCOCTRL_BAND_21MHZ:
ret = 21000000;
break;
case CMU_HFRCOCTRL_BAND_14MHZ:
ret = 14000000;
break;
case CMU_HFRCOCTRL_BAND_11MHZ:
ret = 11000000;
break;
case CMU_HFRCOCTRL_BAND_7MHZ:
ret = 7000000;
break;
case CMU_HFRCOCTRL_BAND_1MHZ:
ret = 1000000;
break;
default:
ret = 0;
break;
}
break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_HFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_LFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}

View File

@ -0,0 +1,215 @@
/***************************************************************************//**
* @file
* @brief CMSIS Cortex-M3 Peripheral Access Layer for EFM32 devices.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __SYSTEM_EFM32_H
#define __SYSTEM_EFM32_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
extern uint32_t SystemCoreClock; /**< System Clock Frequency (Core Clock) */
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/* Interrupt routines - prototypes */
#if defined(_EFM32_GECKO_FAMILY)
void Reset_Handler(void);
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA_IRQHandler(void);
void GPIO_EVEN_IRQHandler(void);
void TIMER0_IRQHandler(void);
void USART0_RX_IRQHandler(void);
void USART0_TX_IRQHandler(void);
void ACMP0_IRQHandler(void);
void ADC0_IRQHandler(void);
void DAC0_IRQHandler(void);
void I2C0_IRQHandler(void);
void GPIO_ODD_IRQHandler(void);
void TIMER1_IRQHandler(void);
void TIMER2_IRQHandler(void);
void USART1_RX_IRQHandler(void);
void USART1_TX_IRQHandler(void);
void USART2_RX_IRQHandler(void);
void USART2_TX_IRQHandler(void);
void UART0_RX_IRQHandler(void);
void UART0_TX_IRQHandler(void);
void LEUART0_IRQHandler(void);
void LEUART1_IRQHandler(void);
void LETIMER0_IRQHandler(void);
void PCNT0_IRQHandler(void);
void PCNT1_IRQHandler(void);
void PCNT2_IRQHandler(void);
void RTC_IRQHandler(void);
void CMU_IRQHandler(void);
void VCMP_IRQHandler(void);
void LCD_IRQHandler(void);
void MSC_IRQHandler(void);
void AES_IRQHandler(void);
#endif
#if defined(_EFM32_TINY_FAMILY)
void Reset_Handler(void);
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA_IRQHandler(void);
void GPIO_EVEN_IRQHandler(void);
void TIMER0_IRQHandler(void);
void USART0_RX_IRQHandler(void);
void USART0_TX_IRQHandler(void);
void ACMP0_IRQHandler(void);
void ADC0_IRQHandler(void);
void DAC0_IRQHandler(void);
void I2C0_IRQHandler(void);
void GPIO_ODD_IRQHandler(void);
void TIMER1_IRQHandler(void);
void USART1_RX_IRQHandler(void);
void USART1_TX_IRQHandler(void);
void LESENSE_IRQHandler(void);
void LEUART0_IRQHandler(void);
void LETIMER0_IRQHandler(void);
void PCNT0_IRQHandler(void);
void RTC_IRQHandler(void);
void CMU_IRQHandler(void);
void VCMP_IRQHandler(void);
void LCD_IRQHandler(void);
void MSC_IRQHandler(void);
void AES_IRQHandler(void);
#endif
#if defined(_EFM32_GIANT_FAMILY)
void Reset_Handler(void);
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA_IRQHandler(void);
void GPIO_EVEN_IRQHandler(void);
void TIMER0_IRQHandler(void);
void USART0_RX_IRQHandler(void);
void USART0_TX_IRQHandler(void);
void USB_IRQHandler(void);
void ACMP0_IRQHandler(void);
void ADC0_IRQHandler(void);
void DAC0_IRQHandler(void);
void I2C0_IRQHandler(void);
void I2C1_IRQHandler(void);
void GPIO_ODD_IRQHandler(void);
void TIMER1_IRQHandler(void);
void TIMER2_IRQHandler(void);
void TIMER3_IRQHandler(void);
void USART1_RX_IRQHandler(void);
void USART1_TX_IRQHandler(void);
void LESENSE_IRQHandler(void);
void USART2_RX_IRQHandler(void);
void USART2_TX_IRQHandler(void);
void UART0_RX_IRQHandler(void);
void UART0_TX_IRQHandler(void);
void UART1_RX_IRQHandler(void);
void UART1_TX_IRQHandler(void);
void LEUART0_IRQHandler(void);
void LEUART1_IRQHandler(void);
void LETIMER0_IRQHandler(void);
void PCNT0_IRQHandler(void);
void PCNT1_IRQHandler(void);
void PCNT2_IRQHandler(void);
void RTC_IRQHandler(void);
void BURTC_IRQHandler(void);
void CMU_IRQHandler(void);
void VCMP_IRQHandler(void);
void LCD_IRQHandler(void);
void MSC_IRQHandler(void);
void AES_IRQHandler(void);
void EBI_IRQHandler(void);
void EMU_IRQHandler(void);
#endif
uint32_t SystemCoreClockGet(void);
/**************************************************************************//**
* @brief
* Update CMSIS SystemCoreClock variable.
*
* @details
* CMSIS defines a global variable SystemCoreClock that shall hold the
* core frequency in Hz. If the core frequency is dynamically changed, the
* variable must be kept updated in order to be CMSIS compliant.
*
* Notice that if only changing core clock frequency through the EFM32 CMU
* API, this variable will be kept updated. This function is only provided
* for CMSIS compliance and if a user modifies the the core clock outside
* the CMU API.
*****************************************************************************/
static __INLINE void SystemCoreClockUpdate(void)
{
SystemCoreClockGet();
}
void SystemInit(void);
uint32_t SystemHFClockGet(void);
uint32_t SystemHFXOClockGet(void);
void SystemHFXOClockSet(uint32_t freq);
uint32_t SystemLFRCOClockGet(void);
uint32_t SystemULFRCOClockGet(void);
uint32_t SystemLFXOClockGet(void);
void SystemLFXOClockSet(uint32_t freq);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_EFM32_H */

View File

@ -0,0 +1,154 @@
================ Revision history ============================================
2.3.2:
- Fixed IAR startup files, corrected alignment of interrupt vector table
- Updated efm32usb library with fixes
- Updated efm32lib with new Tiny Gecko and Giant Gecko features
2.3.0:
- Added DEVICE_FAMILY defines to identify Gecko/Tiny/Leopard/Giant parts
- Fixed missing EMU_IRQ definitions in Leopard Gecko startup files
- Added USART location to Tiny Gecko parts
- Added LEUART locations to Tiny Gecko parts
- Updated efm32lib with new Giant Gecko features (see separate readme)
- Updated efm32usb with USB Host stack support (see separate readme)
2.2.2:
- Removed huge AF_PORT, AF_PIN macros from header files, only peripheral
specific alternate function defines are included
- Updated efm32usb library with fixes
- Updated efm32lib library with fixes
2.2.1:
- Added interleave to all Giant Gecko parts
- Updated efm32lib with more Giant Gecko features
- Added efm32usb, USB Device stack for Giant Gecko USB parts
- Added LOCATION defines for all I2C alternate locations on Tiny Gecko
2.1.1:
- Added header files for Giant Gecko and Leopard Gecko devices
- Minor fix for Gecko devices, EMU_CTRL_MASK was wrong
- Fix for linker issue alignment of .data section in codesourcery .ld files
2.0.1:
- DAC_OPAnMUX_POSSEL_OPAnIN changed to DAC_OPAnMUX_POSSEL_OPAnINP for Tiny
Gecko
- Added CMU_ROUTE_LOCATION, LOC2 for Tiny Gecko
- PRS #define fixes, remove extra IRDA fields only available on USART0
2.0.0:
- This release based on CMSIS_2_00, includes DSP_Lib (for Keil MDKARM, IAR has
a port included with EWARM)
- Removed "shadow" example that used to be in CMSIS directory earlier, use
"blink" from board examples as starting point instead
- Restructured header files to comply with CMSIS_2_00
- CMU_CALCTRL_REFSEL is renamed to CMU_CALCTRL_UPSEL to match reference
manual and clearify new DOWNSEL calibrartion features for Tiny Gecko
- Added header files for new package types for Gecko devices
- Added header files for Tiny Gecko devices
1.3.0:
- DMA register WAITSTATUS changed to CHWAITSTATUS for consistency
DMA test req/sreq registers added, CHSREQSTATUS and CHREQSTATUS
- IFS and IFC interrupt registers are now marked as readable for several
peripherals
- TIMER, CCC renamed to CDTI
- TIMER, QEM has been renamed to QDM
- AF_DBG_SWV/TCLK/TDIO renamed to more commonly used AF_DBG_SWD/SWDIO/SWDCLK
- AF_EBI_ADDRDAT renamed to AF_EBI_AD
- Removed bit fields for extra LCD segment registers for Gecko parts
- Fixed LCD_SEGEN_MASK, bit width was too narrow in version 1.2.x
- Fixed LCD_SYNCBUSY bit fields
- CMU_PCNTCTRL reset values corrected
- PCNT_TOP and PCNT_TOPB reset values corrected
- ADC_LPFMODE_RCFILT and LPFMOD_DECAP definitions corrected (they were
reversed)
- USART_RXDATAFULLRIGHT and USART_RXDATAVRIGHT removed for Gecko parts
- GPIO, renamed INSENSE_PRSSENSE to INSENSE_PRS, similar for INT
to be consistent with updated documentation (Reference Manual)
1.2.1:
- Fixed DEVINFO calibration shift and mask value for temperature sensor
fixed in rev.C Gecko devices
1.2.0:
- Added new subgroup "Parts" for all part definitions in doxygen format
- Removed unused _PARAM_ type definitions, less clutter in header files
- _CMU_PCNTCTRL_RESETVALUE corrected
- Added C startup file for IAR, can be used as replacement for assembly file
- Use #defines instead of "numeric values reentered" in bit field definitions
- TIMER_PARAM_CCNUM(i) changed to TIMER_PARAM_CC_NUM(i)
- DPI_CHAN_COUNT changed to PRS_CHAN_COUNT
1.1.4:
- TIMER_INIT_DEFAULT fix to efm32lib
1.1.3:
- Removed ADC ROUTE register
- Renamed DEVINFO DACCAL -> DAC0CAL for all 3 calibration registers and bit
fields
- Updated efm32lib with new peripherals
1.1.2:
- Added support for CodeSourcery Sourcery G++ compiler and startup files
- Device Information page (DEVINFO_TypeDef) - fixed several issues with
endianness, and other changes to support test revision 4 and above parts.
This has led to a small incompatibilty with test rev <= 4 and rev A parts,
in that the flash and sram size bit fields has changed location.
- DMA_CONTROL_TypeDef changed name to DMA_DESCRIPTOR_TypeDef to be better
aligned with PL230 manual and code
- DMA bit fields not supported on EFM32 was removed for the PL230 controller
- DMA CTRL bit fields renamed to be more consistent with PL230 TRM manual
- Added additional volatile statements to pointers in DMA Control structure
- Fixed several registers that were readable, and was marked as __O (output
only)
1.1.1:
- Fixed startup code, CMSIS SystemInit cannot update global variable
1.1.0:
- Note - some register bit field updates in this release are _not_ backward
compatible
- Updated register bit fields to comply with documentation updates, i.e.
reference manual version > 0.83
- Apply patch to CMSIS core for GCC issues
- Added DMA_CONTROL_TypeDef control block for PrimeCell PL230 DMA controller
- Added ROMTABLE PID / CHIP revision table and masks
- Revised and updated Device Information page structure "DEVINFO page"
This structure is ONLY valid for rev.B production devices
- GPIO EXTIPSEL bit field marked "16" changed to 15 (bug correction)
- Added more bit fields to TIMER_ROUTE registers
- Cosmetic updates in doxygen comments and copyright statements
1.0.4:
- ACMP INPUTSEL bit fields changed from ohm rating to res-n,
- Added bit-band base addresses for peripherals and sram
1.0.3:
- ADC SCANMODE and SCANCTRL bit field updates and corrections
- Moved Readme.txt and Changes.txt to CMSIS/Readme-EFM32.txt and
CMSIS/Changes-EFM32.txt
- CCPEN and CDTIPEN splitted in TIMER_ROUTE
- EMVREG in EMU_CTRL enumeration changed
- LCD DISPCTRL volatage levels are part specific, changed settings changed to
reflect this
- Added "UL" (unsigned long) to some bit fields giving warnings due to sign
conversion
1.0.2:
- Corrected revision numbers in file headers
- Removed example code that was moved into BSP/DVK installer package
1.0.1:
- Updated to use official CMSIS1V30 release
- Corrected IRQ vector table in assembly startup files, IMEM to MSC,
UDMA to DMA
- DMA peripheral/signal names corrected
- Example Blinky application updated to work on all EFM32 MCU-Modules on DVK
- Added "simple" board support package to example
- Added "UL" (unsigned long) tag to several fields
1.0.0:
- Initial release
- Includes CMSIS1V30 2nd PreRelease
- Now requires two include paths, CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32 and
CMSIS/CM3/CoreSupport

View File

@ -0,0 +1,39 @@
* -------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* Date: 30 November 2010
* Revision: V2.00
*
* Project: Cortex Microcontroller Software Interface Standard (CMSIS)
* Title: Release Note for CMSIS
*
* -------------------------------------------------------------------
NOTE - Open the index.html file to access CMSIS documentation
The Cortex Microcontroller Software Interface Standard (CMSIS) provides a single standard across all
Cortex-Mx processor series vendors. It enables code re-use and code sharing across software projects
and reduces time-to-market for new embedded applications.
CMSIS is released under the terms of the end user license agreement ("CMSIS END USER LICENCE AGREEMENT.pdf").
Any user of the software package is bound to the terms and conditions of the end user license agreement.
You will find the following sub-directories:
CM0 - CMSIS Core Support and Device Support package for Cortex-M0.
CM3 - CMSIS Core Support and Device Support package for Cortex-M3.
CM4 - CMSIS Core Support and Device Support package for Cortex-M4.
Documentation - Contains CMSIS documentation.
DSP_Lib - MDK project files, Examples and source files etc.. to build the
CMSIS DSP Software Library for Cortex-M3 and Cortex-M4 processors.
Template_DeviceSupport - Template files for CMSIS Device Support package.
---

View File

@ -0,0 +1,85 @@
================ EFM32 Device Support Library (DSL) ==========================
This directory ,"CMSIS", contains the Energy Micro Support Library for the
EFM32 series of microcontrollers.
================ About CMSIS =================================================
The library is based on CMSIS, the Cortex Microcontroller Software Interface
Standard, as defined by ARM Inc.
For more information about CMSIS see
http://www.onarm.com
http://www.arm.com/products/CPUs/CMSIS.html
In short, CMSIS tries to provide a common interface for programming devices
having one of the Cortex-M core architectures, making code sharing and reuse
easier.
================ Development Environments ====================================
You will need a development environment which supports the Energy Micro EFM32
devices. Currently this is either
IAR Embedded Workbench for ARM 5.40.6 or later, http://www.iar.com
Keil uVision "MDK-ARM" 4.01 or later, http://www.keil.com
Rowley CodeSourcery for ARM v2.0.5 or later, see http://www.rowley.co.uk
Codesourcery Sourcery G++, see http://www.codesourcery.com
It is possible to develop with other tools, but for now these are the well
supported development environment for Energy Micro example code.
This library uses C99-types, requires the presence of <stdint.h> and can use
other functionality standardized in C99. If your compiler has a C99 compliance
toggle, you should enable it for your projects.
================ File structure ==============================================
Short getting started guide:
The quickest way to start is to base your work on one of the simple example
projects for the Energy Micro Development or Stareter Kits. These should be
easy to port and change to adopt to your needs.
The board support packages for the various Energy Micro kits comes with a
"blink" example, that serves as a good starting point for new projects.
Please note that you _will_ need to change the "Debugger" and "Flash/Download"
configuration settings to fit your environment. See your IDE's manual for
details.
Support for the EFM32 device family is located in the directory
CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32
The most convenient way to start a project, is to define the device target
in your compiler options, e.g. add a -DEFM32G890F128 to your compile options
if you are targetting an EFM32G890F128 part.
When this is done, you should include the file "efm32.h" wherever you need
register and bit field definitions for the EFM32 peripherals.
The peripheral registers follow the CMSIS convention of defining a structure
which holds the "volatile" registers. Again, take a look at the examples for
usage.
================ Licenses ====================================================
See the top of each file for SW license. Basically you are free to use the
Energy Micro code for any project using EFM32 devices. Part of the CMSIS
library is copyrighted by ARM Inc. See "License.doc" for ARM's CMSIS license.
================ Software updates ============================================
Energy Micro continually works to provide updated and improved DSL, example
code and other software of use for EFM32 customers. Please check the download
section of
http://www.energymicro.com/downloads
for the latest releases, news and updates.
(C) Copyright Energy Micro AS, 2011

View File

@ -0,0 +1,145 @@
================ Revision history ============================================
2.3.2:
- Added Tiny Gecko and Giant Gecko support in RMU for new reset causes
- CMU_ClockFreqGet will now report correct clock rates if HFLE is set (/4)
- Added Giant Gecko specific MSC_MassErase(), erase entire flash
- Added Giant Gecko specific MSC_BusStrategy (inline) function
- MSC_Init() will now configure TIMEBASE correctly according to AUXHFRCO clock
rate for Tiny Gecko and Giant Gecko
2.3.0:
- USART - Added USART_InitPrsTrigger to initialize USART PRS triggered
transmissions.
- CMU - numerous updates, now supports full clock tree of Giant/Tiny Gecko
- CMU_ClockDivSet/Get will now use real dividend and not logarithmic values
as earlier. Prior enumerated values have been kept for backward compatibility.
- Added support for CMU HFLE and DIV4 factor for core clock for LE
peripherals
- Added support for alternate LCD segment animation range for Giant Gecko
- Fixed bug: Don't enable VCMP low power reference until after warm up,
allow biasprog value of 0 in VCMP_Init()
- Added support for ALTMAP (256MB address map) in EBI_BankAddress()
- TIMER_Init() will now reset CNT value
2.2.2:
- Added DAC0 channel 0 and 1 to ACMP for Tiny and Giant devices
- Fixed bug in CMU for MSC WAITSTATE configuration, leading to too high wait
states depending on clock rate
- Fixed bug in CMU for UART1 clock enable
2.2.1:
- UART_Reset() and LEUART_Reset() will now reset ROUTE register as well, this
will mean GPIO pins will not be driven after this call. Take care to ensure
that GPIO ROUTE register is configured after calls to *UART_Init*Sync
- Fixed problems with EFM_ASSERT when using UART in USART API
- Added Giant Gecko support for EBI (new modes and TFT direct drive)
- Added Giant Gecko support for CMU 2 WAIT STATES, and I2C1
- Added Giant Gecko support for UART1 in CMU
- Added Giant Gecko support for DMA LOOP and 2D Copy operations
2.1.0:
- EMU_Restore will now disable HFRCO if it was not enabled when entering
an Energy Mode
- Run time changes only applies to Gecko devices, filter out Tiny and Giant
for CHIP_Init();
- Added const specificers to various initialization structures, to ensure
they can reside in flash instead of SRAM
- Bugfix in efm32_i2c.c, keep returning i2cTransferInProgress until done
2.0.1:
- Changed enum OPAMP_PosSel_TypeDef. Enum value opaPosSelOpaIn changed from
DAC_OPA0MUX_POSSEL_OPA1IN to DAC_OPA0MUX_POSSEL_OPA0INP.
- Bugfix in efm32_lesense.h, LESENSE_ChClk_TypeDef now contains unshifted
values, fixed the implementation in efm32_lesense.c where the bug prevented
the sampleClk to be set to AUXHFRCO.
2.0.0:
- USART_Init-functions now calls USART_Reset() which will also disable/reset
interrupt
- USART_BaudrateSyncSet() now asserts on invalid oversample configuration
- Added initialization of parity bit in LEUART_Init()
- Added Tiny Gecko support for CMU, ULFRCO, LESENSE clocks and continuous
calibration
- Added Tiny Gecko support for GPIO, EM4 pin retention and wake up support
- Added Tiny Gecko support for I2S, SPI auto TX mode on USART
- Added Tiny Gecko support for CACHE mesasurements for MSC module
- Added Tiny Gecko support for LCD module (with no HIGH segment registers)
- Added Tiny Gecko support for TIMER, PWM 2x, (DT lock not supported)
- Added Tiny Gecko support for LESENSE module
- Added Tiny Gecko support for PRS input in PCNT
- Added Tiny Gecko support for async signals in PRS, PRS_SourceAsyncSignalSet()
- Initial support for some Giant Gecko features, where overlapping with Tiny
- Removed LPFEN / LPFREQ support from DAC
- Fixed comments around interrupt functions, making it clear it is bitwise
logical or interrupt flags
- Fixed PCNT initialization for external clock configurations, making sure
config is synchronized at startup to 3 clocks. Note fix only works for
>revC EFM32G devices.
- Fixed efm32_cmu.c, EFM_ASSERT statement for LEUART clock div logic was
inverted
- Fixed ADC_InitScan, PRSSEL shift value corrected
- Fixed CMU_ClockFreqGet for devices that do not have I2C
- Fixed I2C_TransferInit for devices with more than one I2C-bus (Giant Gecko)
- Changed ACMP_Disable() implementation, now only disables the ACMP instance
by clearing the EN bit in the CTRL register
- Removed ACMP_DisableNoReset() function
- Fixed ACMP_Init(), removed automatic enabling, added new structure member
"enaReq" for ACMP_Init_TypeDef to control, fixed the EFM_ASSERT of the
biasprog parameter
- Added default configuration macro ACMP_INIT_DEFAULT for ACMP_Init_TypeDef
- Fixed ACMP_CapsenseInit(), removed automatic enabling, added new structure member
"enaReq" for ACMP_CapsenseInit_TypeDef to control, fixed the EFM_ASSERT of
the biasprog parameter
- Changed the name of the default configuration macro for
ACMP_CapsenseInit_TypeDef to ACMP_CAPSENSE_INIT_DEFAULT
- Added RTC_Reset and RTC_CounterReset functions for RTC
1.3.0:
- MSC is automatically enabled/disabled when using the MSC API. This saves
power, and reduces errors due to not calling MSC_Init().
- Added API for controlling Cortex-M3 MPU (memory protection unit)
- Adjusted bit fields to comply with latest CMSIS release, see EFM_CMSIS
changes file for details
- Fixed issue with bit mask clearing in ACMP
- Functions ACMP_Enable and ACMP_DisableNoReset added
- Added comment about rev.C chips in PCNT, CMD_LTOPBIM not neccessary any more
- Added missing instance validity asserts to peripherals (ACMP, LEUART, USART)
- Fixed UART0 check in CMU_ClockFreqGet()
- Fixed command sync for PCNT before setting TOPB value during init
- Fixed instance validity check macro in PCNT
- Fixed TIMER_Reset() removed write to unimplemented timer channel registers
- Fixed EFM_ASSERT statements in ACMP, VCMP
- General code style update: added missing curly braces, default cases, etc.
1.2.1:
- Feature complete efm32lib, now also includes peripheral API for modules
AES,PCNT,MSC,ACMP,VCMP,LCD,EBI
- Fixed _TIMER_CC_CTRL_ICEDGE flags for correct timer configuration
- Fixed ADC calibration of Single and Scan mode of operation
- Added PCNT (ChipRev A/B PCNT0 errata NOT supported) and AES support
- Fixed conditional inclusion in efm32_emu.h
- Fixed code for LEUART0 for devices with multiple LEUARTs.
- Fixed incorrect setting of DOUT for GPIO configuration
1.1.4
- Fix for TIMER_INIT_DEFAULT
1.1.3:
- Added ADC, DAC, LETIMER, PRS, TIMER (except DTI) support
- Added utility for fetching chip revision (efm32_system.c/h)
- Removed RTC instance ref in API, only one RTC will be supported
(Affects also define in efm32_cmu.h)
- Added default init struct macros for LEUART, USART
- Added msbf parameter in USART synchronous init struct, USART_InitSync_TypeDef.
- Updated reset for I2C, USART, LEUART to also reset IEN register.
- Corrected fault in GPIO_PortOutSet()
1.1.2:
- Corrected minor issues in EMU, EM3 mode when restoring clocks
- Corrected RMU reset cause checking
- Changed GPIO enumerator symbols to start with gpio (from GPIO_)
- Changed CMU and WDOG enum typedefs to start with CMU_/WDOG_ (from cmu/wdog)
- Added USART/UART, LEUART, DMA, I2C support
1.1.1:
- First version including support for CMU, DBG, EMU, GPIO, RTC, WDOG

View File

@ -0,0 +1,75 @@
================ EFM32 Peripheral Library ===================================
This directory, "efm32lib", contains the Energy Micro Peripheral Support
library for the EFM32 series of microcontrollers.
The "efm32lib" SW is designed to support EFM32 Gecko rev B and later versions.
The following known caveats exists for rev A devices:
- CMU: HFRCO band tuning values are not correctly set for rev A.
- EMU: Errata "Peripheral clocks not gated in EM2/EM3 with debug session
active" has not been implemented with SW workaround for rev A.
Some design guidelines for this library:
* Follow the guidelines established by ARM's and Energy Micro's adaptation
of the CMSIS (see below) standard
* Be usable as a starting point for developing richer, more target specific
functionality (i.e. copy and modify further)
* Ability to be used as a standalone software component, used by other drivers
that should cover "the most common cases"
* Readability of the code and usability preferred before optimization for speed
and size or covering a particular "narrow" purpose
* As little "cross-dependency" between modules as possible, to enable users to
pick and choose what they want
================ About CMSIS ================================================
These APIs are based on EFM32_CMSIS, the Cortex Microcontroller Software
Interface Standard support headers, as supplied by Energy Micro AS.
As a result of this, the library requires basic C99-support. You might have
to enable C99 support in your compiler. Comments are in doxygen compatible
format.
The EFM32_CMSIS library contains all peripheral module registers and bit field
descriptors.
To download EFM32_CMSIS, go to
http://www.energymicro.com/downloads
For more information about CMSIS see
http://www.onarm.com
http://www.arm.com/products/CPUs/CMSIS.html
The requirements for using CMSIS also apply to this package.
================ File structure ==============================================
inc/ - header files
src/ - source files
================ Licenses ====================================================
See the top of each file for SW license. Basically you are free to use the
Energy Micro code for any project using EFM32 devices. Parts of the CMSIS
library is copyrighted by ARM Inc. See "License.doc" for ARM's CMSIS license.
================ Software updates ============================================
Energy Micro continually works to provide updated and improved efm32lib,
example code and other software of use for EFM32 customers. Please check the
download section of Energy Micro's web site at
http://www.energymicro.com/downloads
for the latest releases, news and updates. If you download and install the
Simplicity Studio application, you will be notified about updates when
available.
(C) Copyright Energy Micro AS, 2011

View File

@ -0,0 +1,395 @@
/***************************************************************************//**
* @file
* @brief Analog Comparator (ACMP) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_ACMP_H
#define __EFM32_ACMP_H
#include <stdint.h>
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ACMP
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Resistor values used for capacative sense. See the datasheet for your
* device for details on each resistor value. */
typedef enum
{
/** resistor value 0 */
acmpResistor0 = _ACMP_INPUTSEL_CSRESSEL_RES0,
/** resistor value 1 */
acmpResistor1 = _ACMP_INPUTSEL_CSRESSEL_RES1,
/** resistor value 2 */
acmpResistor2 = _ACMP_INPUTSEL_CSRESSEL_RES2,
/** resistor value 3 */
acmpResistor3 = _ACMP_INPUTSEL_CSRESSEL_RES3
} ACMP_CapsenseResistor_TypeDef;
/** Hysteresis level. See datasheet for your device for details on each
* level. */
typedef enum
{
acmpHysteresisLevel0 = _ACMP_CTRL_HYSTSEL_HYST0, /**< Hysteresis level 0 */
acmpHysteresisLevel1 = _ACMP_CTRL_HYSTSEL_HYST1, /**< Hysteresis level 1 */
acmpHysteresisLevel2 = _ACMP_CTRL_HYSTSEL_HYST2, /**< Hysteresis level 2 */
acmpHysteresisLevel3 = _ACMP_CTRL_HYSTSEL_HYST3, /**< Hysteresis level 3 */
acmpHysteresisLevel4 = _ACMP_CTRL_HYSTSEL_HYST4, /**< Hysteresis level 4 */
acmpHysteresisLevel5 = _ACMP_CTRL_HYSTSEL_HYST5, /**< Hysteresis level 5 */
acmpHysteresisLevel6 = _ACMP_CTRL_HYSTSEL_HYST6, /**< Hysteresis level 6 */
acmpHysteresisLevel7 = _ACMP_CTRL_HYSTSEL_HYST7 /**< Hysteresis level 7 */
} ACMP_HysteresisLevel_TypeDef;
/** ACMP warmup time. The delay is measured in HFPERCLK cycles and should
* be at least 10 us. */
typedef enum
{
/** 4 HFPERCLK cycles warmup */
acmpWarmTime4 = _ACMP_CTRL_WARMTIME_4CYCLES,
/** 8 HFPERCLK cycles warmup */
acmpWarmTime8 = _ACMP_CTRL_WARMTIME_8CYCLES,
/** 16 HFPERCLK cycles warmup */
acmpWarmTime16 = _ACMP_CTRL_WARMTIME_16CYCLES,
/** 32 HFPERCLK cycles warmup */
acmpWarmTime32 = _ACMP_CTRL_WARMTIME_32CYCLES,
/** 64 HFPERCLK cycles warmup */
acmpWarmTime64 = _ACMP_CTRL_WARMTIME_64CYCLES,
/** 128 HFPERCLK cycles warmup */
acmpWarmTime128 = _ACMP_CTRL_WARMTIME_128CYCLES,
/** 256 HFPERCLK cycles warmup */
acmpWarmTime256 = _ACMP_CTRL_WARMTIME_256CYCLES,
/** 512 HFPERCLK cycles warmup */
acmpWarmTime512 = _ACMP_CTRL_WARMTIME_512CYCLES
} ACMP_WarmTime_TypeDef;
/** ACMP inputs. Note that scaled VDD and bandgap references can only be used
* as negative inputs. */
typedef enum
{
/** Channel 0 */
acmpChannel0 = _ACMP_INPUTSEL_NEGSEL_CH0,
/** Channel 1 */
acmpChannel1 = _ACMP_INPUTSEL_NEGSEL_CH1,
/** Channel 2 */
acmpChannel2 = _ACMP_INPUTSEL_NEGSEL_CH2,
/** Channel 3 */
acmpChannel3 = _ACMP_INPUTSEL_NEGSEL_CH3,
/** Channel 4 */
acmpChannel4 = _ACMP_INPUTSEL_NEGSEL_CH4,
/** Channel 5 */
acmpChannel5 = _ACMP_INPUTSEL_NEGSEL_CH5,
/** Channel 6 */
acmpChannel6 = _ACMP_INPUTSEL_NEGSEL_CH6,
/** Channel 7 */
acmpChannel7 = _ACMP_INPUTSEL_NEGSEL_CH7,
/** 1.25V internal reference */
acmpChannel1V25 = _ACMP_INPUTSEL_NEGSEL_1V25,
/** 2.5V internal reference */
acmpChannel2V5 = _ACMP_INPUTSEL_NEGSEL_2V5,
/** Scaled VDD reference */
acmpChannelVDD = _ACMP_INPUTSEL_NEGSEL_VDD,
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** DAC0 channel 0 */
acmpChannelDAC0Ch0 = _ACMP_INPUTSEL_NEGSEL_DAC0CH0,
/** DAC0 channel 1 */
acmpChannelDAC0Ch1 = _ACMP_INPUTSEL_NEGSEL_DAC0CH1,
#endif
} ACMP_Channel_TypeDef;
/*******************************************************************************
****************************** STRUCTS ************************************
******************************************************************************/
/** Capsense initialization structure. */
typedef struct
{
/** Full bias current. See the ACMP chapter about bias and response time in
* the reference manual for details. */
bool fullBias;
/** Half bias current. See the ACMP chapter about bias and response time in
* the reference manual for details. */
bool halfBias;
/** Bias current. See the ACMP chapter about bias and response time in the
* reference manual for details. Valid values are in the range 0-7. */
uint32_t biasProg;
/** Warmup time. This is measured in HFPERCLK cycles and should be
* about 10us in wall clock time. */
ACMP_WarmTime_TypeDef warmTime;
/** Hysteresis level */
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
/** Resistor used in the capacative sensing circuit. For values see
* your device datasheet. */
ACMP_CapsenseResistor_TypeDef resistor;
/** Low power reference enabled. This setting, if enabled, reduces the
* power used by the VDD and bandgap references. */
bool lowPowerReferenceEnabled;
/** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.
* Valid values are in the range 0-63. */
uint32_t vddLevel;
/** If true, ACMP is being enabled after configuration. */
bool enable;
} ACMP_CapsenseInit_TypeDef;
/** Default config for capacitive sense mode initialization. */
#define ACMP_CAPSENSE_INIT_DEFAULT \
{ false, /* fullBias */ \
false, /* halfBias */ \
0x7, /* biasProg */ \
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
acmpHysteresisLevel5, \
acmpResistor3, \
false, /* low power reference */ \
0x3D, /* VDD level */ \
true /* Enable after init. */ \
}
/** ACMP initialization structure. */
typedef struct
{
/** Full bias current. See the ACMP chapter about bias and response time in
* the reference manual for details. */
bool fullBias;
/** Half bias current. See the ACMP chapter about bias and response time in
* the reference manual for details. */
bool halfBias;
/** Bias current. See the ACMP chapter about bias and response time in the
* reference manual for details. Valid values are in the range 0-7. */
uint32_t biasProg;
/** Enable setting the interrupt flag on falling edge */
bool interruptOnFallingEdge;
/** Enable setting the interrupt flag on rising edge */
bool interruptOnRisingEdge;
/** Warmup time. This is measured in HFPERCLK cycles and should be
* about 10us in wall clock time. */
ACMP_WarmTime_TypeDef warmTime;
/** Hysteresis level */
ACMP_HysteresisLevel_TypeDef hysteresisLevel;
/** Inactive value emitted by the ACMP during warmup */
bool inactiveValue;
/** Low power reference enabled. This setting, if enabled, reduces the
* power used by the VDD and bandgap references. */
bool lowPowerReferenceEnabled;
/** Vdd reference value. VDD_SCALED = VDD × VDDLEVEL × 50mV/3.8V.
* Valid values are in the range 0-63. */
uint32_t vddLevel;
/** If true, ACMP is being enabled after configuration. */
bool enable;
} ACMP_Init_TypeDef;
/** Default config for ACMP regular initialization. */
#define ACMP_INIT_DEFAULT \
{ false, /* fullBias */ \
false, /* halfBias */ \
0x7, /* biasProg */ \
false, /* No interrupt on falling edge. */ \
false, /* No interrupt on rising edge. */ \
acmpWarmTime512, /* 512 cycle warmup to be safe */ \
acmpHysteresisLevel5, \
false, /* Disabled emitting inactive value during warmup. */ \
false, /* low power reference */ \
0x3D, /* VDD level */ \
true /* Enable after init. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init);
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel);
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel, ACMP_Channel_TypeDef posSel);
void ACMP_Disable(ACMP_TypeDef *acmp);
void ACMP_Enable(ACMP_TypeDef *acmp);
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert);
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init);
void ACMP_Reset(ACMP_TypeDef *acmp);
/***************************************************************************//**
* @brief
* Clear one or more pending ACMP interrupts.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] flags
* Pending ACMP interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
******************************************************************************/
static __INLINE void ACMP_IntClear(ACMP_TypeDef *acmp, uint32_t flags)
{
acmp->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more ACMP interrupts.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] flags
* ACMP interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
******************************************************************************/
static __INLINE void ACMP_IntDisable(ACMP_TypeDef *acmp, uint32_t flags)
{
acmp->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more ACMP interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using ACMP_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] flags
* ACMP interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the ACMP module (ACMP_IF_nnn).
******************************************************************************/
static __INLINE void ACMP_IntEnable(ACMP_TypeDef *acmp, uint32_t flags)
{
acmp->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending ACMP interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @return
* ACMP interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the ACMP module (ACMP_IF_nnn).
******************************************************************************/
static __INLINE uint32_t ACMP_IntGet(ACMP_TypeDef *acmp)
{
return(acmp->IF);
}
/***************************************************************************//**
* @brief
* Get enabled and pending ACMP interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] usart
* Pointer to ACMP peripheral register block.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled ACMP interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in ACMPx_IEN_nnn
* register (ACMPx_IEN_nnn) and
* - the OR combination of valid interrupt flags of the ACMP module
* (ACMPx_IF_nnn).
******************************************************************************/
static __INLINE uint32_t ACMP_IntGetEnabled(ACMP_TypeDef *acmp)
{
uint32_t tmp;
/* Store ACMPx->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = acmp->IEN;
/* Bitwise AND of pending and enabled interrupts */
return acmp->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending ACMP interrupts from SW.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] flags
* ACMP interrupt sources to set to pending. Use a bitwise logic OR
* combination of valid interrupt flags for the ACMP module (ACMP_IF_nnn).
******************************************************************************/
static __INLINE void ACMP_IntSet(ACMP_TypeDef *acmp, uint32_t flags)
{
acmp->IFS = flags;
}
/** @} (end addtogroup ACMP) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_ACMP_H */

View File

@ -0,0 +1,557 @@
/***************************************************************************//**
* @file
* @brief Analog to Digital Converter (ADC) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_ADC_H
#define __EFM32_ADC_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ADC
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Acquisition time (in ADC clock cycles). */
typedef enum
{
adcAcqTime1 = _ADC_SINGLECTRL_AT_1CYCLE, /**< 1 clock cycle. */
adcAcqTime2 = _ADC_SINGLECTRL_AT_2CYCLES, /**< 2 clock cycles. */
adcAcqTime4 = _ADC_SINGLECTRL_AT_4CYCLES, /**< 4 clock cycles. */
adcAcqTime8 = _ADC_SINGLECTRL_AT_8CYCLES, /**< 8 clock cycles. */
adcAcqTime16 = _ADC_SINGLECTRL_AT_16CYCLES, /**< 16 clock cycles. */
adcAcqTime32 = _ADC_SINGLECTRL_AT_32CYCLES, /**< 32 clock cycles. */
adcAcqTime64 = _ADC_SINGLECTRL_AT_64CYCLES, /**< 64 clock cycles. */
adcAcqTime128 = _ADC_SINGLECTRL_AT_128CYCLES, /**< 128 clock cycles. */
adcAcqTime256 = _ADC_SINGLECTRL_AT_256CYCLES /**< 256 clock cycles. */
} ADC_AcqTime_TypeDef;
/** Lowpass filter mode. */
typedef enum
{
/** No filter or decoupling capacitor. */
adcLPFilterBypass = _ADC_CTRL_LPFMODE_BYPASS,
/** On-chip RC filter. */
adcLPFilterRC = _ADC_CTRL_LPFMODE_RCFILT,
/** On-chip decoupling capacitor. */
adcLPFilterDeCap = _ADC_CTRL_LPFMODE_DECAP
} ADC_LPFilter_TypeDef;
/** Oversample rate select. */
typedef enum
{
/** 2 samples per conversion result. */
adcOvsRateSel2 = _ADC_CTRL_OVSRSEL_X2,
/** 4 samples per conversion result. */
adcOvsRateSel4 = _ADC_CTRL_OVSRSEL_X4,
/** 8 samples per conversion result. */
adcOvsRateSel8 = _ADC_CTRL_OVSRSEL_X8,
/** 16 samples per conversion result. */
adcOvsRateSel16 = _ADC_CTRL_OVSRSEL_X16,
/** 32 samples per conversion result. */
adcOvsRateSel32 = _ADC_CTRL_OVSRSEL_X32,
/** 64 samples per conversion result. */
adcOvsRateSel64 = _ADC_CTRL_OVSRSEL_X64,
/** 128 samples per conversion result. */
adcOvsRateSel128 = _ADC_CTRL_OVSRSEL_X128,
/** 256 samples per conversion result. */
adcOvsRateSel256 = _ADC_CTRL_OVSRSEL_X256,
/** 512 samples per conversion result. */
adcOvsRateSel512 = _ADC_CTRL_OVSRSEL_X512,
/** 1024 samples per conversion result. */
adcOvsRateSel1024 = _ADC_CTRL_OVSRSEL_X1024,
/** 2048 samples per conversion result. */
adcOvsRateSel2048 = _ADC_CTRL_OVSRSEL_X2048,
/** 4096 samples per conversion result. */
adcOvsRateSel4096 = _ADC_CTRL_OVSRSEL_X4096
} ADC_OvsRateSel_TypeDef;
/** Peripheral Reflex System signal used to trigger single sample. */
typedef enum
{
adcPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
adcPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
adcPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
adcPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
adcPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
adcPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
adcPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
adcPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
} ADC_PRSSEL_TypeDef;
/** Reference to ADC sample. */
typedef enum
{
/** Internal 1.25V reference. */
adcRef1V25 = _ADC_SINGLECTRL_REF_1V25,
/** Internal 2.5V reference. */
adcRef2V5 = _ADC_SINGLECTRL_REF_2V5,
/** Buffered VDD. */
adcRefVDD = _ADC_SINGLECTRL_REF_VDD,
/** Internal differential 5V reference. */
adcRef5VDIFF = _ADC_SINGLECTRL_REF_5VDIFF,
/** Single ended ext. ref. from pin 6. */
adcRefExtSingle = _ADC_SINGLECTRL_REF_EXTSINGLE,
/** Differential ext. ref. from pin 6 and 7. */
adcRef2xExtDiff = _ADC_SINGLECTRL_REF_2XEXTDIFF,
/** Unbuffered 2xVDD. */
adcRef2xVDD = _ADC_SINGLECTRL_REF_2XVDD
} ADC_Ref_TypeDef;
/** Sample resolution. */
typedef enum
{
adcRes12Bit = _ADC_SINGLECTRL_RES_12BIT, /**< 12 bit sampling. */
adcRes8Bit = _ADC_SINGLECTRL_RES_8BIT, /**< 8 bit sampling. */
adcRes6Bit = _ADC_SINGLECTRL_RES_6BIT, /**< 6 bit sampling. */
adcResOVS = _ADC_SINGLECTRL_RES_OVS /**< Oversampling. */
} ADC_Res_TypeDef;
/** Single sample input selection. */
typedef enum
{
/* Differential mode disabled */
adcSingleInpCh0 = _ADC_SINGLECTRL_INPUTSEL_CH0, /**< Channel 0. */
adcSingleInpCh1 = _ADC_SINGLECTRL_INPUTSEL_CH1, /**< Channel 1. */
adcSingleInpCh2 = _ADC_SINGLECTRL_INPUTSEL_CH2, /**< Channel 2. */
adcSingleInpCh3 = _ADC_SINGLECTRL_INPUTSEL_CH3, /**< Channel 3. */
adcSingleInpCh4 = _ADC_SINGLECTRL_INPUTSEL_CH4, /**< Channel 4. */
adcSingleInpCh5 = _ADC_SINGLECTRL_INPUTSEL_CH5, /**< Channel 5. */
adcSingleInpCh6 = _ADC_SINGLECTRL_INPUTSEL_CH6, /**< Channel 6. */
adcSingleInpCh7 = _ADC_SINGLECTRL_INPUTSEL_CH7, /**< Channel 7. */
adcSingleInpTemp = _ADC_SINGLECTRL_INPUTSEL_TEMP, /**< Temperature reference. */
adcSingleInpVDDDiv3 = _ADC_SINGLECTRL_INPUTSEL_VDDDIV3, /**< VDD divided by 3. */
adcSingleInpVDD = _ADC_SINGLECTRL_INPUTSEL_VDD, /**< VDD. */
adcSingleInpVSS = _ADC_SINGLECTRL_INPUTSEL_VSS, /**< VSS. */
adcSingleInpVrefDiv2 = _ADC_SINGLECTRL_INPUTSEL_VREFDIV2, /**< Vref divided by 2. */
adcSingleInpDACOut0 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT0, /**< DAC output 0. */
adcSingleInpDACOut1 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT1, /**< DAC output 1. */
/* TBD: Use define when available */
adcSingleInpATEST = 15, /**< ATEST. */
/* Differential mode enabled */
adcSingleInpCh0Ch1 = _ADC_SINGLECTRL_INPUTSEL_CH0CH1, /**< Positive Ch0, negative Ch1. */
adcSingleInpCh2Ch3 = _ADC_SINGLECTRL_INPUTSEL_CH2CH3, /**< Positive Ch2, negative Ch3. */
adcSingleInpCh4Ch5 = _ADC_SINGLECTRL_INPUTSEL_CH4CH5, /**< Positive Ch4, negative Ch5. */
adcSingleInpCh6Ch7 = _ADC_SINGLECTRL_INPUTSEL_CH6CH7, /**< Positive Ch6, negative Ch7. */
/* TBD: Use define when available */
adcSingleInpDiff0 = 4 /**< Differential 0. */
} ADC_SingleInput_TypeDef;
/** Acquisition time (in ADC clock cycles). */
typedef enum
{
/** Start single conversion. */
adcStartSingle = ADC_CMD_SINGLESTART,
/** Start scan sequence. */
adcStartScan = ADC_CMD_SCANSTART,
/**
* Start scan sequence and single conversion, typically used when tailgating
* single conversion after scan sequence.
*/
adcStartScanAndSingle = ADC_CMD_SCANSTART | ADC_CMD_SINGLESTART
} ADC_Start_TypeDef;
/** Warm-up mode. */
typedef enum
{
/** ADC shutdown after each conversion. */
adcWarmupNormal = _ADC_CTRL_WARMUPMODE_NORMAL,
/** Do not warm-up bandgap references. */
adcWarmupFastBG = _ADC_CTRL_WARMUPMODE_FASTBG,
/** Reference selected for scan mode kept warm.*/
adcWarmupKeepScanRefWarm = _ADC_CTRL_WARMUPMODE_KEEPSCANREFWARM,
/** ADC and reference selected for scan mode kept warm.*/
adcWarmupKeepADCWarm = _ADC_CTRL_WARMUPMODE_KEEPADCWARM
} ADC_Warmup_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** ADC init structure, common for single conversion and scan sequence. */
typedef struct
{
/**
* Oversampling rate select. In order to have any effect, oversampling must
* be enabled for single/scan mode.
*/
ADC_OvsRateSel_TypeDef ovsRateSel;
/** Lowpass or decoupling capacitor filter to use. */
ADC_LPFilter_TypeDef lpfMode;
/** Warm-up mode to use for ADC. */
ADC_Warmup_TypeDef warmUpMode;
/**
* Timebase used for ADC warm up. Select N to give (N+1)HFPERCLK cycles.
* (Additional delay is added for bandgap references, please refer to the
* reference manual.) Normally, N should be selected so that the timebase
* is at least 1 us. See ADC_TimebaseCalcDefault() for a way to obtain
* a suggested timebase of at least 1 us.
*/
uint8_t timebase;
/** Clock division factor N, ADC clock = HFPERCLK / (N + 1). */
uint8_t prescale;
/** Enable/disable conversion tailgating. */
bool tailgate;
} ADC_Init_TypeDef;
/** Default config for ADC init structure. */
#define ADC_INIT_DEFAULT \
{ adcOvsRateSel2, /* 2x oversampling (if enabled). */ \
adcLPFilterBypass, /* No input filter selected. */ \
adcWarmupNormal, /* ADC shutdown after each conversion. */ \
_ADC_CTRL_TIMEBASE_DEFAULT, /* Use HW default value. */ \
_ADC_CTRL_PRESC_DEFAULT, /* Use HW default value. */ \
false /* Do not use tailgate. */ \
}
/** Scan sequence init structure. */
typedef struct
{
/**
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
* is enabled.
*/
ADC_PRSSEL_TypeDef prsSel;
/** Acquisition time (in ADC clock cycles). */
ADC_AcqTime_TypeDef acqTime;
/**
* Sample reference selection. Notice that for external references, the
* ADC calibration register must be set explicitly.
*/
ADC_Ref_TypeDef reference;
/** Sample resolution. */
ADC_Res_TypeDef resolution;
/**
* Input scan selection. If single ended (@p diff is false), use logical
* combination of ADC_SCANCTRL_INPUTMASK_CHx defines. If differential input
* (@p diff is true), use logical combination of ADC_SCANCTRL_INPUTMASK_CHxCHy
* defines. (Notice underscore prefix for defines used.)
*/
uint32_t input;
/** Select if single ended or differential input. */
bool diff;
/** Peripheral reflex system trigger enable. */
bool prsEnable;
/** Select if left adjustment should be done. */
bool leftAdjust;
/** Select if continuous conversion until explicit stop. */
bool rep;
} ADC_InitScan_TypeDef;
/** Default config for ADC scan init structure. */
#define ADC_INITSCAN_DEFAULT \
{ adcPRSSELCh0, /* PRS ch0 (if enabled). */ \
adcAcqTime1, /* 1 ADC_CLK cycle acquisition time. */ \
adcRef1V25, /* 1.25V internal reference. */ \
adcRes12Bit, /* 12 bit resolution. */ \
0, /* No input selected. */ \
false, /* Single ended input. */ \
false, /* PRS disabled. */ \
false, /* Right adjust. */ \
false /* Deactivate conversion after one scan sequence. */ \
}
/** Single conversion init structure. */
typedef struct
{
/**
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
* is enabled.
*/
ADC_PRSSEL_TypeDef prsSel;
/** Acquisition time (in ADC clock cycles). */
ADC_AcqTime_TypeDef acqTime;
/**
* Sample reference selection. Notice that for external references, the
* ADC calibration register must be set explicitly.
*/
ADC_Ref_TypeDef reference;
/** Sample resolution. */
ADC_Res_TypeDef resolution;
/**
* Sample input selection, use single ended or differential input according
* to setting of @p diff.
*/
ADC_SingleInput_TypeDef input;
/** Select if single ended or differential input. */
bool diff;
/** Peripheral reflex system trigger enable. */
bool prsEnable;
/** Select if left adjustment should be done. */
bool leftAdjust;
/** Select if continuous conversion until explicit stop. */
bool rep;
} ADC_InitSingle_TypeDef;
/** Default config for ADC single conversion init structure. */
#define ADC_INITSINGLE_DEFAULT \
{ adcPRSSELCh0, /* PRS ch0 (if enabled). */ \
adcAcqTime1, /* 1 ADC_CLK cycle acquisition time. */ \
adcRef1V25, /* 1.25V internal reference. */ \
adcRes12Bit, /* 12 bit resolution. */ \
adcSingleInpCh0, /* CH0 input selected. */ \
false, /* Single ended input. */ \
false, /* PRS disabled. */ \
false, /* Right adjust. */ \
false /* Deactivate conversion after one scan sequence. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get single conversion result.
*
* @note
* Do only use if single conversion data valid.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @return
*
******************************************************************************/
static __INLINE uint32_t ADC_DataSingleGet(ADC_TypeDef *adc)
{
return(adc->SINGLEDATA);
}
/***************************************************************************//**
* @brief
* Get scan result.
*
* @note
* Do only use if scan data valid.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
******************************************************************************/
static __INLINE uint32_t ADC_DataScanGet(ADC_TypeDef *adc)
{
return(adc->SCANDATA);
}
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init);
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init);
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending ADC interrupts.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] flags
* Pending ADC interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the ADC module (ADC_IF_nnn).
******************************************************************************/
static __INLINE void ADC_IntClear(ADC_TypeDef *adc, uint32_t flags)
{
adc->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more ADC interrupts.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] flags
* ADC interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the ADC module (ADC_IF_nnn).
******************************************************************************/
static __INLINE void ADC_IntDisable(ADC_TypeDef *adc, uint32_t flags)
{
adc->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more ADC interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using ADC_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] flags
* ADC interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the ADC module (ADC_IF_nnn).
******************************************************************************/
static __INLINE void ADC_IntEnable(ADC_TypeDef *adc, uint32_t flags)
{
adc->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending ADC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @return
* ADC interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the ADC module (ADC_IF_nnn).
******************************************************************************/
static __INLINE uint32_t ADC_IntGet(ADC_TypeDef *adc)
{
return(adc->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending ADC interrupts from SW.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] flags
* ADC interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the ADC module (ADC_IF_nnn).
******************************************************************************/
static __INLINE void ADC_IntSet(ADC_TypeDef *adc, uint32_t flags)
{
adc->IFS = flags;
}
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq);
/***************************************************************************//**
* @brief
* Start scan sequence and/or single conversion.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] cmd
* Command indicating which type of sampling to start.
******************************************************************************/
static __INLINE void ADC_Start(ADC_TypeDef *adc, ADC_Start_TypeDef cmd)
{
adc->CMD = (uint32_t)cmd;
}
void ADC_Reset(ADC_TypeDef *adc);
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq);
/** @} (end addtogroup ADC) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_ADC_H */

View File

@ -0,0 +1,228 @@
/***************************************************************************//**
* @file
* @brief Advanced encryption standard (AES) accelerator peripheral API for
* EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_AES_H
#define __EFM32_AES_H
#include <stdbool.h>
#include "efm32.h"
#if defined(AES_COUNT) && (AES_COUNT > 0)
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup AES
* @{
******************************************************************************/
/*******************************************************************************
****************************** TYPEDEFS ***********************************
******************************************************************************/
/**
* @brief
* AES counter modification function pointer.
* @details
* Parameters:
* @li ctr - Ptr to byte array (16 bytes) holding counter to be modified.
*/
typedef void (*AES_CtrFuncPtr_TypeDef)(uint8_t *ctr);
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void AES_CBC128(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv,
bool encrypt);
void AES_CBC256(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv,
bool encrypt);
void AES_CFB128(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv,
bool encrypt);
void AES_CFB256(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv,
bool encrypt);
void AES_CTR128(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
uint8_t *ctr,
AES_CtrFuncPtr_TypeDef ctrFunc);
void AES_CTR256(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
uint8_t *ctr,
AES_CtrFuncPtr_TypeDef ctrFunc);
void AES_CTRUpdate32Bit(uint8_t *ctr);
void AES_DecryptKey128(uint8_t *out, const uint8_t *in);
void AES_DecryptKey256(uint8_t *out, const uint8_t *in);
void AES_ECB128(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
bool encrypt);
void AES_ECB256(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
bool encrypt);
/***************************************************************************//**
* @brief
* Clear one or more pending AES interrupts.
*
* @param[in] flags
* Pending AES interrupt source to clear. Use a bitwise logic OR combination of
* valid interrupt flags for the AES module (AES_IF_nnn).
******************************************************************************/
static __INLINE void AES_IntClear(uint32_t flags)
{
AES->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more AES interrupts.
*
* @param[in] flags
* AES interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the AES module (AES_IF_nnn).
******************************************************************************/
static __INLINE void AES_IntDisable(uint32_t flags)
{
AES->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more AES interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using AES_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] flags
* AES interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the AES module (AES_IF_nnn).
******************************************************************************/
static __INLINE void AES_IntEnable(uint32_t flags)
{
AES->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending AES interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* AES interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the AES module (AES_IF_nnn).
******************************************************************************/
static __INLINE uint32_t AES_IntGet(void)
{
return(AES->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending AES interrupts from SW.
*
* @param[in] flags
* AES interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the AES module (AES_IF_nnn).
******************************************************************************/
static __INLINE void AES_IntSet(uint32_t flags)
{
AES->IFS = flags;
}
void AES_OFB128(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv);
void AES_OFB256(uint8_t *out,
const uint8_t *in,
unsigned int len,
const uint8_t *key,
const uint8_t *iv);
/** @} (end addtogroup AES) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_AES_H */
#endif /* defined(AES_COUNT) && (AES_COUNT > 0) */

View File

@ -0,0 +1,74 @@
/***************************************************************************//**
* @file
* @brief EFM32 peripheral API "assert" implementation.
* @author Energy Micro AS
* @version 2.3.2
*
* @details
* By default, EFM32 library assert usage is not included in order to reduce
* footprint and processing overhead. Further, EFM32 assert usage is decoupled
* from ISO C assert handling (NDEBUG usage), to allow a user to use ISO C
* assert without including EFM32 assert statements.
*
* Below are available defines for controlling EFM32 assert inclusion. The defines
* are typically defined for a project to be used by the preprocessor.
*
* @li If DEBUG_EFM is defined, the internal EFM32 library assert handling will
* be used, which may be a quite rudimentary implementation.
*
* @li If DEBUG_EFM_USER is defined instead, the user must provide its own EFM32
* assert handling routine (assertEFM()).
*
* As indicated above, if none of the above defines are used, EFM32 assert
* statements are not compiled.
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_ASSERT_H
#define __EFM32_ASSERT_H
#ifdef __cplusplus
extern "C" {
#endif
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#if defined(DEBUG_EFM) || defined(DEBUG_EFM_USER)
/* Due to footprint considerations, we only pass file name and line number, */
/* not the assert expression (nor function name (C99)) */
void assertEFM(const char *file, int line);
#define EFM_ASSERT(expr) ((expr) ? ((void)0) : assertEFM(__FILE__, __LINE__))
#else
#define EFM_ASSERT(expr) ((void)0)
#endif /* defined(DEBUG_EFM) || defined(DEBUG_EFM_USER) */
/** @endcond */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_ASSERT_H */

View File

@ -0,0 +1,103 @@
/***************************************************************************//**
* @file
* @brief Bitband Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_BITBAND_H
#define __EFM32_BITBAND_H
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup BITBAND
* @brief BITBAND Peripheral API for EFM32
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Perform bit-band operation on peripheral memory location.
*
* @details
* Bit-banding provides atomic read-modify-write cycle for single bit
* modification. Please refer to the reference manual for further details
* about bit-banding.
*
* @param[in,out] addr Peripheral address location to modify bit in.
*
* @param[in] bit Bit position to modify, 0-31.
*
* @param[in] val Value to set bit to, 0 or 1.
******************************************************************************/
static __INLINE void BITBAND_Peripheral(volatile uint32_t *addr,
uint32_t bit,
uint32_t val)
{
uint32_t tmp = BITBAND_PER_BASE + (((uint32_t)addr - PER_MEM_BASE) * 32) + (bit * 4);
*((volatile uint32_t *)tmp) = (uint32_t)val;
}
/***************************************************************************//**
* @brief
* Perform bit-band operation on SRAM memory location.
*
* @details
* Bit-banding provides atomic read-modify-write cycle for single bit
* modification. Please refer to the reference manual for further details
* about bit-banding.
*
* @param[in,out] addr SRAM address location to modify bit in.
*
* @param[in] bit Bit position to modify, 0-31.
*
* @param[in] val Value to set bit to, 0 or 1.
******************************************************************************/
static __INLINE void BITBAND_SRAM(uint32_t *addr, uint32_t bit, uint32_t val)
{
uint32_t tmp = BITBAND_RAM_BASE + (((uint32_t)addr - RAM_MEM_BASE) * 32) + (bit * 4);
*((volatile uint32_t *)tmp) = (uint32_t)val;
}
/** @} (end addtogroup BITBAND) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_BITBAND_H */

View File

@ -0,0 +1,160 @@
/***************************************************************************//**
* @file
* @brief Chip Initialization API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_CHIP_H
#define __EFM32_CHIP_H
#include "efm32.h"
#include "efm32_system.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup CHIP
* @brief Chip Initialization API for EFM32
* @{
******************************************************************************/
/**************************************************************************//**
* @brief
* Chip initialization routine for revision errata workarounds
*
* This init function will configure the EFM32 device to a state where it is
* as similar as later revisions as possible, to improve software compatibility
* with newer parts. See the device specific errata for details.
*****************************************************************************/
static __INLINE void CHIP_Init(void)
{
/* Currently only run time changes for Gecko devices */
#if defined(_EFM32_GECKO_FAMILY)
uint32_t rev;
SYSTEM_ChipRevision_TypeDef chipRev;
volatile uint32_t *reg;
rev = *(volatile uint32_t *)(0x0FE081FC);
/* Engineering Sample calibration setup */
if ((rev >> 24) == 0)
{
reg = (volatile uint32_t *)0x400CA00C;
*reg &= ~(0x70UL);
/* DREG */
reg = (volatile uint32_t *)0x400C6020;
*reg &= ~(0xE0000000UL);
*reg |= ~(7UL << 25);
}
if ((rev >> 24) <= 3)
{
/* DREG */
reg = (volatile uint32_t *)0x400C6020;
*reg &= ~(0x00001F80UL);
/* Update CMU reset values */
reg = (volatile uint32_t *)0x400C8040;
*reg = 0;
reg = (volatile uint32_t *)0x400C8044;
*reg = 0;
reg = (volatile uint32_t *)0x400C8058;
*reg = 0;
reg = (volatile uint32_t *)0x400C8060;
*reg = 0;
reg = (volatile uint32_t *)0x400C8078;
*reg = 0;
}
SYSTEM_ChipRevisionGet(&chipRev);
if (chipRev.major == 0x01)
{
/* Rev A errata handling for EM2/3. Must enable DMA clock in order for EM2/3 */
/* to work. This will be fixed in later chip revisions, so only do for rev A. */
if (chipRev.minor == 00)
{
reg = (volatile uint32_t *)0x400C8040;
*reg |= 0x2;
}
/* Rev A+B errata handling for I2C when using EM2/3. USART0 clock must be enabled */
/* after waking up from EM2/EM3 in order for I2C to work. This will be fixed in */
/* later chip revisions, so only do for rev A+B. */
if (chipRev.minor <= 0x01)
{
reg = (volatile uint32_t *)0x400C8044;
*reg |= 0x1;
}
}
/* Ensure correct ADC/DAC calibration value */
rev = *(volatile uint32_t *)0x0FE081F0;
if (rev < 0x4C8ABA00)
{
uint32_t cal;
/* Enable ADC/DAC clocks */
reg = (volatile uint32_t *)0x400C8044UL;
*reg |= (1 << 14 | 1 << 11);
/* Retrive calibration values */
cal = ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
8) << 24;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
0) << 16;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
8) << 8;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
0) << 0;
/* ADC0->CAL = 1.25 reference */
reg = (volatile uint32_t *)0x40002034UL;
*reg = cal;
/* DAC0->CAL = 1.25 reference */
reg = (volatile uint32_t *)(0x4000402CUL);
cal = *(volatile uint32_t *)0x0FE081C8UL;
*reg = cal;
/* Turn off ADC/DAC clocks */
reg = (volatile uint32_t *)0x400C8044UL;
*reg &= ~(1 << 14 | 1 << 11);
}
#endif
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_CHIP_H */

View File

@ -0,0 +1,819 @@
/***************************************************************************//**
* @file
* @brief Clock management unit (CMU) API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_CMU_H
#define __EFM32_CMU_H
#include <stdbool.h>
#include "efm32.h"
#include "efm32_bitband.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup CMU
* @{
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* Select register ids, for internal use */
#define CMU_NOSEL_REG 0
#define CMU_HFCLKSEL_REG 1
#define CMU_LFACLKSEL_REG 2
#define CMU_LFBCLKSEL_REG 3
#define CMU_DBGCLKSEL_REG 4
#if defined (_EFM32_GIANT_FAMILY)
#define CMU_USBCCLKSEL_REG 5
#endif
#define CMU_SEL_REG_POS 0
#define CMU_SEL_REG_MASK 0xf
/* Divisor register ids, for internal use */
#define CMU_NODIV_REG 0
#define CMU_HFPERCLKDIV_REG 1
#define CMU_HFCORECLKDIV_REG 2
#define CMU_LFAPRESC0_REG 3
#define CMU_LFBPRESC0_REG 4
#if defined (_EFM32_GIANT_FAMILY)
#define CMU_HFCLKDIV_REG 5
#endif
#define CMU_DIV_REG_POS 4
#define CMU_DIV_REG_MASK 0xf
/* Enable register ids, for internal use */
#define CMU_NO_EN_REG 0
#define CMU_HFPERCLKDIV_EN_REG 1
#define CMU_HFPERCLKEN0_EN_REG 2
#define CMU_HFCORECLKEN0_EN_REG 3
#define CMU_LFACLKEN0_EN_REG 4
#define CMU_LFBCLKEN0_EN_REG 5
#define CMU_PCNT_EN_REG 6
#define CMU_EN_REG_POS 8
#define CMU_EN_REG_MASK 0xf
/* Enable register bit position, for internal use */
#define CMU_EN_BIT_POS 12
#define CMU_EN_BIT_MASK 0x1f
/* Clock branch bitfield position, for internal use */
#define CMU_HF_CLK_BRANCH 0
#define CMU_HFPER_CLK_BRANCH 1
#define CMU_HFCORE_CLK_BRANCH 2
#define CMU_LFA_CLK_BRANCH 3
#define CMU_RTC_CLK_BRANCH 4
#define CMU_LETIMER_CLK_BRANCH 5
#define CMU_LCDPRE_CLK_BRANCH 6
#define CMU_LCD_CLK_BRANCH 7
#define CMU_LESENSE_CLK_BRANCH 8
#define CMU_LFB_CLK_BRANCH 9
#define CMU_LEUART0_CLK_BRANCH 10
#define CMU_LEUART1_CLK_BRANCH 11
#define CMU_DBG_CLK_BRANCH 12
#define CMU_AUX_CLK_BRANCH 13
#define CMU_USBC_CLK_BRANCH 14
#define CMU_CLK_BRANCH_POS 17
#define CMU_CLK_BRANCH_MASK 0x1f
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Clock divisors. These values are valid for prescalers. */
#define cmuClkDiv_1 1 /**< Divide clock by 1. */
#define cmuClkDiv_2 2 /**< Divide clock by 2. */
#define cmuClkDiv_4 4 /**< Divide clock by 4. */
#define cmuClkDiv_8 8 /**< Divide clock by 8. */
#define cmuClkDiv_16 16 /**< Divide clock by 16. */
#define cmuClkDiv_32 32 /**< Divide clock by 32. */
#define cmuClkDiv_64 64 /**< Divide clock by 64. */
#define cmuClkDiv_128 128 /**< Divide clock by 128. */
#define cmuClkDiv_256 256 /**< Divide clock by 256. */
#define cmuClkDiv_512 512 /**< Divide clock by 512. */
#define cmuClkDiv_1024 1024 /**< Divide clock by 1024. */
#define cmuClkDiv_2048 2048 /**< Divide clock by 2048. */
#define cmuClkDiv_4096 4096 /**< Divide clock by 4096. */
#define cmuClkDiv_8192 8192 /**< Divide clock by 8192. */
#define cmuClkDiv_16384 16384 /**< Divide clock by 16384. */
#define cmuClkDiv_32768 32768 /**< Divide clock by 32768. */
/** Clock divider configuration */
typedef uint32_t CMU_ClkDiv_TypeDef;
/** High frequency RC bands. */
typedef enum
{
/** 1MHz RC band. */
cmuHFRCOBand_1MHz = _CMU_HFRCOCTRL_BAND_1MHZ,
/** 7MHz RC band. */
cmuHFRCOBand_7MHz = _CMU_HFRCOCTRL_BAND_7MHZ,
/** 11MHz RC band. */
cmuHFRCOBand_11MHz = _CMU_HFRCOCTRL_BAND_11MHZ,
/** 14MHz RC band. */
cmuHFRCOBand_14MHz = _CMU_HFRCOCTRL_BAND_14MHZ,
/** 21MHz RC band. */
cmuHFRCOBand_21MHz = _CMU_HFRCOCTRL_BAND_21MHZ,
/** 28MHz RC band. */
cmuHFRCOBand_28MHz = _CMU_HFRCOCTRL_BAND_28MHZ
} CMU_HFRCOBand_TypeDef;
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** AUX High frequency RC bands. */
typedef enum
{
/** 1MHz RC band. */
cmuAUXHFRCOBand_1MHz = _CMU_AUXHFRCOCTRL_BAND_1MHZ,
/** 7MHz RC band. */
cmuAUXHFRCOBand_7MHz = _CMU_AUXHFRCOCTRL_BAND_7MHZ,
/** 11MHz RC band. */
cmuAUXHFRCOBand_11MHz = _CMU_AUXHFRCOCTRL_BAND_11MHZ,
/** 14MHz RC band. */
cmuAUXHFRCOBand_14MHz = _CMU_AUXHFRCOCTRL_BAND_14MHZ,
/** 21MHz RC band. */
cmuAUXHFRCOBand_21MHz = _CMU_AUXHFRCOCTRL_BAND_21MHZ,
/** 28MHz RC band. */
cmuAUXHFRCOBand_28MHz = _CMU_AUXHFRCOCTRL_BAND_28MHZ
} CMU_AUXHFRCOBand_TypeDef;
#endif
/** Clock points in CMU. Please refer to CMU overview in reference manual. */
typedef enum
{
/*******************/
/* HF clock branch */
/*******************/
/** High frequency clock */
#if defined(_EFM32_GIANT_FAMILY)
cmuClock_HF = (CMU_HFCLKDIV_REG << CMU_DIV_REG_POS) |
(CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#else
cmuClock_HF = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Debug clock */
cmuClock_DBG = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_DBGCLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** AUX clock */
cmuClock_AUX = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/**********************************/
/* HF peripheral clock sub-branch */
/**********************************/
/** High frequency peripheral clock */
cmuClock_HFPER = (CMU_HFPERCLKDIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKDIV_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKDIV_HFPERCLKEN_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** Universal sync/async receiver/transmitter 0 clock. */
#if defined(_CMU_HFPERCLKEN0_USART0_MASK)
cmuClock_USART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_USART0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Universal sync/async receiver/transmitter 1 clock. */
#if defined(_CMU_HFPERCLKEN0_USART1_MASK)
cmuClock_USART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_USART1_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Universal sync/async receiver/transmitter 2 clock. */
#if defined(_CMU_HFPERCLKEN0_USART2_MASK)
cmuClock_USART2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_USART2_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Universal async receiver/transmitter 0 clock. */
#if defined(_CMU_HFPERCLKEN0_UART0_MASK)
cmuClock_UART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_UART0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Universal async receiver/transmitter 1 clock. */
#if defined(_CMU_HFPERCLKEN0_UART1_MASK)
cmuClock_UART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_UART1_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Timer 0 clock. */
#if defined(_CMU_HFPERCLKEN0_TIMER0_MASK)
cmuClock_TIMER0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_TIMER0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Timer 1 clock. */
#if defined(_CMU_HFPERCLKEN0_TIMER1_MASK)
cmuClock_TIMER1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_TIMER1_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Timer 2 clock. */
#if defined(_CMU_HFPERCLKEN0_TIMER2_MASK)
cmuClock_TIMER2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_TIMER2_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Analog comparator 0 clock. */
#if defined(_CMU_HFPERCLKEN0_ACMP0_MASK)
cmuClock_ACMP0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_ACMP0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Analog comparator 1 clock. */
#if defined(_CMU_HFPERCLKEN0_ACMP1_MASK)
cmuClock_ACMP1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_ACMP1_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Peripheral reflex system clock. */
#if defined(_CMU_HFPERCLKEN0_PRS_MASK)
cmuClock_PRS = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_PRS_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Digital to analog converter 0 clock. */
#if defined(_CMU_HFPERCLKEN0_DAC0_MASK)
cmuClock_DAC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_DAC0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** General purpose input/output clock. */
#if defined(GPIO_PRESENT)
cmuClock_GPIO = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_GPIO_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Voltage comparator clock. */
#if defined(VCMP_PRESENT)
cmuClock_VCMP = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_VCMP_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Analog to digital converter 0 clock. */
#if defined(_CMU_HFPERCLKEN0_ADC0_MASK)
cmuClock_ADC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_ADC0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** I2C 0 clock. */
#if defined(_CMU_HFPERCLKEN0_I2C0_MASK)
cmuClock_I2C0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_I2C0_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** I2C 1 clock. */
#if defined(_CMU_HFPERCLKEN0_I2C1_MASK)
cmuClock_I2C1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFPERCLKEN0_I2C1_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/**********************/
/* HF core sub-branch */
/**********************/
/** Core clock */
cmuClock_CORE = (CMU_HFCORECLKDIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** Advanced encryption standard accelerator clock. */
#if defined(AES_PRESENT)
cmuClock_AES = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_AES_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Direct memory access controller clock. */
#if defined(DMA_PRESENT)
cmuClock_DMA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_DMA_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Low energy clocking module clock. */
cmuClock_CORELE = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_LE_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** External bus interface clock. */
#if defined(EBI_PRESENT)
cmuClock_EBI = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_EBI_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
#if defined(USB_PRESENT)
cmuClock_USBC = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_USBCCLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_USBC_SHIFT << CMU_EN_BIT_POS) |
(CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
cmuClock_USB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_HFCORECLKEN0_USB_SHIFT << CMU_EN_BIT_POS) |
(CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/***************/
/* LF A branch */
/***************/
/** Low frequency A clock */
cmuClock_LFA = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_LFACLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** Real time counter clock. */
#if defined(RTC_PRESENT)
cmuClock_RTC = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFACLKEN0_RTC_SHIFT << CMU_EN_BIT_POS) |
(CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Low energy timer 0 clock. */
#if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
cmuClock_LETIMER0 = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFACLKEN0_LETIMER0_SHIFT << CMU_EN_BIT_POS) |
(CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Liquid crystal display, pre FDIV clock. */
#if defined(_CMU_LFACLKEN0_LCD_MASK)
cmuClock_LCDpre = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** Liquid crystal display clock. Please notice that FDIV prescaler
* must be set by special API. */
cmuClock_LCD = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFACLKEN0_LCD_SHIFT << CMU_EN_BIT_POS) |
(CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Pulse counter 0 clock. */
#if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
cmuClock_PCNT0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
(_CMU_PCNTCTRL_PCNT0CLKEN_SHIFT << CMU_EN_BIT_POS) |
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Pulse counter 1 clock. */
#if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
cmuClock_PCNT1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
(_CMU_PCNTCTRL_PCNT1CLKEN_SHIFT << CMU_EN_BIT_POS) |
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Pulse counter 2 clock. */
#if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
cmuClock_PCNT2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_PCNT_EN_REG << CMU_EN_REG_POS) |
(_CMU_PCNTCTRL_PCNT2CLKEN_SHIFT << CMU_EN_BIT_POS) |
(CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** LESENSE clock. */
#if defined(_CMU_LFACLKEN0_LESENSE_MASK)
cmuClock_LESENSE = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFACLKEN0_LESENSE_SHIFT << CMU_EN_BIT_POS) |
(CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/***************/
/* LF B branch */
/***************/
/** Low frequency B clock */
cmuClock_LFB = (CMU_NODIV_REG << CMU_DIV_REG_POS) |
(CMU_LFBCLKSEL_REG << CMU_SEL_REG_POS) |
(CMU_NO_EN_REG << CMU_EN_REG_POS) |
(0 << CMU_EN_BIT_POS) |
(CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS),
/** Low energy universal asynchronous receiver/transmitter 0 clock. */
#if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
cmuClock_LEUART0 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFBCLKEN0_LEUART0_SHIFT << CMU_EN_BIT_POS) |
(CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
/** Low energy universal asynchronous receiver/transmitter 1 clock. */
#if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
cmuClock_LEUART1 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) |
(CMU_NOSEL_REG << CMU_SEL_REG_POS) |
(CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) |
(_CMU_LFBCLKEN0_LEUART1_SHIFT << CMU_EN_BIT_POS) |
(CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS),
#endif
} CMU_Clock_TypeDef;
/** Oscillator types. */
typedef enum
{
cmuOsc_LFXO, /**< Low frequency crystal oscillator. */
cmuOsc_LFRCO, /**< Low frequency RC oscillator. */
cmuOsc_HFXO, /**< High frequency crystal oscillator. */
cmuOsc_HFRCO, /**< High frequency RC oscillator. */
cmuOsc_AUXHFRCO, /**< Auxiliary high frequency RC oscillator. */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
cmuOsc_ULFRCO /**< Ultra low frequency RC oscillator. */
#endif
} CMU_Osc_TypeDef;
/** Selectable clock sources. */
typedef enum
{
cmuSelect_Error, /**< Usage error. */
cmuSelect_Disabled, /**< Clock selector disabled. */
cmuSelect_LFXO, /**< Low frequency crystal oscillator. */
cmuSelect_LFRCO, /**< Low frequency RC oscillator. */
cmuSelect_HFXO, /**< High frequency crystal oscillator. */
cmuSelect_HFRCO, /**< High frequency RC oscillator. */
cmuSelect_CORELEDIV2, /**< Core low energy clock divided by 2. */
cmuSelect_AUXHFRCO, /**< Auxilliary clock source can be used for debug clock */
cmuSelect_HFCLK, /**< Divided HFCLK on Giant for debug clock, undivided on Tiny Gecko and for USBC (not used on Gecko) */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
cmuSelect_ULFRCO, /**< Ultra low frequency RC oscillator. */
#endif
} CMU_Select_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable);
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock);
CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock);
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock);
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div);
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref);
CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void);
void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band);
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void);
void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band);
#endif
void CMU_HFRCOStartupDelaySet(uint32_t delay);
uint32_t CMU_HFRCOStartupDelayGet(void);
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait);
uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc);
void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val);
bool CMU_PCNTClockExternalGet(unsigned int inst);
void CMU_PCNTClockExternalSet(unsigned int inst, bool external);
uint32_t CMU_LCDClkFDIVGet(void);
void CMU_LCDClkFDIVSet(uint32_t div);
void CMU_FreezeEnable(bool enable);
uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef reference);
void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
CMU_Osc_TypeDef upSel);
/***************************************************************************//**
* @brief
* Clear one or more pending CMU interrupts.
*
* @param[in] flags
* CMU interrupt sources to clear.
******************************************************************************/
static __INLINE void CMU_IntClear(uint32_t flags)
{
CMU->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more CMU interrupts.
*
* @param[in] flags
* CMU interrupt sources to disable.
******************************************************************************/
static __INLINE void CMU_IntDisable(uint32_t flags)
{
CMU->IEN &= ~flags;
}
/***************************************************************************//**
* @brief
* Enable one or more CMU interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using CMU_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] flags
* CMU interrupt sources to enable.
******************************************************************************/
static __INLINE void CMU_IntEnable(uint32_t flags)
{
CMU->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending CMU interrupts.
*
* @return
* CMU interrupt sources pending.
******************************************************************************/
static __INLINE uint32_t CMU_IntGet(void)
{
return CMU->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending CMU interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* Pending and enabled CMU interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in CMU_IEN_nnn
* register (CMU_IEN_nnn) and
* - the OR combination of valid interrupt flags of the CMU module
* (CMU_IF_nnn).
******************************************************************************/
static __INLINE uint32_t CMU_IntGetEnabled(void)
{
uint32_t tmp = 0U;
/* Store LESENSE->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = CMU->IEN;
/* Bitwise AND of pending and enabled interrupts */
return CMU->IF & tmp;
}
/**************************************************************************//**
* @brief
* Set one or more pending CMU interrupts from SW.
*
* @param[in] flags
* CMU interrupt sources to set to pending.
*****************************************************************************/
static __INLINE void CMU_IntSet(uint32_t flags)
{
CMU->IFS = flags;
}
/***************************************************************************//**
* @brief
* Lock the CMU in order to protect some of its registers against unintended
* modification.
*
* @details
* Please refer to the reference manual for CMU registers that will be
* locked.
*
* @note
* If locking the CMU registers, they must be unlocked prior to using any
* CMU API functions modifying CMU registers protected by the lock.
******************************************************************************/
static __INLINE void CMU_Lock(void)
{
CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK;
}
/***************************************************************************//**
* @brief
* Unlock the CMU so that writing to locked registers again is possible.
******************************************************************************/
static __INLINE void CMU_Unlock(void)
{
CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK;
}
/***************************************************************************//**
* @brief
* Get calibration count register
* @note
* If continuous calibrartion mode is active, calibration busy will allmost
* always be on, and we just need to read the value, where the normal case
* would be that this function call has been triggered by the CALRDY
* interrupt flag.
* @return
* Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)
* in the period of DOWNSEL oscillator clock cycles configured by a previous
* write operation to CMU->CALCNT
******************************************************************************/
static __INLINE uint32_t CMU_CalibrateCountGet(void)
{
/* Wait until calibration completes, UNLESS continuous calibration mode is */
/* active */
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
if (!(CMU->CALCTRL & CMU_CALCTRL_CONT))
{
while (CMU->STATUS & CMU_STATUS_CALBSY)
;
}
#else
while (CMU->STATUS & CMU_STATUS_CALBSY)
;
#endif
return CMU->CALCNT;
}
/***************************************************************************//**
* @brief
* Starts calibration
* @note
* This call is usually invoked after CMU_CalibrateConfig() and possibly
* CMU_CalibrateCont()
******************************************************************************/
static __INLINE void CMU_CalibrateStart(void)
{
CMU->CMD = CMU_CMD_CALSTART;
}
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Stop the calibration counters
******************************************************************************/
static __INLINE void CMU_CalibrateStop(void)
{
CMU->CMD = CMU_CMD_CALSTOP;
}
/***************************************************************************//**
* @brief
* Configures continuous calibration mode
* @param[in] enable
* If true, enables continuous calibration, if false disables continuous
* calibrartion
******************************************************************************/
static __INLINE void CMU_CalibrateCont(bool enable)
{
BITBAND_Peripheral(&(CMU->CALCTRL), _CMU_CALCTRL_CONT_SHIFT, enable);
}
#endif
/** @} (end addtogroup CMU) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_CMU_H */

View File

@ -0,0 +1,109 @@
/***************************************************************************//**
* @file
* @brief EFM32 general purpose utilities.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_COMMON_H
#define __EFM32_COMMON_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup COMMON
* @brief EFM32 general purpose utilities.
* @{
******************************************************************************/
#if !defined(__GNUC__)
/** Macro for getting minimum value. */
#define EFM32_MIN(a, b) ((a) < (b) ? (a) : (b))
/** Macro for getting maximum value. */
#define EFM32_MAX(a, b) ((a) > (b) ? (a) : (b))
/** Macros for handling packed structs. */
#define STRINGIZE(X) #X
#define EFM32_PACK_START(X) _Pragma( STRINGIZE( pack( ##X## ) ) )
#define EFM32_PACK_END() _Pragma( "pack()" )
#define __attribute__(...)
/** Macros for handling aligned structs. */
#ifdef __CC_ARM
#define EFM32_ALIGN(X) __align(X)
#endif
#ifdef __ICCARM__
#define EFM32_ALIGN(X) _Pragma( STRINGIZE( data_alignment=##X## ) )
#endif
#else
/** Macro for getting minimum value. No sideeffects, a and b are evaluated once only. */
#define EFM32_MIN(a, b) ({ __typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b; })
/** Macro for getting maximum value. No sideeffects, a and b are evaluated once only. */
#define EFM32_MAX(a, b) ({ __typeof__(a) _a = (a); __typeof__(b) _b = (b); _a > _b ? _a : _b; })
/** Macro for handling packed structs.
* @n Use this macro before the struct definition.
* @n X denotes the maximum alignment of struct members. X is not supported on
* gcc, gcc always use 1 byte maximum alignment.
*/
#define EFM32_PACK_START( x )
/** Macro for handling packed structs.
* @n Use this macro after the struct definition.
* @n On gcc add __attribute__ ((packed)) after the closing } of the struct
* definition.
*/
#define EFM32_PACK_END()
/** Macro for aligning a variable.
* @n Use this macro before the variable definition.
* @n X denotes the storage alignment value in bytes.
* @n On gcc use __attribute__ ((aligned(X))) before the ; on normal variables.
* Use __attribute__ ((aligned(X))) before the opening { on struct variables.
*/
#define EFM32_ALIGN(X)
#endif
/** @} (end addtogroup COMMON) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_COMMON_H */

View File

@ -0,0 +1,312 @@
/***************************************************************************//**
* @file
* @brief Digital to Analog Converter (DAC) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_DAC_H
#define __EFM32_DAC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "efm32.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup DAC
* @{
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of DAC register block pointer reference for assert statements. */
#define DAC_REF_VALID(ref) ((ref) == DAC0)
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Conversion mode. */
typedef enum
{
dacConvModeContinuous = _DAC_CTRL_CONVMODE_CONTINUOUS, /**< Continuous mode. */
dacConvModeSampleHold = _DAC_CTRL_CONVMODE_SAMPLEHOLD, /**< Sample/hold mode. */
dacConvModeSampleOff = _DAC_CTRL_CONVMODE_SAMPLEOFF /**< Sample/shut off mode. */
} DAC_ConvMode_TypeDef;
/** Output mode. */
typedef enum
{
dacOutputDisable = _DAC_CTRL_OUTMODE_DISABLE, /**< Output to pin and ADC disabled. */
dacOutputPin = _DAC_CTRL_OUTMODE_PIN, /**< Output to pin only. */
dacOutputADC = _DAC_CTRL_OUTMODE_ADC, /**< Output to ADC only */
dacOutputPinADC = _DAC_CTRL_OUTMODE_PINADC /**< Output to pin and ADC. */
} DAC_Output_TypeDef;
/** Peripheral Reflex System signal used to trigger single sample. */
typedef enum
{
dacPRSSELCh0 = _DAC_CH0CTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
dacPRSSELCh1 = _DAC_CH0CTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
dacPRSSELCh2 = _DAC_CH0CTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
dacPRSSELCh3 = _DAC_CH0CTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
dacPRSSELCh4 = _DAC_CH0CTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
dacPRSSELCh5 = _DAC_CH0CTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
dacPRSSELCh6 = _DAC_CH0CTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
dacPRSSELCh7 = _DAC_CH0CTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
} DAC_PRSSEL_TypeDef;
/** Reference voltage for DAC. */
typedef enum
{
dacRef1V25 = _DAC_CTRL_REFSEL_1V25, /**< Internal 1.25V bandgap reference. */
dacRef2V5 = _DAC_CTRL_REFSEL_2V5, /**< Internal 2.5V bandgap reference. */
dacRefVDD = _DAC_CTRL_REFSEL_VDD /**< VDD reference. */
} DAC_Ref_TypeDef;
/** Refresh interval. */
typedef enum
{
dacRefresh8 = _DAC_CTRL_REFRSEL_8CYCLES, /**< Refresh every 8 prescaled cycles. */
dacRefresh16 = _DAC_CTRL_REFRSEL_16CYCLES, /**< Refresh every 16 prescaled cycles. */
dacRefresh32 = _DAC_CTRL_REFRSEL_32CYCLES, /**< Refresh every 32 prescaled cycles. */
dacRefresh64 = _DAC_CTRL_REFRSEL_64CYCLES /**< Refresh every 64 prescaled cycles. */
} DAC_Refresh_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** DAC init structure, common for both channels. */
typedef struct
{
/** Refresh interval. Only used if REFREN bit set for a DAC channel. */
DAC_Refresh_TypeDef refresh;
/** Reference voltage to use. */
DAC_Ref_TypeDef reference;
/** Output mode */
DAC_Output_TypeDef outMode;
/** Conversion mode. */
DAC_ConvMode_TypeDef convMode;
/**
* Prescaler used to get DAC clock. Derived as follows:
* DACclk=HFPERclk/(2^prescale). The DAC clock should be <= 1MHz.
*/
uint8_t prescale;
/** Enable/disable use of low pass filter on output. */
bool lpEnable;
/** Enable/disable reset of prescaler on ch0 start. */
bool ch0ResetPre;
/** Enable/disable output enable control by CH1 PRS signal. */
bool outEnablePRS;
/** Enable/disable sine mode. */
bool sineEnable;
/** Select if single ended or differential mode. */
bool diff;
} DAC_Init_TypeDef;
/** Default config for DAC init structure. */
#define DAC_INIT_DEFAULT \
{ dacRefresh8, /* Refresh every 8 prescaled cycles. */ \
dacRef1V25, /* 1.25V internal reference. */ \
dacOutputPin, /* Output to pin only. */ \
dacConvModeContinuous, /* Continuous mode. */ \
0, /* No prescaling. */ \
false, /* Do not enable low pass filter. */ \
false, /* Do not reset prescaler on ch0 start. */ \
false, /* DAC output enable always on. */ \
false, /* Disable sine mode. */ \
false /* Single ended mode. */ \
}
/** DAC channel init structure. */
typedef struct
{
/** Enable channel. */
bool enable;
/**
* Peripheral reflex system trigger enable. If false, channel is triggered
* by writing to CHnDATA.
*/
bool prsEnable;
/**
* Enable/disable automatic refresh of channel. Refresh interval must be
* defined in common control init, please see DAC_Init().
*/
bool refreshEnable;
/**
* Peripheral reflex system trigger selection. Only applicable if @p prsEnable
* is enabled.
*/
DAC_PRSSEL_TypeDef prsSel;
} DAC_InitChannel_TypeDef;
/** Default config for DAC channel init structure. */
#define DAC_INITCHANNEL_DEFAULT \
{ false, /* Leave channel disabled when init done. */ \
false, /* Disable PRS triggering. */ \
false, /* Channel not refreshed automatically. */ \
dacPRSSELCh0 /* Select PRS ch0 (if PRS triggering enabled). */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable);
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init);
void DAC_InitChannel(DAC_TypeDef *dac,
const DAC_InitChannel_TypeDef *init,
unsigned int ch);
/***************************************************************************//**
* @brief
* Clear one or more pending DAC interrupts.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] flags
* Pending DAC interrupt source to clear. Use a bitwise logic OR combination of
* valid interrupt flags for the DAC module (DAC_IF_nnn).
******************************************************************************/
static __INLINE void DAC_IntClear(DAC_TypeDef *dac, uint32_t flags)
{
dac->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more DAC interrupts.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] flags
* DAC interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the DAC module (DAC_IF_nnn).
******************************************************************************/
static __INLINE void DAC_IntDisable(DAC_TypeDef *dac, uint32_t flags)
{
dac->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more DAC interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using DAC_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] flags
* DAC interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the DAC module (DAC_IF_nnn).
******************************************************************************/
static __INLINE void DAC_IntEnable(DAC_TypeDef *dac, uint32_t flags)
{
dac->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending DAC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @return
* DAC interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the DAC module (DAC_IF_nnn).
******************************************************************************/
static __INLINE uint32_t DAC_IntGet(DAC_TypeDef *dac)
{
return(dac->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending DAC interrupts from SW.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] flags
* DAC interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the DAC module (DAC_IF_nnn).
******************************************************************************/
static __INLINE void DAC_IntSet(DAC_TypeDef *dac, uint32_t flags)
{
dac->IFS = flags;
}
uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq);
void DAC_Reset(DAC_TypeDef *dac);
/** @} (end addtogroup DAC) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_DAC_H */

View File

@ -0,0 +1,84 @@
/***************************************************************************//**
* @file
* @brief Debug (DBG) API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_DBG_H
#define __EFM32_DBG_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup DBG
* @{
******************************************************************************/
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Check if a debugger is connected (and debug session activated)
*
* @details
* Used to make run-time decisions depending on whether a debug session
* has been active since last reset, ie using a debug probe or similar. In
* some cases special handling is required in that scenario.
*
* @return
* true if a debug session is active since last reset, otherwise false.
******************************************************************************/
static __INLINE bool DBG_Connected(void)
{
if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
{
return true;
}
return false;
}
void DBG_SWOEnable(unsigned int location);
/** @} (end addtogroup DBG) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_DBG_H */

View File

@ -0,0 +1,457 @@
/***************************************************************************//**
* @file
* @brief Direct memory access (DMA) API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_DMA_H
#define __EFM32_DMA_H
#include <stdio.h>
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup DMA
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/**
* Amount source/destination address should be incremented for each data
* transfer.
*/
typedef enum
{
dmaDataInc1 = _DMA_CTRL_SRC_INC_BYTE, /**< Increment address 1 byte. */
dmaDataInc2 = _DMA_CTRL_SRC_INC_HALFWORD, /**< Increment address 2 bytes. */
dmaDataInc4 = _DMA_CTRL_SRC_INC_WORD, /**< Increment address 4 bytes. */
dmaDataIncNone = _DMA_CTRL_SRC_INC_NONE /**< Do not increment address. */
} DMA_DataInc_TypeDef;
/** Data sizes (in number of bytes) to be read/written by DMA transfer. */
typedef enum
{
dmaDataSize1 = _DMA_CTRL_SRC_SIZE_BYTE, /**< 1 byte DMA transfer size. */
dmaDataSize2 = _DMA_CTRL_SRC_SIZE_HALFWORD, /**< 2 byte DMA transfer size. */
dmaDataSize4 = _DMA_CTRL_SRC_SIZE_WORD /**< 4 byte DMA transfer size. */
} DMA_DataSize_TypeDef;
/** Type of DMA transfer. */
typedef enum
{
/** Basic DMA cycle. */
dmaCycleCtrlBasic = _DMA_CTRL_CYCLE_CTRL_BASIC,
/** Auto-request DMA cycle. */
dmaCycleCtrlAuto = _DMA_CTRL_CYCLE_CTRL_AUTO,
/** Ping-pong DMA cycle. */
dmaCycleCtrlPingPong = _DMA_CTRL_CYCLE_CTRL_PINGPONG,
/** Memory scatter-gather DMA cycle. */
dmaCycleCtrlMemScatterGather = _DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER,
/** Peripheral scatter-gather DMA cycle. */
dmaCycleCtrlPerScatterGather = _DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER
} DMA_CycleCtrl_TypeDef;
/** Number of transfers before controller does new arbitration. */
typedef enum
{
dmaArbitrate1 = _DMA_CTRL_R_POWER_1, /**< Arbitrate after 1 DMA transfer. */
dmaArbitrate2 = _DMA_CTRL_R_POWER_2, /**< Arbitrate after 2 DMA transfers. */
dmaArbitrate4 = _DMA_CTRL_R_POWER_4, /**< Arbitrate after 4 DMA transfers. */
dmaArbitrate8 = _DMA_CTRL_R_POWER_8, /**< Arbitrate after 8 DMA transfers. */
dmaArbitrate16 = _DMA_CTRL_R_POWER_16, /**< Arbitrate after 16 DMA transfers. */
dmaArbitrate32 = _DMA_CTRL_R_POWER_32, /**< Arbitrate after 32 DMA transfers. */
dmaArbitrate64 = _DMA_CTRL_R_POWER_64, /**< Arbitrate after 64 DMA transfers. */
dmaArbitrate128 = _DMA_CTRL_R_POWER_128, /**< Arbitrate after 128 DMA transfers. */
dmaArbitrate256 = _DMA_CTRL_R_POWER_256, /**< Arbitrate after 256 DMA transfers. */
dmaArbitrate512 = _DMA_CTRL_R_POWER_512, /**< Arbitrate after 512 DMA transfers. */
dmaArbitrate1024 = _DMA_CTRL_R_POWER_1024 /**< Arbitrate after 1024 DMA transfers. */
} DMA_ArbiterConfig_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/**
* @brief
* DMA interrupt callback function pointer.
* @details
* Parameters:
* @li channel - The DMA channel the callback function is invoked for.
* @li primary - Indicates if callback is invoked for completion of primary
* (true) or alternate (false) descriptor. This is mainly useful for
* ping-pong DMA cycles, in order to know which descriptor to refresh.
* @li user - User definable reference that may be used to pass information
* to be used by the callback handler. If used, the referenced data must be
* valid at the point when the interrupt handler invokes the callback.
* If callback changes any data in the provided user structure, remember
* that those changes are done in interrupt context, and proper protection
* of data may be required.
*/
typedef void (*DMA_FuncPtr_TypeDef)(unsigned int channel, bool primary, void *user);
/**
* @brief
* Callback structure that can be used to define DMA complete actions.
* @details
* A reference to this structure is only stored in the primary descriptor
* for a channel (if callback feature is used). If callback is required
* for both primary and alternate descriptor completion, this must be
* handled by one common callback, using the provided 'primary' parameter
* with the callback function.
*/
typedef struct
{
/**
* Pointer to callback function to invoke when DMA transfer cycle done.
* Notice that this function is invoked in interrupt context, and therefore
* should be short and non-blocking.
*/
DMA_FuncPtr_TypeDef cbFunc;
/** User defined pointer to provide with callback function. */
void *userPtr;
/**
* For internal use only: Indicates if next callback applies to primary
* or alternate descriptor completion. Mainly useful for ping-pong DMA
* cycles. Set this value to 0 prior to configuring callback handling.
*/
uint8_t primary;
} DMA_CB_TypeDef;
/** Configuration structure for a channel. */
typedef struct
{
/**
* Select if channel priority is in the high or default priority group
* with respect to arbitration. Within a priority group, lower numbered
* channels have higher priority than higher numbered channels.
*/
bool highPri;
/**
* Select if interrupt shall be enabled for channel (triggering interrupt
* handler when dma_done signal is asserted). It should normally be
* enabled if using the callback feature for a channel, and disabled if
* not using the callback feature.
*/
bool enableInt;
/**
* Channel control specifying the source of DMA signals. If accessing
* peripherals, use one of the DMAREQ_nnn defines available for the
* peripheral. Set it to 0 for memory-to-memory DMA cycles.
*/
uint32_t select;
/**
* @brief
* User definable callback handling configuration.
* @details
* Please refer to structure definition for details. The callback
* is invoked when the specified DMA cycle is complete (when dma_done
* signal asserted). The callback is invoked in interrupt context,
* and should be efficient and non-blocking. Set to NULL to not
* use the callback feature.
* @note
* The referenced structure is used by the interrupt handler, and must
* be available until no longer used. Thus, in most cases it should
* not be located on the stack.
*/
DMA_CB_TypeDef *cb;
} DMA_CfgChannel_TypeDef;
/**
* Configuration structure for primary or alternate descriptor
* (not used for scatter-gather DMA cycles).
*/
typedef struct
{
/** Destination increment size for each DMA transfer */
DMA_DataInc_TypeDef dstInc;
/** Source increment size for each DMA transfer */
DMA_DataInc_TypeDef srcInc;
/** DMA transfer unit size. */
DMA_DataSize_TypeDef size;
/**
* Arbitration rate, ie number of DMA transfers done before rearbitration
* takes place.
*/
DMA_ArbiterConfig_TypeDef arbRate;
/**
* HPROT signal state, please refer to reference manual, DMA chapter for
* further details. Normally set to 0 if protection is not an issue.
* The following bits are available:
* @li bit 0 - HPROT[1] control for source read accesses,
* privileged/non-privileged access
* @li bit 3 - HPROT[1] control for destination write accesses,
* privileged/non-privileged access
*/
uint8_t hprot;
} DMA_CfgDescr_TypeDef;
#if defined(_EFM32_GIANT_FAMILY)
/**
* Configuration structure for loop mode
*/
typedef struct
{
/** Enable repeated loop */
bool enable;
/** Width of transfer, reload value for nMinus1 */
uint16_t nMinus1;
} DMA_CfgLoop_TypeDef;
/**
* Configuration structure for rectangular copy
*/
typedef struct
{
/** DMA channel destination stride (width of destination image, distance between lines) */
uint16_t dstStride;
/** DMA channel source stride (width of source image, distance between lines) */
uint16_t srcStride;
/** 2D copy height */
uint16_t height;
} DMA_CfgRect_TypeDef;
#endif
/** Configuration structure for alternate scatter-gather descriptor. */
typedef struct
{
/** Pointer to location to transfer data from. */
void *src;
/** Pointer to location to transfer data to. */
void *dst;
/** Destination increment size for each DMA transfer */
DMA_DataInc_TypeDef dstInc;
/** Source increment size for each DMA transfer */
DMA_DataInc_TypeDef srcInc;
/** DMA transfer unit size. */
DMA_DataSize_TypeDef size;
/**
* Arbitration rate, ie number of DMA transfers done before rearbitration
* takes place.
*/
DMA_ArbiterConfig_TypeDef arbRate;
/** Number of DMA transfers minus 1 to do. Must be <= 1023. */
uint16_t nMinus1;
/**
* HPROT signal state, please refer to reference manual, DMA chapter for
* further details. Normally set to 0 if protection is not an issue.
* The following bits are available:
* @li bit 0 - HPROT[1] control for source read accesses,
* privileged/non-privileged access
* @li bit 3 - HPROT[1] control for destination write accesses,
* privileged/non-privileged access
*/
uint8_t hprot;
/** Specify if a memory or peripheral scatter-gather DMA cycle. Notice
* that this parameter should be the same for all alternate
* descriptors.
* @li true - this is a peripheral scatter-gather cycle
* @li false - this is a memory scatter-gather cycle
*/
bool peripheral;
} DMA_CfgDescrSGAlt_TypeDef;
/** DMA init structure */
typedef struct
{
/**
* HPROT signal state when accessing the primary/alternate
* descriptors. Normally set to 0 if protection is not an issue.
* The following bits are available:
* @li bit 0 - HPROT[1] control for descriptor accesses (ie when
* the DMA controller accesses the channel control block itself),
* privileged/non-privileged access
*/
uint8_t hprot;
/**
* Pointer to the controlblock in memory holding descriptors (channel
* control data structures). This memory must be properly aligned
* according to requirements.
*
* Alignment requirements are
* a) 5 bits base requirement, bits [4:0]
* b) Add the number of bits needed to represent the wanted number
* of channels
* c) Align structure with this number of bits set to zero
*
* Examples: 4 channels, 5 + 2 (channels 0 to 3) = 7 bits
* 7 bit alignment, 64 byte address alignment
* 8 channels, 5 + 3 (channels 0 to 7) = 8 bits
* 8 bit alignment, 256 byte address alignment
* 12 channels, 5 + 4 (channels 0 to 11) = 9 bits
* 9 bit alignment, 512 byte address alignment
*
* Please refer to the reference manual, DMA chapter for more details.
*
* It is possible to provide a smaller memory block, only covering
* those channels actually used, if not all available channels are used.
* Ie, if only using 4 channels (0-3), both primary and alternate
* structures, then only 16*2*4 = 128 bytes must be provided. This
* implementation has however no check if later exceeding such a limit
* by configuring for instance channel 4, in which case memory overwrite
* of some other data will occur.
*/
DMA_DESCRIPTOR_TypeDef *controlBlock;
} DMA_Init_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void DMA_ActivateAuto(unsigned int channel,
bool primary,
void *dst,
void *src,
unsigned int nMinus1);
void DMA_ActivateBasic(unsigned int channel,
bool primary,
bool useBurst,
void *dst,
void *src,
unsigned int nMinus1);
void DMA_ActivatePingPong(unsigned int channel,
bool useBurst,
void *primDst,
void *primSrc,
unsigned int primNMinus1,
void *altDst,
void *altSrc,
unsigned int altNMinus1);
void DMA_ActivateScatterGather(unsigned int channel,
bool useBurst,
DMA_DESCRIPTOR_TypeDef *altDescr,
unsigned int count);
void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg);
void DMA_CfgDescr(unsigned int channel,
bool primary,
DMA_CfgDescr_TypeDef *cfg);
#if defined(_EFM32_GIANT_FAMILY)
void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg);
void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg);
/***************************************************************************//**
* @brief
* Clear Loop configuration for channel
*
* @param[in] channel
* Channel to reset loop configuration for
******************************************************************************/
static __INLINE void DMA_ResetLoop(unsigned int channel)
{
/* Clean loop copy operation */
switch(channel)
{
case 0:
DMA->LOOP0 = _DMA_LOOP0_RESETVALUE;
break;
case 1:
DMA->LOOP1 = _DMA_LOOP1_RESETVALUE;
break;
default:
break;
}
}
/***************************************************************************//**
* @brief
* Clear Rect/2D DMA configuration for channel
*
* @param[in] channel
* Channel to reset loop configuration for
******************************************************************************/
static __INLINE void DMA_ResetRect(unsigned int channel)
{
(void) channel;
/* Clear rect copy operation */
DMA->RECT0 = _DMA_RECT0_RESETVALUE;
}
#endif
void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
unsigned int indx,
DMA_CfgDescrSGAlt_TypeDef *cfg);
bool DMA_ChannelEnabled(unsigned int channel);
void DMA_Init(DMA_Init_TypeDef *init);
void DMA_IRQHandler(void);
void DMA_RefreshPingPong(unsigned int channel,
bool primary,
bool useBurst,
void *dst,
void *src,
unsigned int nMinus1,
bool last);
void DMA_Reset(void);
/** @} (end addtogroup DMA) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_DMA_H */

View File

@ -0,0 +1,789 @@
/***************************************************************************//**
* @file
* @brief External Bus Iterface (EBI) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_EBI_H
#define __EFM32_EBI_H
#include "efm32.h"
#if defined(EBI_COUNT) && (EBI_COUNT > 0)
#include "efm32_assert.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup EBI
* @{
******************************************************************************/
/***************************************************************************//**
* @verbatim
*
* --------- ---------
* | EBI | /| |\ | Ext. |
* | | / --------- \ | Async |
* |(EFM32)| \ --------- / | Device|
* | | \| |/ | |
* --------- ---------
* Parallel interface
*
* @endverbatim
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
#define EBI_BANK0 (uint32_t)(1 << 1) /**< EBI address bank 0 */
#define EBI_BANK1 (uint32_t)(1 << 2) /**< EBI address bank 1 */
#define EBI_BANK2 (uint32_t)(1 << 3) /**< EBI address bank 2 */
#define EBI_BANK3 (uint32_t)(1 << 4) /**< EBI address bank 3 */
#define EBI_CS0 (uint32_t)(1 << 1) /**< EBI chip select line 0 */
#define EBI_CS1 (uint32_t)(1 << 2) /**< EBI chip select line 1 */
#define EBI_CS2 (uint32_t)(1 << 3) /**< EBI chip select line 2 */
#define EBI_CS3 (uint32_t)(1 << 4) /**< EBI chip select line 3 */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** EBI Mode of operation */
typedef enum
{
/** 8 data bits, 8 address bits */
ebiModeD8A8 = EBI_CTRL_MODE_D8A8,
/** 16 data bits, 16 address bits, using address latch enable */
ebiModeD16A16ALE = EBI_CTRL_MODE_D16A16ALE,
/** 8 data bits, 24 address bits, using address latch enable */
ebiModeD8A24ALE = EBI_CTRL_MODE_D8A24ALE,
/** Mode D16 */
#if defined(_EFM32_GIANT_FAMILY)
ebiModeD16 = EBI_CTRL_MODE_D16,
#endif
} EBI_Mode_TypeDef;
/** EBI Polarity configuration */
typedef enum
{
/** Active Low */
ebiActiveLow = 0,
/** Active High */
ebiActiveHigh = 1
} EBI_Polarity_TypeDef;
/** EBI Pin Line types */
typedef enum
{
/** Address Ready line */
ebiLineARDY,
/** Address Latch Enable line */
ebiLineALE,
/** Write Enable line */
ebiLineWE,
/** Read Enable line */
ebiLineRE,
/** Chip Select line */
ebiLineCS,
#if defined(_EFM32_GIANT_FAMILY)
/** BL line */
ebiLineBL,
#endif
#if defined(_EFM32_GIANT_FAMILY)
/** TFT VSYNC line */
ebiLineTFTVSync,
/** TFT HSYNC line */
ebiLineTFTHSync,
/** TFT Data enable line */
ebiLineTFTDataEn,
/** TFT DCLK line */
ebiLineTFTDClk,
/** TFT Chip select line */
ebiLineTFTCS,
#endif
} EBI_Line_TypeDef;
#if defined(_EFM32_GIANT_FAMILY)
/** Address Pin Enable, lower limit - lower range of pins to enable */
typedef enum
{
/** Adress lines EBI_A[0] and upwards are enabled by APEN */
ebiALowA0 = EBI_ROUTE_ALB_A0,
/** Adress lines EBI_A[8] and upwards are enabled by APEN */
ebiALowA8 = EBI_ROUTE_ALB_A8,
/** Adress lines EBI_A[16] and upwards are enabled by APEN */
ebiALowA16 = EBI_ROUTE_ALB_A16,
/** Adress lines EBI_A[24] and upwards are enabled by APEN */
ebiALowA24 = EBI_ROUTE_ALB_A24,
} EBI_ALow_TypeDef;
/** Adress Pin Enable, high limit - higher limit of pins to enable */
typedef enum
{
/** All EBI_A pins are disabled */
ebiAHighA0 = EBI_ROUTE_APEN_A0,
/** All EBI_A[4:ALow] are enabled */
ebiAHighA5 = EBI_ROUTE_APEN_A5,
/** All EBI_A[5:ALow] are enabled */
ebiAHighA6 = EBI_ROUTE_APEN_A6,
/** All EBI_A[6:ALow] are enabled */
ebiAHighA7 = EBI_ROUTE_APEN_A7,
/** All EBI_A[7:ALow] are enabled */
ebiAHighA8 = EBI_ROUTE_APEN_A8,
/** All EBI_A[8:ALow] are enabled */
ebiAHighA9 = EBI_ROUTE_APEN_A9,
/** All EBI_A[9:ALow] are enabled */
ebiAHighA10 = EBI_ROUTE_APEN_A10,
/** All EBI_A[10:ALow] are enabled */
ebiAHighA11 = EBI_ROUTE_APEN_A11,
/** All EBI_A[11:ALow] are enabled */
ebiAHighA12 = EBI_ROUTE_APEN_A12,
/** All EBI_A[12:ALow] are enabled */
ebiAHighA13 = EBI_ROUTE_APEN_A13,
/** All EBI_A[13:ALow] are enabled */
ebiAHighA14 = EBI_ROUTE_APEN_A14,
/** All EBI_A[14:ALow] are enabled */
ebiAHighA15 = EBI_ROUTE_APEN_A15,
/** All EBI_A[15:ALow] are enabled */
ebiAHighA16 = EBI_ROUTE_APEN_A16,
/** All EBI_A[16:ALow] are enabled */
ebiAHighA17 = EBI_ROUTE_APEN_A17,
/** All EBI_A[17:ALow] are enabled */
ebiAHighA18 = EBI_ROUTE_APEN_A18,
/** All EBI_A[18:ALow] are enabled */
ebiAHighA19 = EBI_ROUTE_APEN_A19,
/** All EBI_A[19:ALow] are enabled */
ebiAHighA20 = EBI_ROUTE_APEN_A20,
/** All EBI_A[20:ALow] are enabled */
ebiAHighA21 = EBI_ROUTE_APEN_A21,
/** All EBI_A[21:ALow] are enabled */
ebiAHighA22 = EBI_ROUTE_APEN_A22,
/** All EBI_A[22:ALow] are enabled */
ebiAHighA23 = EBI_ROUTE_APEN_A23,
/** All EBI_A[23:ALow] are enabled */
ebiAHighA24 = EBI_ROUTE_APEN_A24,
/** All EBI_A[24:ALow] are enabled */
ebiAHighA25 = EBI_ROUTE_APEN_A25,
/** All EBI_A[25:ALow] are enabled */
ebiAHighA26 = EBI_ROUTE_APEN_A26,
/** All EBI_A[26:ALow] are enabled */
ebiAHighA27 = EBI_ROUTE_APEN_A27,
/** All EBI_A[27:ALow] are enabled */
ebiAHighA28 = EBI_ROUTE_APEN_A28,
} EBI_AHigh_TypeDef;
/** EBI I/O Alternate Pin Location */
typedef enum {
/** EBI PIN I/O Location 0 */
ebiLocation0 = EBI_ROUTE_LOCATION_LOC0,
/** EBI PIN I/O Location 1 */
ebiLocation1 = EBI_ROUTE_LOCATION_LOC1,
/** EBI PIN I/O Location 2 */
ebiLocation2 = EBI_ROUTE_LOCATION_LOC2,
/** EBI PIN I/O Location 3 */
// ebiLocation3 = EBI_ROUTE_LOCATION_LOC3,
} EBI_Location_TypeDef;
#endif
/* TFT support */
#if defined(_EFM32_GIANT_FAMILY)
/** EBI TFT Graphics Bank Select */
typedef enum
{
/** Memory BANK0 contains frame buffer */
ebiTFTBank0 = EBI_TFTCTRL_BANKSEL_BANK0,
/** Memory BANK1 contains frame buffer */
ebiTFTBank1 = EBI_TFTCTRL_BANKSEL_BANK1,
/** Memory BANK2 contains frame buffer */
ebiTFTBank2 = EBI_TFTCTRL_BANKSEL_BANK2,
/** Memory BANK3 contains frame buffer */
ebiTFTBank3 = EBI_TFTCTRL_BANKSEL_BANK3
} EBI_TFTBank_TypeDef;
/** Masking and Alpha blending source color*/
typedef enum
{
/** Use memory as source color for masking/alpha blending */
ebiTFTColorSrcMem = EBI_TFTCTRL_COLOR1SRC_MEM,
/** Use PIXEL1 register as source color for masking/alpha blending */
ebiTFTColorSrcPixel1 = EBI_TFTCTRL_COLOR1SRC_PIXEL1,
} EBI_TFTColorSrc_TypeDef;
/** Bus Data Interleave Mode */
typedef enum
{
/** Unlimited interleaved accesses per EBI_DCLK period. Can cause jitter */
ebiTFTInterleaveUnlimited = EBI_TFTCTRL_INTERLEAVE_UNLIMITED,
/** Allow 1 interleaved access per EBI_DCLK period */
ebiTFTInterleaveOnePerDClk = EBI_TFTCTRL_INTERLEAVE_ONEPERDCLK,
/** Only allow accesses during porch periods */
ebiTFTInterleavePorch = EBI_TFTCTRL_INTERLEAVE_PORCH,
} EBI_TFTInterleave_TypeDef;
/** Control frame base pointer copy */
typedef enum
{
/** Trigger update of frame buffer pointer on vertical sync */
ebiTFTFrameBufTriggerVSync = EBI_TFTCTRL_FBCTRIG_VSYNC,
/** Trigger update of frame buffer pointer on horizontal sync */
ebiTFTFrameBufTriggerHSync = EBI_TFTCTRL_FBCTRIG_HSYNC,
} EBI_TFTFrameBufTrigger_TypeDef;
/** Control of mask and alpha blending mode */
typedef enum
{
/** Masking and blending are disabled */
ebiTFTMBDisabled = EBI_TFTCTRL_MASKBLEND_DISABLED,
/** Internal masking */
ebiTFTMBIMask = EBI_TFTCTRL_MASKBLEND_IMASK,
/** Internal alpha blending */
ebiTFTMBIAlpha = EBI_TFTCTRL_MASKBLEND_IALPHA,
/** Internal masking and alpha blending are enabled */
ebiTFTMBIMaskAlpha = EBI_TFTCTRL_MASKBLEND_IMASKIALPHA,
/** External masking */
ebiTFTMBEMask = EBI_TFTCTRL_MASKBLEND_EMASK,
/** External alpha blending */
ebiTFTMBEAlpha = EBI_TFTCTRL_MASKBLEND_EALPHA,
/** External masking and alpha blending */
ebiTFTMBEMaskAlpha = EBI_TFTCTRL_MASKBLEND_EMASKEALPHA,
} EBI_TFTMaskBlend_TypeDef;
/** TFT Direct Drive mode */
typedef enum
{
/** Disabled */
ebiTFTDDModeDisabled = EBI_TFTCTRL_DD_DISABLED,
/** Direct Drive from internal memory */
ebiTFTDDModeInternal = EBI_TFTCTRL_DD_INTERNAL,
/** Direct Drive from external memory */
ebiTFTDDModeExternal = EBI_TFTCTRL_DD_EXTERNAL,
} EBI_TFTDDMode_TypeDef;
/** TFT Data Increment Width */
typedef enum
{
/** Pixel increments are 1 byte at a time */
ebiTFTWidthByte = EBI_TFTCTRL_WIDTH_BYTE,
/** Pixel increments are 2 bytes (half word) */
ebiTFTWidthHalfWord = EBI_TFTCTRL_WIDTH_HALFWORD,
} EBI_TFTWidth_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** EBI Initialization structure */
typedef struct
{
/** EBI operation mode, data and address limits */
EBI_Mode_TypeDef mode;
/** Address Ready pin polarity, active high or low */
EBI_Polarity_TypeDef ardyPolarity;
/** Address Latch Enable pin polarity, active high or low */
EBI_Polarity_TypeDef alePolarity;
/** Write Enable pin polarity, active high or low */
EBI_Polarity_TypeDef wePolarity;
/** Read Enable pin polarity, active high or low */
EBI_Polarity_TypeDef rePolarity;
/** Chip Select pin polarity, active high or low */
EBI_Polarity_TypeDef csPolarity;
#if defined(_EFM32_GIANT_FAMILY)
/** Byte Lane pin polaritym, active high or low */
EBI_Polarity_TypeDef blPolarity;
/** Flag to enable or disable Byte Lane support */
bool blEnable;
/** Flag to enable or disable idle state insertion between transfers */
bool noIdle;
#endif
/** Flag to enable or disable Address Ready support */
bool ardyEnable;
/** Set to turn off 32 cycle timeout ability */
bool ardyDisableTimeout;
/** Mask of flags which selects address banks to configure EBI_BANK<0-3> */
uint32_t banks;
/** Mask of flags which selects chip select lines to configure EBI_CS<0-3> */
uint32_t csLines;
/** Number of cycles address is held after Adress Latch Enable is asserted */
int addrSetupCycles;
/** Number of cycles address is driven onto the ADDRDAT bus before ALE is asserted */
int addrHoldCycles;
#if defined(_EFM32_GIANT_FAMILY)
/** Enable or disables half cycle duration of the ALE strobe in the last address setup cycle */
bool addrHalfALE;
#endif
/** Number of cycles for address setup before REn is asserted */
int readSetupCycles;
/** Number of cycles REn is held active */
int readStrobeCycles;
/** Number of cycles CSn is held active after REn is deasserted */
int readHoldCycles;
#if defined(_EFM32_GIANT_FAMILY)
/** Enable or disable page mode reads */
bool readPageMode;
/** Enables or disable prefetching from sequential addresses */
bool readPrefetch;
/** Enabled or disables half cycle duration of the REn signal in the last strobe cycle */
bool readHalfRE;
#endif
/** Number of cycles for address setup before WEn is asserted */
int writeSetupCycles;
/** Number of cycles WEn is held active */
int writeStrobeCycles;
/** Number of cycles CSn is held active after WEn is deasserted */
int writeHoldCycles;
#if defined(_EFM32_GIANT_FAMILY)
/** Enable or disable the write buffer */
bool writeBufferDisable;
/** Enables or disables half cycle duration of the WEn signal in the last strobe cycle */
bool writeHalfWE;
/** Lower address pin limit to enable */
EBI_ALow_TypeDef aLow;
/** High address pin limit to enable */
EBI_AHigh_TypeDef aHigh;
/** Pin Location */
EBI_Location_TypeDef location;
#endif
/** Flag, if EBI should be enabled after configuration */
bool enable;
} EBI_Init_TypeDef;
/** Default config for EBI init structures */
#if defined(_EFM32_GIANT_FAMILY)
#define EBI_INIT_DEFAULT \
{ ebiModeD8A8, /* 8 bit address, 8 bit data */ \
ebiActiveLow, /* ARDY polarity */ \
ebiActiveLow, /* ALE polarity */ \
ebiActiveLow, /* WE polarity */ \
ebiActiveLow, /* RE polarity */ \
ebiActiveLow, /* CS polarity */ \
ebiActiveLow, /* BL polarity */ \
false, /* enable BL */ \
false, /* enable NOIDLE */ \
false, /* enable ARDY */ \
false, /* don't disable ARDY timeout */ \
EBI_BANK0, /* enable bank 0 */ \
EBI_CS0, /* enable chip select 0 */ \
0, /* addr setup cycles */ \
1, /* addr hold cycles */ \
false, /* do not enable half cycle ALE strobe */ \
0, /* read setup cycles */ \
0, /* read strobe cycles */ \
0, /* read hold cycles */ \
false, /* disable page mode */ \
false, /* disable prefetch */ \
false, /* do not enable half cycle REn strobe */ \
0, /* write setup cycles */ \
0, /* write strobe cycles */ \
1, /* write hold cycles */ \
false, /* do not disable the write buffer */ \
false, /* do not enable halc cycle WEn strobe */ \
ebiALowA0, /* ALB - Low bound, address lines */ \
ebiAHighA0, /* APEN - High bound, address lines */ \
ebiLocation0, /* Use Location 0 */ \
true, /* enable EBI */ \
}
#else
#define EBI_INIT_DEFAULT \
{ ebiModeD8A8, /* 8 bit address, 8 bit data */ \
ebiActiveLow, /* ARDY polarity */ \
ebiActiveLow, /* ALE polarity */ \
ebiActiveLow, /* WE polarity */ \
ebiActiveLow, /* RE polarity */ \
ebiActiveLow, /* CS polarity */ \
false, /* enable ARDY */ \
false, /* don't disable ARDY timeout */ \
EBI_BANK0, /* enable bank 0 */ \
EBI_CS0, /* enable chip select 0 */ \
0, /* addr setup cycles */ \
1, /* addr hold cycles */ \
0, /* read setup cycles */ \
0, /* read strobe cycles */ \
0, /* read hold cycles */ \
0, /* write setup cycles */ \
0, /* write strobe cycles */ \
1, /* write hold cycles */ \
true, /* enable EBI */ \
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
/** TFT Initialization structure */
typedef struct
{
/** External memory bank for driving display */
EBI_TFTBank_TypeDef bank;
/** Width */
EBI_TFTWidth_TypeDef width;
/** Color source for masking and alpha blending */
EBI_TFTColorSrc_TypeDef colSrc;
/** Bus Interleave mode */
EBI_TFTInterleave_TypeDef interleave;
/** Trigger for updating frame buffer pointer */
EBI_TFTFrameBufTrigger_TypeDef fbTrigger;
/** Drive DCLK from negative clock edge of internal clock */
bool shiftDClk;
/** Masking and alpha blending mode */
EBI_TFTMaskBlend_TypeDef maskBlend;
/** TFT Direct Drive mode */
EBI_TFTDDMode_TypeDef driveMode;
/** TFT Polarity for Chip Select (CS) Line */
EBI_Polarity_TypeDef csPolarity;
/** TFT Polarity for Data Clock (DCLK) Line */
EBI_Polarity_TypeDef dclkPolarity;
/** TFT Polarity for Data Enable (DATAEN) Line */
EBI_Polarity_TypeDef dataenPolarity;
/** TFT Polarity for Horizontal Sync (HSYNC) Line */
EBI_Polarity_TypeDef hsyncPolarity;
/** TFT Polarity for Vertical Sync (VSYNC) Line */
EBI_Polarity_TypeDef vsyncPolarity;
/** Horizontal size in pixels */
int hsize;
/** Horizontal Front Porch Size */
int hPorchFront;
/** Horizontal Back Porch Size */
int hPorchBack;
/** Horizontal Synchronization Pulse Width */
int hPulseWidth;
/** Vertical size in pixels */
int vsize;
/** Vertical Front Porch Size */
int vPorchFront;
/** Vertical Back Porch Size */
int vPorchBack;
/** Vertical Synchronization Pulse Width */
int vPulseWidth;
/** TFT Frame Buffer address, offset to EBI bank base address */
uint32_t addressOffset;
/** TFT DCLK period in internal cycles */
int dclkPeriod;
/** Starting position of External Direct Drive relative to DCLK inactive edge */
int startPosition;
/** Number of cycles RGB data is driven before active edge of DCLK */
int setupCycles;
/** Number of cycles RGB data is held after active edge of DCLK */
int holdCycles;
} EBI_TFTInit_TypeDef;
#define EBI_TFTINIT_DEFAULT \
{ ebiTFTBank0, /* Select EBI Bank 0 */ \
ebiTFTWidthHalfWord, /* Select 2-byte increments */ \
ebiTFTColorSrcMem, /* Use memory as source for mask/blending */ \
ebiTFTInterleaveUnlimited, /* Unlimited interleaved accesses */ \
ebiTFTFrameBufTriggerVSync, /* VSYNC as frame buffer update trigger */ \
false, /* Drive DCLK from negative edge of internal clock */ \
ebiTFTMBDisabled, /* No masking and alpha blending enabled */ \
ebiTFTDDModeExternal, /* Drive from external memory */ \
ebiActiveLow, /* CS Active Low polarity */ \
ebiActiveLow, /* DCLK Active Low polarity */ \
ebiActiveLow, /* DATAEN Active Low polarity */ \
ebiActiveLow, /* HSYNC Active Low polarity */ \
ebiActiveLow, /* VSYNC Active Low polarity */ \
320, /* Horizontal size in pixels */ \
1, /* Horizontal Front Porch */ \
29, /* Horizontal Back Porch */ \
2, /* Horizontal Synchronization Pulse Width */ \
240, /* Vertical size in pixels */ \
1, /* Vertical Front Porch */ \
4, /* Vertical Back Porch */ \
2, /* Vertical Synchronization Pulse Width */ \
0x0000, /* Address offset to EBI memory base */ \
5, /* DCLK Period */ \
2, /* DCLK Start */ \
1, /* DCLK Setup cycles */ \
1, /* DCLK Hold cycles */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void EBI_Init(const EBI_Init_TypeDef *ebiInit);
void EBI_Disable(void);
uint32_t EBI_BankAddress(uint32_t bank);
void EBI_BankEnable(uint32_t banks, bool enable);
#if defined(_EFM32_GIANT_FAMILY)
void EBI_TFTInit(const EBI_TFTInit_TypeDef *ebiTFTInit);
void EBI_TFTSizeSet(uint32_t horizontal, uint32_t vertical);
void EBI_TFTHPorchSet(int front, int back, int pulseWidth);
void EBI_TFTVPorchSet(int front, int back, int pulseWidth);
void EBI_TFTTimingSet(int dclkPeriod, int start, int setup, int hold);
#endif
#if defined(_EFM32_GIANT_FAMILY)
/* This functionality is only available on devices with independent timing support */
void EBI_BankReadTimingSet(uint32_t bank, int setupCycles, int strobeCycles, int holdCycles);
void EBI_BankReadTimingConfig(uint32_t bank, bool pageMode, bool prefetch, bool halfRE);
void EBI_BankWriteTimingSet(uint32_t bank, int setupCycles, int strobeCycles, int holdCycles);
void EBI_BankWriteTimingConfig(uint32_t bank, bool writeBufDisable, bool halfWE);
void EBI_BankAddressTimingSet(uint32_t bank, int setupCycles, int holdCycles);
void EBI_BankAddressTimingConfig(uint32_t bank, bool halfALE);
void EBI_BankPolaritySet(uint32_t bank, EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity);
void EBI_BankByteLaneEnable(uint32_t bank, bool enable);
void EBI_BankPage(uint32_t bank, bool enable);
void EBI_AltMapEnable(bool enable);
/* TBD: NAND support */
/* TBD: ECC support */
/***************************************************************************//**
* @brief
* Enable or disable TFT Direct Drive
*
* @param[in] mode
* Drive from Internal or External memory, or Disable Direct Drive
******************************************************************************/
static __INLINE void EBI_TFTEnable(EBI_TFTDDMode_TypeDef mode)
{
EBI->TFTCTRL = (EBI->TFTCTRL & ~(_EBI_TFTCTRL_DD_MASK)) | (uint32_t) mode;
}
/***************************************************************************//**
* @brief
* Configure frame buffer pointer
*
* @param[in] address
* Frame pointer address, as offset by EBI base address
******************************************************************************/
static __INLINE void EBI_TFTFrameBaseSet(uint32_t address)
{
EBI->TFTFRAMEBASE = (uint32_t) address;
}
/***************************************************************************//**
* @brief Set TFT Pixel Color 0 or 1
*
* @param[in] pixel
* Which pixel instance to set
* @param[in] color
* Color of pixel, 16-bit value
******************************************************************************/
static __INLINE void EBI_TFTPixelSet(int pixel, uint32_t color)
{
EFM_ASSERT(pixel == 0 || pixel == 1);
if (pixel == 0)
{
EBI->TFTPIXEL0 = color;
}
if (pixel == 1)
{
EBI->TFTPIXEL1 = color;
}
}
/***************************************************************************//**
* @brief Masking and Blending Mode Set
*
* @param[in] alpha
* 8-bit value indicating blending factor
******************************************************************************/
static __INLINE void EBI_TFTMaskBlendMode(EBI_TFTMaskBlend_TypeDef maskBlend)
{
EBI->TFTCTRL = (EBI->TFTCTRL & (~_EBI_TFTCTRL_MASKBLEND_MASK))|maskBlend;
}
/***************************************************************************//**
* @brief Set TFT Alpha Blending Factor
*
* @param[in] alpha
* 8-bit value indicating blending factor
******************************************************************************/
static __INLINE void EBI_TFTAlphaBlendSet(uint8_t alpha)
{
EBI->TFTALPHA = alpha;
}
/***************************************************************************//**
* @brief Set TFT mask value
* Data accesses that matches this value are suppressed
* @param[in] mask
******************************************************************************/
static __INLINE void EBI_TFTMaskSet(uint32_t mask)
{
EBI->TFTMASK = mask;
}
/***************************************************************************//**
* @brief Get current vertical position counter
* @return
* Returns the current line position for the visible part of a frame
******************************************************************************/
static __INLINE uint32_t EBI_TFTVCount(void)
{
return((EBI->TFTSTATUS & _EBI_TFTSTATUS_VCNT_MASK) >> _EBI_TFTSTATUS_VCNT_SHIFT);
}
/***************************************************************************//**
* @brief Get current horizontal position counter
* @return
* Returns the current horizontal pixel position within a visible line
******************************************************************************/
static __INLINE uint32_t EBI_TFTHCount(void)
{
return((EBI->TFTSTATUS & _EBI_TFTSTATUS_HCNT_MASK) >> _EBI_TFTSTATUS_HCNT_SHIFT);
}
/***************************************************************************//**
* @brief Set Frame Buffer Trigger
* Frame buffer pointer will be updated either on each horizontal line (hsync)
* or vertical update (vsync)(
******************************************************************************/
static __INLINE void EBI_TFTFBTriggerSet(EBI_TFTFrameBufTrigger_TypeDef sync)
{
EBI->TFTCTRL = ((EBI->TFTCTRL & ~_EBI_TFTCTRL_FBCTRIG_MASK)|sync);
}
/***************************************************************************//**
* @brief Set horizontal TFT stride value in number of bytes
*
* @param[in] nbytes
* Number of bytes to add to frame buffer pointer after each horizontal line
* update
******************************************************************************/
static __INLINE void EBI_TFTHStrideSet(uint32_t nbytes)
{
EFM_ASSERT(nbytes < 0x1000);
EBI->TFTSTRIDE = (EBI->TFTSTRIDE & ~(_EBI_TFTSTRIDE_HSTRIDE_MASK))|
(nbytes<<_EBI_TFTSTRIDE_HSTRIDE_SHIFT);
}
/***************************************************************************//**
* @brief
* Clear one or more pending EBI interrupts.
* @param[in] flags
* Pending EBI interrupt source to clear. Use a logical OR combination
* of valid interrupt flags for the EBI module (EBI_IF_nnn).
******************************************************************************/
static __INLINE void EBI_IntClear(uint32_t flags)
{
EBI->IFC = flags;
}
/***************************************************************************//**
* @brief
* Set one or more pending EBI interrupts from SW.
*
* @param[in] flags
* EBI interrupt sources to set to pending. Use a logical OR combination of
* valid interrupt flags for the EBI module (EBI_IF_nnn).
******************************************************************************/
static __INLINE void EBI_IntSet(uint32_t flags)
{
EBI->IFS = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more EBI interrupts
*
* @param[in] flags
* EBI interrupt sources to disable. Use logical OR combination of valid
* interrupt flags for the EBI module (EBI_IF_nnn)
******************************************************************************/
static __INLINE void EBI_IntDisable(uint32_t flags)
{
EBI->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more EBI interrupts
*
* @param[in] flags
* EBI interrupt sources to enable. Use logical OR combination of valid
* interrupt flags for the EBI module (EBI_IF_nnn)
******************************************************************************/
static __INLINE void EBI_IntEnable(uint32_t flags)
{
EBI->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending EBI interrupt flags
*
* @note
* The event bits are not cleared by the use of this function
*
* @return
* EBI interrupt sources pending, a logical combination of valid EBI
* interrupt flags, EBI_IF_nnn
******************************************************************************/
static __INLINE uint32_t EBI_IntGet(void)
{
return(EBI->IF);
}
#endif
void EBI_ChipSelectEnable(uint32_t banks, bool enable);
void EBI_ReadTimingSet(int setupCycles, int strobeCycles, int holdCycles);
void EBI_WriteTimingSet(int setupCycles, int strobeCycles, int holdCycles);
void EBI_AddressTimingSet(int setupCycles, int holdCycles);
void EBI_PolaritySet(EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity);
/** @} (end addtogroup EBI) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */
#endif /* __EFM32_EBI_H */

View File

@ -0,0 +1,287 @@
/***************************************************************************//**
* @file
* @brief Energy management unit (EMU) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_EMU_H
#define __EFM32_EMU_H
#include <stdbool.h>
#include "efm32.h"
#include "efm32_bitband.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup EMU
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
#if defined(_EFM32_GIANT_FAMILY)
/** EM4 duty oscillator */
typedef enum
{
/** Select ULFRCO as duty oscillator in EM4 */
emuEM4Osc_ULFRCO = EMU_EM4CONF_OSC_ULFRCO,
/** Select LFXO as duty oscillator in EM4 */
emuEM4Osc_LFXO = EMU_EM4CONF_OSC_LFXO,
/** Select LFRCO as duty oscillator in EM4 */
emuEM4Osc_LFRCO = EMU_EM4CONF_OSC_LFRCO
} EMU_EM4Osc_TypeDef;
/** Backup Power Voltage Probe types */
typedef enum
{
/** Disable voltage probe */
emuProbe_Disable = EMU_BUCTRL_PROBE_DISABLE,
/** Connect probe to VDD_DREG */
emuProbe_VDDDReg = EMU_BUCTRL_PROBE_VDDDREG,
/** Connect probe to BU_IN */
emuProbe_BUIN = EMU_BUCTRL_PROBE_BUIN,
/** Connect probe to BU_OUT */
emuProbe_BUOUT = EMU_BUCTRL_PROBE_BUOUT
} EMU_Probe_TypeDef;
/** Backup Power Domain resistor selection */
typedef enum
{
/** Main power and backup power connected with RES0 series resistance */
emuRes_Res0 = EMU_PWRCONF_PWRRES_RES0,
/** Main power and backup power connected with RES1 series resistance */
emuRes_Res1 = EMU_PWRCONF_PWRRES_RES1,
/** Main power and backup power connected with RES2 series resistance */
emuRes_Res2 = EMU_PWRCONF_PWRRES_RES2,
/** Main power and backup power connected with RES3 series resistance */
emuRes_Res3 = EMU_PWRCONF_PWRRES_RES3,
} EMU_Resistor_TypeDef;
/** Backup Power Domain power connection */
typedef enum
{
/** No connection between main and backup power */
emuPower_None = EMU_BUINACT_PWRCON_NONE,
/** Main power and backup power connected through diode,
allowing current from backup to main only */
emuPower_BUMain = EMU_BUINACT_PWRCON_BUMAIN,
/** Main power and backup power connected through diode,
allowing current from main to backup only */
emuPower_MainBU = EMU_BUINACT_PWRCON_MAINBU,
/** Main power and backup power connected without diode */
emuPower_NoDiode = EMU_BUINACT_PWRCON_NODIODE,
} EMU_Power_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
#if defined(_EFM32_GIANT_FAMILY)
/** Energy Mode 4 initialization structure */
typedef struct
{
/** Lock configuration of regulator, BOD and oscillator */
bool lockConfig;
/** EM4 duty oscillator */
EMU_EM4Osc_TypeDef osc;
/** Wake up on EM4 BURTC interrupt */
bool buRtcWakeup;
/** Enable EM4 voltage regulator */
bool vreg;
} EMU_EM4Init_TypeDef;
/** Default initialization of EM4 configuration */
#define EMU_EM4INIT_DEFAULT \
{ false, /* Dont't lock configuration after it's been set */ \
emuEM4Osc_ULFRCO, /* Use default ULFRCO oscillator */ \
true, /* Wake up on EM4 BURTC interrupt */ \
true, /* Enable VREG */ \
}
/** Backup Power Domain Initialization structure */
typedef struct
{
/* Backup Power Domain power configuration */
/** Voltage probe select, selects ADC voltage */
EMU_Probe_TypeDef probe;
/** Enable BOD calibration mode */
bool bodCal;
/** Enable BU_STAT status pin for active BU mode */
bool statusPinEnable;
/* Backup Power Domain connection configuration */
/** Power domain resistor */
EMU_Resistor_TypeDef resistor;
/** BU_VOUT strong enable */
bool voutStrong;
/** BU_VOUT medium enable */
bool voutMed;
/** BU_VOUT weak enable */
bool voutWeak;
/* Backup Power Domain inactive configuration */
/** Power connection, when not in Backup Mode */
EMU_Power_TypeDef inactivePower;
/** Threshold range for backup BOD sensing on VDD_DREG, when not in Backup Mode */
uint32_t inactiveThresRange;
/** Threshold for backup BOD sesning on VDD_DREG, when not in Backup Mode */
uint32_t inactiveThreshold;
/* Backup Power Domain active configuration */
/** Power connection, when in Backup Mode */
EMU_Power_TypeDef activePower;
/** Threshold range for backup BOD sensing when in Backup Mode */
uint32_t activeThresRange;
/** Threshold for backup BOD sesning on VDD_DREG, when in Backup Mode */
uint32_t activeThreshold;
/** Enable backup power domain, and release reset, enable BU_VIN pin */
bool enable;
} EMU_BUPDInit_TypeDef;
/** Default */
#define EMU_BUPDINIT_DEFAULT \
{ emuProbe_Disable, /* Do not enable voltage probe */ \
false, /* Disable BOD calibration mode */ \
false, /* Disable BU_STAT pin for backup mode indication */ \
\
emuRes_Res0, /* RES0 series resistance between main and backup power */ \
false, /* Don't enable strong switch */ \
false, /* Don't enable medium switch */ \
false, /* Don't enable weak switch */ \
\
emuPower_None, /* No connection between main and backup power (inactive mode) */ \
0, /* Default threshold range for backup BOD sense (inactive mode) */ \
0, /* Default threshold for backup BOD snese (inactive mode) */ \
\
emuPower_None, /* No connection between main and backup power (active mode) */ \
0, /* Default threshold range for backup BOD sense (active mode) */ \
0, /* Default threshold for backup BOD snese (active mode) */ \
\
true /* Enable BUPD enter on BOD, enable BU_VIN pin, release BU reset */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enter energy mode 1 (EM1).
******************************************************************************/
static __INLINE void EMU_EnterEM1(void)
{
/* Just enter Cortex-M3 sleep mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__WFI();
}
void EMU_EnterEM2(bool restore);
void EMU_EnterEM3(bool restore);
void EMU_EnterEM4(void);
void EMU_MemPwrDown(uint32_t blocks);
void EMU_UpdateOscConfig(void);
#if defined(_EFM32_GIANT_FAMILY)
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init);
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *budpdInit);
/***************************************************************************//**
* @brief
* Disable BU_VIN support
* @param[in] enable
* If true, enables BU_VIN input pin support, if false disables it
******************************************************************************/
static __INLINE void EMU_BUPinEnable(bool enable)
{
BITBAND_Peripheral(&(EMU->ROUTE), _EMU_ROUTE_BUVINPEN_SHIFT, enable);
}
#endif
/***************************************************************************//**
* @brief
* Lock the EMU in order to protect all its registers against unintended
* modification.
*
* @note
* If locking the EMU registers, they must be unlocked prior to using any
* EMU API functions modifying EMU registers. An exception to this is the
* energy mode entering API (EMU_EnterEMn()), which can be used when the
* EMU registers are locked.
******************************************************************************/
static __INLINE void EMU_Lock(void)
{
EMU->LOCK = EMU_LOCK_LOCKKEY_LOCK;
}
/***************************************************************************//**
* @brief
* Unlock the EMU so that writing to locked registers again is possible.
******************************************************************************/
static __INLINE void EMU_Unlock(void)
{
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
}
/***************************************************************************//**
* @brief
* Block entering EM2 or higher number energy modes.
******************************************************************************/
static __INLINE void EMU_EM2Block(void)
{
BITBAND_Peripheral(&(EMU->CTRL), _EMU_CTRL_EM2BLOCK_SHIFT, 1U);
}
/***************************************************************************//**
* @brief
* Unblock entering EM2 or higher number energy modes.
******************************************************************************/
static __INLINE void EMU_EM2UnBlock(void)
{
BITBAND_Peripheral(&(EMU->CTRL), _EMU_CTRL_EM2BLOCK_SHIFT, 0U);
}
/** @} (end addtogroup EMU) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_EMU_H */

View File

@ -0,0 +1,439 @@
/***************************************************************************//**
* @file
* @brief General Purpose IO (GPIO) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_GPIO_H
#define __EFM32_GPIO_H
#include <stdbool.h>
#include "efm32.h"
#include "efm32_bitband.h"
#include "efm32_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** GPIO ports identificator. */
typedef enum
{
gpioPortA = 0, /**< Port A */
gpioPortB = 1, /**< Port B */
gpioPortC = 2, /**< Port C */
gpioPortD = 3, /**< Port D */
gpioPortE = 4, /**< Port E */
gpioPortF = 5 /**< Port F */
} GPIO_Port_TypeDef;
/** GPIO drive mode. */
typedef enum
{
/** Default 6mA */
gpioDriveModeStandard = GPIO_P_CTRL_DRIVEMODE_STANDARD,
/** 0.5 mA */
gpioDriveModeLowest = GPIO_P_CTRL_DRIVEMODE_LOWEST,
/** 20 mA */
gpioDriveModeHigh = GPIO_P_CTRL_DRIVEMODE_HIGH,
/** 2 mA */
gpioDriveModeLow = GPIO_P_CTRL_DRIVEMODE_LOW
} GPIO_DriveMode_TypeDef;
/** Pin mode. For more details on each mode, please refer to the EFM32
* reference manual. */
typedef enum
{
/** Input disabled. Pullup if DOUT is set. */
gpioModeDisabled = _GPIO_P_MODEL_MODE0_DISABLED,
/** Input enabled. Filter if DOUT is set */
gpioModeInput = _GPIO_P_MODEL_MODE0_INPUT,
/** Input enabled. DOUT determines pull direction */
gpioModeInputPull = _GPIO_P_MODEL_MODE0_INPUTPULL,
/** Input enabled with filter. DOUT determines pull direction */
gpioModeInputPullFilter = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER,
/** Push-pull output */
gpioModePushPull = _GPIO_P_MODEL_MODE0_PUSHPULL,
/** Push-pull output with drive-strength set by DRIVEMODE */
gpioModePushPullDrive = _GPIO_P_MODEL_MODE0_PUSHPULLDRIVE,
/** Wired-or output */
gpioModeWiredOr = _GPIO_P_MODEL_MODE0_WIREDOR,
/** Wired-or output with pull-down */
gpioModeWiredOrPullDown = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN,
/** Open-drain output */
gpioModeWiredAnd = _GPIO_P_MODEL_MODE0_WIREDAND,
/** Open-drain output with filter */
gpioModeWiredAndFilter = _GPIO_P_MODEL_MODE0_WIREDANDFILTER,
/** Open-drain output with pullup */
gpioModeWiredAndPullUp = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP,
/** Open-drain output with filter and pullup */
gpioModeWiredAndPullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER,
/** Open-drain output with drive-strength set by DRIVEMODE */
gpioModeWiredAndDrive = _GPIO_P_MODEL_MODE0_WIREDANDDRIVE,
/** Open-drain output with filter and drive-strength set by DRIVEMODE */
gpioModeWiredAndDriveFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER,
/** Open-drain output with pullup and drive-strength set by DRIVEMODE */
gpioModeWiredAndDrivePullUp = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP,
/** Open-drain output with filter, pullup and drive-strength set by DRIVEMODE */
gpioModeWiredAndDrivePullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER
} GPIO_Mode_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location);
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
static __INLINE void GPIO_EM4SetPinRetention(bool enable);
#endif
/***************************************************************************//**
* @brief
* Enable/disable serial wire clock pin.
*
* @note
* Disabling SWDClk will disable the debug interface, which may result in
* a lockout if done early in startup (before debugger is able to halt core).
*
* @param[in] enable
* @li false - disable serial wire clock.
* @li true - enable serial wire clock (default after reset).
******************************************************************************/
static __INLINE void GPIO_DbgSWDClkEnable(bool enable)
{
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWCLKPEN_SHIFT, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Enable/disable serial wire data pin.
*
* @note
* Disabling SWDClk will disable the debug interface, which may result in
* a lockout if done early in startup (before debugger is able to halt core).
*
* @param[in] enable
* @li false - disable serial wire data pin.
* @li true - enable serial wire data pin (default after reset).
******************************************************************************/
static __INLINE void GPIO_DbgSWDIOEnable(bool enable)
{
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWDIOPEN_SHIFT, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Enable/Disable serial wire output pin.
*
* @note
* Enabling this pin is not sufficient to fully enable serial wire output
* which is also dependent on issues outside the GPIO module. Please refer to
* DBG_SWOEnable().
*
* @param[in] enable
* @li false - disable serial wire viewer pin (default after reset).
* @li true - enable serial wire viewer pin.
******************************************************************************/
static __INLINE void GPIO_DbgSWOEnable(bool enable)
{
BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWOPEN_SHIFT, (unsigned int)enable);
}
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode);
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/**************************************************************************//**
* @brief
* Disable GPIO pin wake-up from EM4.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to disable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
static __INLINE void GPIO_EM4DisablePinWakeup(uint32_t pinmask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
GPIO->EM4WUEN &= ~pinmask;
}
/**************************************************************************//**
* @brief
* Enable GPIO pin wake-up from EM4. When the function exits,
* EM4 mode can be safely entered.
*
* @note
* It is assumed that the GPIO pin modes are set correctly.
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
* @param[in] polaritymask
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
static __INLINE void GPIO_EM4EnablePinWakeup(uint32_t pinmask,
uint32_t polaritymask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
GPIO->EM4WUPOL |= pinmask & polaritymask;
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
}
/**************************************************************************//**
* @brief
* Check which GPIO pin(s) that caused a wake-up from EM4.
*
* @return
* Bitmask containing the bitwise logic OR of which GPIO pin(s) caused the
* wake-up. Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
static __INLINE uint32_t GPIO_EM4GetPinWakeupCause(void)
{
return GPIO->EM4WUCAUSE & _GPIO_EM4WUCAUSE_MASK;
}
/**************************************************************************//**
* @brief
* Enable GPIO pin retention of output enable, output value, pull enable and
* pull direction in EM4.
*
* @param[in] enable
* @li true - enable EM4 pin retention.
* @li false - disable EM4 pin retention.
*****************************************************************************/
static __INLINE void GPIO_EM4SetPinRetention(bool enable)
{
if (enable)
{
GPIO->CTRL |= GPIO_CTRL_EM4RET;
}
else
{
GPIO->CTRL &= ~GPIO_CTRL_EM4RET;
}
}
#endif
/***************************************************************************//**
* @brief
* Enable/disable input sensing.
*
* @details
* Disabling input sensing if not used, can save some energy consumption.
*
* @param[in] val
* Bitwise logic OR of one or more of:
* @li GPIO_INSENSE_INTSENSE - interrupt input sensing.
* @li GPIO_INSENSE_PRSSENSE - peripheral reflex system input sensing.
*
* @param[in] mask
* Mask containing bitwise logic OR of bits similar as for @p val used to indicate
* which input sense options to disable/enable.
******************************************************************************/
static __INLINE void GPIO_InputSenseSet(uint32_t val, uint32_t mask)
{
GPIO->INSENSE = (GPIO->INSENSE & ~mask) | (val & mask);
}
/***************************************************************************//**
* @brief
* Clear one or more pending GPIO interrupts.
*
* @param[in] flags
* Bitwise logic OR of GPIO interrupt sources to clear.
******************************************************************************/
static __INLINE void GPIO_IntClear(uint32_t flags)
{
GPIO->IFC = flags;
}
void GPIO_IntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
bool risingEdge,
bool fallingEdge,
bool enable);
/***************************************************************************//**
* @brief
* Disable one or more GPIO interrupts.
*
* @param[in] flags
* GPIO interrupt sources to disable.
******************************************************************************/
static __INLINE void GPIO_IntDisable(uint32_t flags)
{
GPIO->IEN &= ~flags;
}
/***************************************************************************//**
* @brief
* Enable one or more GPIO interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using GPIO_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] flags
* GPIO interrupt sources to enable.
******************************************************************************/
static __INLINE void GPIO_IntEnable(uint32_t flags)
{
GPIO->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending GPIO interrupts.
*
* @return
* GPIO interrupt sources pending.
******************************************************************************/
static __INLINE uint32_t GPIO_IntGet(void)
{
return(GPIO->IF);
}
/***************************************************************************//**
* @brief
* Get enabled and pending GPIO interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled GPIO interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in GPIO_IEN register
* and
* - the OR combination of valid interrupt flags in GPIO_IF register.
******************************************************************************/
static __INLINE uint32_t GPIO_IntGetEnabled(void)
{
uint32_t tmp;
/* Store GPIO->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = GPIO->IEN;
/* Bitwise AND of pending and enabled interrupts */
return GPIO->IF & tmp;
}
/**************************************************************************//**
* @brief
* Set one or more pending GPIO interrupts from SW.
*
* @param[in] flags
* GPIO interrupt sources to set to pending.
*****************************************************************************/
static __INLINE void GPIO_IntSet(uint32_t flags)
{
GPIO->IFS = flags;
}
/***************************************************************************//**
* @brief
* Locks the GPIO configuration.
******************************************************************************/
static __INLINE void GPIO_Lock(void)
{
GPIO->LOCK = GPIO_LOCK_LOCKKEY_LOCK;
}
unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin);
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out);
void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin);
unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port, unsigned int pin);
void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin);
void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin);
uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port);
void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins);
uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port);
void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins);
void GPIO_PortOutSetVal(GPIO_Port_TypeDef port, uint32_t val, uint32_t mask);
void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins);
/***************************************************************************//**
* @brief
* Unlocks the GPIO configuration.
******************************************************************************/
static __INLINE void GPIO_Unlock(void)
{
GPIO->LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
}
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_GPIO_H */

View File

@ -0,0 +1,483 @@
/***************************************************************************//**
* @file
* @brief Inter-intergrated circuit (I2C) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_I2C_H
#define __EFM32_I2C_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup I2C
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/**
* @brief
* Standard mode max frequency assuming using 4:4 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 4.7us, min Thigh = 4.0us,
* max Trise=1.0us, max Tfall=0.3us. Since ratio is 4:4, have to use
* worst case value of Tlow or Thigh as base.
*
* 1/(Tlow + Thigh + 1us + 0.3us) = 1/(4.7 + 4.7 + 1.3)us = 93458Hz
*/
#define I2C_FREQ_STANDARD_MAX 93500
/**
* @brief
* Fast mode max frequency assuming using 6:3 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 1.3us, min Thigh = 0.6us,
* max Trise=0.3us, max Tfall=0.3us. Since ratio is 6:3, have to use
* worst case value of Tlow or 2xThigh as base.
*
* 1/(Tlow + Thigh + 0.3us + 0.3us) = 1/(1.3 + 0.65 + 0.6)us = 392157Hz
*/
#define I2C_FREQ_FAST_MAX 392500
/**
* @brief
* Fast mode+ max frequency assuming using 11:6 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 0.5us, min Thigh = 0.26us,
* max Trise=0.012us, max Tfall=0.12us. Since ratio is 11:6, have to use
* worst case value of Tlow or (11/6)xThigh as base.
*
* 1/(Tlow + Thigh + 0.12us + 0.12us) = 1/(0.5 + 0.273 + 0.24)us = 987167Hz
*/
#define I2C_FREQ_FASTPLUS_MAX 987500
/**
* @brief
* Indicate plain write sequence: S+ADDR(W)+DATA0+P.
* @details
* @li S - Start
* @li ADDR(W) - address with W/R bit cleared
* @li DATA0 - Data taken from buffer with index 0
* @li P - Stop
*/
#define I2C_FLAG_WRITE 0x0001
/**
* @brief
* Indicate plain read sequence: S+ADDR(R)+DATA0+P.
* @details
* @li S - Start
* @li ADDR(R) - address with W/R bit set
* @li DATA0 - Data read into buffer with index 0
* @li P - Stop
*/
#define I2C_FLAG_READ 0x0002
/**
* @brief
* Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
* @details
* @li S - Start
* @li Sr - Repeated start
* @li ADDR(W) - address with W/R bit cleared
* @li ADDR(R) - address with W/R bit set
* @li DATAn - Data written from/read into buffer with index n
* @li P - Stop
*/
#define I2C_FLAG_WRITE_READ 0x0004
/**
* @brief
* Indicate write sequence using two buffers: S+ADDR(W)+DATA0+DATA1+P.
* @details
* @li S - Start
* @li ADDR(W) - address with W/R bit cleared
* @li DATAn - Data written from buffer with index n
* @li P - Stop
*/
#define I2C_FLAG_WRITE_WRITE 0x0008
/** Use 10 bit address. */
#define I2C_FLAG_10BIT_ADDR 0x0010
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Clock low to high ratio settings. */
typedef enum
{
i2cClockHLRStandard = _I2C_CTRL_CLHR_STANDARD, /**< Ratio is 4:4 */
i2cClockHLRAsymetric = _I2C_CTRL_CLHR_ASYMMETRIC, /**< Ratio is 6:3 */
i2cClockHLRFast = _I2C_CTRL_CLHR_FAST /**< Ratio is 11:3 */
} I2C_ClockHLR_TypeDef;
/** Return codes for single master mode transfer function. */
typedef enum
{
/* In progress code (>0) */
i2cTransferInProgress = 1, /**< Transfer in progress. */
/* Complete code (=0) */
i2cTransferDone = 0, /**< Transfer completed successfully. */
/* Transfer error codes (<0) */
i2cTransferNack = -1, /**< NACK received during transfer. */
i2cTransferBusErr = -2, /**< Bus error during transfer (misplaced START/STOP). */
i2cTransferArbLost = -3, /**< Arbitration lost during transfer. */
i2cTransferUsageFault = -4, /**< Usage fault. */
i2cTransferSwFault = -5 /**< SW fault. */
} I2C_TransferReturn_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** I2C initialization structure. */
typedef struct
{
/** Enable I2C peripheral when init completed. */
bool enable;
/** Set to master (true) or slave (false) mode */
bool master;
/**
* I2C reference clock assumed when configuring bus frequency setup.
* Set it to 0 if currently configurated reference clock shall be used
* This parameter is only applicable if operating in master mode.
*/
uint32_t refFreq;
/**
* (Max) I2C bus frequency to use. This parameter is only applicable
* if operating in master mode.
*/
uint32_t freq;
/** Clock low/high ratio control. */
I2C_ClockHLR_TypeDef clhr;
} I2C_Init_TypeDef;
/** Suggested default config for I2C init structure. */
#define I2C_INIT_DEFAULT \
{ true, /* Enable when init done */ \
true, /* Set to master mode */ \
0, /* Use currently configured reference clock */ \
I2C_FREQ_STANDARD_MAX, /* Set to standard rate assuring being */ \
/* within I2C spec */ \
i2cClockHLRStandard /* Set to use 4:4 low/high duty cycle */ \
}
/**
* @brief
* Master mode transfer message structure used to define a complete
* I2C transfer sequence (from start to stop).
* @details
* The structure allows for defining the following types of sequences,
* please refer to defines for sequence details.
* @li #I2C_FLAG_READ - data read into buf[0].data
* @li #I2C_FLAG_WRITE - data written from buf[0].data
* @li #I2C_FLAG_WRITE_READ - data written from buf[0].data and read
* into buf[1].data
* @li #I2C_FLAG_WRITE_WRITE - data written from buf[0].data and
* buf[1].data
*/
typedef struct
{
/**
* @brief
* Address to use after (repeated) start.
* @details
* Layout details, A = address bit, X = don't care bit (set to 0):
* @li 7 bit address - use format AAAA AAAX.
* @li 10 bit address - use format XXXX XAAX AAAA AAAA
*/
uint16_t addr;
/** Flags defining sequence type and details, see I2C_FLAG_... defines. */
uint16_t flags;
/**
* Buffers used to hold data to send from or receive into depending
* on sequence type.
*/
struct
{
/** Buffer used for data to transmit/receive, must be @p len long. */
uint8_t *data;
/**
* Number of bytes in @p data to send or receive. Notice that when
* receiving data to this buffer, at least 1 byte must be received.
* Setting @p len to 0 in the receive case is considered a usage fault.
* Transmitting 0 bytes is legal, in which case only the address
* is transmitted after the start condition.
*/
uint16_t len;
} buf[2];
} I2C_TransferSeq_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c);
void I2C_BusFreqSet(I2C_TypeDef *i2c,
uint32_t refFreq,
uint32_t freq,
I2C_ClockHLR_TypeDef type);
void I2C_Enable(I2C_TypeDef *i2c, bool enable);
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending I2C interrupts.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* Pending I2C interrupt source to clear. Use a bitwse logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
static __INLINE void I2C_IntClear(I2C_TypeDef *i2c, uint32_t flags)
{
i2c->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more I2C interrupts.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
static __INLINE void I2C_IntDisable(I2C_TypeDef *i2c, uint32_t flags)
{
i2c->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more I2C interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using I2C_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
static __INLINE void I2C_IntEnable(I2C_TypeDef *i2c, uint32_t flags)
{
i2c->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending I2C interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
static __INLINE uint32_t I2C_IntGet(I2C_TypeDef *i2c)
{
return(i2c->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending I2C interrupts from SW.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
static __INLINE void I2C_IntSet(I2C_TypeDef *i2c, uint32_t flags)
{
i2c->IFS = flags;
}
void I2C_Reset(I2C_TypeDef *i2c);
/***************************************************************************//**
* @brief
* Get slave address used for I2C peripheral (when operating in slave mode).
*
* @details
* For 10 bit addressing mode, the address is split in two bytes, and only
* the first byte setting is fetched, effectively only controlling the 2 most
* significant bits of the 10 bit address. Full handling of 10 bit addressing
* in slave mode requires additional SW handling.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C slave address in use. The 7 most significant bits define the actual
* address, the least significant bit is reserved and always returned as 0.
******************************************************************************/
static __INLINE uint8_t I2C_SlaveAddressGet(I2C_TypeDef *i2c)
{
return((uint8_t)(i2c->SADDR));
}
/***************************************************************************//**
* @brief
* Set slave address to use for I2C peripheral (when operating in slave mode).
*
* @details
* For 10 bit addressing mode, the address is split in two bytes, and only
* the first byte is set, effectively only controlling the 2 most significant
* bits of the 10 bit address. Full handling of 10 bit addressing in slave
* mode requires additional SW handling.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] addr
* I2C slave address to use. The 7 most significant bits define the actual
* address, the least significant bit is reserved and always set to 0.
******************************************************************************/
static __INLINE void I2C_SlaveAddressSet(I2C_TypeDef *i2c, uint8_t addr)
{
i2c->SADDR = (uint32_t)addr & 0xfe;
}
/***************************************************************************//**
* @brief
* Get slave address mask used for I2C peripheral (when operating in slave
* mode).
*
* @details
* The address mask defines how the comparator works. A bit position with
* value 0 means that the corresponding slave address bit is ignored during
* comparison (don't care). A bit position with value 1 means that the
* corresponding slave address bit must match.
*
* For 10 bit addressing mode, the address is split in two bytes, and only
* the mask for the first address byte is fetched, effectively only
* controlling the 2 most significant bits of the 10 bit address.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C slave address mask in use. The 7 most significant bits define the
* actual address mask, the least significant bit is reserved and always
* returned as 0.
******************************************************************************/
static __INLINE uint8_t I2C_SlaveAddressMaskGet(I2C_TypeDef *i2c)
{
return((uint8_t)(i2c->SADDRMASK));
}
/***************************************************************************//**
* @brief
* Set slave address mask used for I2C peripheral (when operating in slave
* mode).
*
* @details
* The address mask defines how the comparator works. A bit position with
* value 0 means that the corresponding slave address bit is ignored during
* comparison (don't care). A bit position with value 1 means that the
* corresponding slave address bit must match.
*
* For 10 bit addressing mode, the address is split in two bytes, and only
* the mask for the first address byte is set, effectively only controlling
* the 2 most significant bits of the 10 bit address.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] mask
* I2C slave address mask to use. The 7 most significant bits define the
* actual address mask, the least significant bit is reserved and should
* be 0.
******************************************************************************/
static __INLINE void I2C_SlaveAddressMaskSet(I2C_TypeDef *i2c, uint8_t mask)
{
i2c->SADDRMASK = (uint32_t)mask & 0xfe;
}
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c);
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
I2C_TransferSeq_TypeDef *seq);
/** @} (end addtogroup I2C) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_I2C_H */

View File

@ -0,0 +1,110 @@
/***************************************************************************//**
* @file
* @brief Interrupt enable/disable unit API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_INT_H
#define __EFM32_INT_H
#include "efm32.h"
extern uint32_t INT_LockCnt;
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup INT
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Disable interrupts.
*
* @return
* The resulting interrupt nesting level.
*
* @details
* Disable interrupts and increment lock level counter.
*
******************************************************************************/
static __INLINE uint32_t INT_Disable(void)
{
__disable_irq();
if (INT_LockCnt < UINT32_MAX)
{
INT_LockCnt++;
}
return INT_LockCnt;
}
/***************************************************************************//**
* @brief
* Enable interrupts.
*
* @return
* The resulting interrupt nesting level.
*
* @details
* Decrement interrupt lock level counter and enable interrupts if counter
* reached zero.
*
******************************************************************************/
static __INLINE uint32_t INT_Enable(void)
{
uint32_t retVal;
if (INT_LockCnt > 0)
{
INT_LockCnt--;
retVal = INT_LockCnt;
if (retVal == 0)
{
__enable_irq();
}
return retVal;
}
else
{
return 0;
}
}
/** @} (end addtogroup INT) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_INT_H */

View File

@ -0,0 +1,627 @@
/***************************************************************************//**
* @file
* @brief Liquid Crystal Display (LCD) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_LCD_H
#define __EFM32_LCD_H
#include "efm32.h"
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LCD
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** MUX setting */
typedef enum
{
/** Static (segments can be multiplexed with LCD_COM[0]) */
lcdMuxStatic = LCD_DISPCTRL_MUX_STATIC,
/** Duplex / 1/2 Duty cycle (segments can be multiplexed with LCD_COM[0:1]) */
lcdMuxDuplex = LCD_DISPCTRL_MUX_DUPLEX,
/** Triplex / 1/3 Duty cycle (segments can be multiplexed with LCD_COM[0:2]) */
lcdMuxTriplex = LCD_DISPCTRL_MUX_TRIPLEX,
/** Quadruplex / 1/4 Duty cycle (segments can be multiplexed with LCD_COM[0:3]) */
lcdMuxQuadruplex = LCD_DISPCTRL_MUX_QUADRUPLEX,
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** Sextaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */
lcdMuxSextaplex = LCD_DISPCTRL_MUXE_MUXE | LCD_DISPCTRL_MUX_DUPLEX,
/** Octaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */
lcdMuxOctaplex = LCD_DISPCTRL_MUXE_MUXE | LCD_DISPCTRL_MUX_QUADRUPLEX
#endif
} LCD_Mux_TypeDef;
/** Bias setting */
typedef enum
{
/** Static (2 levels) */
lcdBiasStatic = LCD_DISPCTRL_BIAS_STATIC,
/** 1/2 Bias (3 levels) */
lcdBiasOneHalf = LCD_DISPCTRL_BIAS_ONEHALF,
/** 1/3 Bias (4 levels) */
lcdBiasOneThird = LCD_DISPCTRL_BIAS_ONETHIRD,
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** 1/4 Bias (5 levels) */
lcdBiasOneFourth = LCD_DISPCTRL_BIAS_ONEFOURTH,
#endif
} LCD_Bias_TypeDef;
/** Wave type */
typedef enum
{
/** Low power optimized waveform output */
lcdWaveLowPower = LCD_DISPCTRL_WAVE_LOWPOWER,
/** Regular waveform output */
lcdWaveNormal = LCD_DISPCTRL_WAVE_NORMAL
} LCD_Wave_TypeDef;
/** VLCD Voltage Source */
typedef enum
{
/** VLCD Powered by VDD */
lcdVLCDSelVDD = LCD_DISPCTRL_VLCDSEL_VDD,
/** VLCD Powered by external VDD / Voltage Boost */
lcdVLCDSelVExtBoost = LCD_DISPCTRL_VLCDSEL_VEXTBOOST
} LCD_VLCDSel_TypeDef;
/** Contrast Configuration */
typedef enum
{
/** Contrast is adjusted relative to VDD (VLCD) */
lcdConConfVLCD = LCD_DISPCTRL_CONCONF_VLCD,
/** Contrast is adjusted relative to Ground */
lcdConConfGND = LCD_DISPCTRL_CONCONF_GND
} LCD_ConConf_TypeDef;
/** Voltage Boost Level - Datasheets document setting for each part number */
typedef enum
{
lcdVBoostLevel0 = LCD_DISPCTRL_VBLEV_LEVEL0, /**< Voltage boost LEVEL0 */
lcdVBoostLevel1 = LCD_DISPCTRL_VBLEV_LEVEL1, /**< Voltage boost LEVEL1 */
lcdVBoostLevel2 = LCD_DISPCTRL_VBLEV_LEVEL2, /**< Voltage boost LEVEL2 */
lcdVBoostLevel3 = LCD_DISPCTRL_VBLEV_LEVEL3, /**< Voltage boost LEVEL3 */
lcdVBoostLevel4 = LCD_DISPCTRL_VBLEV_LEVEL4, /**< Voltage boost LEVEL4 */
lcdVBoostLevel5 = LCD_DISPCTRL_VBLEV_LEVEL5, /**< Voltage boost LEVEL5 */
lcdVBoostLevel6 = LCD_DISPCTRL_VBLEV_LEVEL6, /**< Voltage boost LEVEL6 */
lcdVBoostLevel7 = LCD_DISPCTRL_VBLEV_LEVEL7 /**< Voltage boost LEVEL7 */
} LCD_VBoostLevel_TypeDef;
/** Frame Counter Clock Prescaler, FC-CLK = FrameRate (Hz) / this factor */
typedef enum
{
/** Prescale Div 1 */
lcdFCPrescDiv1 = LCD_BACTRL_FCPRESC_DIV1,
/** Prescale Div 2 */
lcdFCPrescDiv2 = LCD_BACTRL_FCPRESC_DIV2,
/** Prescale Div 4 */
lcdFCPrescDiv4 = LCD_BACTRL_FCPRESC_DIV4,
/** Prescale Div 8 */
lcdFCPrescDiv8 = LCD_BACTRL_FCPRESC_DIV8
} LCD_FCPreScale_TypeDef;
/** Segment selection */
typedef enum
{
/** Select segment lines 0 to 3 */
lcdSegment0_3 = (1 << 0),
/** Select segment lines 4 to 7 */
lcdSegment4_7 = (1 << 1),
/** Select segment lines 8 to 11 */
lcdSegment8_11 = (1 << 2),
/** Select segment lines 12 to 15 */
lcdSegment12_15 = (1 << 3),
/** Select segment lines 16 to 19 */
lcdSegment16_19 = (1 << 4),
/** Select segment lines 20 to 23 */
lcdSegment20_23 = (1 << 5),
#if defined(_EFM32_TINY_FAMILY)
/** Select all segment lines */
lcdSegmentAll = (0x003f)
#endif
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** Select segment lines 24 to 27 */
lcdSegment24_27 = (1 << 6),
/** Select segment lines 28 to 31 */
lcdSegment28_31 = (1 << 7),
/** Select segment lines 32 to 35 */
lcdSegment32_35 = (1 << 8),
/** Select segment lines 36 to 39 */
lcdSegment36_39 = (1 << 9),
/** Select all segment lines */
lcdSegmentAll = (0x03ff)
#endif
} LCD_SegmentRange_TypeDef;
/** Update Data Control */
typedef enum
{
/** Regular update, data transfer done immediately */
lcdUpdateCtrlRegular = LCD_CTRL_UDCTRL_REGULAR,
/** Data transfer done at Frame Counter event */
lcdUpdateCtrlFCEvent = LCD_CTRL_UDCTRL_FCEVENT,
/** Data transfer done at Frame Start */
lcdUpdateCtrlFrameStart = LCD_CTRL_UDCTRL_FRAMESTART
} LCD_UpdateCtrl_TypeDef;
/** Animation Shift operation; none, left or right */
typedef enum
{
/** No shift */
lcdAnimShiftNone = _LCD_BACTRL_AREGASC_NOSHIFT,
/** Shift segment bits left */
lcdAnimShiftLeft = _LCD_BACTRL_AREGASC_SHIFTLEFT,
/** Shift segment bits right */
lcdAnimShiftRight = _LCD_BACTRL_AREGASC_SHIFTRIGHT
} LCD_AnimShift_TypeDef;
/** Animation Logic Control, how AReg and BReg should be combined */
typedef enum
{
/** Use bitwise logic AND to mix animation register A (AREGA) and B (AREGB) */
lcdAnimLogicAnd = LCD_BACTRL_ALOGSEL_AND,
/** Use bitwise logic OR to mix animation register A (AREGA) and B (AREGB) */
lcdAnimLogicOr = LCD_BACTRL_ALOGSEL_OR
} LCD_AnimLogic_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** LCD Animation Configuration */
typedef struct
{
/** Enable Animation at end of initialization */
bool enable;
/** Initial Animation Register A Value */
uint32_t AReg;
/** Shift operation of Animation Register A */
LCD_AnimShift_TypeDef AShift;
/** Initial Animation Register B Value */
uint32_t BReg;
/** Shift operation of Animation Register B */
LCD_AnimShift_TypeDef BShift;
/** A and B Logical Operation to use for mixing and outputting resulting segments */
LCD_AnimLogic_TypeDef animLogic;
#if defined(_EFM32_GIANT_FAMILY)
/** Number of first segment to animate. Options are 0 or 8 for Giant/Leopard. End is startSeg+7 */
int startSeg;
#endif
} LCD_AnimInit_TypeDef;
/** LCD Frame Control Initialization */
typedef struct
{
/** Enable at end */
bool enable;
/** Frame Counter top value */
uint32_t top;
/** Frame Counter clock prescaler */
LCD_FCPreScale_TypeDef prescale;
} LCD_FrameCountInit_TypeDef;
/** LCD Controller Initialization structure */
typedef struct
{
/** Enable controller at end of initialization */
bool enable;
/** Mux configuration */
LCD_Mux_TypeDef mux;
/** Bias configuration */
LCD_Bias_TypeDef bias;
/** Wave configuration */
LCD_Wave_TypeDef wave;
/** VLCD Select */
LCD_VLCDSel_TypeDef vlcd;
/** Contrast Configuration */
LCD_ConConf_TypeDef contrast;
} LCD_Init_TypeDef;
/** Default config for LCD init structure, enables 160 segments */
#define LCD_INIT_DEFAULT \
{ true, \
lcdMuxQuadruplex, \
lcdBiasOneThird, \
lcdWaveLowPower, \
lcdVLCDSelVDD, \
lcdConConfVLCD \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void LCD_Init(const LCD_Init_TypeDef *lcdInit);
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd);
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud);
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit);
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit);
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segment, bool enable);
void LCD_SegmentSet(int com, int bit, bool enable);
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits);
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits);
#endif
void LCD_ContrastSet(int level);
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost);
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
void LCD_BiasSegmentSet(int segment, int biasLevel);
void LCD_BiasComSet(int com, int biasLevel);
#endif
static __INLINE void LCD_Enable(bool enable);
static __INLINE void LCD_AnimEnable(bool enable);
static __INLINE void LCD_BlinkEnable(bool enable);
static __INLINE void LCD_BlankEnable(bool enable);
static __INLINE void LCD_FrameCountEnable(bool enable);
static __INLINE int LCD_AnimState(void);
static __INLINE int LCD_BlinkState(void);
static __INLINE void LCD_FreezeEnable(bool enable);
static __INLINE uint32_t LCD_SyncBusyGet(void);
static __INLINE void LCD_SyncBusyDelay(uint32_t flags);
static __INLINE uint32_t LCD_IntGet(void);
static __INLINE uint32_t LCD_IntGetEnabled(void);
static __INLINE void LCD_IntSet(uint32_t flags);
static __INLINE void LCD_IntEnable(uint32_t flags);
static __INLINE void LCD_IntDisable(uint32_t flags);
static __INLINE void LCD_IntClear(uint32_t flags);
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
static __INLINE void LCD_DSCEnable(bool enable);
#endif
/***************************************************************************//**
* @brief
* Enable or disable LCD controller
*
* @param[in] enable
* If true, enables LCD controller with current configuration, if false
* disables LCD controller. CMU clock for LCD must be enabled for correct
* operation.
******************************************************************************/
static __INLINE void LCD_Enable(bool enable)
{
if (enable)
{
LCD->CTRL |= LCD_CTRL_EN;
}
else
{
LCD->CTRL &= ~(LCD_CTRL_EN);
}
}
/***************************************************************************//**
* @brief
* Enables or disables LCD Animation feature
*
* @param[in] enable
* Boolean true enables animation, false disables animation
******************************************************************************/
static __INLINE void LCD_AnimEnable(bool enable)
{
if (enable)
{
LCD->BACTRL |= LCD_BACTRL_AEN;
}
else
{
LCD->BACTRL &= ~(LCD_BACTRL_AEN);
}
}
/***************************************************************************//**
* @brief
* Enables or disables LCD blink
*
* @param[in] enable
* Boolean true enables blink, false disables blink
******************************************************************************/
static __INLINE void LCD_BlinkEnable(bool enable)
{
if (enable)
{
LCD->BACTRL |= LCD_BACTRL_BLINKEN;
}
else
{
LCD->BACTRL &= ~(LCD_BACTRL_BLINKEN);
}
}
/***************************************************************************//**
* @brief
* Disables all segments, while keeping segment state
*
* @param[in] enable
* Boolean true clears all segments, boolean false restores all segment lines
******************************************************************************/
static __INLINE void LCD_BlankEnable(bool enable)
{
if (enable)
{
LCD->BACTRL |= LCD_BACTRL_BLANK;
}
else
{
LCD->BACTRL &= ~(LCD_BACTRL_BLANK);
}
}
/***************************************************************************//**
* @brief
* Enables or disables LCD Frame Control
*
* @param[in] enable
* Boolean true enables frame counter, false disables frame counter
******************************************************************************/
static __INLINE void LCD_FrameCountEnable(bool enable)
{
if (enable)
{
LCD->BACTRL |= LCD_BACTRL_FCEN;
}
else
{
LCD->BACTRL &= ~(LCD_BACTRL_FCEN);
}
}
/***************************************************************************//**
* @brief
* Returns current animation state
*
* @return
* Animation state, in range 0-15
******************************************************************************/
static __INLINE int LCD_AnimState(void)
{
return (int)(LCD->STATUS & _LCD_STATUS_ASTATE_MASK) >> _LCD_STATUS_ASTATE_SHIFT;
}
/***************************************************************************//**
* @brief
* Returns current blink state
*
* @return
* Return value is 1 if segments are enabled, 0 if disabled
******************************************************************************/
static __INLINE int LCD_BlinkState(void)
{
return (int)(LCD->STATUS & _LCD_STATUS_BLINK_MASK) >> _LCD_STATUS_BLINK_SHIFT;
}
/***************************************************************************//**
* @brief
* When set, LCD registers will not be updated until cleared,
*
* @param[in] enable
* When enable is true, update is stopped, when false all registers are
* updated
******************************************************************************/
static __INLINE void LCD_FreezeEnable(bool enable)
{
if (enable)
{
LCD->FREEZE = LCD_FREEZE_REGFREEZE_FREEZE;
}
else
{
LCD->FREEZE = LCD_FREEZE_REGFREEZE_UPDATE;
}
}
/***************************************************************************//**
* @brief
* Returns SYNCBUSY bits, indicating which registers have pending updates
*
* @return
* Bit fields for LCD registers which have pending updates
******************************************************************************/
static __INLINE uint32_t LCD_SyncBusyGet(void)
{
return(LCD->SYNCBUSY);
}
/***************************************************************************//**
* @brief
* Polls LCD SYNCBUSY flags, until flag has been cleared
*
* @param[in] flags
* Bit fields for LCD registers that shall be updated before we continue
******************************************************************************/
static __INLINE void LCD_SyncBusyDelay(uint32_t flags)
{
while (LCD->SYNCBUSY & flags)
;
}
/***************************************************************************//**
* @brief
* Get pending LCD interrupt flags
*
* @return
* Pending LCD interrupt sources. Returns a set of interrupt flags OR-ed
* together for multiple interrupt sources in the LCD module (LCD_IFS_nnn).
******************************************************************************/
static __INLINE uint32_t LCD_IntGet(void)
{
return(LCD->IF);
}
/***************************************************************************//**
* @brief
* Get enabled and pending LCD interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* Pending and enabled LCD interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in LCD_IEN_nnn
* register (LCD_IEN_nnn) and
* - the bitwise OR combination of valid interrupt flags of the LCD module
* (LCD_IF_nnn).
******************************************************************************/
static __INLINE uint32_t LCD_IntGetEnabled(void)
{
uint32_t tmp = 0U;
/* Store LCD->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = LCD->IEN;
/* Bitwise AND of pending and enabled interrupts */
return LCD->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending LCD interrupts from SW.
*
* @param[in] flags
* LCD interrupt sources to set to pending. Use a set of interrupt flags
* OR-ed together to set multiple interrupt sources for the LCD module
* (LCD_IFS_nnn).
******************************************************************************/
static __INLINE void LCD_IntSet(uint32_t flags)
{
LCD->IFS = flags;
}
/***************************************************************************//**
* @brief
* Enable LCD interrupts
*
* @param[in] flags
* LCD interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt sources for the LCD module
* (LCD_IFS_nnn).
******************************************************************************/
static __INLINE void LCD_IntEnable(uint32_t flags)
{
LCD->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Disable LCD interrupts
*
* @param[in] flags
* LCD interrupt sources to disable. Use a set of interrupt flags OR-ed
* together to disable multiple interrupt sources for the LCD module
* (LCD_IFS_nnn).
******************************************************************************/
static __INLINE void LCD_IntDisable(uint32_t flags)
{
LCD->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Clear one or more interrupt flags
*
* @param[in] flags
* LCD interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources for the LCD module
* (LCD_IFS_nnn).
******************************************************************************/
static __INLINE void LCD_IntClear(uint32_t flags)
{
LCD->IFC = flags;
}
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Enable or disable LCD Direct Segment Control
*
* @param[in] enable
* If true, enables LCD controller Direct Segment Control
* Segment and COM line bias levels needs to be set explicitly with the
* LCD_BiasSegmentSet() and LCD_BiasComSet() function calls.
******************************************************************************/
static __INLINE void LCD_DSCEnable(bool enable)
{
if (enable)
{
LCD->CTRL |= LCD_CTRL_DSC;
}
else
{
LCD->CTRL &= ~(LCD_CTRL_DSC);
}
}
#endif
/** @} (end addtogroup LCD) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */
#endif /* __EFM32_LCD_H */

View File

@ -0,0 +1,259 @@
/***************************************************************************//**
* @file
* @brief Low Energy Timer (LETIMER) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_LETIMER_H
#define __EFM32_LETIMER_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LETIMER
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Repeat mode. */
typedef enum
{
/** Count until stopped by SW. */
letimerRepeatFree = _LETIMER_CTRL_REPMODE_FREE,
/** Count REP0 times. */
letimerRepeatOneshot = _LETIMER_CTRL_REPMODE_ONESHOT,
/**
* Count REP0 times, if REP1 has been written to, it is loaded into
* REP0 when REP0 is about to be decremented to 0.
*/
letimerRepeatBuffered = _LETIMER_CTRL_REPMODE_BUFFERED,
/**
* Run as long as both REP0 and REP1 are not 0. Both REP0 and REP1
* are decremented when counter underflows.
*/
letimerRepeatDouble = _LETIMER_CTRL_REPMODE_DOUBLE
} LETIMER_RepeatMode_TypeDef;
/** Underflow action on output. */
typedef enum
{
/** No output action. */
letimerUFOANone = _LETIMER_CTRL_UFOA0_NONE,
/** Toggle output when counter underflows. */
letimerUFOAToggle = _LETIMER_CTRL_UFOA0_TOGGLE,
/** Hold output one LETIMER clock cycle when counter underflows. */
letimerUFOAPulse = _LETIMER_CTRL_UFOA0_PULSE,
/** Set output idle when counter underflows, and active when matching COMP1. */
letimerUFOAPwm = _LETIMER_CTRL_UFOA0_PWM
} LETIMER_UFOA_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** LETIMER initialization structure. */
typedef struct
{
bool enable; /**< Start counting when init completed. */
bool debugRun; /**< Counter shall keep running during debug halt. */
bool rtcComp0Enable; /**< Start counting on RTC COMP0 match. */
bool rtcComp1Enable; /**< Start counting on RTC COMP1 match. */
bool comp0Top; /**< Load COMP0 register into CNT when counter underflows. */
bool bufTop; /**< Load COMP1 into COMP0 when REP0 reaches 0. */
uint8_t out0Pol; /**< Idle value for output 0. */
uint8_t out1Pol; /**< Idle value for output 1. */
LETIMER_UFOA_TypeDef ufoa0; /**< Underflow output 0 action. */
LETIMER_UFOA_TypeDef ufoa1; /**< Underflow output 1 action. */
LETIMER_RepeatMode_TypeDef repMode; /**< Repeat mode. */
} LETIMER_Init_TypeDef;
/** Default config for LETIMER init structure. */
#define LETIMER_INIT_DEFAULT \
{ true, /* Enable timer when init complete. */ \
false, /* Stop counter during debug halt. */ \
false, /* Do not start counting on RTC COMP0 match. */ \
false, /* Do not start counting on RTC COMP1 match. */ \
false, /* Do not load COMP0 into CNT on underflow. */ \
false, /* Do not load COMP1 into COMP0 when REP0 reaches 0. */ \
0, /* Idle value 0 for output 0. */ \
0, /* Idle value 0 for output 1. */ \
letimerUFOANone, /* No action on underflow on output 0. */ \
letimerUFOANone, /* No action on underflow on output 1. */ \
letimerRepeatFree /* Count until stopped by SW. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp);
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
unsigned int comp,
uint32_t value);
/***************************************************************************//**
* @brief
* Get LETIMER counter value.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @return
* Current LETIMER counter value.
******************************************************************************/
static __INLINE uint32_t LETIMER_CounterGet(LETIMER_TypeDef *letimer)
{
return(letimer->CNT);
}
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable);
void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable);
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending LETIMER interrupts.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* Pending LETIMER interrupt source to clear. Use a bitwise logic OR
* combination of valid interrupt flags for the LETIMER module
* (LETIMER_IF_nnn).
******************************************************************************/
static __INLINE void LETIMER_IntClear(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more LETIMER interrupts.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
static __INLINE void LETIMER_IntDisable(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more LETIMER interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using LETIMER_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
static __INLINE void LETIMER_IntEnable(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending LETIMER interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @return
* LETIMER interrupt sources pending. A bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
static __INLINE uint32_t LETIMER_IntGet(LETIMER_TypeDef *letimer)
{
return(letimer->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending LETIMER interrupts from SW.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to set to pending. Use a bitwise logic OR
* combination of valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
static __INLINE void LETIMER_IntSet(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IFS = flags;
}
uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep);
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
unsigned int rep,
uint32_t value);
void LETIMER_Reset(LETIMER_TypeDef *letimer);
/** @} (end addtogroup LETIMER) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_LETIMER_H */

View File

@ -0,0 +1,255 @@
/***************************************************************************//**
* @file
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
* peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_LEUART_H
#define __EFM32_LEUART_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LEUART
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Databit selection. */
typedef enum
{
leuartDatabits8 = LEUART_CTRL_DATABITS_EIGHT, /**< 8 databits. */
leuartDatabits9 = LEUART_CTRL_DATABITS_NINE /**< 9 databits. */
} LEUART_Databits_TypeDef;
/** Enable selection. */
typedef enum
{
/** Disable both receiver and transmitter. */
leuartDisable = 0x0,
/** Enable receiver only, transmitter disabled. */
leuartEnableRx = LEUART_CMD_RXEN,
/** Enable transmitter only, receiver disabled. */
leuartEnableTx = LEUART_CMD_TXEN,
/** Enable both receiver and transmitter. */
leuartEnable = (LEUART_CMD_RXEN | LEUART_CMD_TXEN)
} LEUART_Enable_TypeDef;
/** Parity selection. */
typedef enum
{
leuartNoParity = LEUART_CTRL_PARITY_NONE, /**< No parity. */
leuartEvenParity = LEUART_CTRL_PARITY_EVEN, /**< Even parity. */
leuartOddParity = LEUART_CTRL_PARITY_ODD /**< Odd parity. */
} LEUART_Parity_TypeDef;
/** Stopbits selection. */
typedef enum
{
leuartStopbits1 = LEUART_CTRL_STOPBITS_ONE, /**< 1 stopbits. */
leuartStopbits2 = LEUART_CTRL_STOPBITS_TWO /**< 2 stopbits. */
} LEUART_Stopbits_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Init structure. */
typedef struct
{
/** Specifies whether TX and/or RX shall be enabled when init completed. */
LEUART_Enable_TypeDef enable;
/**
* LEUART reference clock assumed when configuring baudrate setup. Set
* it to 0 if currently configurated reference clock shall be used.
*/
uint32_t refFreq;
/** Desired baudrate. */
uint32_t baudrate;
/** Number of databits in frame. */
LEUART_Databits_TypeDef databits;
/** Parity mode to use. */
LEUART_Parity_TypeDef parity;
/** Number of stopbits to use. */
LEUART_Stopbits_TypeDef stopbits;
} LEUART_Init_TypeDef;
/** Default config for LEUART init structure. */
#define LEUART_INIT_DEFAULT \
{ leuartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
9600, /* 9600 bits/s. */ \
leuartDatabits8, /* 8 databits. */ \
leuartNoParity, /* No parity. */ \
leuartStopbits1 /* 1 stopbit. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv);
uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart);
void LEUART_BaudrateSet(LEUART_TypeDef *leuart,
uint32_t refFreq,
uint32_t baudrate);
void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable);
void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable);
void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending LEUART interrupts.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] flags
* Pending LEUART interrupt source to clear. Use a bitwise logic OR
* combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).
******************************************************************************/
static __INLINE void LEUART_IntClear(LEUART_TypeDef *leuart, uint32_t flags)
{
leuart->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more LEUART interrupts.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] flags
* LEUART interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the LEUART module (LEUART_IF_nnn).
******************************************************************************/
static __INLINE void LEUART_IntDisable(LEUART_TypeDef *leuart, uint32_t flags)
{
leuart->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more LEUART interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using LEUART_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] flags
* LEUART interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the LEUART module (LEUART_IF_nnn).
******************************************************************************/
static __INLINE void LEUART_IntEnable(LEUART_TypeDef *leuart, uint32_t flags)
{
leuart->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending LEUART interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @return
* LEUART interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the LEUART module (LEUART_IF_nnn).
******************************************************************************/
static __INLINE uint32_t LEUART_IntGet(LEUART_TypeDef *leuart)
{
return(leuart->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending LEUART interrupts from SW.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] flags
* LEUART interrupt sources to set to pending. Use a bitwise logic OR
* combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).
******************************************************************************/
static __INLINE void LEUART_IntSet(LEUART_TypeDef *leuart, uint32_t flags)
{
leuart->IFS = flags;
}
void LEUART_Reset(LEUART_TypeDef *leuart);
uint8_t LEUART_Rx(LEUART_TypeDef *leuart);
uint16_t LEUART_RxExt(LEUART_TypeDef *leuart);
void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data);
void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data);
/** @} (end addtogroup LEUART) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_LEUART_H */

View File

@ -0,0 +1,236 @@
/***************************************************************************//**
* @file
* @brief Memory protection unit (MPU) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_MPU_H
#define __EFM32_MPU_H
#include "efm32.h"
#if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1)
#include "efm32_assert.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup MPU
* @{
******************************************************************************/
/** @anchor MPU_CTRL_PRIVDEFENA
* Argument to MPU_enable(). Enables priviledged
* access to default memory map. */
#define MPU_CTRL_PRIVDEFENA MPU_CTRL_PRIVDEFENA_Msk
/** @anchor MPU_CTRL_HFNMIENA
* Argument to MPU_enable(). Enables MPU during hard fault,
* NMI, and FAULTMASK handlers. */
#define MPU_CTRL_HFNMIENA MPU_CTRL_HFNMIENA_Msk
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/**
* Size of an MPU region.
*/
typedef enum
{
mpuRegionSize32b = 4, /**< 32 byte region size. */
mpuRegionSize64b = 5, /**< 64 byte region size. */
mpuRegionSize128b = 6, /**< 128 byte region size. */
mpuRegionSize256b = 7, /**< 256 byte region size. */
mpuRegionSize512b = 8, /**< 512 byte region size. */
mpuRegionSize1Kb = 9, /**< 1K byte region size. */
mpuRegionSize2Kb = 10, /**< 2K byte region size. */
mpuRegionSize4Kb = 11, /**< 4K byte region size. */
mpuRegionSize8Kb = 12, /**< 8K byte region size. */
mpuRegionSize16Kb = 13, /**< 16K byte region size. */
mpuRegionSize32Kb = 14, /**< 32K byte region size. */
mpuRegionSize64Kb = 15, /**< 64K byte region size. */
mpuRegionSize128Kb = 16, /**< 128K byte region size. */
mpuRegionSize256Kb = 17, /**< 256K byte region size. */
mpuRegionSize512Kb = 18, /**< 512K byte region size. */
mpuRegionSize1Mb = 19, /**< 1M byte region size. */
mpuRegionSize2Mb = 20, /**< 2M byte region size. */
mpuRegionSize4Mb = 21, /**< 4M byte region size. */
mpuRegionSize8Mb = 22, /**< 8M byte region size. */
mpuRegionSize16Mb = 23, /**< 16M byte region size. */
mpuRegionSize32Mb = 24, /**< 32M byte region size. */
mpuRegionSize64Mb = 25, /**< 64M byte region size. */
mpuRegionSize128Mb = 26, /**< 128M byte region size. */
mpuRegionSize256Mb = 27, /**< 256M byte region size. */
mpuRegionSize512Mb = 28, /**< 512M byte region size. */
mpuRegionSize1Gb = 29, /**< 1G byte region size. */
mpuRegionSize2Gb = 30, /**< 2G byte region size. */
mpuRegionSize4Gb = 31 /**< 4G byte region size. */
} MPU_RegionSize_TypeDef;
/**
* MPU region access permission attributes.
*/
typedef enum
{
mpuRegionNoAccess = 0, /**< No access what so ever. */
mpuRegionApPRw = 1, /**< Priviledged state R/W only. */
mpuRegionApPRwURo = 2, /**< Priviledged state R/W, User state R only. */
mpuRegionApFullAccess = 3, /**< R/W in Priviledged and User state. */
mpuRegionApPRo = 5, /**< Priviledged R only. */
mpuRegionApPRo_URo = 6 /**< R only in Priviledged and User state. */
} MPU_RegionAp_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** MPU Region init structure. */
typedef struct
{
bool regionEnable; /**< MPU region enable. */
uint8_t regionNo; /**< MPU region number. */
uint32_t baseAddress; /**< Region baseaddress. */
MPU_RegionSize_TypeDef size; /**< Memory region size. */
MPU_RegionAp_TypeDef accessPermission; /**< Memory access permissions. */
bool disableExec; /**< Disable execution. */
bool shareable; /**< Memory shareable attribute. */
bool cacheable; /**< Memory cacheable attribute. */
bool bufferable; /**< Memory bufferable attribute. */
uint8_t srd; /**< Memory subregion disable bits. */
uint8_t tex; /**< Memory type extension attributes. */
} MPU_RegionInit_TypeDef;
/** Default configuration of MPU region init structure for flash memory. */
#define MPU_INIT_FLASH_DEFAULT \
{ \
true, /* Enable MPU region. */ \
0, /* MPU Region number. */ \
FLASH_MEM_BASE, /* Flash base address. */ \
mpuRegionSize1Mb, /* Size - Set to max. for EFM32. */ \
mpuRegionApFullAccess, /* Access permissions. */ \
false, /* Execution allowed. */ \
false, /* Not shareable. */ \
true, /* Cacheable. */ \
false, /* Not bufferable. */ \
0, /* No subregions. */ \
0 /* No TEX attributes. */ \
}
/** Default configuration of MPU region init structure for sram memory. */
#define MPU_INIT_SRAM_DEFAULT \
{ \
true, /* Enable MPU region. */ \
1, /* MPU Region number. */ \
RAM_MEM_BASE, /* SRAM base address. */ \
mpuRegionSize128Kb, /* Size - Set to max. for EFM32. */ \
mpuRegionApFullAccess, /* Access permissions. */ \
false, /* Execution allowed. */ \
true, /* Shareable. */ \
true, /* Cacheable. */ \
false, /* Not bufferable. */ \
0, /* No subregions. */ \
0 /* No TEX attributes. */ \
}
/** Default configuration of MPU region init structure for onchip peripherals.*/
#define MPU_INIT_PERIPHERAL_DEFAULT \
{ \
true, /* Enable MPU region. */ \
0, /* MPU Region number. */ \
0, /* Region base address. */ \
mpuRegionSize32b, /* Size - Set to minimum */ \
mpuRegionApFullAccess, /* Access permissions. */ \
true, /* Execution not allowed. */ \
true, /* Shareable. */ \
false, /* Not cacheable. */ \
true, /* Bufferable. */ \
0, /* No subregions. */ \
0 /* No TEX attributes. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void MPU_ConfigureRegion(const MPU_RegionInit_TypeDef *init);
/***************************************************************************//**
* @brief
* Disable the MPU
* @details
* Disable MPU and MPU fault exceptions.
******************************************************************************/
static __INLINE void MPU_Disable(void)
{
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; /* Disable fault exceptions */
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; /* Disable the MPU */
}
/***************************************************************************//**
* @brief
* Enable the MPU
* @details
* Enable MPU and MPU fault exceptions.
* @param[in] flags
* Use a logical OR of @ref MPU_CTRL_PRIVDEFENA and
* @ref MPU_CTRL_HFNMIENA as needed.
******************************************************************************/
static __INLINE void MPU_Enable(uint32_t flags)
{
EFM_ASSERT(!(flags & ~(MPU_CTRL_PRIVDEFENA_Msk |
MPU_CTRL_HFNMIENA_Msk |
MPU_CTRL_ENABLE_Msk)));
MPU->CTRL = flags | MPU_CTRL_ENABLE_Msk; /* Enable the MPU */
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; /* Enable fault exceptions */
}
/** @} (end addtogroup MPU) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* defined(__MPU_PRESENT) && (EBI_COUNT == 1) */
#endif /* __EFM32_MPU_H */

View File

@ -0,0 +1,367 @@
/***************************************************************************//**
* @file
* @brief Flash controller module (MSC) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_MSC_H
#define __EFM32_MSC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "efm32.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup MSC
* @brief Flash controller (MSC) peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************* DEFINES *****************************************
******************************************************************************/
/**
* @brief
* The timeout used while waiting for the flash to become ready after
* a write. This number indicates the number of iterations to perform before
* issuing a timeout.
* @note
* This timeout is set very large (in the order of 100x longer than
* necessary). This is to avoid any corner cases.
*
*/
#define MSC_PROGRAM_TIMEOUT 10000000ul
/*******************************************************************************
************************* TYPEDEFS ****************************************
******************************************************************************/
/** Return codes for writing/erasing the flash */
typedef enum
{
mscReturnOk = 0, /**< Flash write/erase successful. */
mscReturnInvalidAddr = -1, /**< Invalid address. Write to an address that is not flash. */
mscReturnLocked = -2, /**< Flash address is locked. */
mscReturnTimeOut = -3, /**< Timeout while writing to flash. */
mscReturnUnaligned = -4 /**< Unaligned access to flash. */
} msc_Return_TypeDef;
#if defined (_EFM32_GIANT_FAMILY)
/** Strategy for prioritized bus access */
typedef enum {
mscBusStrategyCPU = MSC_READCTRL_BUSSTRATEGY_CPU, /**< Prioritize CPU bus accesses */
mscBusStrategyDMA = MSC_READCTRL_BUSSTRATEGY_DMA, /**< Prioritize DMA bus accesses */
mscBusStrategyDMAEM2 = MSC_READCTRL_BUSSTRATEGY_DMAEM2, /**< Prioritize DMAEM2 for bus accesses */
mscBusStrategyNone = MSC_READCTRL_BUSSTRATEGY_NONE /**< No unit has bus priority */
} mscBusStrategy_Typedef;
#endif
/*******************************************************************************
************************* PROTOTYPES **************************************
******************************************************************************/
void MSC_Deinit(void);
void MSC_Init(void);
/***************************************************************************//**
* @brief
* Clear one or more pending MSC interrupts.
*
* @param[in] flags
* Pending MSC intterupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
static __INLINE void MSC_IntClear(uint32_t flags)
{
MSC->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more MSC interrupts.
*
* @param[in] flags
* MSC interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
static __INLINE void MSC_IntDisable(uint32_t flags)
{
MSC->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more MSC interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using MSC_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] flags
* MSC interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
static __INLINE void MSC_IntEnable(uint32_t flags)
{
MSC->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending MSV interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* MSC interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
static __INLINE uint32_t MSC_IntGet(void)
{
return(MSC->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending MSC interrupts from SW.
*
* @param[in] flags
* MSC interrupt sources to set to pending. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
static __INLINE void MSC_IntSet(uint32_t flags)
{
MSC->IFS = flags;
}
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Starts measuring cache hit ratio.
* @details
* This function starts the performance counters. It is defined inline to
* minimize the impact of this code on the measurement itself.
******************************************************************************/
static __INLINE void MSC_StartCacheMeasurement(void)
{
/* Clear CMOF and CHOF to catch these later */
MSC->IFC = MSC_IF_CHOF | MSC_IF_CMOF;
/* Start performance counters */
MSC->CMD = MSC_CMD_STARTPC;
}
/***************************************************************************//**
* @brief
* Stops measuring the hit rate.
* @note
* This function is defined inline to minimize the impact of this
* code on the measurement itself.
* This code only works for relatively short sections of code. If you wish
* to measure longer sections of code you need to implement a IRQ Handler for
* The CHOF and CMOF overflow interrupts. Theses overflows needs to be
* counted and included in the total.
* The functions can then be implemented as follows:
* @verbatim
* volatile uint32_t hitOverflows
* volatile uint32_t missOverflows
*
* void MSC_IRQHandler(void)
* {
* uint32_t flags;
* flags = MSC->IF;
* if (flags & MSC_IF_CHOF)
* {
* MSC->IFC = MSC_IF_CHOF;
* hitOverflows++;
* }
* if (flags & MSC_IF_CMOF)
* {
* MSC->IFC = MSC_IF_CMOF;
* missOverflows++;
* }
* }
*
* void startPerformanceCounters(void)
* {
* hitOverflows = 0;
* missOverflows = 0;
*
* MSC_IntEnable(MSC_IF_CHOF | MSC_IF_CMOF);
* NVIC_EnableIRQ(MSC_IRQn);
*
* MSC_StartCacheMeasurement();
* }
* @endverbatim
* @return
* Returns -1 if there has been no cache accesses.
* Returns -2 if there has been an overflow in the performance counters.
* If not, it will return the percentage of hits versus misses.
******************************************************************************/
static __INLINE int32_t MSC_GetCacheMeasurement(void)
{
int32_t total;
/* Stop the counter before computing the hit-rate */
MSC->CMD = MSC_CMD_STOPPC;
/* Check for overflows in performance counters */
if (MSC->IF & (MSC_IF_CHOF | MSC_IF_CMOF))
return -2;
/* Because the hits and misses are volatile, we need to split this up into
* two statements to avoid a compiler warning regarding the order of volatile
* accesses. */
total = MSC->CACHEHITS;
total += MSC->CACHEMISSES;
/* To avoid a division by zero. */
if (total == 0)
return -1;
return (MSC->CACHEHITS * 100) / total;
}
/***************************************************************************//**
* @brief
* Flush the contents of the instruction cache.
******************************************************************************/
static __INLINE void MSC_FlushCache(void)
{
MSC->CMD = MSC_CMD_INVCACHE;
}
/***************************************************************************//**
* @brief
* Enable or disable instruction cache functionality
* @param[in] enable
* Enable instruction cache. Default is on.
******************************************************************************/
static __INLINE void MSC_EnableCache(bool enable)
{
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_IFCDIS_SHIFT, ~enable);
}
/***************************************************************************//**
* @brief
* Enable or disable instruction cache functionality in IRQs
* @param[in] enable
* Enable instruction cache. Default is on.
******************************************************************************/
static __INLINE void MSC_EnableCacheIRQs(bool enable)
{
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_ICCDIS_SHIFT, ~enable);
}
/***************************************************************************//**
* @brief
* Enable or disable instruction cache flushing when writing to flash
* @param[in] enable
* Enable automatic cache flushing. Default is on.
******************************************************************************/
static __INLINE void MSC_EnableAutoCacheFlush(bool enable)
{
BITBAND_Peripheral(&(MSC->READCTRL), _MSC_READCTRL_AIDIS_SHIFT, ~enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Configure which unit should get priority on system bus.
* @param[in] mode
* Unit to prioritize bus accesses for.
******************************************************************************/
static __INLINE void MSC_BusStrategy(mscBusStrategy_Typedef mode)
{
MSC->READCTRL = (MSC->READCTRL & ~(_MSC_READCTRL_BUSSTRATEGY_MASK))|mode;
}
#endif
#ifdef __CC_ARM /* MDK-ARM compiler */
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes);
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress);
#if defined (_EFM32_GIANT_FAMILY)
msc_Return_TypeDef MSC_MassErase(void);
#endif
#endif /* __CC_ARM */
#ifdef __ICCARM__ /* IAR compiler */
__ramfunc msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes);
__ramfunc msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress);
#if defined (_EFM32_GIANT_FAMILY)
__ramfunc msc_Return_TypeDef MSC_MassErase(void);
#endif
#endif /* __ICCARM__ */
#ifdef __GNUC__ /* GCC based compilers */
#ifdef __CROSSWORKS_ARM /* Rowley Crossworks */
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes) __attribute__ ((section(".fast")));
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".fast")));
#if defined (_EFM32_GIANT_FAMILY)
msc_Return_TypeDef MSC_MassErase(void) __attribute__ ((section(".fast")));
#endif
#else /* Sourcery G++ */
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes) __attribute__ ((section(".ram")));
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress) __attribute__ ((section(".ram")));
#if defined (_EFM32_GIANT_FAMILY)
msc_Return_TypeDef MSC_MassErase(void) __attribute__ ((section(".ram")));
#endif
#endif /* __GNUC__ */
#endif /* __CROSSWORKS_ARM */
/** @} (end addtogroup MSC) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_MSC_H */

View File

@ -0,0 +1,538 @@
/**************************************************************************//**
* @file
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#ifndef __EFM32_OPAMP_H
#define __EFM32_OPAMP_H
#include "efm32.h"
#if defined(OPAMP_PRESENT) && (OPAMP_COUNT == 1)
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "efm32_dac.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup OPAMP
* @{
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of DAC OPA number for assert statements. */
#define DAC_OPA_VALID(opa) ((opa) <= OPA2)
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** OPAMP selector values. */
typedef enum
{
OPA0 = 0, /**< Select OPA0. */
OPA1 = 1, /**< Select OPA1. */
OPA2 = 2 /**< Select OPA2. */
} OPAMP_TypeDef;
/** OPAMP negative terminal input selection values. */
typedef enum
{
opaNegSelDisable = DAC_OPA0MUX_NEGSEL_DISABLE, /**< Input disabled. */
opaNegSelUnityGain = DAC_OPA0MUX_NEGSEL_UG, /**< Unity gain feedback path. */
opaNegSelResTap = DAC_OPA0MUX_NEGSEL_OPATAP, /**< Feedback resistor ladder tap. */
opaNegSelNegPad = DAC_OPA0MUX_NEGSEL_NEGPAD /**< Negative pad as input. */
} OPAMP_NegSel_TypeDef;
/** OPAMP positive terminal input selection values. */
typedef enum
{
opaPosSelDisable = DAC_OPA0MUX_POSSEL_DISABLE, /**< Input disabled. */
opaPosSelDac = DAC_OPA0MUX_POSSEL_DAC, /**< DAC as input (not OPA2). */
opaPosSelPosPad = DAC_OPA0MUX_POSSEL_POSPAD, /**< Positive pad as input. */
opaPosSelOpaIn = DAC_OPA0MUX_POSSEL_OPA0INP, /**< Input from OPAx. */
opaPosSelResTapOpa0 = DAC_OPA0MUX_POSSEL_OPATAP /**< Feedback resistor ladder tap from OPA0. */
} OPAMP_PosSel_TypeDef;
/** OPAMP output terminal selection values. */
typedef enum
{
opaOutModeDisable = DAC_OPA0MUX_OUTMODE_DISABLE, /**< OPA output disabled. */
opaOutModeMain = DAC_OPA0MUX_OUTMODE_MAIN, /**< Main output to pin enabled. */
opaOutModeAlt = DAC_OPA0MUX_OUTMODE_ALT, /**< Alternate output(s) enabled (not OPA2). */
opaOutModeAll = DAC_OPA0MUX_OUTMODE_ALL /**< Both main and alternate enabled (not OPA2). */
} OPAMP_OutMode_TypeDef;
/** OPAMP gain values. */
typedef enum
{
opaResSelDefault = DAC_OPA0MUX_RESSEL_DEFAULT, /**< Default value when resistor ladder is unused. */
opaResSelR2eq0_33R1 = DAC_OPA0MUX_RESSEL_RES0, /**< R2 = 0.33 * R1 */
opaResSelR2eqR1 = DAC_OPA0MUX_RESSEL_RES1, /**< R2 = R1 */
opaResSelR1eq1_67R1 = DAC_OPA0MUX_RESSEL_RES2, /**< R2 = 1.67 R1 */
opaResSelR2eq2R1 = DAC_OPA0MUX_RESSEL_RES3, /**< R2 = 2 * R1 */
opaResSelR2eq3R1 = DAC_OPA0MUX_RESSEL_RES4, /**< R2 = 3 * R1 */
opaResSelR2eq4_33R1 = DAC_OPA0MUX_RESSEL_RES5, /**< R2 = 4.33 * R1 */
opaResSelR2eq7R1 = DAC_OPA0MUX_RESSEL_RES6, /**< R2 = 7 * R1 */
opaResSelR2eq15R1 = DAC_OPA0MUX_RESSEL_RES7 /**< R2 = 15 * R1 */
} OPAMP_ResSel_TypeDef;
/** OPAMP resistor ladder input selector values. */
typedef enum
{
opaResInMuxDisable = DAC_OPA0MUX_RESINMUX_DISABLE, /**< Resistor ladder disabled. */
opaResInMuxOpaIn = DAC_OPA0MUX_RESINMUX_OPA0INP, /**< Input from OPAx. */
opaResInMuxNegPad = DAC_OPA0MUX_RESINMUX_NEGPAD, /**< Input from negative pad. */
opaResInMuxPosPad = DAC_OPA0MUX_RESINMUX_POSPAD, /**< Input from positive pad. */
opaResInMuxVss = DAC_OPA0MUX_RESINMUX_VSS /**< Input connected to Vss. */
} OPAMP_ResInMux_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** OPAMP init structure. */
typedef struct
{
OPAMP_NegSel_TypeDef negSel; /**< Select input source for negative terminal. */
OPAMP_PosSel_TypeDef posSel; /**< Select input source for positive terminal. */
OPAMP_OutMode_TypeDef outMode; /**< Output terminal connection. */
OPAMP_ResSel_TypeDef resSel; /**< Select R2/R1 resistor ratio. */
OPAMP_ResInMux_TypeDef resInMux; /**< Select input source for resistor ladder. */
uint32_t outPen; /**< Select alternate output terminal connections. */
uint32_t bias; /**< Set OPAMP bias current. */
bool halfBias; /**< Divide OPAMP bias current by 2. */
bool lpfPosPadDisable; /**< Disable low pass filter on positive pad. */
bool lpfNegPadDisable; /**< Disable low pass filter on negative pad. */
bool nextOut; /**< Enable NEXTOUT signal source. */
bool npEn; /**< Enable positive pad. */
bool ppEn; /**< Enable negative pad. */
bool shortInputs; /**< Short OPAMP input terminals. */
bool hcmDisable; /**< Disable input rail-to-rail capability. */
bool defaultOffset; /**< Use factory calibrated opamp offset value. */
uint32_t offset; /**< Opamp offset value when @ref defaultOffset is false.*/
} OPAMP_Init_TypeDef;
/** Configuration of OPA0/1 in unity gain voltage follower mode. */
#define OPA_INIT_UNITY_GAIN \
{ \
opaNegSelUnityGain, /* Unity gain. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelDefault, /* Resistor ladder is not used. */ \
opaResInMuxDisable, /* Resistor ladder disabled. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in unity gain voltage follower mode. */
#define OPA_INIT_UNITY_GAIN_OPA2 \
{ \
opaNegSelUnityGain, /* Unity gain. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelDefault, /* Resistor ladder is not used. */ \
opaResInMuxDisable, /* Resistor ladder disabled. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0/1 in non-inverting amplifier mode. */
#define OPA_INIT_NON_INVERTING \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
true, /* Neg pad enabled, used as signal ground. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in non-inverting amplifier mode. */
#define OPA_INIT_NON_INVERTING_OPA2 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
true, /* Neg pad enabled, used as signal ground. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0/1 in inverting amplifier mode. */
#define OPA_INIT_INVERTING \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
true, /* Neg pad enabled, used as signal input. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in inverting amplifier mode. */
#define OPA_INIT_INVERTING_OPA2 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
true, /* Neg pad enabled, used as signal input. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0 in cascaded non-inverting amplifier mode. */
#define OPA_INIT_CASCADED_NON_INVERTING_OPA0 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA1). */ \
true, /* Neg pad enabled, used as signal ground. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA1 in cascaded non-inverting amplifier mode. */
#define OPA_INIT_CASCADED_NON_INVERTING_OPA1 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelOpaIn, /* Pos input from OPA0 output. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA2). */ \
true, /* Neg pad enabled, used as signal ground. */ \
false, /* Pos pad disabled. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in cascaded non-inverting amplifier mode. */
#define OPA_INIT_CASCADED_NON_INVERTING_OPA2 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelOpaIn, /* Pos input from OPA1 output. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eq0_33R1, /* R2 = 1/3 R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
true, /* Neg pad enabled, used as signal ground. */ \
false, /* Pos pad disabled. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0 in cascaded inverting amplifier mode. */
#define OPA_INIT_CASCADED_INVERTING_OPA0 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA1). */ \
true, /* Neg pad enabled, used as signal input. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA1 in cascaded inverting amplifier mode. */
#define OPA_INIT_CASCADED_INVERTING_OPA1 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxOpaIn, /* Resistor ladder input from OPA0. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA2). */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in cascaded inverting amplifier mode. */
#define OPA_INIT_CASCADED_INVERTING_OPA2 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxOpaIn, /* Resistor ladder input from OPA1. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Alternate output 0 enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0 in two-opamp differential driver mode. */
#define OPA_INIT_DIFF_DRIVER_OPA0 \
{ \
opaNegSelUnityGain, /* Unity gain. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelDefault, /* Resistor ladder is not used. */ \
opaResInMuxDisable, /* Resistor ladder disabled. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA1). */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA1 in two-opamp differential driver mode. */
#define OPA_INIT_DIFF_DRIVER_OPA1 \
{ \
opaNegSelResTap, /* Neg input from resistor ladder tap. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxOpaIn, /* Resistor ladder input from OPA0. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal ground. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA0 in three-opamp differential receiver mode. */
#define OPA_INIT_DIFF_RECEIVER_OPA0 \
{ \
opaNegSelUnityGain, /* Unity gain. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxNegPad, /* Resistor ladder input from neg pad. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA2). */ \
true, /* Neg pad enabled, used as signal ground. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA1 in three-opamp differential receiver mode. */
#define OPA_INIT_DIFF_RECEIVER_OPA1 \
{ \
opaNegSelUnityGain, /* Unity gain. */ \
opaPosSelPosPad, /* Pos input from pad. */ \
opaOutModeAll, /* Both main and alternate outputs. */ \
opaResSelDefault, /* Resistor ladder is not used. */ \
opaResInMuxDisable, /* Disable resistor ladder. */ \
0, /* No alternate outputs enabled. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
true, /* Pass output to next stage (OPA2). */ \
false, /* Neg pad disabled. */ \
true, /* Pos pad enabled, used as signal input. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/** Configuration of OPA2 in three-opamp differential receiver mode. */
#define OPA_INIT_DIFF_RECEIVER_OPA2 \
{ \
opaNegSelResTap, /* Input from resistor ladder tap. */ \
opaPosSelResTapOpa0, /* Input from OPA0 resistor ladder tap. */ \
opaOutModeMain, /* Main output enabled. */ \
opaResSelR2eqR1, /* R2 = R1 */ \
opaResInMuxOpaIn, /* Resistor ladder input from OPA1. */ \
DAC_OPA0MUX_OUTPEN_OUT0, /* Enable alternate output 0. */ \
_DAC_BIASPROG_BIASPROG_DEFAULT, /* Default bias setting. */ \
_DAC_BIASPROG_HALFBIAS_DEFAULT, /* Default half-bias setting. */ \
false, /* No low pass filter on pos pad. */ \
false, /* No low pass filter on neg pad. */ \
false, /* No nextout output enabled. */ \
false, /* Neg pad disabled. */ \
false, /* Pos pad disabled. */ \
false, /* No shorting of inputs. */ \
false, /* Rail-to-rail input enabled. */ \
true, /* Use factory calibrated opamp offset. */ \
0 /* Opamp offset value (not used). */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void OPAMP_Disable(DAC_TypeDef *dac, OPAMP_TypeDef opa);
void OPAMP_Enable(DAC_TypeDef *dac, OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init);
/** @} (end addtogroup OPAMP) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) */
#endif /* __EFM32_DAC_H */

View File

@ -0,0 +1,454 @@
/***************************************************************************//**
* @file
* @brief Pulse Counter (PCNT) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_PCNT_H
#define __EFM32_PCNT_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup PCNT
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Mode selection. */
typedef enum
{
/** Disable pulse counter. */
pcntModeDisable = _PCNT_CTRL_MODE_DISABLE,
/** Single input LFACLK oversampling mode (available in EM0-EM2). */
pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE,
/** Externally clocked single input counter mode (available in EM0-EM3). */
pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE,
/** Externally clocked quadrature decoder mode (available in EM0-EM3). */
pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD
} PCNT_Mode_TypeDef;
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
/** Counter event selection.
* Note: unshifted values are being used for enumeration because multiple
* configuration structure members use this type definition. */
typedef enum
{
/** Counts up on up-count and down on down-count events. */
pcntCntEventBoth = _PCNT_CTRL_CNTEV_BOTH,
/** Only counts up on up-count events. */
pcntCntEventUp = _PCNT_CTRL_CNTEV_UP,
/** Only counts down on down-count events. */
pcntCntEventDown = _PCNT_CTRL_CNTEV_DOWN,
/** Never counts. */
pcntCntEventNone = _PCNT_CTRL_CNTEV_NONE
} PCNT_CntEvent_TypeDef;
/** PRS sources for @p s0PRS and @p s1PRS. */
typedef enum
{
pcntPRSCh0 = 0, /**< PRS channel 0. */
pcntPRSCh1 = 1, /**< PRS channel 1. */
pcntPRSCh2 = 2, /**< PRS channel 2. */
pcntPRSCh3 = 3, /**< PRS channel 3. */
pcntPRSCh4 = 4, /**< PRS channel 4. */
pcntPRSCh5 = 5, /**< PRS channel 5. */
pcntPRSCh6 = 6, /**< PRS channel 6. */
pcntPRSCh7 = 7 /**< PRS channel 7. */
} PCNT_PRSSel_TypeDef;
/** PRS inputs of PCNT. */
typedef enum
{
pcntPRSInputS0 = 0, /** PRS input 0. */
pcntPRSInputS1 = 1 /** PRS input 1. */
} PCNT_PRSInput_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Init structure. */
typedef struct
{
/** Mode to operate in. */
PCNT_Mode_TypeDef mode;
/** Initial counter value (refer to reference manual for max value allowed).
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, the counter
* value is reset to HW reset value. */
uint32_t counter;
/** Initial top value (refer to reference manual for max value allowed).
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, the top
* value is reset to HW reset value. */
uint32_t top;
/** Polarity of incoming edge.
* @li #pcntModeExtSingle mode - if false, positive edges are counted,
* otherwise negative edges.
* @li #pcntModeExtQuad mode - if true, counting direction is inverted. */
bool negEdge;
/** Counting direction, only applicable for #pcntModeOvsSingle and
* #pcntModeExtSingle modes. */
bool countDown;
/** Enable filter, only available in #pcntModeOvsSingle mode. */
bool filter;
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
/** Set to true to enable hysteresis. When its enabled, the PCNT will always
* overflow and underflow to TOP/2. */
bool hyst;
/** Set to true to enable S1 to determine the direction of counting in
* OVSSINGLE or EXTCLKSINGLE modes.
* When S1 is high, the count direction is given by CNTDIR, and when S1 is
* low, the count direction is the opposite. */
bool s1CntDir;
/** Selects whether the regular counter responds to up-count events,
* down-count events, both or none. */
PCNT_CntEvent_TypeDef cntEvent;
/** Selects whether the auxiliary counter responds to up-count events,
* down-count events, both or none. */
PCNT_CntEvent_TypeDef auxCntEvent;
/** Select PRS channel as input to S0IN in PCNTx_INPUT register. */
PCNT_PRSSel_TypeDef s0PRS;
/** Select PRS channel as input to S1IN in PCNTx_INPUT register. */
PCNT_PRSSel_TypeDef s1PRS;
#endif
} PCNT_Init_TypeDef;
/** Default config for PCNT init structure. */
#if defined (_EFM32_GECKO_FAMILY)
#define PCNT_INIT_DEFAULT \
{ pcntModeDisable, /* Disabled by default. */ \
_PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
_PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \
false, /* Use positive edge. */ \
false, /* Up-counting. */ \
false /* Filter disabled. */ \
}
#elif (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
#define PCNT_INIT_DEFAULT \
{ pcntModeDisable, /* Disabled by default. */ \
_PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
_PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \
false, /* Use positive edge. */ \
false, /* Up-counting. */ \
false, /* Filter disabled. */ \
false, /* Hysteresis disabled. */ \
true, /* Counter direction is given by CNTDIR. */ \
pcntCntEventUp, /* Regular counter counts up on upcount events. */ \
pcntCntEventNone, /* Auxiliary counter doesn't respond to events. */ \
pcntPRSCh0, /* PRS channel 0 selected as S0IN. */ \
pcntPRSCh0 /* PRS channel 0 selected as S1IN. */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get pulse counter value.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* Current pulse counter value.
******************************************************************************/
static __INLINE uint32_t PCNT_CounterGet(PCNT_TypeDef *pcnt)
{
return pcnt->CNT;
}
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
/***************************************************************************//**
* @brief
* Get auxiliary counter value.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* Current auxiliary counter value.
******************************************************************************/
static __INLINE uint32_t PCNT_AuxCounterGet(PCNT_TypeDef *pcnt)
{
return pcnt->AUXCNT;
}
#endif
void PCNT_CounterReset(PCNT_TypeDef *pcnt);
void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top);
/***************************************************************************//**
* @brief
* Set counter value.
*
* @details
* The pulse counter is disabled while changing counter value, and reenabled
* (if originally enabled) when counter value has been set.
*
* @note
* This function will stall until synchronization to low frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module, since stall time may be
* undefined in that case. The counter should normally only be set when
* operating in (or about to enable) #pcntModeOvsSingle mode.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] count
* Value to set in counter register.
******************************************************************************/
static __INLINE void PCNT_CounterSet(PCNT_TypeDef *pcnt, uint32_t count)
{
PCNT_CounterTopSet(pcnt, count, pcnt->TOP);
}
void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode);
void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable);
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init);
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
PCNT_PRSInput_TypeDef prsInput,
bool enable);
#endif
/***************************************************************************//**
* @brief
* Clear one or more pending PCNT interrupts.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] flags
* Pending PCNT interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
static __INLINE void PCNT_IntClear(PCNT_TypeDef *pcnt, uint32_t flags)
{
pcnt->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more PCNT interrupts.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
static __INLINE void PCNT_IntDisable(PCNT_TypeDef *pcnt, uint32_t flags)
{
pcnt->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more PCNT interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using PCNT_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
static __INLINE void PCNT_IntEnable(PCNT_TypeDef *pcnt, uint32_t flags)
{
pcnt->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending PCNT interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* PCNT interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
static __INLINE uint32_t PCNT_IntGet(PCNT_TypeDef *pcnt)
{
return pcnt->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending PCNT interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* Pending and enabled PCNT interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in PCNT_IEN_nnn
* register (PCNT_IEN_nnn) and
* - the OR combination of valid interrupt flags of the PCNT module
* (PCNT_IF_nnn).
******************************************************************************/
static __INLINE uint32_t PCNT_IntGetEnabled(PCNT_TypeDef *pcnt)
{
uint32_t tmp = 0U;
/* Store pcnt->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = pcnt->IEN;
/* Bitwise AND of pending and enabled interrupts */
return pcnt->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending PCNT interrupts from SW.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
static __INLINE void PCNT_IntSet(PCNT_TypeDef *pcnt, uint32_t flags)
{
pcnt->IFS = flags;
}
void PCNT_Reset(PCNT_TypeDef *pcnt);
/***************************************************************************//**
* @brief
* Get pulse counter top buffer value.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* Current pulse counter top buffer value.
******************************************************************************/
static __INLINE uint32_t PCNT_TopBufferGet(PCNT_TypeDef *pcnt)
{
return pcnt->TOPB;
}
void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val);
/***************************************************************************//**
* @brief
* Get pulse counter top value.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @return
* Current pulse counter top value.
******************************************************************************/
static __INLINE uint32_t PCNT_TopGet(PCNT_TypeDef *pcnt)
{
return pcnt->TOP;
}
void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val);
/** @} (end addtogroup PCNT) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_PCNT_H */

View File

@ -0,0 +1,123 @@
/***************************************************************************//**
* @file
* @brief Peripheral Reflex System (PRS) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_PRS_H
#define __EFM32_PRS_H
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup PRS
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Edge detection type. */
typedef enum
{
prsEdgeOff = PRS_CH_CTRL_EDSEL_OFF, /**< Leave signal as is. */
prsEdgePos = PRS_CH_CTRL_EDSEL_POSEDGE, /**< Generate pules on positive edge. */
prsEdgeNeg = PRS_CH_CTRL_EDSEL_NEGEDGE, /**< Generate pules on negative edge. */
prsEdgeBoth = PRS_CH_CTRL_EDSEL_BOTHEDGES /**< Generate pules on both edges. */
} PRS_Edge_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Set level control bit for one or more channels.
*
* @details
* The level value for a channel is XORed with both the pulse possible issued
* by PRS_PulseTrigger() and the PRS input signal selected for the channel(s).
*
* @param[in] level
* Level to use for channels indicated by @p mask. Use logical OR combination
* of PRS_SWLEVEL_CHnLEVEL defines for channels to set high level, otherwise 0.
*
* @param[in] mask
* Mask indicating which channels to set level for. Use logical OR combination
* of PRS_SWLEVEL_CHnLEVEL defines.
******************************************************************************/
static __INLINE void PRS_LevelSet(uint32_t level, uint32_t mask)
{
PRS->SWLEVEL = (PRS->SWLEVEL & ~mask) | (level & mask);
}
/***************************************************************************//**
* @brief
* Trigger a high pulse (one HFPERCLK) for one or more channels.
*
* @details
* Setting a bit for a channel causes the bit in the register to remain high
* for one HFPERCLK cycle. The pulse is XORed with both the corresponding bit
* in PRS SWLEVEL register and the PRS input signal selected for the
* channel(s).
*
* @param[in] channels
* Logical ORed combination of channels to trigger a pulse for. Use
* PRS_SWPULSE_CHnPULSE defines.
******************************************************************************/
static __INLINE void PRS_PulseTrigger(uint32_t channels)
{
PRS->SWPULSE = channels & _PRS_SWPULSE_MASK;
}
void PRS_SourceSignalSet(unsigned int ch,
uint32_t source,
uint32_t signal,
PRS_Edge_TypeDef edge);
#if ((defined _EFM32_TINY_FAMILY) || (defined _EFM32_GIANT_FAMILY))
void PRS_SourceAsyncSignalSet(unsigned int ch,
uint32_t source,
uint32_t signal);
#endif
/** @} (end addtogroup PRS) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_PRS_H */

View File

@ -0,0 +1,63 @@
/***************************************************************************//**
* @file
* @brief Reset Management Unit (RMU) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_RMU_H
#define __EFM32_RMU_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RMU
* @{
******************************************************************************/
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void RMU_LockupResetDisable(bool disable);
void RMU_ResetCauseClear(void);
uint32_t RMU_ResetCauseGet(void);
/** @} (end addtogroup RMU) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_RMU_H */

View File

@ -0,0 +1,182 @@
/***************************************************************************//**
* @file
* @brief Real Time Counter (RTC) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_RTC_H
#define __EFM32_RTC_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RTC
* @{
******************************************************************************/
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** RTC initialization structure. */
typedef struct
{
bool enable; /**< Start counting when init completed. */
bool debugRun; /**< Counter shall keep running during debug halt. */
bool comp0Top; /**< Use compare register 0 as max count value. */
} RTC_Init_TypeDef;
/** Suggested default config for RTC init structure. */
#define RTC_INIT_DEFAULT \
{ true, /* Start counting when init done */ \
false, /* Disable updating during debug halt */ \
true /* Restart counting from 0 when reaching COMP0 */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t RTC_CompareGet(unsigned int comp);
void RTC_CompareSet(unsigned int comp, uint32_t value);
/***************************************************************************//**
* @brief
* Get RTC counter value.
*
* @return
* Current RTC counter value.
******************************************************************************/
static __INLINE uint32_t RTC_CounterGet(void)
{
return(RTC->CNT);
}
void RTC_CounterReset(void);
void RTC_Enable(bool enable);
void RTC_FreezeEnable(bool enable);
void RTC_Init(const RTC_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending RTC interrupts.
*
* @param[in] flags
* RTC interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources for the RTC module
* (RTC_IFS_nnn).
******************************************************************************/
static __INLINE void RTC_IntClear(uint32_t flags)
{
RTC->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more RTC interrupts.
*
* @param[in] flags
* RTC interrupt sources to disable. Use a set of interrupt flags OR-ed
* together to disable multiple interrupt sources for the RTC module
* (RTC_IFS_nnn).
******************************************************************************/
static __INLINE void RTC_IntDisable(uint32_t flags)
{
RTC->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more RTC interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using RTC_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] flags
* RTC interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt sources for the RTC module
* (RTC_IFS_nnn).
******************************************************************************/
static __INLINE void RTC_IntEnable(uint32_t flags)
{
RTC->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending RTC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* Pending RTC interrupt sources. Returns a set of interrupt flags OR-ed
* together for multiple interrupt sources in the RTC module (RTC_IFS_nnn).
******************************************************************************/
static __INLINE uint32_t RTC_IntGet(void)
{
return(RTC->IF);
}
/***************************************************************************//**
* @brief
* Set one or more pending RTC interrupts from SW.
*
* @param[in] flags
* RTC interrupt sources to set to pending. Use a set of interrupt flags
* OR-ed together to set multiple interrupt sources for the RTC module
* (RTC_IFS_nnn).
******************************************************************************/
static __INLINE void RTC_IntSet(uint32_t flags)
{
RTC->IFS = flags;
}
void RTC_Reset(void);
/** @} (end addtogroup RTC) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_RTC_H */

View File

@ -0,0 +1,74 @@
/***************************************************************************//**
* @file
* @brief System API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_SYSTEM_H
#define __EFM32_SYSTEM_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @{
******************************************************************************/
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Chip revision details */
typedef struct
{
uint8_t major; /**< Major revision number */
uint8_t minor; /**< Minor revision number */
} SYSTEM_ChipRevision_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev);
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress);
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_SYSTEM_H */

View File

@ -0,0 +1,642 @@
/***************************************************************************//**
* @file
* @brief Timer/counter (TIMER) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_TIMER_H
#define __EFM32_TIMER_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Timer compare/capture mode. */
typedef enum
{
timerCCModeOff = _TIMER_CC_CTRL_MODE_OFF, /**< Channel turned off. */
timerCCModeCapture = _TIMER_CC_CTRL_MODE_INPUTCAPTURE, /**< Input capture. */
timerCCModeCompare = _TIMER_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Output compare. */
timerCCModePWM = _TIMER_CC_CTRL_MODE_PWM /**< Pulse-Width modulation. */
} TIMER_CCMode_TypeDef;
/** Clock select. */
typedef enum
{
/** Prescaled HFPER clock. */
timerClkSelHFPerClk = _TIMER_CTRL_CLKSEL_PRESCHFPERCLK,
/** Prescaled HFPER clock. */
timerClkSelCC1 = _TIMER_CTRL_CLKSEL_CC1,
/**
* Cascaded, clocked by underflow (down-counting) or overflow (up-counting)
* by lower numbered timer.
*/
timerClkSelCascade = _TIMER_CTRL_CLKSEL_TIMEROUF
} TIMER_ClkSel_TypeDef;
/** Input capture edge select. */
typedef enum
{
/** Rising edges detected. */
timerEdgeRising = _TIMER_CC_CTRL_ICEDGE_RISING,
/** Falling edges detected. */
timerEdgeFalling = _TIMER_CC_CTRL_ICEDGE_FALLING,
/** Both edges detected. */
timerEdgeBoth = _TIMER_CC_CTRL_ICEDGE_BOTH,
/** No edge detection, leave signal as is. */
timerEdgeNone = _TIMER_CC_CTRL_ICEDGE_NONE
} TIMER_Edge_TypeDef;
/** Input capture event control. */
typedef enum
{
/** PRS output pulse, interrupt flag and DMA request set on every capture. */
timerEventEveryEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYEDGE,
/** PRS output pulse, interrupt flag and DMA request set on every second capture. */
timerEventEvery2ndEdge = _TIMER_CC_CTRL_ICEVCTRL_EVERYSECONDEDGE,
/**
* PRS output pulse, interrupt flag and DMA request set on rising edge (if
* input capture edge = BOTH).
*/
timerEventRising = _TIMER_CC_CTRL_ICEVCTRL_RISING,
/**
* PRS output pulse, interrupt flag and DMA request set on falling edge (if
* input capture edge = BOTH).
*/
timerEventFalling = _TIMER_CC_CTRL_ICEVCTRL_FALLING
} TIMER_Event_TypeDef;
/** Input edge action. */
typedef enum
{
/** No action taken. */
timerInputActionNone = _TIMER_CTRL_FALLA_NONE,
/** Start counter without reload. */
timerInputActionStart = _TIMER_CTRL_FALLA_START,
/** Stop counter without reload. */
timerInputActionStop = _TIMER_CTRL_FALLA_STOP,
/** Reload and start counter. */
timerInputActionReloadStart = _TIMER_CTRL_FALLA_RELOADSTART
} TIMER_InputAction_TypeDef;
/** Timer mode. */
typedef enum
{
timerModeUp = _TIMER_CTRL_MODE_UP, /**< Up-counting. */
timerModeDown = _TIMER_CTRL_MODE_DOWN, /**< Down-counting. */
timerModeUpDown = _TIMER_CTRL_MODE_UPDOWN, /**< Up/down-counting. */
timerModeQDec = _TIMER_CTRL_MODE_QDEC /**< Quadrature decoder. */
} TIMER_Mode_TypeDef;
/** Compare/capture output action. */
typedef enum
{
/** No action. */
timerOutputActionNone = _TIMER_CC_CTRL_CUFOA_NONE,
/** Toggle on event. */
timerOutputActionToggle = _TIMER_CC_CTRL_CUFOA_TOGGLE,
/** Clear on event. */
timerOutputActionClear = _TIMER_CC_CTRL_CUFOA_CLEAR,
/** Set on event. */
timerOutputActionSet = _TIMER_CC_CTRL_CUFOA_SET
} TIMER_OutputAction_TypeDef;
/** Prescaler. */
typedef enum
{
timerPrescale1 = _TIMER_CTRL_PRESC_DIV1, /**< Divide by 1. */
timerPrescale2 = _TIMER_CTRL_PRESC_DIV2, /**< Divide by 2. */
timerPrescale4 = _TIMER_CTRL_PRESC_DIV4, /**< Divide by 4. */
timerPrescale8 = _TIMER_CTRL_PRESC_DIV8, /**< Divide by 8. */
timerPrescale16 = _TIMER_CTRL_PRESC_DIV16, /**< Divide by 16. */
timerPrescale32 = _TIMER_CTRL_PRESC_DIV32, /**< Divide by 32. */
timerPrescale64 = _TIMER_CTRL_PRESC_DIV64, /**< Divide by 64. */
timerPrescale128 = _TIMER_CTRL_PRESC_DIV128, /**< Divide by 128. */
timerPrescale256 = _TIMER_CTRL_PRESC_DIV256, /**< Divide by 256. */
timerPrescale512 = _TIMER_CTRL_PRESC_DIV512, /**< Divide by 512. */
timerPrescale1024 = _TIMER_CTRL_PRESC_DIV1024 /**< Divide by 1024. */
} TIMER_Prescale_TypeDef;
/** Peripheral Reflex System signal. */
typedef enum
{
timerPRSSELCh0 = _ADC_SINGLECTRL_PRSSEL_PRSCH0, /**< PRS channel 0. */
timerPRSSELCh1 = _ADC_SINGLECTRL_PRSSEL_PRSCH1, /**< PRS channel 1. */
timerPRSSELCh2 = _ADC_SINGLECTRL_PRSSEL_PRSCH2, /**< PRS channel 2. */
timerPRSSELCh3 = _ADC_SINGLECTRL_PRSSEL_PRSCH3, /**< PRS channel 3. */
timerPRSSELCh4 = _ADC_SINGLECTRL_PRSSEL_PRSCH4, /**< PRS channel 4. */
timerPRSSELCh5 = _ADC_SINGLECTRL_PRSSEL_PRSCH5, /**< PRS channel 5. */
timerPRSSELCh6 = _ADC_SINGLECTRL_PRSSEL_PRSCH6, /**< PRS channel 6. */
timerPRSSELCh7 = _ADC_SINGLECTRL_PRSSEL_PRSCH7 /**< PRS channel 7. */
} TIMER_PRSSEL_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** TIMER initialization structure. */
typedef struct
{
/** Start counting when init completed. */
bool enable;
/** Counter shall keep running during debug halt. */
bool debugRun;
/** Prescaling factor, if HFPER clock used. */
TIMER_Prescale_TypeDef prescale;
/** Clock selection. */
TIMER_ClkSel_TypeDef clkSel;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** 2x Count mode, counter increments/decrements by 2, meant for PWN mode. */
bool count2x;
/** ATI (Always Track Inputs) makes CCPOL always track
* the polarity of the inputs. */
bool ati;
#endif
/** Action on falling input edge. */
TIMER_InputAction_TypeDef fallAction;
/** Action on rising input edge. */
TIMER_InputAction_TypeDef riseAction;
/** Counting mode. */
TIMER_Mode_TypeDef mode;
/** DMA request clear on active. */
bool dmaClrAct;
/** Select X2 or X4 quadrature decode mode (if used). */
bool quadModeX4;
/** Determines if only counting up or down once. */
bool oneShot;
/** Timer start/stop/reload by other timers. */
bool sync;
} TIMER_Init_TypeDef;
/** Default config for TIMER init structure. */
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
#define TIMER_INIT_DEFAULT \
{ true, /* Enable timer when init complete. */ \
false, /* Stop counter during debug halt. */ \
timerPrescale1, /* No prescaling. */ \
timerClkSelHFPerClk, /* Select HFPER clock. */ \
false, /* Not 2x count mode. */ \
false, /* No ATI. */ \
timerInputActionNone, /* No action on falling input edge. */ \
timerInputActionNone, /* No action on rising input edge. */ \
timerModeUp, /* Up-counting. */ \
false, /* Do not clear DMA requests when DMA channel is active. */ \
false, /* Select X2 quadrature decode mode (if used). */ \
false, /* Disable one shot. */ \
false /* Not started/stopped/reloaded by other timers. */ \
}
#else
#define TIMER_INIT_DEFAULT \
{ true, /* Enable timer when init complete. */ \
false, /* Stop counter during debug halt. */ \
timerPrescale1, /* No prescaling. */ \
timerClkSelHFPerClk, /* Select HFPER clock. */ \
timerInputActionNone, /* No action on falling input edge. */ \
timerInputActionNone, /* No action on rising input edge. */ \
timerModeUp, /* Up-counting. */ \
false, /* Do not clear DMA requests when DMA channel is active. */ \
false, /* Select X2 quadrature decode mode (if used). */ \
false, /* Disable one shot. */ \
false /* Not started/stopped/reloaded by other timers. */ \
}
#endif
/** TIMER compare/capture initialization structure. */
typedef struct
{
/** Input capture event control. */
TIMER_Event_TypeDef eventCtrl;
/** Input capture edge select. */
TIMER_Edge_TypeDef edge;
/**
* Peripheral reflex system trigger selection. Only applicable if @p prsInput
* is enabled.
*/
TIMER_PRSSEL_TypeDef prsSel;
/** Counter underflow output action. */
TIMER_OutputAction_TypeDef cufoa;
/** Counter overflow output action. */
TIMER_OutputAction_TypeDef cofoa;
/** Counter match output action. */
TIMER_OutputAction_TypeDef cmoa;
/** Compare/capture channel mode. */
TIMER_CCMode_TypeDef mode;
/** Enable digital filter. */
bool filter;
/** Select TIMERnCCx (false) or PRS input (true). */
bool prsInput;
/**
* Compare output initial state. Only used in Output Compare and PWM mode.
* When true, the compare/PWM output is set high when the counter is
* disabled. When counting resumes, this value will represent the initial
* value for the compare/PWM output. If the bit is cleared, the output
* will be cleared when the counter is disabled.
*/
bool coist;
/** Invert output from compare/capture channel. */
bool outInvert;
} TIMER_InitCC_TypeDef;
/** Default config for TIMER compare/capture init structure. */
#define TIMER_INITCC_DEFAULT \
{ timerEventEveryEdge, /* Event on every capture. */ \
timerEdgeRising, /* Input capture edge on rising edge. */ \
timerPRSSELCh0, /* Not used by default, select PRS channel 0. */ \
timerOutputActionNone, /* No action on underflow. */ \
timerOutputActionNone, /* No action on overflow. */ \
timerOutputActionNone, /* No action on match. */ \
timerCCModeOff, /* Disable compare/capture channel. */ \
false, /* Disable filter. */ \
false, /* Select TIMERnCCx input. */ \
false, /* Clear output when countre disabled. */ \
false /* Do not invert output. */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get capture value for compare/capture channel when operating in capture
* mode.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to access.
*
* @return
* Current capture value.
******************************************************************************/
static __INLINE uint32_t TIMER_CaptureGet(TIMER_TypeDef *timer, unsigned int ch)
{
return(timer->CC[ch].CCV);
}
/***************************************************************************//**
* @brief
* Set compare value buffer for compare/capture channel when operating in
* compare or PWM mode.
*
* @details
* The compare value buffer holds the value which will be written to
* TIMERn_CCx_CCV on an update event if the buffer has been updated since
* the last event.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to access.
*
* @param[in] val
* Value to set in compare value buffer register.
******************************************************************************/
static __INLINE void TIMER_CompareBufSet(TIMER_TypeDef *timer,
unsigned int ch,
uint32_t val)
{
timer->CC[ch].CCVB = val;
}
/***************************************************************************//**
* @brief
* Set compare value for compare/capture channel when operating in compare
* or PWM mode.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to access.
*
* @param[in] val
* Value to set in compare value register.
******************************************************************************/
static __INLINE void TIMER_CompareSet(TIMER_TypeDef *timer,
unsigned int ch,
uint32_t val)
{
timer->CC[ch].CCV = val;
}
/***************************************************************************//**
* @brief
* Get TIMER counter value.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @return
* Current TIMER counter value.
******************************************************************************/
static __INLINE uint32_t TIMER_CounterGet(TIMER_TypeDef *timer)
{
return(timer->CNT);
}
/***************************************************************************//**
* @brief
* Set TIMER counter value.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] val
* Value to set counter to.
******************************************************************************/
static __INLINE void TIMER_CounterSet(TIMER_TypeDef *timer, uint32_t val)
{
timer->CNT = val;
}
void TIMER_Enable(TIMER_TypeDef *rtc, bool enable);
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init);
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending TIMER interrupts.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] flags
* Pending TIMER interrupt source(s) to clear. Use one or more valid
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void TIMER_IntClear(TIMER_TypeDef *timer, uint32_t flags)
{
timer->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more TIMER interrupts.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] flags
* TIMER interrupt source(s) to disable. Use one or more valid
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void TIMER_IntDisable(TIMER_TypeDef *timer, uint32_t flags)
{
timer->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more TIMER interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using TIMER_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] flags
* TIMER interrupt source(s) to enable. Use one or more valid
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void TIMER_IntEnable(TIMER_TypeDef *timer, uint32_t flags)
{
timer->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending TIMER interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @return
* TIMER interrupt source(s) pending. Returns one or more valid
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE uint32_t TIMER_IntGet(TIMER_TypeDef *timer)
{
return(timer->IF);
}
/***************************************************************************//**
* @brief
* Get enabled and pending TIMER interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled TIMER interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in TIMERx_IEN_nnn
* register (TIMERx_IEN_nnn) and
* - the OR combination of valid interrupt flags of the TIMER module
* (TIMERx_IF_nnn).
******************************************************************************/
static __INLINE uint32_t TIMER_IntGetEnabled(TIMER_TypeDef *timer)
{
uint32_t tmp;
/* Store TIMER->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = timer->IEN;
/* Bitwise AND of pending and enabled interrupts */
return timer->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending TIMER interrupts from SW.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] flags
* TIMER interrupt source(s) to set to pending. Use one or more valid
* interrupt flags for the TIMER module (TIMER_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void TIMER_IntSet(TIMER_TypeDef *timer, uint32_t flags)
{
timer->IFS = flags;
}
#ifdef TIMER_DTLOCK_LOCKKEY_LOCK
void TIMER_Lock(TIMER_TypeDef *timer);
#endif
void TIMER_Reset(TIMER_TypeDef *timer);
/***************************************************************************//**
* @brief
* Set top value buffer for timer.
*
* @details
* When the top value buffer register is updated, the value is loaded into
* the top value register at the next wrap around. This feature is useful
* in order to update the top value safely when the timer is running.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] val
* Value to set in top value buffer register.
******************************************************************************/
static __INLINE void TIMER_TopBufSet(TIMER_TypeDef *timer, uint32_t val)
{
timer->TOPB = val;
}
/***************************************************************************//**
* @brief
* Get top value setting for timer.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @return
* Current top value.
******************************************************************************/
static __INLINE uint32_t TIMER_TopGet(TIMER_TypeDef *timer)
{
return(timer->TOP);
}
/***************************************************************************//**
* @brief
* Set top value for timer.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] val
* Value to set in top value register.
******************************************************************************/
static __INLINE void TIMER_TopSet(TIMER_TypeDef *timer, uint32_t val)
{
timer->TOP = val;
}
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
void TIMER_Unlock(TIMER_TypeDef *timer);
#endif
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_TIMER_H */

View File

@ -0,0 +1,645 @@
/***************************************************************************//**
* @file
* @brief Universal synchronous/asynchronous receiver/transmitter (USART/UART)
* peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_USART_H
#define __EFM32_USART_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup USART
* @brief Universal Synchronous/Asynchronous Receiver/Transmitter (USART) peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Databit selection. */
typedef enum
{
usartDatabits4 = USART_FRAME_DATABITS_FOUR, /**< 4 databits (not available for UART). */
usartDatabits5 = USART_FRAME_DATABITS_FIVE, /**< 5 databits (not available for UART). */
usartDatabits6 = USART_FRAME_DATABITS_SIX, /**< 6 databits (not available for UART). */
usartDatabits7 = USART_FRAME_DATABITS_SEVEN, /**< 7 databits (not available for UART). */
usartDatabits8 = USART_FRAME_DATABITS_EIGHT, /**< 8 databits. */
usartDatabits9 = USART_FRAME_DATABITS_NINE, /**< 9 databits. */
usartDatabits10 = USART_FRAME_DATABITS_TEN, /**< 10 databits (not available for UART). */
usartDatabits11 = USART_FRAME_DATABITS_ELEVEN, /**< 11 databits (not available for UART). */
usartDatabits12 = USART_FRAME_DATABITS_TWELVE, /**< 12 databits (not available for UART). */
usartDatabits13 = USART_FRAME_DATABITS_THIRTEEN, /**< 13 databits (not available for UART). */
usartDatabits14 = USART_FRAME_DATABITS_FOURTEEN, /**< 14 databits (not available for UART). */
usartDatabits15 = USART_FRAME_DATABITS_FIFTEEN, /**< 15 databits (not available for UART). */
usartDatabits16 = USART_FRAME_DATABITS_SIXTEEN /**< 16 databits (not available for UART). */
} USART_Databits_TypeDef;
/** Enable selection. */
typedef enum
{
/** Disable both receiver and transmitter. */
usartDisable = 0x0,
/** Enable receiver only, transmitter disabled. */
usartEnableRx = USART_CMD_RXEN,
/** Enable transmitter only, receiver disabled. */
usartEnableTx = USART_CMD_TXEN,
/** Enable both receiver and transmitter. */
usartEnable = (USART_CMD_RXEN | USART_CMD_TXEN)
} USART_Enable_TypeDef;
/** Oversampling selection, used for asynchronous operation. */
typedef enum
{
usartOVS16 = USART_CTRL_OVS_X16, /**< 16x oversampling (normal). */
usartOVS8 = USART_CTRL_OVS_X8, /**< 8x oversampling. */
usartOVS6 = USART_CTRL_OVS_X6, /**< 6x oversampling. */
usartOVS4 = USART_CTRL_OVS_X4 /**< 4x oversampling. */
} USART_OVS_TypeDef;
/** Parity selection, mainly used for asynchronous operation. */
typedef enum
{
usartNoParity = USART_FRAME_PARITY_NONE, /**< No parity. */
usartEvenParity = USART_FRAME_PARITY_EVEN, /**< Even parity. */
usartOddParity = USART_FRAME_PARITY_ODD /**< Odd parity. */
} USART_Parity_TypeDef;
/** Stopbits selection, used for asynchronous operation. */
typedef enum
{
usartStopbits0p5 = USART_FRAME_STOPBITS_HALF, /**< 0.5 stopbits. */
usartStopbits1 = USART_FRAME_STOPBITS_ONE, /**< 1 stopbits. */
usartStopbits1p5 = USART_FRAME_STOPBITS_ONEANDAHALF, /**< 1.5 stopbits. */
usartStopbits2 = USART_FRAME_STOPBITS_TWO /**< 2 stopbits. */
} USART_Stopbits_TypeDef;
/** Clock polarity/phase mode. */
typedef enum
{
/** Clock idle low, sample on rising edge. */
usartClockMode0 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLELEADING,
/** Clock idle low, sample on falling edge. */
usartClockMode1 = USART_CTRL_CLKPOL_IDLELOW | USART_CTRL_CLKPHA_SAMPLETRAILING,
/** Clock idle high, sample on falling edge. */
usartClockMode2 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLELEADING,
/** Clock idle high, sample on rising edge. */
usartClockMode3 = USART_CTRL_CLKPOL_IDLEHIGH | USART_CTRL_CLKPHA_SAMPLETRAILING
} USART_ClockMode_TypeDef;
/** Pulse width selection for IrDA mode. */
typedef enum
{
/** IrDA pulse width is 1/16 for OVS=0 and 1/8 for OVS=1 */
usartIrDAPwONE = USART_IRCTRL_IRPW_ONE,
/** IrDA pulse width is 2/16 for OVS=0 and 2/8 for OVS=1 */
usartIrDAPwTWO = USART_IRCTRL_IRPW_TWO,
/** IrDA pulse width is 3/16 for OVS=0 and 3/8 for OVS=1 */
usartIrDAPwTHREE = USART_IRCTRL_IRPW_THREE,
/** IrDA pulse width is 4/16 for OVS=0 and 4/8 for OVS=1 */
usartIrDAPwFOUR = USART_IRCTRL_IRPW_FOUR
} USART_IrDAPw_Typedef;
/** PRS channel selection for IrDA mode. */
typedef enum
{
usartIrDAPrsCh0 = USART_IRCTRL_IRPRSSEL_PRSCH0, /**< PRS channel 0 */
usartIrDAPrsCh1 = USART_IRCTRL_IRPRSSEL_PRSCH1, /**< PRS channel 1 */
usartIrDAPrsCh2 = USART_IRCTRL_IRPRSSEL_PRSCH2, /**< PRS channel 2 */
usartIrDAPrsCh3 = USART_IRCTRL_IRPRSSEL_PRSCH3, /**< PRS channel 3 */
usartIrDAPrsCh4 = USART_IRCTRL_IRPRSSEL_PRSCH4, /**< PRS channel 4 */
usartIrDAPrsCh5 = USART_IRCTRL_IRPRSSEL_PRSCH5, /**< PRS channel 5 */
usartIrDAPrsCh6 = USART_IRCTRL_IRPRSSEL_PRSCH6, /**< PRS channel 6 */
usartIrDAPrsCh7 = USART_IRCTRL_IRPRSSEL_PRSCH7 /**< PRS channel 7 */
} USART_IrDAPrsSel_Typedef;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** I2S format selection. */
typedef enum
{
usartI2sFormatW32D32 = USART_I2SCTRL_FORMAT_W32D32, /**< 32-bit word, 32-bit data */
usartI2sFormatW32D24M = USART_I2SCTRL_FORMAT_W32D24M, /**< 32-bit word, 32-bit data with 8 lsb masked */
usartI2sFormatW32D24 = USART_I2SCTRL_FORMAT_W32D24, /**< 32-bit word, 24-bit data */
usartI2sFormatW32D16 = USART_I2SCTRL_FORMAT_W32D16, /**< 32-bit word, 16-bit data */
usartI2sFormatW32D8 = USART_I2SCTRL_FORMAT_W32D8, /**< 32-bit word, 8-bit data */
usartI2sFormatW16D16 = USART_I2SCTRL_FORMAT_W16D16, /**< 16-bit word, 16-bit data */
usartI2sFormatW16D8 = USART_I2SCTRL_FORMAT_W16D8, /**< 16-bit word, 8-bit data */
usartI2sFormatW8D8 = USART_I2SCTRL_FORMAT_W8D8 /**< 8-bit word, 8-bit data */
} USART_I2sFormat_TypeDef;
/** I2S frame data justify. */
typedef enum
{
usartI2sJustifyLeft = USART_I2SCTRL_JUSTIFY_LEFT, /**< Data is left-justified within the frame */
usartI2sJustifyRight = USART_I2SCTRL_JUSTIFY_RIGHT /**< Data is right-justified within the frame */
} USART_I2sJustify_TypeDef;
/** USART Rx input PRS selection. */
typedef enum
{
usartPrsRxCh0 = USART_INPUT_RXPRSSEL_PRSCH0, /**< PRSCH0 selected as USART_INPUT */
usartPrsRxCh1 = USART_INPUT_RXPRSSEL_PRSCH1, /**< PRSCH1 selected as USART_INPUT */
usartPrsRxCh2 = USART_INPUT_RXPRSSEL_PRSCH2, /**< PRSCH2 selected as USART_INPUT */
usartPrsRxCh3 = USART_INPUT_RXPRSSEL_PRSCH3, /**< PRSCH3 selected as USART_INPUT */
usartPrsRxCh4 = USART_INPUT_RXPRSSEL_PRSCH4, /**< PRSCH4 selected as USART_INPUT */
usartPrsRxCh5 = USART_INPUT_RXPRSSEL_PRSCH5, /**< PRSCH5 selected as USART_INPUT */
usartPrsRxCh6 = USART_INPUT_RXPRSSEL_PRSCH6, /**< PRSCH6 selected as USART_INPUT */
#if defined(_EFM32_TINY_FAMILY)
usartPrsRxCh7 = USART_INPUT_RXPRSSEL_PRSCH7 /**< PRSCH7 selected as USART_INPUT */
#elif defined(_EFM32_GIANT_FAMILY)
usartPrsRxCh7 = USART_INPUT_RXPRSSEL_PRSCH7, /**< PRSCH7 selected as USART_INPUT */
usartPrsRxCh8 = USART_INPUT_RXPRSSEL_PRSCH8, /**< PRSCH8 selected as USART_INPUT */
usartPrsRxCh9 = USART_INPUT_RXPRSSEL_PRSCH9, /**< PRSCH9 selected as USART_INPUT */
usartPrsRxCh10 = USART_INPUT_RXPRSSEL_PRSCH10, /**< PRSCH10 selected as USART_INPUT */
usartPrsRxCh11 = USART_INPUT_RXPRSSEL_PRSCH11 /**< PRSCH11 selected as USART_INPUT */
#else
#error Unknown EFM32 family.
#endif
} USART_PrsRxCh_TypeDef;
#endif
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** USART PRS Transmit Trigger Channels */
typedef enum
{
usartPrsTriggerCh0 = USART_TRIGCTRL_TSEL_PRSCH0, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh1 = USART_TRIGCTRL_TSEL_PRSCH1, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh2 = USART_TRIGCTRL_TSEL_PRSCH2, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh3 = USART_TRIGCTRL_TSEL_PRSCH3, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh4 = USART_TRIGCTRL_TSEL_PRSCH4, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh5 = USART_TRIGCTRL_TSEL_PRSCH5, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh6 = USART_TRIGCTRL_TSEL_PRSCH6, /**< PRSCH0 selected as USART Trigger */
usartPrsTriggerCh7 = USART_TRIGCTRL_TSEL_PRSCH7, /**< PRSCH0 selected as USART Trigger */
} USART_PrsTriggerCh_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Asynchronous mode init structure. */
typedef struct
{
/** Specifies whether TX and/or RX shall be enabled when init completed. */
USART_Enable_TypeDef enable;
/**
* USART/UART reference clock assumed when configuring baudrate setup. Set
* it to 0 if currently configurated reference clock shall be used.
*/
uint32_t refFreq;
/** Desired baudrate. */
uint32_t baudrate;
/** Oversampling used. */
USART_OVS_TypeDef oversampling;
/** Number of databits in frame. Notice that UART modules only support 8 or
* 9 databits. */
USART_Databits_TypeDef databits;
/** Parity mode to use. */
USART_Parity_TypeDef parity;
/** Number of stopbits to use. */
USART_Stopbits_TypeDef stopbits;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** Majority Vote Disable for 16x, 8x and 6x oversampling modes. */
bool mvdis;
/** Enable USART Rx via PRS. */
bool prsRxEnable;
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
USART_PrsRxCh_TypeDef prsRxCh;
#endif
} USART_InitAsync_TypeDef;
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/** USART PRS trigger enable */
typedef struct
{
#if defined(_EFM32_GIANT_FAMILY)
/** Enable AUTOTX */
bool autoTxTriggerEnable;
#endif
/** Trigger receive via PRS channel */
bool rxTriggerEnable;
/** Trigger transmit via PRS channel */
bool txTriggerEnable;
/** PRS channel to be used to trigger auto transmission */
USART_PrsTriggerCh_TypeDef prsTriggerChannel;
} USART_PrsTriggerInit_TypeDef;
#endif
/** Default config for USART async init structure. */
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
#define USART_INITASYNC_DEFAULT \
{ usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartNoParity, /* No parity. */ \
usartStopbits1, /* 1 stopbit. */ \
false, /* Do not disable majority vote. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0 /* PRS channel 0. */ \
}
#else
#define USART_INITASYNC_DEFAULT \
{ usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartNoParity, /* No parity. */ \
usartStopbits1 /* 1 stopbit. */ \
}
#endif
/** Synchronous mode init structure. */
typedef struct
{
/** Specifies whether TX and/or RX shall be enabled when init completed. */
USART_Enable_TypeDef enable;
/**
* USART/UART reference clock assumed when configuring baudrate setup. Set
* it to 0 if currently configurated reference clock shall be used.
*/
uint32_t refFreq;
/** Desired baudrate. */
uint32_t baudrate;
/** Number of databits in frame. */
USART_Databits_TypeDef databits;
/** Select if to operate in master or slave mode. */
bool master;
/** Select if to send most or least significant bit first. */
bool msbf;
/** Clock polarity/phase mode. */
USART_ClockMode_TypeDef clockMode;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** Enable USART Rx via PRS. */
bool prsRxEnable;
/** Select PRS channel for USART Rx. (Only valid if prsRxEnable is true). */
USART_PrsRxCh_TypeDef prsRxCh;
/** Enable AUTOTX mode. Transmits as long as RX is not full.
* If TX is empty, underflows are generated. */
bool autoTx;
#endif
} USART_InitSync_TypeDef;
/** Default config for USART sync init structure. */
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
#define USART_INITSYNC_DEFAULT \
{ usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* 1 Mbits/s. */ \
usartDatabits8, /* 8 databits. */ \
true, /* Master mode. */ \
false, /* Send least significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Not USART PRS input mode. */ \
usartPrsRxCh0, /* PRS channel 0. */ \
false /* No AUTOTX mode. */ \
}
#else
#define USART_INITSYNC_DEFAULT \
{ usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* 1 Mbits/s. */ \
usartDatabits8, /* 8 databits. */ \
true, /* Master mode. */ \
false, /* Send least significant bit first. */ \
usartClockMode0 /* Clock idle low, sample on rising edge. */ \
}
#endif
/** IrDA mode init structure. Inherited from asynchronous mode init structure */
typedef struct
{
/** General Async initialization structure. */
USART_InitAsync_TypeDef async;
/** Set to invert Rx signal before IrDA demodulator. */
bool irRxInv;
/** Set to enable filter on IrDA demodulator. */
bool irFilt;
/** Configure the pulse width generated by the IrDA modulator as a fraction
* of the configured USART bit period. */
USART_IrDAPw_Typedef irPw;
/** Enable the PRS channel selected by irPrsSel as input to IrDA module
* instead of TX. */
bool irPrsEn;
/** A PRS can be used as input to the pulse modulator instead of TX.
* This value selects the channel to use. */
USART_IrDAPrsSel_Typedef irPrsSel;
} USART_InitIrDA_TypeDef;
/** Default config for IrDA mode init structure. */
#define USART_INITIRDA_DEFAULT \
{ \
{ usartEnable, /* Enable RX/TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
115200, /* 115200 bits/s. */ \
usartOVS16, /* 16x oversampling. */ \
usartDatabits8, /* 8 databits. */ \
usartEvenParity, /* Even parity. */ \
usartStopbits1 /* 1 stopbit. */ \
}, \
false, /* Rx invert disabled. */ \
false, /* Filtering disabled. */ \
usartIrDAPwTHREE, /* Pulse width is set to ONE. */ \
false, /* Routing to PRS is disabled. */ \
usartIrDAPrsCh0 /* PRS channel 0. */ \
}
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
/** I2S mode init structure. Inherited from synchronous mode init structure */
typedef struct
{
/** General Sync initialization structure. */
USART_InitSync_TypeDef sync;
/** I2S mode. */
USART_I2sFormat_TypeDef format;
/** Delay on I2S data. Set to add a one-cycle delay between a transition
* on the word-clock and the start of the I2S word.
* Should be set for standard I2S format. */
bool delay;
/** Separate DMA Request For Left/Right Data. */
bool dmaSplit;
/** Justification of I2S data within the frame */
USART_I2sJustify_TypeDef justify;
/** Stero or Mono, set to true for mono. */
bool mono;
} USART_InitI2s_TypeDef;
/** Default config for I2S mode init structure. */
#define USART_INITI2S_DEFAULT \
{ \
{ usartEnableTx, /* Enable TX when init completed. */ \
0, /* Use current configured reference clock for configuring baudrate. */ \
1000000, /* Baudrate 1M bits/s. */ \
usartDatabits16, /* 16 databits. */ \
true, /* Operate as I2S master. */ \
true, /* Most significant bit first. */ \
usartClockMode0, /* Clock idle low, sample on rising edge. */ \
false, /* Don't enable USARTRx via PRS. */ \
usartPrsRxCh0, /* PRS channel selection (dummy). */ \
false /* Disable AUTOTX mode. */ \
}, \
usartI2sFormatW16D16, /* 16-bit word, 16-bit data */ \
true, /* Delay on I2S data. */ \
false, /* No DMA split. */ \
usartI2sJustifyLeft, /* Data is left-justified within the frame */ \
false /* Stereo mode. */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void USART_BaudrateAsyncSet(USART_TypeDef *usart,
uint32_t refFreq,
uint32_t baudrate,
USART_OVS_TypeDef ovs);
uint32_t USART_BaudrateCalc(uint32_t refFreq,
uint32_t clkdiv,
bool syncmode,
USART_OVS_TypeDef ovs);
uint32_t USART_BaudrateGet(USART_TypeDef *usart);
void USART_BaudrateSyncSet(USART_TypeDef *usart,
uint32_t refFreq,
uint32_t baudrate);
void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable);
void USART_InitAsync(USART_TypeDef *usart, const USART_InitAsync_TypeDef *init);
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init);
void USART_InitIrDA(const USART_InitIrDA_TypeDef *init);
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
void USART_InitI2s(USART_TypeDef *usart, USART_InitI2s_TypeDef *init);
void USART_InitPrsTrigger(USART_TypeDef *usart, const USART_PrsTriggerInit_TypeDef *init);
#endif
/***************************************************************************//**
* @brief
* Clear one or more pending USART interrupts.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* Pending USART/UART interrupt source(s) to clear. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void USART_IntClear(USART_TypeDef *usart, uint32_t flags)
{
usart->IFC = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more USART interrupts.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to disable. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void USART_IntDisable(USART_TypeDef *usart, uint32_t flags)
{
usart->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more USART interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using USART_IntClear() prior to enabling
* if such a pending interrupt should be ignored.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to enable. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void USART_IntEnable(USART_TypeDef *usart, uint32_t flags)
{
usart->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending USART interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @return
* USART/UART interrupt source(s) pending. Returns one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE uint32_t USART_IntGet(USART_TypeDef *usart)
{
return usart->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending USART interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled USART interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in USARTx_IEN_nnn
* register (USARTx_IEN_nnn) and
* - the OR combination of valid interrupt flags of the USART module
* (USARTx_IF_nnn).
******************************************************************************/
static __INLINE uint32_t USART_IntGetEnabled(USART_TypeDef *usart)
{
uint32_t tmp;
/* Store USARTx->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = usart->IEN;
/* Bitwise AND of pending and enabled interrupts */
return usart->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending USART interrupts from SW.
*
* @param[in] usart
* Pointer to USART/UART peripheral register block.
*
* @param[in] flags
* USART/UART interrupt source(s) to set to pending. Use one or more valid
* interrupt flags for the USART module (USART_IF_nnn) OR'ed together.
******************************************************************************/
static __INLINE void USART_IntSet(USART_TypeDef *usart, uint32_t flags)
{
usart->IFS = flags;
}
void USART_Reset(USART_TypeDef *usart);
uint8_t USART_Rx(USART_TypeDef *usart);
uint16_t USART_RxDouble(USART_TypeDef *usart);
uint32_t USART_RxDoubleExt(USART_TypeDef *usart);
uint16_t USART_RxExt(USART_TypeDef *usart);
void USART_Tx(USART_TypeDef *usart, uint8_t data);
void USART_TxDouble(USART_TypeDef *usart, uint16_t data);
void USART_TxDoubleExt(USART_TypeDef *usart, uint32_t data);
void USART_TxExt(USART_TypeDef *usart, uint16_t data);
/** @} (end addtogroup USART) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_USART_H */

View File

@ -0,0 +1,352 @@
/***************************************************************************//**
* @file
* @brief Voltage Comparator (VCMP) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_VCMP_H
#define __EFM32_VCMP_H
#include "efm32.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup VCMP
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Warm-up Time in High Frequency Peripheral Clock cycles */
typedef enum
{
/** 4 cycles */
vcmpWarmTime4Cycles = _VCMP_CTRL_WARMTIME_4CYCLES,
/** 8 cycles */
vcmpWarmTime8Cycles = _VCMP_CTRL_WARMTIME_8CYCLES,
/** 16 cycles */
vcmpWarmTime16Cycles = _VCMP_CTRL_WARMTIME_16CYCLES,
/** 32 cycles */
vcmpWarmTime32Cycles = _VCMP_CTRL_WARMTIME_32CYCLES,
/** 64 cycles */
vcmpWarmTime64Cycles = _VCMP_CTRL_WARMTIME_64CYCLES,
/** 128 cycles */
vcmpWarmTime128Cycles = _VCMP_CTRL_WARMTIME_128CYCLES,
/** 256 cycles */
vcmpWarmTime256Cycles = _VCMP_CTRL_WARMTIME_256CYCLES,
/** 512 cycles */
vcmpWarmTime512Cycles = _VCMP_CTRL_WARMTIME_512CYCLES
} VCMP_WarmTime_TypeDef;
/** Hyseresis configuration */
typedef enum
{
/** Normal operation, no hysteresis */
vcmpHystNone,
/** Digital output will not toggle until positive edge is at least
* 20mV above or below negative input voltage */
vcmpHyst20mV
} VCMP_Hysteresis_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** VCMP Initialization structure */
typedef struct
{
/** If set to true, will reduce by half the bias current */
bool halfBias;
/** BIAS current configuration, depends on halfBias setting,
* above, see reference manual */
int biasProg;
/** Enable interrupt for falling edge */
bool irqFalling;
/** Enable interrupt for rising edge */
bool irqRising;
/** Warm-up time in clock cycles */
VCMP_WarmTime_TypeDef warmup;
/** Hysteresis configuration */
VCMP_Hysteresis_TypeDef hyst;
/** Output value when comparator is inactive, should be 0 or 1 */
int inactive;
/** Enable low power mode for VDD and bandgap reference */
bool lowPowerRef;
/** Trigger level, according to formula
* VDD Trigger Level = 1.667V + 0.034V x triggerLevel */
int triggerLevel;
/** Enable VCMP after configuration */
bool enable;
} VCMP_Init_TypeDef;
/** Default VCMP initialization structure */
#define VCMP_INIT_DEFAULT \
{ true, /** Half Bias enabled */ \
0x7, /** Bias curernt 0.7 uA when half bias enabled */ \
false, /** Falling edge sense not enabled */ \
false, /** Rising edge sense not enabled */ \
vcmpWarmTime4Cycles, /** 4 clock cycles warm-up time */ \
vcmpHystNone, /** No hysteresis */ \
0, /** 0 in digital ouput when inactive */ \
true, /** Do not use low power reference */ \
39, /** Trigger level just below 3V */ \
true, /** Enable after init */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit);
void VCMP_LowPowerRefSet(bool enable);
void VCMP_TriggerSet(int level);
static __INLINE void VCMP_Enable(void);
static __INLINE void VCMP_Disable(void);
static __INLINE uint32_t VCMP_VoltageToLevel(float v);
static __INLINE bool VCMP_VDDLower(void);
static __INLINE bool VCMP_VDDHigher(void);
static __INLINE bool VCMP_Ready(void);
static __INLINE void VCMP_IntClear(uint32_t flags);
static __INLINE void VCMP_IntSet(uint32_t flags);
static __INLINE void VCMP_IntDisable(uint32_t flags);
static __INLINE void VCMP_IntEnable(uint32_t flags);
static __INLINE uint32_t VCMP_IntGet(void);
static __INLINE uint32_t VCMP_IntGetEnabled(void);
/***************************************************************************//**
* @brief
* Enable Voltage Comparator
******************************************************************************/
static __INLINE void VCMP_Enable(void)
{
VCMP->CTRL |= VCMP_CTRL_EN;
}
/***************************************************************************//**
* @brief
* Disable Voltage Comparator
******************************************************************************/
static __INLINE void VCMP_Disable(void)
{
VCMP->CTRL &= ~(VCMP_CTRL_EN);
}
/***************************************************************************//**
* @brief
* Calculate voltage to trigger level
*
* @note
* You need soft float support for this function to be working
*
* @param[in] v
* Voltage Level for trigger
******************************************************************************/
static __INLINE uint32_t VCMP_VoltageToLevel(float v)
{
return (uint32_t)((v - (float)1.667) / (float)0.034);
}
/***************************************************************************//**
* @brief
* Returns true, if Voltage Comparator indicated VDD < trigger level, else
* false
******************************************************************************/
static __INLINE bool VCMP_VDDLower(void)
{
if (VCMP->STATUS & VCMP_STATUS_VCMPOUT)
{
return false;
}
else
{
return true;
}
}
/***************************************************************************//**
* @brief
* Returns true, if Voltage Comparator indicated VDD > trigger level, else
* false
******************************************************************************/
static __INLINE bool VCMP_VDDHigher(void)
{
if (VCMP->STATUS & VCMP_STATUS_VCMPOUT)
{
return true;
}
else
{
return false;
}
}
/***************************************************************************//**
* @brief
* VCMP output is ready
******************************************************************************/
static __INLINE bool VCMP_Ready(void)
{
if (VCMP->STATUS & VCMP_STATUS_VCMPACT)
{
return true;
}
else
{
return false;
}
}
/***************************************************************************//**
* @brief
* Clear one or more pending VCMP interrupts.
*
* @param[in] flags
* VCMP interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources for the VCMP module
* (VCMP_IFS_nnn).
******************************************************************************/
static __INLINE void VCMP_IntClear(uint32_t flags)
{
VCMP->IFC = flags;
}
/***************************************************************************//**
* @brief
* Set one or more pending VCMP interrupts from SW.
*
* @param[in] flags
* VCMP interrupt sources to set to pending. Use a set of interrupt flags
* OR-ed together to set multiple interrupt sources for the VCMP module
* (VCMP_IFS_nnn).
******************************************************************************/
static __INLINE void VCMP_IntSet(uint32_t flags)
{
VCMP->IFS = flags;
}
/***************************************************************************//**
* @brief
* Disable one or more VCMP interrupts
*
* @param[in] flags
* VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt sources for the VCMP module
* (VCMP_IFS_nnn).
******************************************************************************/
static __INLINE void VCMP_IntDisable(uint32_t flags)
{
VCMP->IEN &= ~(flags);
}
/***************************************************************************//**
* @brief
* Enable one or more VCMP interrupts
*
* @param[in] flags
* VCMP interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt sources for the VCMP module
* (VCMP_IFS_nnn).
******************************************************************************/
static __INLINE void VCMP_IntEnable(uint32_t flags)
{
VCMP->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending VCMP interrupt flags
*
* @note
* The event bits are not cleared by the use of this function
*
* @return
* Pending VCMP interrupt sources. Returns a set of interrupt flags OR-ed
* together for multiple interrupt sources in the VCMP module (VCMP_IFS_nnn).
******************************************************************************/
static __INLINE uint32_t VCMP_IntGet(void)
{
return(VCMP->IF);
}
/***************************************************************************//**
* @brief
* Get enabled and pending VCMP interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* Pending and enabled VCMP interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in VCMP_IEN_nnn
* register (VCMP_IEN_nnn) and
* - the OR combination of valid interrupt flags of the VCMP module
* (VCMP_IF_nnn).
******************************************************************************/
static __INLINE uint32_t VCMP_IntGetEnabled(void)
{
uint32_t tmp = 0U;
/* Store VCMP->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
tmp = VCMP->IEN;
/* Bitwise AND of pending and enabled interrupts */
return VCMP->IF & tmp;
}
/** @} (end addtogroup VCMP) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_VCMP_H */

View File

@ -0,0 +1,146 @@
/***************************************************************************//**
* @file
* @brief Watchdog (WDOG) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef __EFM32_WDOG_H
#define __EFM32_WDOG_H
#include <stdbool.h>
#include "efm32.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup WDOG
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Watchdog clock selection. */
typedef enum
{
wdogClkSelULFRCO = _WDOG_CTRL_CLKSEL_ULFRCO, /**< Ultra low frequency (1 kHz) clock */
wdogClkSelLFRCO = _WDOG_CTRL_CLKSEL_LFRCO, /**< Low frequency RC oscillator */
wdogClkSelLFXO = _WDOG_CTRL_CLKSEL_LFXO /**< Low frequency crystal oscillator */
} WDOG_ClkSel_TypeDef;
/** Watchdog period selection. */
typedef enum
{
wdogPeriod_9 = 0x0, /**< 9 clock periods */
wdogPeriod_17 = 0x1, /**< 17 clock periods */
wdogPeriod_33 = 0x2, /**< 33 clock periods */
wdogPeriod_65 = 0x3, /**< 65 clock periods */
wdogPeriod_129 = 0x4, /**< 129 clock periods */
wdogPeriod_257 = 0x5, /**< 257 clock periods */
wdogPeriod_513 = 0x6, /**< 513 clock periods */
wdogPeriod_1k = 0x7, /**< 1025 clock periods */
wdogPeriod_2k = 0x8, /**< 2049 clock periods */
wdogPeriod_4k = 0x9, /**< 4097 clock periods */
wdogPeriod_8k = 0xA, /**< 8193 clock periods */
wdogPeriod_16k = 0xB, /**< 16385 clock periods */
wdogPeriod_32k = 0xC, /**< 32769 clock periods */
wdogPeriod_64k = 0xD, /**< 65537 clock periods */
wdogPeriod_128k = 0xE, /**< 131073 clock periods */
wdogPeriod_256k = 0xF /**< 262145 clock periods */
} WDOG_PeriodSel_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Watchdog initialization structure. */
typedef struct
{
/** Enable watchdog when init completed. */
bool enable;
/** Counter shall keep running during debug halt. */
bool debugRun;
/** Counter shall keep running when in EM2. */
bool em2Run;
/** Counter shall keep running when in EM3. */
bool em3Run;
/** Block EMU from entering EM4. */
bool em4Block;
/** Block SW from disabling LFRCO/LFXO oscillators. */
bool swoscBlock;
/** Block SW from modifying the configuration (a reset is needed to reconfigure). */
bool lock;
/** Clock source to use for watchdog. */
WDOG_ClkSel_TypeDef clkSel;
/** Watchdog timeout period. */
WDOG_PeriodSel_TypeDef perSel;
} WDOG_Init_TypeDef;
/** Suggested default config for WDOG init structure. */
#define WDOG_INIT_DEFAULT \
{ true, /* Start watchdog when init done */ \
false, /* WDOG not counting during debug halt */ \
false, /* WDOG not counting when in EM2 */ \
false, /* WDOG not counting when in EM3 */ \
false, /* EM4 can be entered */ \
false, /* Do not block disabling LFRCO/LFXO in CMU */ \
false, /* Do not lock WDOG configuration (if locked, reset needed to unlock) */ \
wdogClkSelULFRCO, /* Select 1kHZ WDOG oscillator */ \
wdogPeriod_256k /* Set longest possible timeout period */ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void WDOG_Enable(bool enable);
void WDOG_Feed(void);
void WDOG_Init(const WDOG_Init_TypeDef *init);
void WDOG_Lock(void);
/** @} (end addtogroup WDOG) */
/** @} (end addtogroup EFM32_Library) */
#ifdef __cplusplus
}
#endif
#endif /* __EFM32_WDOG_H */

View File

@ -0,0 +1,294 @@
/***************************************************************************//**
* @file
* @brief Analog Comparator (ACMP) peripheral module library implementation
* for EFM32 devices.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdbool.h>
#include "efm32_acmp.h"
#include "efm32_bitband.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ACMP
* @brief Analog comparator (ACMP) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of ACMP register block pointer reference
* for assert statements. */
#if (ACMP_COUNT == 1)
#define ACMP_REF_VALID(ref) ((ref) == ACMP0)
#elif (ACMP_COUNT == 2)
#define ACMP_REF_VALID(ref) (((ref) == ACMP0) || ((ref) == ACMP1))
#else
#error Undefined number of analog comparators (ACMP).
#endif
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets up the ACMP for use in capacative sense applications.
*
* @details
* This function sets up the ACMP for use in capacacitve sense applications.
* To use the capacative sense functionality in the ACMP you need to use
* the PRS output of the ACMP module to count the number of oscillations
* in the capacative sense circuit (possibly using a TIMER).
*
* @note
* A basic example of capacative sensing can be found in the STK BSP
* (capsense demo).
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] init
* Pointer to initialization structure used to configure ACMP for capacative
* sensing operation.
******************************************************************************/
void ACMP_CapsenseInit(ACMP_TypeDef *acmp, const ACMP_CapsenseInit_TypeDef *init)
{
/* Make sure the module exists on the selected chip */
EFM_ASSERT(ACMP_REF_VALID(acmp));
/* Make sure that vddLevel is within bounds */
EFM_ASSERT(init->vddLevel < 64);
/* Make sure biasprog is within bounds */
EFM_ASSERT(init->biasProg < 16);
/* Set control register. No need to set interrupt modes */
acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
| (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
| (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
| (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
| (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT);
/* Select capacative sensing mode by selecting a resistor and enabling it */
acmp->INPUTSEL = (init->resistor << _ACMP_INPUTSEL_CSRESSEL_SHIFT)
| ACMP_INPUTSEL_CSRESEN
| (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
| (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT)
| ACMP_INPUTSEL_NEGSEL_CAPSENSE;
/* Enable ACMP if requested.
* Note: BITBAND_Peripheral() function is used for setting/clearing single
* bit peripheral register bitfields. */
BITBAND_Peripheral(&(acmp->CTRL),
(uint32_t)_ACMP_CTRL_EN_SHIFT,
(uint32_t)init->enable);
}
/***************************************************************************//**
* @brief
* Sets the ACMP channel used for capacative sensing.
*
* @note
* A basic example of capacative sensing can be found in the STK BSP
* (capsense demo).
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
*
* @param[in] channel
* The ACMP channel to use for capacative sensing (Possel).
******************************************************************************/
void ACMP_CapsenseChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef channel)
{
/* Make sure that only external channels are used */
EFM_ASSERT(channel < _ACMP_INPUTSEL_NEGSEL_1V25);
/* Set channel as positive channel in ACMP */
SET_BIT_FIELD(acmp->INPUTSEL, _ACMP_INPUTSEL_POSSEL_MASK, channel,
_ACMP_INPUTSEL_POSSEL_SHIFT);
}
/***************************************************************************//**
* @brief
* Disables the ACMP.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
******************************************************************************/
void ACMP_Disable(ACMP_TypeDef *acmp)
{
acmp->CTRL &= ~ACMP_CTRL_EN;
}
/***************************************************************************//**
* @brief
* Enables the ACMP.
*
* @param[in] acmp
* Pointer to ACMP peripheral register block.
******************************************************************************/
void ACMP_Enable(ACMP_TypeDef *acmp)
{
acmp->CTRL |= ACMP_CTRL_EN;
}
/***************************************************************************//**
* @brief
* Reset ACMP to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] acmp
* Pointer to the ACMP peripheral register block.
******************************************************************************/
void ACMP_Reset(ACMP_TypeDef *acmp)
{
/* Make sure the module exists on the selected chip */
EFM_ASSERT(ACMP_REF_VALID(acmp));
acmp->CTRL = _ACMP_CTRL_RESETVALUE;
acmp->INPUTSEL = _ACMP_INPUTSEL_RESETVALUE;
acmp->IEN = _ACMP_IEN_RESETVALUE;
acmp->IFC = _ACMP_IF_MASK;
}
/***************************************************************************//**
* @brief
* Sets up GPIO output from the ACMP.
*
* @note
* GPIO must be enabled in the CMU before this function call, i.e.
* @verbatim CMU_ClockEnable(cmuClock_GPIO, true); @endverbatim
*
* @param[in] acmp
* Pointer to the ACMP peripheral register block.
*
* @param location
* The pin location to use. See the datasheet for location to pin mappings.
*
* @param enable
* Enable or disable pin output.
*
* @param invert
* Invert output.
******************************************************************************/
void ACMP_GPIOSetup(ACMP_TypeDef *acmp, uint32_t location, bool enable, bool invert)
{
/* Sanity checking of location */
EFM_ASSERT(location < 4);
/* Set GPIO inversion */
SET_BIT_FIELD(acmp->CTRL, _ACMP_CTRL_GPIOINV_MASK, invert,
_ACMP_CTRL_GPIOINV_SHIFT);
acmp->ROUTE = (location << _ACMP_ROUTE_LOCATION_SHIFT)
| (enable << _ACMP_ROUTE_ACMPPEN_SHIFT);
}
/***************************************************************************//**
* @brief
* Sets which channels should be used in ACMP comparisons.
*
* @param[in] acmp
* Pointer to the ACMP peripheral register block.
*
* @param negSel
* Channel to use on the negative input to the ACMP.
*
* @param posSel
* Channel to use on the positive input to the ACMP.
******************************************************************************/
void ACMP_ChannelSet(ACMP_TypeDef *acmp, ACMP_Channel_TypeDef negSel,
ACMP_Channel_TypeDef posSel)
{
/* Make sure that only external channels are used as ACMP positive input */
EFM_ASSERT(posSel < _ACMP_INPUTSEL_NEGSEL_1V25);
/* Sanity checking of ACMP negative input */
EFM_ASSERT(negSel <= _ACMP_INPUTSEL_NEGSEL_VDD);
acmp->INPUTSEL = (acmp->INPUTSEL & ~(_ACMP_INPUTSEL_POSSEL_MASK |
_ACMP_INPUTSEL_NEGSEL_MASK))
| (negSel << _ACMP_INPUTSEL_NEGSEL_SHIFT)
| (posSel << _ACMP_INPUTSEL_POSSEL_SHIFT);
}
/***************************************************************************//**
* @brief
*
*
* @param[in] acmp
* Pointer to the ACMP peripheral register block.
*
* @param[in] init
* Pointer to initialization structure used to configure ACMP for capacative
* sensing operation.
******************************************************************************/
void ACMP_Init(ACMP_TypeDef *acmp, const ACMP_Init_TypeDef *init)
{
/* Make sure the module exists on the selected chip */
EFM_ASSERT(ACMP_REF_VALID(acmp));
/* Make sure biasprog is within bounds */
EFM_ASSERT(init->biasProg < 16);
/* Set control register. No need to set interrupt modes */
acmp->CTRL = (init->fullBias << _ACMP_CTRL_FULLBIAS_SHIFT)
| (init->halfBias << _ACMP_CTRL_HALFBIAS_SHIFT)
| (init->biasProg << _ACMP_CTRL_BIASPROG_SHIFT)
| (init->interruptOnFallingEdge << _ACMP_CTRL_IFALL_SHIFT)
| (init->interruptOnRisingEdge << _ACMP_CTRL_IRISE_SHIFT)
| (init->warmTime << _ACMP_CTRL_WARMTIME_SHIFT)
| (init->hysteresisLevel << _ACMP_CTRL_HYSTSEL_SHIFT)
| (init->inactiveValue << _ACMP_CTRL_INACTVAL_SHIFT);
acmp->INPUTSEL = (init->lowPowerReferenceEnabled << _ACMP_INPUTSEL_LPREF_SHIFT)
| (init->vddLevel << _ACMP_INPUTSEL_VDDLEVEL_SHIFT);
/* Enable ACMP if requested.
* Note: BITBAND_Peripheral() function is used for setting/clearing single
* bit peripheral register bitfields. */
BITBAND_Peripheral(&(acmp->CTRL),
(uint32_t)_ACMP_CTRL_EN_SHIFT,
(uint32_t)init->enable);
}
/** @} (end addtogroup ACMP) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,510 @@
/***************************************************************************//**
* @file
* @brief Analog to Digital Converter (ADC) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_adc.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ADC
* @brief Analog to Digital Converter (ADC) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of ADC register block pointer reference for assert statements. */
#define ADC_REF_VALID(ref) ((ref) == ADC0)
/** Max ADC clock */
#define ADC_MAX_CLOCK 13000000
/** Min ADC clock */
#define ADC_MIN_CLOCK 32000
/** @endcond */
/*******************************************************************************
*************************** LOCAL FUNCTIONS *******************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Load SCAN calibrate register with predefined values for a certain
* reference.
*
* @details
* During production, calibration values are made and stored in the device
* information page for known references. Notice that for external references,
* calibration values must be determined explicitly, and this function
* will not modify the calibration register.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] ref
* Reference to load calibrated values for. No values are loaded for
* external references.
******************************************************************************/
static void ADC_CalibrateLoadScan(ADC_TypeDef *adc, ADC_Ref_TypeDef ref)
{
uint32_t cal;
/* Load proper calibration data depending on selected reference */
/* NOTE: We use ...SCAN... defines below, they are the same as */
/* similar ...SINGLE... defines. */
switch (ref)
{
case adcRef1V25:
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef2V5:
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >>
_DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >>
_DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRefVDD:
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >>
_DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >>
_DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef5VDIFF:
cal = adc->CAL & ~(_ADC_CAL_SCANOFFSET_MASK | _ADC_CAL_SCANGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >>
_DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SCANGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >>
_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef2xVDD:
/* Gain value not of relevance for this reference, leave as is */
cal = adc->CAL & ~_ADC_CAL_SCANOFFSET_MASK;
cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >>
_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SCANOFFSET_SHIFT;
adc->CAL = cal;
break;
/* For external references, the calibration must be determined for the */
/* specific application and set explicitly. */
default:
break;
}
}
/***************************************************************************//**
* @brief
* Load SINGLE calibrate register with predefined values for a certain
* reference.
*
* @details
* During production, calibration values are made and stored in the device
* information page for known references. Notice that for external references,
* calibration values must be determined explicitly, and this function
* will not modify the calibration register.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] ref
* Reference to load calibrated values for. No values are loaded for
* external references.
******************************************************************************/
static void ADC_CalibrateLoadSingle(ADC_TypeDef *adc, ADC_Ref_TypeDef ref)
{
uint32_t cal;
/* Load proper calibration data depending on selected reference */
/* NOTE: We use ...SCAN... defines below, they are the same as */
/* similar ...SINGLE... defines. */
switch (ref)
{
case adcRef1V25:
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef2V5:
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_GAIN_MASK) >>
_DEVINFO_ADC0CAL0_2V5_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_2V5_OFFSET_MASK) >>
_DEVINFO_ADC0CAL0_2V5_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRefVDD:
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_GAIN_MASK) >>
_DEVINFO_ADC0CAL1_VDD_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_VDD_OFFSET_MASK) >>
_DEVINFO_ADC0CAL1_VDD_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef5VDIFF:
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_GAIN_MASK) >>
_DEVINFO_ADC0CAL1_5VDIFF_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL1 & _DEVINFO_ADC0CAL1_5VDIFF_OFFSET_MASK) >>
_DEVINFO_ADC0CAL1_5VDIFF_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
break;
case adcRef2xVDD:
/* Gain value not of relevance for this reference, leave as is */
cal = adc->CAL & ~_ADC_CAL_SINGLEOFFSET_MASK;
cal |= ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_MASK) >>
_DEVINFO_ADC0CAL2_2XVDDVSS_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
break;
/* For external references, the calibration must be determined for the */
/* specific application and set explicitly. */
default:
break;
}
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize ADC.
*
* @details
* Initializes common parts for both single conversion and scan sequence.
* In addition, single and/or scan control configuration must be done, please
* refer to ADC_InitSingle() and ADC_InitScan() respectively.
*
* @note
* This function will stop any ongoing conversion.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] init
* Pointer to ADC initialization structure.
******************************************************************************/
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
{
uint32_t tmp;
EFM_ASSERT(ADC_REF_VALID(adc));
/* Make sure conversion is not in progress */
adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
tmp = ((uint32_t)(init->ovsRateSel) << _ADC_CTRL_OVSRSEL_SHIFT) |
(((uint32_t)(init->timebase) << _ADC_CTRL_TIMEBASE_SHIFT) & _ADC_CTRL_TIMEBASE_MASK) |
(((uint32_t)(init->prescale) << _ADC_CTRL_PRESC_SHIFT) & _ADC_CTRL_PRESC_MASK) |
((uint32_t)(init->lpfMode) << _ADC_CTRL_LPFMODE_SHIFT) |
((uint32_t)(init->warmUpMode) << _ADC_CTRL_WARMUPMODE_SHIFT);
if (init->tailgate)
{
tmp |= ADC_CTRL_TAILGATE;
}
adc->CTRL = tmp;
}
/***************************************************************************//**
* @brief
* Initialize ADC scan sequence.
*
* @details
* Please refer to ADC_StartScan() for starting scan sequence.
*
* When selecting an external reference, the gain and offset calibration
* must be set explicitly (CAL register). For other references, the
* calibration is updated with values defined during manufacturing.
*
* @note
* This function will stop any ongoing scan sequence.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] init
* Pointer to ADC initialization structure.
******************************************************************************/
void ADC_InitScan(ADC_TypeDef *adc, const ADC_InitScan_TypeDef *init)
{
uint32_t tmp;
EFM_ASSERT(ADC_REF_VALID(adc));
/* Make sure scan sequence is not in progress */
adc->CMD = ADC_CMD_SCANSTOP;
/* Load proper calibration data depending on selected reference */
ADC_CalibrateLoadScan(adc, init->reference);
tmp = ((uint32_t)(init->prsSel) << _ADC_SCANCTRL_PRSSEL_SHIFT) |
((uint32_t)(init->acqTime) << _ADC_SCANCTRL_AT_SHIFT) |
((uint32_t)(init->reference) << _ADC_SCANCTRL_REF_SHIFT) |
init->input |
((uint32_t)(init->resolution) << _ADC_SCANCTRL_RES_SHIFT);
if (init->prsEnable)
{
tmp |= ADC_SCANCTRL_PRSEN;
}
if (init->leftAdjust)
{
tmp |= ADC_SCANCTRL_ADJ_LEFT;
}
if (init->diff)
{
tmp |= ADC_SCANCTRL_DIFF;
}
if (init->rep)
{
tmp |= ADC_SCANCTRL_REP;
}
adc->SCANCTRL = tmp;
}
/***************************************************************************//**
* @brief
* Initialize single ADC sample conversion.
*
* @details
* Please refer to ADC_StartSingle() for starting single conversion.
*
* When selecting an external reference, the gain and offset calibration
* must be set explicitly (CAL register). For other references, the
* calibration is updated with values defined during manufacturing.
*
* @note
* This function will stop any ongoing single conversion.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
*
* @param[in] init
* Pointer to ADC initialization structure.
******************************************************************************/
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init)
{
uint32_t tmp;
EFM_ASSERT(ADC_REF_VALID(adc));
/* Make sure single conversion is not in progress */
adc->CMD = ADC_CMD_SINGLESTOP;
/* Load proper calibration data depending on selected reference */
ADC_CalibrateLoadSingle(adc, init->reference);
tmp = ((uint32_t)(init->prsSel) << _ADC_SINGLECTRL_PRSSEL_SHIFT) |
((uint32_t)(init->acqTime) << _ADC_SINGLECTRL_AT_SHIFT) |
((uint32_t)(init->reference) << _ADC_SINGLECTRL_REF_SHIFT) |
((uint32_t)(init->input) << _ADC_SINGLECTRL_INPUTSEL_SHIFT) |
((uint32_t)(init->resolution) << _ADC_SINGLECTRL_RES_SHIFT);
if (init->prsEnable)
{
tmp |= ADC_SINGLECTRL_PRSEN;
}
if (init->leftAdjust)
{
tmp |= ADC_SINGLECTRL_ADJ_LEFT;
}
if (init->diff)
{
tmp |= ADC_SINGLECTRL_DIFF;
}
if (init->rep)
{
tmp |= ADC_SINGLECTRL_REP;
}
adc->SINGLECTRL = tmp;
}
/***************************************************************************//**
* @brief
* Calculate prescaler value used to determine ADC clock.
*
* @details
* The ADC clock is given by: HFPERCLK / (prescale + 1).
*
* @param[in] adcFreq ADC frequency wanted. The frequency will automatically
* be adjusted to be within valid range according to reference manual.
*
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
* use currently defined HFPER clock setting.
*
* @return
* Prescaler value to use for ADC in order to achieve a clock value
* <= @p adcFreq.
******************************************************************************/
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
{
uint32_t ret;
/* Make sure selected ADC clock is within valid range */
if (adcFreq > ADC_MAX_CLOCK)
{
adcFreq = ADC_MAX_CLOCK;
}
else if (adcFreq < ADC_MIN_CLOCK)
{
adcFreq = ADC_MIN_CLOCK;
}
/* Use current HFPER frequency? */
if (!hfperFreq)
{
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
}
ret = (hfperFreq + adcFreq - 1) / adcFreq;
if (ret)
{
ret--;
}
return (uint8_t)ret;
}
/***************************************************************************//**
* @brief
* Reset ADC to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] adc
* Pointer to ADC peripheral register block.
******************************************************************************/
void ADC_Reset(ADC_TypeDef *adc)
{
uint32_t cal;
/* Stop conversions, before resetting other registers. */
adc->CMD = ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP;
adc->SINGLECTRL = _ADC_SINGLECTRL_RESETVALUE;
adc->SCANCTRL = _ADC_SCANCTRL_RESETVALUE;
adc->CTRL = _ADC_CTRL_RESETVALUE;
adc->IEN = _ADC_IEN_RESETVALUE;
adc->IFC = _ADC_IFC_MASK;
adc->BIASPROG = _ADC_BIASPROG_RESETVALUE;
cal = adc->CAL & ~(_ADC_CAL_SINGLEOFFSET_MASK | _ADC_CAL_SINGLEGAIN_MASK);
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_GAIN_MASK) >>
_DEVINFO_ADC0CAL0_1V25_GAIN_SHIFT) << _ADC_CAL_SINGLEGAIN_SHIFT;
cal |= ((DEVINFO->ADC0CAL0 & _DEVINFO_ADC0CAL0_1V25_OFFSET_MASK) >>
_DEVINFO_ADC0CAL0_1V25_OFFSET_SHIFT) << _ADC_CAL_SINGLEOFFSET_SHIFT;
adc->CAL = cal;
/* Do not reset route register, setting should be done independently */
}
/***************************************************************************//**
* @brief
* Calculate timebase value in order to get a timebase providing at least 1us.
*
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
* use currently defined HFPER clock setting.
*
* @return
* Timebase value to use for ADC in order to achieve at least 1 us.
******************************************************************************/
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
{
if (!hfperFreq)
{
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
/* Just in case, make sure we get non-zero freq for below calculation */
if (!hfperFreq)
{
hfperFreq = 1;
}
}
/* Determine number of HFPERCLK cycle >= 1us */
hfperFreq += 999999;
hfperFreq /= 1000000;
/* Return timebase value (N+1 format) */
return (uint8_t)(hfperFreq - 1);
}
/** @} (end addtogroup ADC) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,64 @@
/***************************************************************************//**
* @file
* @brief Assert API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_assert.h"
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* Currently this implementation only enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* Please notice that this function is not used unless DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @par file
* Name of source file where assertion failed.
*
* @par line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (1)
;
}
#endif /* DEBUG_EFM */

View File

@ -0,0 +1,287 @@
/***************************************************************************//**
* @file
* @brief Digital to Analog Coversion (DAC) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_dac.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup DAC
* @brief Digital to Analog Coversion (DAC) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of DAC channel for assert statements. */
#define DAC_CH_VALID(ch) ((ch) <= 1)
/** Max DAC clock */
#define DAC_MAX_CLOCK 1000000
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enable/disable DAC channel.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] ch
* Channel to enable/disable.
*
* @param[in] enable
* true to enable DAC channel, false to disable.
******************************************************************************/
void DAC_Enable(DAC_TypeDef *dac, unsigned int ch, bool enable)
{
volatile uint32_t *reg;
EFM_ASSERT(DAC_REF_VALID(dac));
EFM_ASSERT(DAC_CH_VALID(ch));
if (!ch)
{
reg = &(dac->CH0CTRL);
}
else
{
reg = &(dac->CH1CTRL);
}
BITBAND_Peripheral(reg, _DAC_CH0CTRL_EN_SHIFT, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Initialize DAC.
*
* @details
* Initializes common parts for both channels. In addition, channel control
* configuration must be done, please refer to DAC_InitChannel().
*
* @note
* This function will disable both channels prior to configuration.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] init
* Pointer to DAC initialization structure.
******************************************************************************/
void DAC_Init(DAC_TypeDef *dac, const DAC_Init_TypeDef *init)
{
uint32_t tmp;
EFM_ASSERT(DAC_REF_VALID(dac));
/* Make sure both channels are disabled. */
BITBAND_Peripheral(&(dac->CH0CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
BITBAND_Peripheral(&(dac->CH1CTRL), _DAC_CH0CTRL_EN_SHIFT, 0);
/* Load proper calibration data depending on selected reference */
switch (init->reference)
{
case dacRef2V5:
dac->CAL = DEVINFO->DAC0CAL1;
break;
case dacRefVDD:
dac->CAL = DEVINFO->DAC0CAL2;
break;
default: /* 1.25V */
dac->CAL = DEVINFO->DAC0CAL0;
break;
}
tmp = ((uint32_t)(init->refresh) << _DAC_CTRL_REFRSEL_SHIFT) |
(((uint32_t)(init->prescale) << _DAC_CTRL_PRESC_SHIFT) & _DAC_CTRL_PRESC_MASK) |
((uint32_t)(init->reference) << _DAC_CTRL_REFSEL_SHIFT) |
((uint32_t)(init->outMode) << _DAC_CTRL_OUTMODE_SHIFT) |
((uint32_t)(init->convMode) << _DAC_CTRL_CONVMODE_SHIFT);
if (init->ch0ResetPre)
{
tmp |= DAC_CTRL_CH0PRESCRST;
}
if (init->outEnablePRS)
{
tmp |= DAC_CTRL_OUTENPRS;
}
if (init->sineEnable)
{
tmp |= DAC_CTRL_SINEMODE;
}
if (init->diff)
{
tmp |= DAC_CTRL_DIFF;
}
dac->CTRL = tmp;
}
/***************************************************************************//**
* @brief
* Initialize DAC channel.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] init
* Pointer to DAC initialization structure.
*
* @param[in] ch
* Channel number to initialize.
******************************************************************************/
void DAC_InitChannel(DAC_TypeDef *dac,
const DAC_InitChannel_TypeDef *init,
unsigned int ch)
{
uint32_t tmp;
EFM_ASSERT(DAC_REF_VALID(dac));
EFM_ASSERT(DAC_CH_VALID(ch));
tmp = (uint32_t)(init->prsSel) << _DAC_CH0CTRL_PRSSEL_SHIFT;
if (init->enable)
{
tmp |= DAC_CH0CTRL_EN;
}
if (init->prsEnable)
{
tmp |= DAC_CH0CTRL_PRSEN;
}
if (init->refreshEnable)
{
tmp |= DAC_CH0CTRL_REFREN;
}
if (ch)
{
dac->CH1CTRL = tmp;
}
else
{
dac->CH0CTRL = tmp;
}
}
/***************************************************************************//**
* @brief
* Calculate prescaler value used to determine DAC clock.
*
* @details
* The DAC clock is given by: HFPERCLK / (prescale ^ 2).
*
* @param[in] dacFreq DAC frequency wanted. The frequency will automatically
* be adjusted to be below max allowed DAC clock.
*
* @param[in] hfperFreq Frequency in Hz of reference HFPER clock. Set to 0 to
* use currently defined HFPER clock setting.
*
* @return
* Prescaler value to use for DAC in order to achieve a clock value
* <= @p dacFreq.
******************************************************************************/
uint8_t DAC_PrescaleCalc(uint32_t dacFreq, uint32_t hfperFreq)
{
uint32_t ret;
/* Make sure selected DAC clock is below max value */
if (dacFreq > DAC_MAX_CLOCK)
{
dacFreq = DAC_MAX_CLOCK;
}
/* Use current HFPER frequency? */
if (!hfperFreq)
{
hfperFreq = CMU_ClockFreqGet(cmuClock_HFPER);
}
/* Iterate in order to determine best prescale value. Only a few possible */
/* values. We start with lowest prescaler value in order to get first */
/* equal or below wanted DAC frequency value. */
for (ret = 0; ret <= (_DAC_CTRL_PRESC_MASK >> _DAC_CTRL_PRESC_SHIFT); ret++)
{
if ((hfperFreq >> ret) <= dacFreq)
break;
}
return((uint8_t)ret);
}
/***************************************************************************//**
* @brief
* Reset DAC to same state as after a HW reset.
*
* @param[in] dac
* Pointer to ADC peripheral register block.
******************************************************************************/
void DAC_Reset(DAC_TypeDef *dac)
{
/* Disable channels, before resetting other registers. */
dac->CH0CTRL = _DAC_CH0CTRL_RESETVALUE;
dac->CH1CTRL = _DAC_CH1CTRL_RESETVALUE;
dac->CTRL = _DAC_CTRL_RESETVALUE;
dac->IEN = _DAC_IEN_RESETVALUE;
dac->IFC = _DAC_IFC_MASK;
dac->CAL = DEVINFO->DAC0CAL0;
dac->BIASPROG = _DAC_BIASPROG_RESETVALUE;
/* Do not reset route register, setting should be done independently */
}
/** @} (end addtogroup DAC) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,109 @@
/***************************************************************************//**
* @file
* @brief Debug (DBG) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_assert.h"
#include "efm32_dbg.h"
#include "efm32_cmu.h"
#include "efm32_gpio.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup DBG
* @brief Debug (DBG) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enable Serial Wire Output (SWO) pin.
*
* @details
* The SWO pin (sometimes denoted SWV, serial wire viewer) allows for
* miscellaneous output to be passed from the Cortex-M3 debug trace module to
* an external debug probe. By default, the debug trace module and pin output
* may be disabled.
*
* Since the SWO pin is only useful when using a debugger, a suggested use
* of this function during startup may be:
* @verbatim
* if (DBG_Connected())
* {
* DBG_SWOEnable(1);
* }
* @endverbatim
* By checking if debugger is attached, some setup leading to higher energy
* consumption when debugger is attached, can be avoided when not using
* a debugger.
*
* Another alternative may be to set the debugger tool chain to configure
* the required setup (similar to the content of this function) by some
* sort of toolchain scripting during its attach/reset procedure. In that
* case, the above suggested code for enabling the SWO pin is not required
* in the application.
*
* @param[in] location
* Pin location used for SWO pin on the application in use.
******************************************************************************/
void DBG_SWOEnable(unsigned int location)
{
int port;
int pin;
EFM_ASSERT(location < AFCHANLOC_MAX);
port = AF_DBG_SWO_PORT(location);
pin = AF_DBG_SWO_PIN(location);
/* Port/pin location not defined for device? */
if ((pin < 0) || (port < 0))
{
EFM_ASSERT(0);
return;
}
/* Ensure auxiliary clock going to the Cortex debug trace module is enabled */
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, false);
/* Set selected pin location for SWO pin and enable it */
GPIO_DbgLocationSet(location);
GPIO_DbgSWOEnable(true);
/* Configure SWO pin for output */
GPIO_PinModeSet((GPIO_Port_TypeDef)port, pin, gpioModePushPull, 0);
}
/** @} (end addtogroup DBG) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,499 @@
/***************************************************************************//**
* @file
* @brief Energy Management Unit (EMU) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_emu.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup EMU
* @brief Energy Management Unit (EMU) Peripheral API for EFM32
* @{
******************************************************************************/
/* Consistency check, since restoring assumes similar bitpositions in */
/* CMU OSCENCMD and STATUS regs */
#if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
#error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
#endif
#if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
#error Conflict in HFXOENS and HFXOEN bitpositions
#endif
#if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
#error Conflict in LFRCOENS and LFRCOEN bitpositions
#endif
#if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
#error Conflict in LFXOENS and LFXOEN bitpositions
#endif
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* CMU configured oscillator selection and oscillator enable status. When a
* user configures oscillators, this varaiable shall shadow the configuration.
* It is used by the EMU module in order to be able to restore the oscillator
* config after having been in certain energy modes (since HW may automatically
* alter config when going into an energy mode). It is the responsibility of
* the CMU module to keep it up-to-date (or a user if not using the CMU API
* for oscillator control).
*/
static uint16_t cmuStatus;
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Restore oscillators and core clock after having been in EM2 or EM3.
******************************************************************************/
static void EMU_Restore(void)
{
uint32_t cmuLocked;
/* Although we could use the CMU API for most of the below handling, we */
/* would like this function to be as efficient as possible. */
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* AUXHFRCO was automatically disabled (except if using debugger). */
/* HFXO was automatically disabled. */
/* LFRCO/LFXO were possibly disabled by SW in EM3. */
/* Restore according to status prior to entering EM. */
CMU->OSCENCMD = cmuStatus & (CMU_STATUS_AUXHFRCOENS |
CMU_STATUS_HFXOENS |
CMU_STATUS_LFRCOENS |
CMU_STATUS_LFXOENS);
/* Restore oscillator used for clocking core */
switch (cmuStatus & (CMU_STATUS_HFXOSEL | CMU_STATUS_HFRCOSEL |
CMU_STATUS_LFXOSEL | CMU_STATUS_LFRCOSEL))
{
case CMU_STATUS_LFRCOSEL:
/* Wait for LFRCO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
break;
case CMU_STATUS_LFXOSEL:
/* Wait for LFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
break;
case CMU_STATUS_HFXOSEL:
/* Wait for HFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
break;
default: /* CMU_STATUS_HFRCOSEL */
/* If core clock was HFRCO core clock, it is automatically restored to */
/* state prior to entering energy mode. No need for further action. */
break;
}
/* If HFRCO was disabled before entering Energy Mode, turn it off again */
/* as it is automatically enabled by wake up */
if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
{
CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
}
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enter energy mode 2 (EM2).
*
* @details
* When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
* and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
* EM0, HFRCO is re-enabled and the core will be clocked by the configured
* HFRCO band. This ensures a quick wakeup from EM2.
*
* However, prior to entering EM2, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF oscillators according to state prior to entering EM2,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use the HFXO oscillator, which has been
* disabled during EM2 mode, this function will stall until the oscillator
* has stabilized. Stalling time can be reduced by adding interrupt
* support detecting stable oscillator, and an asynchronous switch to the
* original oscillator. See CMU documentation. Such a feature is however
* outside the scope of the implementation in this function.
* @par
* If HFXO is re-enabled by this function, and NOT used to clock the core,
* this function will not wait for HFXO to stabilize. This must be considered
* by the application if trying to use features relying on that oscillator
* upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM2. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM2(bool restore)
{
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 3 (EM3).
*
* @details
* When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
* HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
* the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
* re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
* configured HFRCO band. This ensures a quick wakeup from EM3.
*
* However, prior to entering EM3, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF/LF oscillators according to state prior to entering EM3,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use an oscillator other than HFRCO, this
* function will stall until the oscillator has stabilized. Stalling time
* can be reduced by adding interrupt support detecting stable oscillator,
* and an asynchronous switch to the original oscillator. See CMU
* documentation. Such a feature is however outside the scope of the
* implementation in this function.
* @par
* If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
* the core, this function will not wait for those oscillators to stabilize.
* This must be considered by the application if trying to use features
* relying on those oscillators upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM3. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM3(bool restore)
{
uint32_t cmuLocked;
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* Disable LF oscillators */
CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 4 (EM4).
*
* @note
* Only a power on reset or external reset pin can wake the device from EM4.
******************************************************************************/
void EMU_EnterEM4(void)
{
int i;
/* Make sure register write lock is disabled */
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
for (i = 0; i < 4; i++)
{
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
EMU->CTRL = (3 << _EMU_CTRL_EM4CTRL_SHIFT);
}
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
}
/***************************************************************************//**
* @brief
* Power down memory block.
*
* @param[in] blocks
* Specifies a logical OR of bits indicating memory blocks to power down.
* Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
* be disabled. Please refer to the EFM32 reference manual for available
* memory blocks for a device.
*
* @note
* Only a reset can make the specified memory block(s) available for use
* after having been powered down. Function will be void for devices not
* supporting this feature.
******************************************************************************/
void EMU_MemPwrDown(uint32_t blocks)
{
#if defined(_EMU_MEMCTRL_RESETVALUE)
EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
EMU->MEMCTRL = blocks;
#else
(void)blocks;
#endif
}
/***************************************************************************//**
* @brief
* Update EMU module with CMU oscillator selection/enable status.
*
* @details
* When entering EM2 and EM3, the HW may change the core clock oscillator
* used, as well as disabling some oscillators. The user may optionally select
* to restore the oscillators after waking up from EM2 and EM3 through the
* SW API.
*
* However, in order to support this in a safe way, the EMU module must
* be kept up-to-date on the actual selected configuration. The CMU
* module must keep the EMU module up-to-date.
*
* This function is mainly intended for internal use by the CMU module,
* but if the applications changes oscillator configurations without
* using the CMU API, this function can be used to keep the EMU module
* up-to-date.
******************************************************************************/
void EMU_UpdateOscConfig(void)
{
/* Fetch current configuration */
cmuStatus = (uint16_t)(CMU->STATUS);
}
#if defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Update EMU module with Energy Mode 4 configuration
*
* @param[in] em4init
* Energy Mode 4 configuration structure
******************************************************************************/
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init)
{
uint32_t em4conf = EMU->EM4CONF;
/* Clear fields that will be reconfigured */
em4conf &= ~(
_EMU_EM4CONF_LOCKCONF_MASK|
_EMU_EM4CONF_OSC_MASK|
_EMU_EM4CONF_BURTCWU_MASK|
_EMU_EM4CONF_VREGEN_MASK);
/* Configure new settings */
em4conf |= (
(em4init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)|
(em4init->osc)|
(em4init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)|
(em4init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
/* Apply configuration. Note that lock can be set after this stage. */
EMU->EM4CONF = em4conf;
}
/***************************************************************************//**
* @brief
* Configure BackUp Power Domain settings
*
* @note
* stig note to self: Touches RMU->CTRL BUPD?
*
* @param[in] bupdInit
* Backup power domain initialization structure
******************************************************************************/
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
{
uint32_t reg;
EFM_ASSERT(bupdInit->inactiveThresRange < 4);
EFM_ASSERT(bupdInit->inactiveThreshold < 4);
EFM_ASSERT(bupdInit->activeThresRange < 4);
EFM_ASSERT(bupdInit->activeThreshold < 4);
/* Set power connection configuration */
reg = EMU->PWRCONF & ~(
_EMU_PWRCONF_PWRRES_MASK|
_EMU_PWRCONF_VOUTSTRONG_MASK|
_EMU_PWRCONF_VOUTMED_MASK|
_EMU_PWRCONF_VOUTWEAK_MASK);
reg |= (bupdInit->resistor|
(bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
(bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
(bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
EMU->PWRCONF = reg;
/* Set backup domain inactive mode configuration */
reg = EMU->BUINACT & ~(
_EMU_BUINACT_PWRCON_MASK|
_EMU_BUINACT_BUENRANGE_MASK|
_EMU_BUINACT_BUENTHRES_MASK);
reg |= (bupdInit->inactivePower|
(bupdInit->inactiveThresRange << _EMU_BUINACT_BUENRANGE_SHIFT)|
(bupdInit->inactiveThreshold << _EMU_BUINACT_BUENTHRES_SHIFT));
EMU->BUINACT = reg;
/* Set backup domain active mode configuration */
reg = EMU->BUACT & ~(
_EMU_BUACT_PWRCON_MASK|
_EMU_BUACT_BUEXRANGE_MASK|
_EMU_BUACT_BUEXTHRES_MASK);
reg |= (bupdInit->activePower|
(bupdInit->activeThresRange << _EMU_BUACT_BUEXRANGE_SHIFT)|
(bupdInit->activeThreshold << _EMU_BUACT_BUEXTHRES_SHIFT));
EMU->BUACT = reg;
/* Set power control configuration */
reg = EMU->BUCTRL & ~(
_EMU_BUCTRL_PROBE_MASK|
_EMU_BUCTRL_BODCAL_MASK|
_EMU_BUCTRL_STATEN_MASK|
_EMU_BUCTRL_EN_MASK);
/* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
release reset */
reg |= (bupdInit->probe|
(bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
(bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
(bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
/* Enable configuration */
EMU->BUCTRL = reg;
/* If enable is true, enable BU_VIN input power pin, if not disable it */
EMU_BUPinEnable(bupdInit->enable);
/* If enable is true, release BU reset, if not keep reset asserted */
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
}
#endif
/** @} (end addtogroup EMU) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,487 @@
/***************************************************************************//**
* @file
* @brief General Purpose IO (GPIO) peripheral API for EFM32
* devices.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_gpio.h"
#include "efm32_bitband.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
/** Validation of pin typically usable in assert statements. */
#define GPIO_PIN_VALID(pin) ((pin) < 16)
/** Validation of port typically usable in assert statements. */
#define GPIO_PORT_VALID(port) ((port) <= gpioPortF)
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |
(location << _GPIO_ROUTE_SWLOCATION_SHIFT);
}
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure GPIO interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected pin is cleared by this
* function.
*
* @note
* A certain pin number can only be associated with one port. Ie, if GPIO
* interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
* pin 1 from any other ports for interrupts. Please refer to the reference
* manual.
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The GPIO interrupt number (= port pin).
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_IntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp;
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (pin < 8)
{
GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
(port << (4 * pin));
}
else
{
tmp = pin - 8;
GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
(port << (4 * tmp));
}
/* Enable/disable rising edge */
BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);
/* Enable/disable falling edge */
BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << pin;
/* Finally enable/disable interrupt */
BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Read the pad value for a single pin in a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number to read.
*
* @return
* The pin value, 0 or 1.
******************************************************************************/
unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
return((unsigned int)((GPIO->P[port].DIN >> pin) & 0x1));
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
* Notice that this parameter is not used if disabling a pin, leaving the
* corresponding DOUT bit unchanged.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8)
{
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xF << (pin * 4))) |
(mode << (pin * 4));
}
else
{
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xF << ((pin - 8) * 4))) |
(mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
}
/***************************************************************************//**
* @brief
* Set a single pin in GPIO data out port register to 0.
*
* @note
* In order for the setting to take effect on the output pad, the pin must
* have been configured properly. If not, it will take effect whenever the
* pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin to set.
******************************************************************************/
void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
GPIO->P[port].DOUTCLR = 1 << pin;
}
/***************************************************************************//**
* @brief
* Get current setting for a pin in a GPIO port data out register.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin to get setting for.
*
* @return
* The DOUT setting for the requested pin, 0 or 1.
******************************************************************************/
unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port, unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
return((unsigned int)((GPIO->P[port].DOUT >> pin) & 0x1));
}
/***************************************************************************//**
* @brief
* Set a single pin in GPIO data out register to 1.
*
* @note
* In order for the setting to take effect on the output pad, the pin must
* have been configured properly. If not, it will take effect whenever the
* pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin to set.
******************************************************************************/
void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
GPIO->P[port].DOUTSET = 1 << pin;
}
/***************************************************************************//**
* @brief
* Toggle a single pin in GPIO port data out register.
*
* @note
* In order for the setting to take effect on the output pad, the pin must
* have been configured properly. If not, it will take effect whenever the
* pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin to toggle.
******************************************************************************/
void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
GPIO->P[port].DOUTTGL = 1 << pin;
}
/***************************************************************************//**
* @brief
* Read the pad values for GPIO port.
*
* @param[in] port
* The GPIO port to access.
******************************************************************************/
uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
return(GPIO->P[port].DIN & _GPIO_P_DIN_DIN_MASK);
}
/***************************************************************************//**
* @brief
* Set bits in DOUT register for a port to 0.
*
* @note
* In order for the setting to take effect on the output pad, the pin must
* have been configured properly. If not, it will take effect whenever the
* pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pins
* Bit mask for bits to clear in DOUT register.
******************************************************************************/
void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
GPIO->P[port].DOUTCLR = pins & _GPIO_P_DOUTCLR_DOUTCLR_MASK;
}
/***************************************************************************//**
* @brief
* Get current setting for a GPIO port data out register.
*
* @param[in] port
* The GPIO port to access.
*
* @return
* The data out setting for the requested port.
******************************************************************************/
uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
return(GPIO->P[port].DOUT & _GPIO_P_DOUT_DOUT_MASK);
}
/***************************************************************************//**
* @brief
* Set bits GPIO data out register to 1.
*
* @note
* In order for the setting to take effect on the respective output pads, the
* pins must have been configured properly. If not, it will take effect
* whenever the pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pins
* Bit mask for bits to set to 1 in DOUT register.
******************************************************************************/
void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
GPIO->P[port].DOUTSET = pins & _GPIO_P_DOUTSET_DOUTSET_MASK;
}
/***************************************************************************//**
* @brief
* Set GPIO port data out register.
*
* @note
* In order for the setting to take effect on the respective output pads, the
* pins must have been configured properly. If not, it will take effect
* whenever the pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] val
* Value to write to port data out register.
*
* @param[in] mask
* Mask indicating which bits to modify.
******************************************************************************/
void GPIO_PortOutSetVal(GPIO_Port_TypeDef port, uint32_t val, uint32_t mask)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
GPIO->P[port].DOUT = (GPIO->P[port].DOUT & ~mask) | (val & mask);
}
/***************************************************************************//**
* @brief
* Toggle a single pin in GPIO port data out register.
*
* @note
* In order for the setting to take effect on the output pad, the pin must
* have been configured properly. If not, it will take effect whenever the
* pin has been properly configured.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pins
* Bitmask with pins to toggle.
******************************************************************************/
void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins)
{
EFM_ASSERT(GPIO_PORT_VALID(port));
GPIO->P[port].DOUTTGL = pins & _GPIO_P_DOUTTGL_DOUTTGL_MASK;
}
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,789 @@
/***************************************************************************//**
* @file
* @brief Inter-integrated Circuit (I2C) Peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32.h"
#include "efm32_i2c.h"
#include "efm32_cmu.h"
#include "efm32_bitband.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup I2C
* @brief Inter-integrated Circuit (I2C) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of I2C register block pointer reference for assert statements. */
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_TINY_FAMILY)
#define I2C_REF_VALID(ref) ((ref) == I2C0)
#endif
#if defined(_EFM32_GIANT_FAMILY)
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
#endif
/** Error flags indicating I2C transfer has failed somehow. */
/* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
/* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
/* RXUF is only likely to occur with this SW if using a debugger peeking into */
/* RXDATA register. Thus, we ignore those types of fault. */
#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Master mode transfer states. */
typedef enum
{
i2cStateStartAddrSend, /**< Send start + (first part of) address. */
i2cStateAddrWFAckNack, /**< Wait for ACK/NACK on (first part of) address. */
i2cStateAddrWF2ndAckNack, /**< Wait for ACK/NACK on second part of 10 bit address. */
i2cStateRStartAddrSend, /**< Send repeated start + (first part of) address. */
i2cStateRAddrWFAckNack, /**< Wait for ACK/NACK on address sent after repeated start. */
i2cStateDataSend, /**< Send data. */
i2cStateDataWFAckNack, /**< Wait for ACK/NACK on data sent. */
i2cStateWFData, /**< Wait for data. */
i2cStateWFStopSent, /**< Wait for STOP to have been transmitted. */
i2cStateDone /**< Transfer completed successfully. */
} I2C_TransferState_TypeDef;
/** @endcond */
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Structure used to store state information on an ongoing master mode transfer. */
typedef struct
{
/** Current state. */
I2C_TransferState_TypeDef state;
/** Result return code. */
I2C_TransferReturn_TypeDef result;
/** Offset in current sequence buffer. */
uint16_t offset;
/* Index to current sequence buffer in use. */
uint8_t bufIndx;
/** Reference to I2C transfer sequence definition provided by user. */
I2C_TransferSeq_TypeDef *seq;
} I2C_Transfer_TypeDef;
/** @endcond */
/*******************************************************************************
***************************** LOCAL DATA *******^**************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
* index (0x3) to reflect default setting just in case.
*/
static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 3, 4 + 4 };
/** Transfer state info for ongoing master mode transfer */
static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get current configured I2C bus frequency.
*
* @details
* This frequency is only of relevance when acting as master.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Current I2C frequency in Hz.
******************************************************************************/
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
{
uint32_t hfperclk;
uint32_t n;
/* Max frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4) */
hfperclk = CMU_ClockFreqGet(cmuClock_HFPER);
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
return(hfperclk / ((n * (i2c->CLKDIV + 1)) + 4));
}
/***************************************************************************//**
* @brief
* Set I2C bus frequency.
*
* @details
* The bus frequency is only of relevance when acting as a master. The bus
* frequency should not be set higher than the max frequency accepted by the
* slowest device on the bus.
*
* Notice that due to asymmetric requirements on low and high I2C clock
* cycles by the I2C specification, the actual max frequency allowed in order
* to comply with the specification may be somewhat lower than expected.
*
* Please refer to the reference manual, details on I2C clock generation,
* for max allowed theoretical frequencies for different modes.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] refFreq
* I2C reference clock frequency in Hz that will be used. If set to 0,
* the currently configured reference clock is assumed. Setting it to a higher
* than actual configured value only has the consequence of reducing the real
* I2C frequency.
*
* @param[in] freq
* Bus frequency to set (actual bus speed may be lower due to integer
* prescaling). Safe (according to I2C specification) max frequencies for
* standard, fast and fast+ modes are available using I2C_FREQ_ defines.
* (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
* Slowest slave device on bus must always be considered.
*
* @param[in] type
* Clock low to high ratio type to use. If not using i2cClockHLRStandard,
* make sure all devices on the bus support the specified mode. Using a
* non-standard ratio is useful to achieve higher bus clock in fast and
* fast+ modes.
******************************************************************************/
void I2C_BusFreqSet(I2C_TypeDef *i2c,
uint32_t refFreq,
uint32_t freq,
I2C_ClockHLR_TypeDef type)
{
uint32_t n;
uint32_t div;
/* Unused parameter */
(void)type;
/* Avoid divide by 0 */
EFM_ASSERT(freq);
if (!freq)
{
return;
}
/* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), thus */
/* DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 */
if (!refFreq)
{
refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
}
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
div = (refFreq - (4 * freq)) / (n * freq);
EFM_ASSERT(div);
if (div)
{
div--;
}
/* Clock divisor must be at least 1 in slave mode according to reference */
/* manual (in which case there is normally no need to set bus frequency). */
if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div)
{
div = 1;
}
EFM_ASSERT(div <= _I2C_CLKDIV_DIV_MASK);
i2c->CLKDIV = div;
}
/***************************************************************************//**
* @brief
* Enable/disable I2C.
*
* @note
* After enabling the I2C (from being disabled), the I2C is in BUSY state.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
BITBAND_Peripheral(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Initialize I2C.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] init
* Pointer to I2C initialization structure.
******************************************************************************/
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
i2c->IEN = 0;
i2c->IFC = _I2C_IFC_MASK;
I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
BITBAND_Peripheral(&(i2c->CTRL),
_I2C_CTRL_SLAVE_SHIFT,
~((unsigned int)(init->master)));
BITBAND_Peripheral(&(i2c->CTRL),
_I2C_CTRL_EN_SHIFT,
(unsigned int)(init->enable));
}
/***************************************************************************//**
* @brief
* Reset I2C to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
******************************************************************************/
void I2C_Reset(I2C_TypeDef *i2c)
{
i2c->CTRL = _I2C_CTRL_RESETVALUE;
i2c->CLKDIV = _I2C_CLKDIV_RESETVALUE;
i2c->SADDR = _I2C_SADDR_RESETVALUE;
i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
i2c->IEN = _I2C_IEN_RESETVALUE;
i2c->IFC = _I2C_IFC_MASK;
/* Do not reset route register, setting should be done independently */
}
/***************************************************************************//**
* @brief
* Continue an initiated I2C transfer (single master mode only).
*
* @details
* This function is used repeatedly after a I2C_TransferInit() in order to
* complete a transfer. It may be used in polled mode as the below example
* shows:
* @verbatim
* I2C_TransferReturn_TypeDef ret;
*
* // Do a polled transfer
* ret = I2C_TransferInit(I2C0, seq);
* while (ret == i2cTransferInProgress)
* {
* ret = I2C_Transfer(I2C0);
* }
* @endverbatim
* It may also be used in interrupt driven mode, where this function is invoked
* from the interrupt handler. Notice that if used in interrupt mode, NVIC
* interrupts must be configured and enabled for the I2C bus used. I2C
* peripheral specific interrupts are managed by this SW.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Returns status for ongoing transfer.
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li #i2cTransferDone - transfer completed successfully.
* @li otherwise some sort of error has occurred.
*
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
{
uint32_t tmp;
uint32_t pending;
I2C_Transfer_TypeDef *transfer;
I2C_TransferSeq_TypeDef *seq;
EFM_ASSERT(I2C_REF_VALID(i2c));
/* Support up to 2 I2C buses */
if (i2c == I2C0)
{
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1)
{
transfer = i2cTransfer + 1;
}
#endif
else
{
return(i2cTransferUsageFault);
}
seq = transfer->seq;
for (;; )
{
pending = i2c->IF;
/* If some sort of fault, abort transfer. */
if (pending & I2C_IF_ERRORS)
{
if (pending & I2C_IF_ARBLOST)
{
/* If arbitration fault, it indicates either a slave device */
/* not responding as expected, or other master which is not */
/* supported by this SW. */
transfer->result = i2cTransferArbLost;
}
else if (pending & I2C_IF_BUSERR)
{
/* A bus error indicates a misplaced start or stop, which should */
/* not occur in master mode controlled by this SW. */
transfer->result = i2cTransferBusErr;
}
/* If error situation occurred, it is difficult to know */
/* exact cause and how to resolve. It will be up to a wrapper */
/* to determine how to handle a fault/recovery if possible. */
transfer->state = i2cStateDone;
goto done;
}
switch (transfer->state)
{
/***************************************************/
/* Send first start+address (first byte if 10 bit) */
/***************************************************/
case i2cStateStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR)
{
tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
/* In 10 bit address mode, the address following the first */
/* start always indicate write. */
}
else
{
tmp = (uint32_t)(seq->addr) & 0xfe;
if (seq->flags & I2C_FLAG_READ)
{
/* Indicate read request */
tmp |= 1;
}
}
transfer->state = i2cStateAddrWFAckNack;
i2c->TXDATA = tmp; /* Data not transmitted until START sent */
i2c->CMD = I2C_CMD_START;
goto done;
/*******************************************************/
/* Wait for ACK/NACK on address (first byte if 10 bit) */
/*******************************************************/
case i2cStateAddrWFAckNack:
if (pending & I2C_IF_NACK)
{
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
}
else if (pending & I2C_IF_ACK)
{
i2c->IFC = I2C_IFC_ACK;
/* If 10 bit address, send 2nd byte of address. */
if (seq->flags & I2C_FLAG_10BIT_ADDR)
{
transfer->state = i2cStateAddrWF2ndAckNack;
i2c->TXDATA = (uint32_t)(seq->addr) & 0xff;
}
else
{
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_READ)
{
transfer->state = i2cStateWFData;
}
else
{
transfer->state = i2cStateDataSend;
continue;
}
}
}
goto done;
/******************************************************/
/* Wait for ACK/NACK on second byte of 10 bit address */
/******************************************************/
case i2cStateAddrWF2ndAckNack:
if (pending & I2C_IF_NACK)
{
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
}
else if (pending & I2C_IF_ACK)
{
i2c->IFC = I2C_IFC_ACK;
/* If using plain read sequence with 10 bit address, switch to send */
/* repeated start. */
if (seq->flags & I2C_FLAG_READ)
{
transfer->state = i2cStateRStartAddrSend;
}
/* Otherwise expected to write 0 or more bytes */
else
{
transfer->state = i2cStateDataSend;
}
continue;
}
goto done;
/*******************************/
/* Send repeated start+address */
/*******************************/
case i2cStateRStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR)
{
tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
}
else
{
tmp = seq->addr & 0xfe;
}
/* If this is a write+read combined sequence, then read is about to start */
if (seq->flags & I2C_FLAG_WRITE_READ)
{
/* Indicate read request */
tmp |= 1;
}
transfer->state = i2cStateRAddrWFAckNack;
/* We have to write START cmd first since repeated start, otherwise */
/* data would be sent first. */
i2c->CMD = I2C_CMD_START;
i2c->TXDATA = tmp;
goto done;
/**********************************************************************/
/* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
/**********************************************************************/
case i2cStateRAddrWFAckNack:
if (pending & I2C_IF_NACK)
{
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
}
else if (pending & I2C_IF_ACK)
{
i2c->IFC = I2C_IFC_ACK;
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_WRITE_READ)
{
transfer->state = i2cStateWFData;
}
else
{
transfer->state = i2cStateDataSend;
continue;
}
}
goto done;
/*****************************/
/* Send a data byte to slave */
/*****************************/
case i2cStateDataSend:
/* Reached end of data buffer? */
if (transfer->offset >= seq->buf[transfer->bufIndx].len)
{
/* Move to next message part */
transfer->offset = 0;
transfer->bufIndx++;
/* Send repeated start when switching to read mode on 2nd buffer */
if (seq->flags & I2C_FLAG_WRITE_READ)
{
transfer->state = i2cStateRStartAddrSend;
continue;
}
/* Only writing from one buffer, or finished both buffers */
if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1))
{
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
goto done;
}
/* Reprocess in case next buffer is empty */
continue;
}
/* Send byte */
i2c->TXDATA = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
transfer->state = i2cStateDataWFAckNack;
goto done;
/*********************************************************/
/* Wait for ACK/NACK from slave after sending data to it */
/*********************************************************/
case i2cStateDataWFAckNack:
if (pending & I2C_IF_NACK)
{
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
}
else if (pending & I2C_IF_ACK)
{
i2c->IFC = I2C_IFC_ACK;
transfer->state = i2cStateDataSend;
continue;
}
goto done;
/****************************/
/* Wait for data from slave */
/****************************/
case i2cStateWFData:
if (pending & I2C_IF_RXDATAV)
{
uint8_t data;
/* Must read out data in order to not block further progress */
data = (uint8_t)(i2c->RXDATA);
/* Make sure not storing beyond end of buffer just in case */
if (transfer->offset < seq->buf[transfer->bufIndx].len)
{
seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
}
/* If we have read all requested data, then the sequence should end */
if (transfer->offset >= seq->buf[transfer->bufIndx].len)
{
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_NACK;
i2c->CMD = I2C_CMD_STOP;
}
else
{
/* Send ACK and wait for next byte */
i2c->CMD = I2C_CMD_ACK;
}
}
goto done;
/***********************************/
/* Wait for STOP to have been sent */
/***********************************/
case i2cStateWFStopSent:
if (pending & I2C_IF_MSTOP)
{
i2c->IFC = I2C_IFC_MSTOP;
transfer->state = i2cStateDone;
}
goto done;
/******************************/
/* Unexpected state, SW fault */
/******************************/
default:
transfer->result = i2cTransferSwFault;
transfer->state = i2cStateDone;
goto done;
}
}
done:
if (transfer->state == i2cStateDone)
{
/* Disable interrupt sources when done */
i2c->IEN = 0;
/* Update result unless some fault already occurred */
if (transfer->result == i2cTransferInProgress)
{
transfer->result = i2cTransferDone;
}
}
/* Until transfer is done keep returning i2cTransferInProgress */
else
{
return(i2cTransferInProgress);
}
return transfer->result;
}
/***************************************************************************//**
* @brief
* Prepare and start an I2C transfer (single master mode only).
*
* @details
* This function must be invoked in order to start an I2C transfer
* sequence. In order to actually complete the transfer, I2C_Transfer() must
* be used either in polled mode or by adding a small driver wrapper utilizing
* interrupts.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] seq
* Pointer to sequence structure defining the I2C transfer to take place. The
* referenced structure must exist until the transfer has fully completed.
*
* @return
* Returns status for ongoing transfer:
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li otherwise some sort of error has occurred.
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
I2C_TransferSeq_TypeDef *seq)
{
I2C_Transfer_TypeDef *transfer;
EFM_ASSERT(I2C_REF_VALID(i2c));
EFM_ASSERT(seq);
/* Support up to 2 I2C buses */
if (i2c == I2C0)
{
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1)
{
transfer = i2cTransfer + 1;
}
#endif
else
{
return(i2cTransferUsageFault);
}
/* Check if in busy state. Since this SW assumes single master, we can */
/* just issue an abort. The BUSY state is normal after a reset. */
if (i2c->STATE & I2C_STATE_BUSY)
{
i2c->CMD = I2C_CMD_ABORT;
}
/* Make sure user is not trying to read 0 bytes, it is not */
/* possible according to I2C spec, since slave will always start */
/* sending first byte ACK on address. The read operation can */
/* only be stopped by NACKing a received byte, ie minimum 1 byte. */
if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len)) ||
((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
)
{
return(i2cTransferUsageFault);
}
/* Prepare for a transfer */
transfer->state = i2cStateStartAddrSend;
transfer->result = i2cTransferInProgress;
transfer->offset = 0;
transfer->bufIndx = 0;
transfer->seq = seq;
/* Ensure buffers are empty */
i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
if (i2c->IF & I2C_IF_RXDATAV)
{
i2c->RXDATA;
}
/* Clear all pending interrupts prior to starting transfer. */
i2c->IFC = _I2C_IFC_MASK;
/* Enable those interrupts we are interested in throughout transfer. */
/* Notice that the I2C interrupt must also be enabled in the NVIC, but */
/* that is left for an additional driver wrapper. */
i2c->IEN = I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP |
I2C_IF_RXDATAV | I2C_IF_ERRORS;
/* Start transfer */
return(I2C_Transfer(i2c));
}
/** @} (end addtogroup I2C) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,66 @@
/**************************************************************************//**
* @file
* @brief Interrupt enable/disable unit API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#include <stdint.h>
#include "efm32_int.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup INT
* @brief Safe nesting interrupt disable/enable API for EFM32.
* @details
* This module contains functions to safely disable and enable interrupts
* at cpu level. INT_Disable() disables interrupts and increments a lock
* level counter. INT_Enable() decrements the lock level counter and enable
* interrupts if the counter was decremented to zero.
*
* These functions would normally be used to secure critical regions.
*
* These functions should also be used inside interrupt handlers:
* @verbatim
* void SysTick_Handler(void)
* {
* INT_Disable();
* .
* .
* .
* INT_Enable();
* }
* @endverbatim
******************************************************************************/
/** Interrupt lock level counter. Set to zero initially as we normally enter
* main with interrupts enabled */
uint32_t INT_LockCnt = 0;
/** @} (end addtogroup INT) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,758 @@
/***************************************************************************//**
* @file
* @brief Liquid Crystal Display (LCD) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_lcd.h"
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
#include "efm32_assert.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LCD
* @brief Liquid Crystal Display (LCD) Peripheral API for EFM32
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Initalize Liquid Crystal Display (LCD) controller
*
* @details
* This function call will only configure the LCD controller. You must enable
* it afterwards, potentially configuring Frame Control and interrupts first
* according to requirements.
*
* @param[in] lcdInit
* Pointer to initialization structure which configures LCD controller.
*
******************************************************************************/
void LCD_Initialize(const LCD_Init_TypeDef *lcdInit)
{
uint32_t dispCtrl = LCD->DISPCTRL;
EFM_ASSERT(lcdInit != (void *) 0);
/* Disable controller before reconfiguration */
LCD_Enable(false);
/* Make sure we don't touch other bit fields (i.e. voltage boost) */
dispCtrl &= ~(
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
_LCD_DISPCTRL_MUXE_MASK |
#endif
_LCD_DISPCTRL_MUX_MASK |
_LCD_DISPCTRL_BIAS_MASK |
_LCD_DISPCTRL_WAVE_MASK |
_LCD_DISPCTRL_VLCDSEL_MASK |
_LCD_DISPCTRL_CONCONF_MASK);
/* Configure controller according to initialization structure */
dispCtrl |= lcdInit->mux; /* also configures MUXE */
dispCtrl |= lcdInit->bias;
dispCtrl |= lcdInit->wave;
dispCtrl |= lcdInit->vlcd;
dispCtrl |= lcdInit->contrast;
/* Update display controller */
LCD->DISPCTRL = dispCtrl;
/* Enable controller if wanted */
if (lcdInit->enable)
{
LCD_Enable(true);
}
}
/***************************************************************************//**
* @brief
* Select source for VLCD
*
* @param[in] vlcd
* Select source for VLD voltage
******************************************************************************/
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd)
{
uint32_t dispctrl = LCD->DISPCTRL;
/* Select VEXT or VDD */
dispctrl &= ~(_LCD_DISPCTRL_VLCDSEL_MASK);
switch (vlcd)
{
case lcdVLCDSelVExtBoost:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VEXTBOOST;
break;
case lcdVLCDSelVDD:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VDD;
break;
default:
break;
}
LCD->DISPCTRL = dispctrl;
}
/***************************************************************************//**
* @brief
* Configure Update Control
*
* @param[in] ud
* Configures LCD update method
******************************************************************************/
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud)
{
LCD->CTRL = (LCD->CTRL & ~_LCD_CTRL_UDCTRL_MASK) | ud;
}
/***************************************************************************//**
* @brief
* Initialize LCD Frame Counter
*
* @param[in] fcInit
* Pointer to Frame Counter initialization structure
******************************************************************************/
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(fcInit != (void *) 0);
/* Verify FC Top Counter to be within limits */
EFM_ASSERT(fcInit->top < 64);
/* Reconfigure frame count configuration */
bactrl &= ~(_LCD_BACTRL_FCTOP_MASK |
_LCD_BACTRL_FCPRESC_MASK);
bactrl |= (fcInit->top << _LCD_BACTRL_FCTOP_SHIFT);
bactrl |= fcInit->prescale;
/* Set Blink and Animation Control Register */
LCD->BACTRL = bactrl;
LCD_FrameCountEnable(fcInit->enable);
}
/***************************************************************************//**
* @brief
* Configures LCD controller Animation feature
*
* @param[in] animInit
* Pointer to LCD Animation initialization structure
******************************************************************************/
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(animInit != (void *) 0);
/* Set Animation Register Values */
LCD->AREGA = animInit->AReg;
LCD->AREGB = animInit->BReg;
/* Configure Animation Shift and Logic */
bactrl &= ~(_LCD_BACTRL_AREGASC_MASK |
_LCD_BACTRL_AREGBSC_MASK |
_LCD_BACTRL_ALOGSEL_MASK);
bactrl |= (animInit->AShift << _LCD_BACTRL_AREGASC_SHIFT);
bactrl |= (animInit->BShift << _LCD_BACTRL_AREGBSC_SHIFT);
bactrl |= animInit->animLogic;
#if defined(_EFM32_GIANT_FAMILY)
if(animInit->startSeg == 0)
{
bactrl |= LCD_BACTRL_ALOC_SEG0TO7;
}
else if(animInit->startSeg == 8)
{
bactrl |= LCD_BACTRL_ALOC_SEG8TO15;
}
#endif
/* Reconfigure */
LCD->BACTRL = bactrl;
/* Enable */
LCD_AnimEnable(animInit->enable);
}
/***************************************************************************//**
* @brief
* Enables update of this range of LCD segment lines
*
* @param[in] segmentRange
* Range of 4 LCD segments lines to enable or disable, for all enabled COM
* lines
*
* @param[in] enable
* Bool true to enable segment updates, false to disable updates
******************************************************************************/
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segmentRange, bool enable)
{
if (enable)
{
LCD->SEGEN |= segmentRange;
}
else
{
LCD->SEGEN &= ~((uint32_t)segmentRange);
}
}
/***************************************************************************//**
* @brief
* Turn on or clear a segment
*
* @note
* On Gecko Family, max configuration is (COM-lines x Segment-Lines) 4x40
* On Tiny Family, max configuration is 8x20 or 4x24
* On Giant Family, max configuration is 8x36 or 4x40
*
* @param[in] com
* COM line to change
*
* @param[in] bit
* Bit index of which field to change
*
* @param[in] enable
* When true will set segment, when false will clear segment
******************************************************************************/
void LCD_SegmentSet(int com, int bit, bool enable)
{
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/* Tiny and Giant Family supports up to 8 COM lines */
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
EFM_ASSERT(bit < 40);
#else
/* Tiny Gecko Family supports only "low" segment registers */
EFM_ASSERT(bit < 32);
#endif
/* Use bitband access for atomic bit set/clear of segment */
switch (com)
{
case 0:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD0L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD0H), bit, (unsigned int)enable);
}
#endif
break;
case 1:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD1L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD1H), bit, (unsigned int)enable);
}
#endif
break;
case 2:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD2L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD2H), bit, (unsigned int)enable);
}
#endif
break;
case 3:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD3L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD3H), bit, (unsigned int)enable);
}
#endif
break;
case 4:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD4L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD4H), bit, (unsigned int)enable);
}
#endif
break;
case 5:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD5L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD5H), bit, (unsigned int)enable);
}
#endif
break;
case 6:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD6L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD6H), bit, (unsigned int)enable);
}
#endif
break;
case 7:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD7L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD7H), bit, (unsigned int)enable);
}
#endif
break;
default:
EFM_ASSERT(0);
break;
}
}
/***************************************************************************//**
* @brief
* Updates the 0-31 lowest segments on a given COM-line in one operation,
* according to bit mask
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 0-31
*
* @param[in] bits
* Bit pattern for segments 0-31
******************************************************************************/
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
/* Maximum number of com lines */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
switch (com)
{
case 0:
segData = LCD->SEGD0L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0L = segData;
break;
case 1:
segData = LCD->SEGD1L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1L = segData;
break;
case 2:
segData = LCD->SEGD2L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2L = segData;
break;
case 3:
segData = LCD->SEGD3L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3L = segData;
break;
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
case 4:
segData = LCD->SEGD4L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
case 5:
segData = LCD->SEGD5L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
case 6:
segData = LCD->SEGD6L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
case 7:
segData = LCD->SEGD7L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7L = segData;
break;
#endif
default:
EFM_ASSERT(0);
break;
}
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Updated the high (32-39) segments on a given COM-line in one operation
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 32-39
*
* @param[in] bits
* Bit pattern for segments 32-39
******************************************************************************/
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
#if defined(_EFM32_GIANT_FAMILY)
EFM_ASSERT(com < 8);
#endif
#if defined(_EFM32_GECKO_FAMILY)
EFM_ASSERT(com < 4);
#endif
/* Maximum number of com lines */
switch (com)
{
case 0:
segData = LCD->SEGD0H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0H = segData;
break;
case 1:
segData = LCD->SEGD1H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1H = segData;
break;
case 2:
segData = LCD->SEGD2H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2H = segData;
break;
case 3:
segData = LCD->SEGD3H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3H = segData;
break;
#if defined(_EFM32_GIANT_FAMILY)
case 4:
segData = LCD->SEGD4H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY)
case 5:
segData = LCD->SEGD5H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY)
case 6:
segData = LCD->SEGD6H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY)
case 7:
segData = LCD->SEGD7H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7H = segData;
break;
#endif
default:
break;
}
}
#endif
/***************************************************************************//**
* @brief
* Configure contrast level on LCD panel
*
* @param[in] level
* Contrast level in the range 0-31
******************************************************************************/
void LCD_ContrastSet(int level)
{
EFM_ASSERT(level < 32);
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_CONLEV_MASK)
| (level << _LCD_DISPCTRL_CONLEV_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure voltage booster
*
* The resulting voltage level is described in each part number's data sheet
*
* @param[in] vboost
* Voltage boost level
******************************************************************************/
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost)
{
/* Reconfigure Voltage Boost */
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_VBLEV_MASK) | vboost;
}
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line for Direct Segment Control
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD0L/SEGD1H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] segmentLine
* Segment line number
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasSegmentSet(int segmentLine, int biasLevel)
{
int biasRegister;
int bitShift;
volatile uint32_t *segmentRegister;
#if defined(_EFM32_TINY_FAMILY)
EFM_ASSERT(segmentLine < 20);
#endif
#if defined(_EFM32_GIANT_FAMILY)
EFM_ASSERT(segmentLine < 40);
#endif
#if defined(_EFM32_TINY_FAMILY)
/* Bias config for 8 segment lines per SEGDnL register */
biasRegister = segmentLine / 8;
bitShift = (segmentLine % 8) * 4;
switch (biasRegister)
{
case 0:
segmentRegister = &LCD->SEGD0L;
break;
case 1:
segmentRegister = &LCD->SEGD1L;
break;
case 2:
segmentRegister = &LCD->SEGD2L;
break;
case 3:
segmentRegister = &LCD->SEGD3L;
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
#if defined(_EFM32_GIANT_FAMILY)
/* Bias config for 10 segment lines per SEGDn L+H registers */
biasRegister = segmentLine / 10;
bitShift = (segmentLine % 10) * 4;
switch (biasRegister)
{
case 0:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD0L;
}
else
{
segmentRegister = &LCD->SEGD0H;
bitShift -= 32;
}
break;
case 1:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD1L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 2:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD2L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 3:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD3L;
}
else
{
segmentRegister = &LCD->SEGD3H;
bitShift -= 32;
}
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
/* Configure new bias setting */
*segmentRegister = (*segmentRegister & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD4L/SEGD4H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] comLine
* COM line number, 0-7
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasComSet(int comLine, int biasLevel)
{
int bitShift;
EFM_ASSERT(comLine < 8);
bitShift = comLine * 4;
LCD->SEGD4L = (LCD->SEGD4L & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
#endif
/** @} (end addtogroup LCD) */
/** @} (end addtogroup EFM32_Library) */
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */

View File

@ -0,0 +1,529 @@
/***************************************************************************//**
* @file
* @brief Low Energy Timer (LETIMER) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_letimer.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LETIMER
* @brief Low Energy Timer (LETIMER) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of valid comparator register for assert statements. */
#define LETIMER_COMP_REG_VALID(reg) (((reg) <= 1))
/** Validation of LETIMER register block pointer reference for assert statements. */
#define LETIMER_REF_VALID(ref) ((ref) == LETIMER0)
/** Validation of valid repeat counter register for assert statements. */
#define LETIMER_REP_REG_VALID(reg) (((reg) <= 1))
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#if defined(_EFM32_GECKO_FAMILY)
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @note
* This only applies to the Gecko Family, see the reference manual
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
* for details.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
static __INLINE void LETIMER_Sync(LETIMER_TypeDef *letimer, uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (letimer->FREEZE & LETIMER_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain, only required for Gecko Family of devices */
while (letimer->SYNCBUSY & mask)
;
}
#endif
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get LETIMER compare register value.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block
*
* @param[in] comp
* Compare register to get, either 0 or 1
*
* @return
* Compare register value, 0 if invalid register selected.
******************************************************************************/
uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp)
{
uint32_t ret;
EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_COMP_REG_VALID(comp));
/* Initialize selected compare value */
switch (comp)
{
case 0:
ret = letimer->COMP0;
break;
case 1:
ret = letimer->COMP1;
break;
default:
/* Unknown compare register selected */
ret = 0;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set LETIMER compare register value.
*
* @note
* The setting of a compare register requires synchronization into the
* low frequency domain. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. This only applies to the Gecko Family, see
* comment in the LETIMER_Sync() internal function call.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block
*
* @param[in] comp
* Compare register to set, either 0 or 1
*
* @param[in] value
* Initialization value (<= 0x0000ffff)
******************************************************************************/
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
unsigned int comp,
uint32_t value)
{
volatile uint32_t *compReg;
uint32_t syncbusy;
EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
LETIMER_COMP_REG_VALID(comp) &&
((value & ~(_LETIMER_COMP0_COMP0_MASK >> _LETIMER_COMP0_COMP0_SHIFT)) == 0));
/* Initialize selected compare value */
switch (comp)
{
case 0:
compReg = &(letimer->COMP0);
syncbusy = LETIMER_SYNCBUSY_COMP0;
break;
case 1:
compReg = &(letimer->COMP1);
syncbusy = LETIMER_SYNCBUSY_COMP1;
break;
default:
/* Unknown compare register selected, abort */
return;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, syncbusy);
#endif
*compReg = value;
}
/***************************************************************************//**
* @brief
* Start/stop LETIMER.
*
* @note
* The enabling/disabling of the LETIMER modifies the LETIMER CMD register
* which requires synchronization into the low frequency domain. If this
* register is modified before a previous update to the same register has
* completed, this function will stall until the previous synchronization has
* completed. This only applies to the Gecko Family, see comment in the
* LETIMER_Sync() internal function call.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable)
{
EFM_ASSERT(LETIMER_REF_VALID(letimer));
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
#endif
if (enable)
{
letimer->CMD = LETIMER_CMD_START;
}
else
{
letimer->CMD = LETIMER_CMD_STOP;
}
}
/***************************************************************************//**
* @brief
* LETIMER register synchronization freeze control.
*
* @details
* Some LETIMER registers require synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing LETIMER synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disables freeze, modified registers are propagated to LF
* domain
******************************************************************************/
void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable)
{
if (enable)
{
/*
* Wait for any ongoing LF synchronization to complete. This is just to
* protect against the rare case when a user
* - modifies a register requiring LF sync
* - then enables freeze before LF sync completed
* - then modifies the same register again
* since modifying a register while it is in sync progress should be
* avoided.
*/
while (letimer->SYNCBUSY)
;
letimer->FREEZE = LETIMER_FREEZE_REGFREEZE;
}
else
{
letimer->FREEZE = 0;
}
}
/***************************************************************************//**
* @brief
* Initialize LETIMER.
*
* @details
* Note that the compare/repeat values must be set separately with
* LETIMER_CompareSet() and LETIMER_RepeatSet(). That should probably be done
* prior to the use of this function if configuring the LETIMER to start when
* initialization is completed.
*
* @note
* The initialization of the LETIMER modifies the LETIMER CTRL/CMD registers
* which require synchronization into the low frequency domain. If any of those
* registers are modified before a previous update to the same register has
* completed, this function will stall until the previous synchronization has
* completed. This only applies to the Gecko Family, see comment in the
* LETIMER_Sync() internal function call.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] init
* Pointer to LETIMER initialization structure.
******************************************************************************/
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init)
{
uint32_t tmp = 0;
EFM_ASSERT(LETIMER_REF_VALID(letimer));
/* Stop timer if specified to be disabled and running */
if (!(init->enable) && (letimer->STATUS & LETIMER_STATUS_RUNNING))
{
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
#endif
letimer->CMD = LETIMER_CMD_STOP;
}
/* Configure DEBUGRUN flag, sets whether or not counter should be
* updated when debugger is active */
if (init->debugRun)
{
tmp |= LETIMER_CTRL_DEBUGRUN;
}
if (init->rtcComp0Enable)
{
tmp |= LETIMER_CTRL_RTCC0TEN;
}
if (init->rtcComp1Enable)
{
tmp |= LETIMER_CTRL_RTCC1TEN;
}
if (init->comp0Top)
{
tmp |= LETIMER_CTRL_COMP0TOP;
}
if (init->bufTop)
{
tmp |= LETIMER_CTRL_BUFTOP;
}
if (init->out0Pol)
{
tmp |= LETIMER_CTRL_OPOL0;
}
if (init->out1Pol)
{
tmp |= LETIMER_CTRL_OPOL1;
}
tmp |= init->ufoa0 << _LETIMER_CTRL_UFOA0_SHIFT;
tmp |= init->ufoa1 << _LETIMER_CTRL_UFOA1_SHIFT;
tmp |= init->repMode << _LETIMER_CTRL_REPMODE_SHIFT;
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CTRL);
#endif
letimer->CTRL = tmp;
/* Start timer if specified to be enabled and not already running */
if (init->enable && !(letimer->STATUS & LETIMER_STATUS_RUNNING))
{
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, LETIMER_SYNCBUSY_CMD);
#endif
letimer->CMD = LETIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Get LETIMER repeat register value.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block
*
* @param[in] rep
* Repeat register to get, either 0 or 1
*
* @return
* Repeat register value, 0 if invalid register selected.
******************************************************************************/
uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep)
{
uint32_t ret;
EFM_ASSERT(LETIMER_REF_VALID(letimer) && LETIMER_REP_REG_VALID(rep));
/* Initialize selected compare value */
switch (rep)
{
case 0:
ret = letimer->REP0;
break;
case 1:
ret = letimer->REP1;
break;
default:
/* Unknown compare register selected */
ret = 0;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set LETIMER repeat counter register value.
*
* @note
* The setting of a repeat counter register requires synchronization into the
* low frequency domain. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. This only applies to the Gecko Family, see
* comment in the LETIMER_Sync() internal function call.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block
*
* @param[in] rep
* Repeat counter register to set, either 0 or 1
*
* @param[in] value
* Initialization value (<= 0x0000ffff)
******************************************************************************/
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
unsigned int rep,
uint32_t value)
{
volatile uint32_t *repReg;
#if defined(_EFM32_GECKO_FAMILY)
uint32_t syncbusy;
#endif
EFM_ASSERT(LETIMER_REF_VALID(letimer) &&
LETIMER_REP_REG_VALID(rep) &&
((value & ~(_LETIMER_REP0_REP0_MASK >> _LETIMER_REP0_REP0_SHIFT)) == 0));
/* Initialize selected compare value */
switch (rep)
{
case 0:
repReg = &(letimer->REP0);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = LETIMER_SYNCBUSY_REP0;
#endif
break;
case 1:
repReg = &(letimer->REP1);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = LETIMER_SYNCBUSY_REP1;
#endif
break;
default:
/* Unknown compare register selected, abort */
return;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
LETIMER_Sync(letimer, syncbusy);
#endif
*repReg = value;
}
/***************************************************************************//**
* @brief
* Reset LETIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
******************************************************************************/
void LETIMER_Reset(LETIMER_TypeDef *letimer)
{
/* Freeze registers to avoid stalling for LF synchronization */
LETIMER_FreezeEnable(letimer, true);
/* Make sure disabled first, before resetting other registers */
letimer->CMD = LETIMER_CMD_STOP | LETIMER_CMD_CLEAR |
LETIMER_CMD_CTO0 | LETIMER_CMD_CTO1;
letimer->CTRL = _LETIMER_CTRL_RESETVALUE;
letimer->COMP0 = _LETIMER_COMP0_RESETVALUE;
letimer->COMP1 = _LETIMER_COMP1_RESETVALUE;
letimer->REP0 = _LETIMER_REP0_RESETVALUE;
letimer->REP1 = _LETIMER_REP1_RESETVALUE;
letimer->IEN = _LETIMER_IEN_RESETVALUE;
letimer->IFC = _LETIMER_IFC_MASK;
/* Do not reset route register, setting should be done independently */
/* Unfreeze registers, pass new settings on to LETIMER */
LETIMER_FreezeEnable(letimer, false);
}
/** @} (end addtogroup LETIMER) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,635 @@
/***************************************************************************//**
* @file
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
* peripheral module peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_leuart.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LEUART
* @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
* Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of LEUART register block pointer reference
* for assert statements. */
#if (LEUART_COUNT == 1)
#define LEUART_REF_VALID(ref) ((ref) == LEUART0)
#elif (LEUART_COUNT == 2)
#define LEUART_REF_VALID(ref) (((ref) == LEUART0) || ((ref) == LEUART1))
#else
#error Undefined number of low energy UARTs (LEUART).
#endif
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
static __INLINE void LEUART_Sync(LEUART_TypeDef *leuart, uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (leuart->FREEZE & LEUART_FREEZE_REGFREEZE)
{
return;
}
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain */
while (leuart->SYNCBUSY & mask)
;
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Calculate baudrate for LEUART given reference frequency and clock division.
*
* @details
* This function returns the baudrate that a LEUART module will use if
* configured with the given frequency and clock divisor. Notice that
* this function will not use actual HW configuration. It can be used
* to determinate if a given configuration is sufficiently accurate for the
* application.
*
* @param[in] refFreq
* LEUART peripheral frequency used.
*
* @param[in] clkdiv
* Clock division factor to be used.
*
* @return
* Baudrate with given settings.
******************************************************************************/
uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv)
{
uint32_t divisor;
uint32_t remainder;
uint32_t quotient;
uint32_t br;
/* Mask out unused bits */
clkdiv &= _LEUART_CLKDIV_MASK;
/* We want to use integer division to avoid forcing in float division */
/* utils, and yet keep rounding effect errors to a minimum. */
/*
* Baudrate is given by:
*
* br = fLEUARTn/(1 + (CLKDIV / 256))
*
* which can be rewritten to
*
* br = (256 * fLEUARTn)/(256 + CLKDIV)
*
* Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow
* if using 32 bit arithmetic. However, since fLEUARTn may be derived from
* HFCORECLK as well, we must consider overflow when using integer arithmetic.
*/
/*
* The basic problem with integer division in the above formula is that
* the dividend (256 * fLEUARTn) may become higher than max 32 bit
* integer. Yet we want to evaluate dividend first before dividing in
* order to get as small rounding effects as possible. We do not want
* to make too harsh restrictions on max fLEUARTn value either.
*
* For division a/b, we can write
*
* a = qb + r
*
* where q is the quotient and r is the remainder, both integers.
*
* The orignal baudrate formula can be rewritten as
*
* br = 256a / b = 256(qb + r)/b = 256q + 256r/b
*
* where a is 'refFreq' and b is 'divisor', referring to variable names.
*/
divisor = 256 + clkdiv;
quotient = refFreq / divisor;
remainder = refFreq % divisor;
/* Since divisor >= 256, the below cannot exceed max 32 bit value. */
br = 256 * quotient;
/*
* Remainder < (256 + clkdiv), which means dividend (256 * remainder) worst case is
* 256*(256 + 0x7ff8) = 0x80F800.
*/
br += (256 * remainder) / divisor;
return br;
}
/***************************************************************************//**
* @brief
* Get current baudrate for LEUART.
*
* @details
* This function returns the actual baudrate (not considering oscillator
* inaccuracies) used by a LEUART peripheral.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @return
* Current baudrate.
******************************************************************************/
uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart)
{
uint32_t freq;
CMU_Clock_TypeDef clock;
/* Get current frequency */
if (leuart == LEUART0)
{
clock = cmuClock_LEUART0;
}
#if (LEUART_COUNT > 1)
else if (leuart == LEUART1)
{
clock = cmuClock_LEUART1;
}
#endif
else
{
EFM_ASSERT(0);
return 0;
}
freq = CMU_ClockFreqGet(clock);
return LEUART_BaudrateCalc(freq, leuart->CLKDIV);
}
/***************************************************************************//**
* @brief
* Configure baudrate (or as close as possible to specified baudrate).
*
* @note
* The setting of a baudrate requires synchronization into the
* low frequency domain. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] refFreq
* LEUART reference clock frequency in Hz that will be used. If set to 0,
* the currently configured reference clock is assumed.
*
* @param[in] baudrate
* Baudrate to try to achieve for LEUART.
******************************************************************************/
void LEUART_BaudrateSet(LEUART_TypeDef *leuart,
uint32_t refFreq,
uint32_t baudrate)
{
uint32_t clkdiv;
CMU_Clock_TypeDef clock;
/* Inhibit divide by 0 */
EFM_ASSERT(baudrate);
/*
* We want to use integer division to avoid forcing in float division
* utils, and yet keep rounding effect errors to a minimum.
*
* CLKDIV in asynchronous mode is given by:
*
* CLKDIV = 256*(fLEUARTn/br - 1) = ((256*fLEUARTn)/br) - 256
*
* Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow
* if using 32 bit arithmetic. However, since fLEUARTn may be derived from
* HFCORECLK as well, we must consider overflow when using integer arithmetic.
*
* The basic problem with integer division in the above formula is that
* the dividend (256 * fLEUARTn) may become higher than max 32 bit
* integer. Yet, we want to evaluate dividend first before dividing in
* order to get as small rounding effects as possible. We do not want
* to make too harsh restrictions on max fLEUARTn value either.
*
* Since the last 3 bits of CLKDIV are don't care, we can base our
* integer arithmetic on the below formula
*
* CLKDIV/8 = ((32*fLEUARTn)/br) - 32
*
* and calculate 1/8 of CLKDIV first. This allows for fLEUARTn
* up to 128MHz without overflowing a 32 bit value!
*/
/* Get current frequency? */
if (!refFreq)
{
if (leuart == LEUART0)
{
clock = cmuClock_LEUART0;
}
#if (LEUART_COUNT > 1)
else if (leuart == LEUART1)
{
clock = cmuClock_LEUART1;
}
#endif
else
{
EFM_ASSERT(0);
return;
}
refFreq = CMU_ClockFreqGet(clock);
}
/* Calculate and set CLKDIV with fractional bits */
clkdiv = (32 * refFreq) / baudrate;
clkdiv -= 32;
clkdiv *= 8;
/* LF register about to be modified require sync. busy check */
LEUART_Sync(leuart, LEUART_SYNCBUSY_CLKDIV);
leuart->CLKDIV = clkdiv;
}
/***************************************************************************//**
* @brief
* Enable/disable LEUART receiver and/or transmitter.
*
* @details
* Notice that this function does not do any configuration. Enabling should
* normally be done after initialization is done (if not enabled as part
* of init).
*
* @note
* Enabling/disabling requires synchronization into the low frequency domain.
* If the same register is modified before a previous update has completed,
* this function will stall until the previous synchronization has completed.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] enable
* Select status for receiver/transmitter.
******************************************************************************/
void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable)
{
uint32_t tmp;
/* Make sure the module exists on the selected chip */
EFM_ASSERT(LEUART_REF_VALID(leuart));
/* Disable as specified */
tmp = ~((uint32_t)(enable));
tmp &= (_LEUART_CMD_RXEN_MASK | _LEUART_CMD_TXEN_MASK);
tmp <<= 1;
/* Enable as specified */
tmp |= (uint32_t)(enable);
/* LF register about to be modified require sync. busy check */
LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
leuart->CMD = tmp;
}
/***************************************************************************//**
* @brief
* LEUART register synchronization freeze control.
*
* @details
* Some LEUART registers require synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing LEUART synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disables freeze, modified registers are propagated to LF
* domain
******************************************************************************/
void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable)
{
if (enable)
{
/*
* Wait for any ongoing LF synchronization to complete. This is just to
* protect against the rare case when a user
* - modifies a register requiring LF sync
* - then enables freeze before LF sync completed
* - then modifies the same register again
* since modifying a register while it is in sync progress should be
* avoided.
*/
while (leuart->SYNCBUSY)
;
leuart->FREEZE = LEUART_FREEZE_REGFREEZE;
}
else
{
leuart->FREEZE = 0;
}
}
/***************************************************************************//**
* @brief
* Init LEUART.
*
* @details
* This function will configure basic settings in order to operate in normal
* asynchronous mode. Consider using LEUART_Reset() prior to this function if
* state of configuration is not known, since only configuration settings
* specified by @p init are set.
*
* Special control setup not covered by this function may be done either
* before or after using this function (but normally before enabling)
* by direct modification of the CTRL register.
*
* Notice that pins used by the LEUART module must be properly configured
* by the user explicitly, in order for the LEUART to work as intended.
* (When configuring pins, one should remember to consider the sequence of
* configuration, in order to avoid unintended pulses/glitches on output
* pins.)
*
* @note
* Initializing requires synchronization into the low frequency domain.
* If the same register is modified before a previous update has completed,
* this function will stall until the previous synchronization has completed.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] init
* Pointer to initialization structure used to configure basic async setup.
******************************************************************************/
void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef *init)
{
/* Make sure the module exists on the selected chip */
EFM_ASSERT(LEUART_REF_VALID(leuart));
/* LF register about to be modified require sync. busy check */
LEUART_Sync(leuart, LEUART_SYNCBUSY_CMD);
/* Ensure disabled while doing config */
leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS;
/* Freeze registers to avoid stalling for LF synchronization */
LEUART_FreezeEnable(leuart, true);
/* Configure databits and stopbits */
leuart->CTRL = (leuart->CTRL & ~(_LEUART_CTRL_PARITY_MASK |
_LEUART_CTRL_STOPBITS_MASK)) |
(uint32_t)(init->databits) |
(uint32_t)(init->parity) |
(uint32_t)(init->stopbits);
/* Configure baudrate */
LEUART_BaudrateSet(leuart, init->refFreq, init->baudrate);
/* Finally enable (as specified) */
leuart->CMD = (uint32_t)(init->enable);
/* Unfreeze registers, pass new settings on to LEUART */
LEUART_FreezeEnable(leuart, false);
}
/***************************************************************************//**
* @brief
* Reset LEUART to same state as after a HW reset.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
******************************************************************************/
void LEUART_Reset(LEUART_TypeDef *leuart)
{
/* Make sure the module exists on the selected chip */
EFM_ASSERT(LEUART_REF_VALID(leuart));
/* Freeze registers to avoid stalling for LF synchronization */
LEUART_FreezeEnable(leuart, true);
/* Make sure disabled first, before resetting other registers */
leuart->CMD = LEUART_CMD_RXDIS | LEUART_CMD_TXDIS | LEUART_CMD_RXBLOCKDIS |
LEUART_CMD_CLEARTX | LEUART_CMD_CLEARRX;
leuart->CTRL = _LEUART_CTRL_RESETVALUE;
leuart->CLKDIV = _LEUART_CLKDIV_RESETVALUE;
leuart->STARTFRAME = _LEUART_STARTFRAME_RESETVALUE;
leuart->SIGFRAME = _LEUART_SIGFRAME_RESETVALUE;
leuart->IEN = _LEUART_IEN_RESETVALUE;
leuart->IFC = _LEUART_IFC_MASK;
leuart->PULSECTRL = _LEUART_PULSECTRL_RESETVALUE;
leuart->ROUTE = _LEUART_ROUTE_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* Unfreeze registers, pass new settings on to LEUART */
LEUART_FreezeEnable(leuart, false);
}
/***************************************************************************//**
* @brief
* Receive one 8 bit frame, (or part of 9 bit frame).
*
* @details
* This function is normally used to receive one frame when operating with
* frame length 8 bits. Please refer to LEUART_RxExt() for reception of
* 9 bit frames.
*
* Notice that possible parity/stop bits are not considered part of specified
* frame bit length.
*
* @note
* This function will stall if buffer is empty, until data is received.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
uint8_t LEUART_Rx(LEUART_TypeDef *leuart)
{
while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
;
return (uint8_t)(leuart->RXDATA);
}
/***************************************************************************//**
* @brief
* Receive one 8-9 bit frame, with extended information.
*
* @details
* This function is normally used to receive one frame and additional RX
* status information is required.
*
* @note
* This function will stall if buffer is empty, until data is received.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @return
* Data received.
******************************************************************************/
uint16_t LEUART_RxExt(LEUART_TypeDef *leuart)
{
while (!(leuart->STATUS & LEUART_STATUS_RXDATAV))
;
return (uint16_t)(leuart->RXDATAX);
}
/***************************************************************************//**
* @brief
* Transmit one frame.
*
* @details
* Depending on frame length configuration, 8 (least significant) bits from
* @p data are transmitted. If frame length is 9, 8 bits are transmitted from
* @p data and one bit as specified by CTRL register, BIT8DV field. Please
* refer to LEUART_TxExt() for transmitting 9 bit frame with full control of
* all 9 bits.
*
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @note
* This function will stall if buffer is full, until buffer becomes available.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] data
* Data to transmit. See details above for further info.
******************************************************************************/
void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data)
{
/* Check that transmit buffer is empty */
while (!(leuart->STATUS & LEUART_STATUS_TXBL))
;
/* LF register about to be modified require sync. busy check */
LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATA);
leuart->TXDATA = (uint32_t)data;
}
/***************************************************************************//**
* @brief
* Transmit one 8-9 bit frame with extended control.
*
* @details
* Notice that possible parity/stop bits in asynchronous mode are not
* considered part of specified frame bit length.
*
* @note
* This function will stall if buffer is full, until buffer becomes available.
*
* @param[in] leuart
* Pointer to LEUART peripheral register block.
*
* @param[in] data
* Data to transmit with extended control. Least significant bits contains
* frame bits, and additional control bits are available as documented in
* the EFM32 reference manual (set to 0 if not used).
******************************************************************************/
void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data)
{
/* Check that transmit buffer is empty */
while (!(leuart->STATUS & LEUART_STATUS_TXBL))
;
/* LF register about to be modified require sync. busy check */
LEUART_Sync(leuart, LEUART_SYNCBUSY_TXDATAX);
leuart->TXDATAX = (uint32_t)data;
}
/** @} (end addtogroup LEUART) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,117 @@
/***************************************************************************//**
* @file
* @brief Memory Protection Unit (MPU) Peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_mpu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup MPU
* @brief Memory Protection Unit (MPU) Peripheral API for EFM32
* @details
* This module contains functions to enable, disable and setup the MPU.
* The MPU is used to control access attributes and permissions in the
* memory map. The settings that can be controlled are:
*
* @li Executable attribute.
* @li Cachable, bufferable and shareable attributes.
* @li Cache policy.
* @li Access permissions: Priviliged or User state, read or write access,
* and combinations of all these.
*
* The MPU can be activated and deactivated with functions:
* @verbatim
* MPU_Enable(..);
* MPU_Disable();@endverbatim
* The MPU can control 8 memory regions with individual access control
* settings. Section attributes and permissions are set with:
* @verbatim
* MPU_ConfigureRegion(..);@endverbatim
* It is advisable to disable the MPU when altering region settings.
*
*
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Configure an MPU region.
*
* @details
* Writes to MPU RBAR and RASR registers.
* Refer to Cortex-M3 Reference Manual, MPU chapter for further details.
* To disable a region it is only required to set init->regionNo to the
* desired value and init->regionEnable = false.
*
* @param[in] init
* Pointer to a structure containing MPU region init information.
******************************************************************************/
void MPU_ConfigureRegion(const MPU_RegionInit_TypeDef *init)
{
EFM_ASSERT(init->regionNo < ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >>
MPU_TYPE_DREGION_Pos));
MPU->RNR = init->regionNo;
if (init->regionEnable)
{
EFM_ASSERT(!(init->baseAddress & ~MPU_RBAR_ADDR_Msk));
EFM_ASSERT(init->tex <= 0x7);
MPU->RBAR = init->baseAddress;
MPU->RASR = ((init->disableExec ? 1 : 0) << MPU_RASR_XN_Pos) |
(init->accessPermission << MPU_RASR_AP_Pos) |
(init->tex << MPU_RASR_TEX_Pos) |
((init->shareable ? 1 : 0) << MPU_RASR_S_Pos) |
((init->cacheable ? 1 : 0) << MPU_RASR_C_Pos) |
((init->bufferable ? 1 : 0) << MPU_RASR_B_Pos) |
(init->srd << MPU_RASR_SRD_Pos) |
(init->size << MPU_RASR_SIZE_Pos) |
(1 << MPU_RASR_ENA_Pos);
}
else
{
MPU->RBAR = 0;
MPU->RASR = 0;
}
}
/** @} (end addtogroup CMU) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,369 @@
/***************************************************************************//**
* @file
* @brief Flash controller (MSC) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_msc.h"
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
#include "efm32_cmu.h"
#endif
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup MSC
* @brief Flash controller (MSC) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enables the flash controller for writing.
* @note
* IMPORTANT: This function must be called before flash operations when
* AUXHFRCO clock has been changed from default 14MHz band.
******************************************************************************/
void MSC_Init(void)
{
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
uint32_t freq, cycles;
#endif
/* Enable writing to the MSC */
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
/* Unlock the MSC */
MSC->LOCK = MSC_UNLOCK_CODE;
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
#if defined (_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/* Configure MSC->TIMEBASE according to selected frequency */
freq = CMU_ClockFreqGet(cmuClock_AUX);
if( freq > 7000000)
{
/* Calculate number of clock cycles for 1us as base period */
freq = (freq * 11) / 10;
cycles = (freq / 1000000) + 1;
/* Configure clock cycles for flash timing */
MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK|
_MSC_TIMEBASE_PERIOD_MASK))|
MSC_TIMEBASE_PERIOD_1US|
(cycles << _MSC_TIMEBASE_BASE_SHIFT);
}
else
{
/* Calculate number of clock cycles for 5us as base period */
freq = (freq * 5 * 11) / 10;
cycles = (freq / 1000000) + 1;
/* Configure clock cycles for flash timing */
MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK|
_MSC_TIMEBASE_PERIOD_MASK))|
MSC_TIMEBASE_PERIOD_5US|
(cycles << _MSC_TIMEBASE_BASE_SHIFT);
}
#endif
}
/***************************************************************************//**
* @brief
* Disables the flash controller for writing.
******************************************************************************/
void MSC_Deinit(void)
{
/* Enable writing to the MSC */
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
/* Lock the MSC */
MSC->LOCK = 0;
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
}
/***************************************************************************//**
* @brief
* Erases a page in flash memory.
* @note
* This function MUST be executed from RAM. Failure to execute this portion
* of the code in RAM will result in a hardfault. For IAR, Rowley and
* Codesourcery this will be achieved automatically. For Keil uVision 4 you
* must define a section called "ram_code" and place this manually in your
* project's scatter file.
* @param[in] startAddress
* Pointer to the flash page to erase. Must be aligned to beginning of page
* boundary.
* @return
* Returns the status of erase operation, #msc_Return_TypeDef
* @verbatim
* flashReturnOk - Operation completed successfully.
* flashReturnInvalidAddr - Operation tried to erase a non-flash area.
* flashReturnLocked - Operation tried to erase a locked area of the flash.
* flashReturnTimeOut - Operation timed out waiting for flash operation
* to complete.
* @endverbatim
******************************************************************************/
#ifdef __CC_ARM /* MDK-ARM compiler */
#pragma arm section code="ram_code"
#endif /* __CC_ARM */
#if defined( __ICCARM__ )
/* Suppress warnings originating from use of EFM_ASSERT(): */
/* "Call to a non __ramfunc function from within a __ramfunc function" */
/* "Possible rom access from within a __ramfunc function" */
#pragma diag_suppress=Ta022
#pragma diag_suppress=Ta023
#endif
msc_Return_TypeDef MSC_ErasePage(uint32_t *startAddress)
{
int timeOut = MSC_PROGRAM_TIMEOUT;
/* Address must be aligned to pages */
EFM_ASSERT((((uint32_t)startAddress) & 0x1FF) == 0);
/* Enable writing to the MSC */
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
/* Load address */
MSC->ADDRB = (uint32_t)startAddress;
MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
/* Check for invalid address */
if (MSC->STATUS & MSC_STATUS_INVADDR)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnInvalidAddr;
}
/* Check for write protected page */
if (MSC->STATUS & MSC_STATUS_LOCKED)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnLocked;
}
/* Send erase page command */
MSC->WRITECMD = MSC_WRITECMD_ERASEPAGE;
/* Wait for the erase to complete */
while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
{
timeOut--;
}
if (timeOut == 0)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnTimeOut;
}
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnOk;
}
#if defined( __ICCARM__ )
#pragma diag_default=Ta022
#pragma diag_default=Ta023
#endif
/***************************************************************************//**
* @brief
* Writes a single word to flash memory. Data to write must be aligned to
* words and contain a number of bytes that is divisable by four.
* @note
* The flash must be erased prior to writing a new word.
* This function must be run from RAM. Failure to execute this portion
* of the code in RAM will result in a hardfault. For IAR, Rowley and
* Codesourcery this will be achieved automatically. For Keil uVision 4 you
* must define a section called "ram_code" and place this manually in your
* project's scatter file.
*
* @param[in] address
* Pointer to the flash word to write to. Must be aligned to words.
* @param[in] data
* Data to write to flash.
* @param[in] numBytes
* Number of bytes to write from flash. NB: Must be divisable by four.
* @return
* Returns the status of the write operation, #msc_Return_TypeDef
* @verbatim
* flashReturnOk - Operation completed successfully.
* flashReturnInvalidAddr - Operation tried to erase a non-flash area.
* flashReturnLocked - Operation tried to erase a locked area of the flash.
* flashReturnTimeOut - Operation timed out waiting for flash operation
* to complete.
* @endverbatim
******************************************************************************/
#ifdef __CC_ARM /* MDK-ARM compiler */
#pragma arm section code="ram_code"
#endif /* __CC_ARM */
#if defined( __ICCARM__ )
/* Suppress warnings originating from use of EFM_ASSERT(): */
/* "Call to a non __ramfunc function from within a __ramfunc function" */
/* "Possible rom access from within a __ramfunc function" */
#pragma diag_suppress=Ta022
#pragma diag_suppress=Ta023
#endif
msc_Return_TypeDef MSC_WriteWord(uint32_t *address, void const *data, int numBytes)
{
int timeOut;
int wordCount;
int numWords;
/* Check alignment (Must be aligned to words) */
EFM_ASSERT(((uint32_t) address & 0x3) == 0);
/* Check number of bytes. Must be divisable by four */
EFM_ASSERT((numBytes & 0x3) == 0);
/* Enable writing to the MSC */
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
/* Convert bytes to words */
numWords = numBytes >> 2;
for (wordCount = 0; wordCount < numWords; wordCount++)
{
/* Load address */
MSC->ADDRB = (uint32_t)(address + wordCount);
MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
/* Check for invalid address */
if (MSC->STATUS & MSC_STATUS_INVADDR)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnInvalidAddr;
}
/* Check for write protected page */
if (MSC->STATUS & MSC_STATUS_LOCKED)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnLocked;
}
/* Wait for the MSC to be ready for a new data word */
/* Due to the timing of this function, the MSC should already by ready */
timeOut = MSC_PROGRAM_TIMEOUT;
while (((MSC->STATUS & MSC_STATUS_WDATAREADY) == 0) && (timeOut != 0))
{
timeOut--;
}
/* Check for timeout */
if (timeOut == 0)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnTimeOut;
}
/* Load data into write data register */
MSC->WDATA = *(((uint32_t *)data) + wordCount);
/* Trigger write once */
MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;
/* Wait for the write to complete */
timeOut = MSC_PROGRAM_TIMEOUT;
while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
{
timeOut--;
}
/* Check for timeout */
if (timeOut == 0)
{
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnTimeOut;
}
}
/* Disable writing to the MSC */
MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
return mscReturnOk;
}
#if defined( __ICCARM__ )
#pragma diag_default=Ta022
#pragma diag_default=Ta023
#endif
#if defined(_EFM32_GIANT_FAMILY)
/***************************************************************************//**
* @brief
* Erase entire flash in one operation
* @note
* This command will erase the entire contents of the device.
* Use with care, both a debug session and all contents of the flash will be
* lost. The lock bit, MLW will prevent this operation from executing and
* might prevent successful mass erase.
******************************************************************************/
#ifdef __CC_ARM /* MDK-ARM compiler */
#pragma arm section code="ram_code"
#endif /* __CC_ARM */
msc_Return_TypeDef MSC_MassErase(void)
{
/* Enable writing to the MSC */
MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
/* Unlock device mass erase */
MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_UNLOCK;
/* Erase first 512K block */
MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN0;
/* Waiting for erase to complete */
while ((MSC->STATUS & MSC_STATUS_BUSY)){}
#if FLASH_SIZE >= (512*1024)
/* Erase second 512K block */
MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN1;
/* Waiting for erase to complete */
while ((MSC->STATUS & MSC_STATUS_BUSY)){}
#endif
/* Restore mass erase lock */
MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_LOCK;
/* This will only successfully return if calling function is also in SRAM */
return mscReturnOk;
}
#endif
/** @} (end addtogroup MSC) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,402 @@
/**************************************************************************//**
* @file
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
* @author Energy Micro AS
* @version 2.3.2
******************************************************************************
* @section License
* <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#include "efm32.h"
#if defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 )
#include "efm32_system.h"
#include "efm32_assert.h"
#include "efm32_opamp.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup OPAMP
* @brief Operational Amplifier (OPAMP) peripheral API for EFM32.
* @details
* This module contains functions to:
* @li OPAMP_Enable() Configure and enable an opamp.
* @li OPAMP_Disable() Disable an opamp.
*
* All OPAMP functions assume that the DAC clock is running. If the DAC is not
* used, the clock can be turned off when the opamp's are configured.
*
* If the available gain values dont suit the application at hand, the resistor
* ladders can be disabled and external gain programming resistors used.
*
* A number of predefined opamp setup macros are available for configuration
* of the most common opamp topologies (see figures below).
*
* @note
* <em>The terms POSPAD and NEGPAD in the figures are used to indicate that these
* pads should be connected to a suitable signal ground.</em>
*
* \n<b>Unity gain voltage follower.</b>\n
* Use predefined macros @ref OPA_INIT_UNITY_GAIN and
* @ref OPA_INIT_UNITY_GAIN_OPA2.
* @verbatim
|\
___________|+\
| \_______
___|_ / |
| | / |
| |/ |
|___________|
@endverbatim
*
* \n<b>Non-inverting amplifier.</b>\n
* Use predefined macros @ref OPA_INIT_NON_INVERTING and
* @ref OPA_INIT_NON_INVERTING_OPA2.
* @verbatim
|\
___________|+\
| \_______
___|_ / |
| | / |
| |/ |
|_____R2____|
|
R1
|
NEGPAD @endverbatim
*
* \n<b>Inverting amplifier.</b>\n
* Use predefined macros @ref OPA_INIT_INVERTING and
* @ref OPA_INIT_INVERTING_OPA2.
* @verbatim
_____R2____
| |
| |\ |
____R1_|___|_\ |
| \____|___
___| /
| |+/
| |/
|
POSPAD @endverbatim
*
* \n<b>Cascaded non-inverting amplifiers.</b>\n
* Use predefined macros @ref OPA_INIT_CASCADED_NON_INVERTING_OPA0,
* @ref OPA_INIT_CASCADED_NON_INVERTING_OPA1 and
* @ref OPA_INIT_CASCADED_NON_INVERTING_OPA2.
* @verbatim
|\ |\ |\
___________|+\ OPA0 ___________|+\ OPA1 ___________|+\ OPA2
| \_________| | \_________| | \_______
___|_ / | ___|_ / | ___|_ / |
| | / | | | / | | | / |
| |/ | | |/ | | |/ |
|_____R2____| |_____R2____| |_____R2____|
| | |
R1 R1 R1
| | |
NEGPAD NEGPAD NEGPAD @endverbatim
*
* \n<b>Cascaded inverting amplifiers.</b>\n
* Use predefined macros @ref OPA_INIT_CASCADED_INVERTING_OPA0,
* @ref OPA_INIT_CASCADED_INVERTING_OPA1 and
* @ref OPA_INIT_CASCADED_INVERTING_OPA2.
* @verbatim
_____R2____ _____R2____ _____R2____
| | | | | |
| |\ | | |\ | | |\ |
____R1_|___|_\ | ____R1_|___|_\ | ____R1_|___|_\ |
| \____|____| | \____|___| | \____|__
___| / ___| / ___| /
| |+/ OPA0 | |+/ OPA1 | |+/ OPA2
| |/ | |/ | |/
| | |
POSPAD POSPAD POSPAD @endverbatim
*
* \n<b>Differential driver with two opamp's.</b>\n
* Use predefined macros @ref OPA_INIT_DIFF_DRIVER_OPA0 and
* @ref OPA_INIT_DIFF_DRIVER_OPA1.
* @verbatim
__________________________
| +
| _____R2____
|\ | | |
___________|+\ OPA0 | | |\ OPA1 |
| \_________|____R1_|___|_\ | _
___|_ / | | \____|______
| | / | ___| /
| |/ | | |+/
|________________| | |/
|
POSPAD @endverbatim
*
* \n<b>Differential receiver with three opamp's.</b>\n
* Use predefined macros @ref OPA_INIT_DIFF_RECEIVER_OPA0,
* @ref OPA_INIT_DIFF_RECEIVER_OPA1 and @ref OPA_INIT_DIFF_RECEIVER_OPA2.
* @verbatim
|\
__________|+\ OPA1
_ | \_________
___|_ / | | _____R2____
| | / | | | |
| |/ | | | |\ |
|___________| |____R1_|___|_\ |
| \____|___
|\ ____R1_ ___| /
+__________|+\ OPA0 | | |+/ OPA2
| \_________| | |/
___|_ / | R2
| | / | |
| |/ | NEGPAD OPA0
|___________|
@endverbatim
*
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Disable an Operational Amplifier.
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] opa
* Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2.
******************************************************************************/
void OPAMP_Disable( DAC_TypeDef *dac, OPAMP_TypeDef opa )
{
EFM_ASSERT( DAC_REF_VALID( dac ) );
EFM_ASSERT( DAC_OPA_VALID( opa ) );
if ( opa == OPA0 )
{
dac->CH0CTRL &= ~DAC_CH0CTRL_EN;
dac->OPACTRL &= ~DAC_OPACTRL_OPA0EN;
}
else if ( opa == OPA1 )
{
dac->CH1CTRL &= ~DAC_CH1CTRL_EN;
dac->OPACTRL &= ~DAC_OPACTRL_OPA1EN;
}
else /* OPA2 */
{
dac->OPACTRL &= ~DAC_OPACTRL_OPA2EN;
}
}
/***************************************************************************//**
* @brief
* Configure and enable an Operational Amplifier.
*
* @details
*
* @param[in] dac
* Pointer to DAC peripheral register block.
*
* @param[in] opa
* Selects an OPA, valid vaules are @ref OPA0, @ref OPA1 and @ref OPA2.
*
* @param[in] init
* Pointer to a structure containing OPAMP init information.
******************************************************************************/
void OPAMP_Enable( DAC_TypeDef *dac, OPAMP_TypeDef opa, const OPAMP_Init_TypeDef *init )
{
uint32_t offset;
EFM_ASSERT( DAC_REF_VALID( dac ) );
EFM_ASSERT( DAC_OPA_VALID( opa ) );
EFM_ASSERT( init->bias <= ( _DAC_BIASPROG_BIASPROG_MASK >>
_DAC_BIASPROG_BIASPROG_SHIFT ) );
if ( opa == OPA0 )
{
EFM_ASSERT( ( init->outPen & ~_DAC_OPA0MUX_OUTPEN_MASK ) == 0 );
dac->BIASPROG = ( dac->BIASPROG
& ~( _DAC_BIASPROG_BIASPROG_MASK |
DAC_BIASPROG_HALFBIAS ) ) |
( init->bias << _DAC_BIASPROG_BIASPROG_SHIFT ) |
( init->halfBias ? DAC_BIASPROG_HALFBIAS : 0 );
if ( init->defaultOffset )
{
offset = SYSTEM_GetCalibrationValue( &dac->CAL );
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK ) |
( offset & _DAC_CAL_CH0OFFSET_MASK );
}
else
{
EFM_ASSERT( init->offset <= ( _DAC_CAL_CH0OFFSET_MASK >>
_DAC_CAL_CH0OFFSET_SHIFT ) );
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH0OFFSET_MASK ) |
( init->offset << _DAC_CAL_CH0OFFSET_SHIFT );
}
dac->OPA0MUX = (uint32_t)init->resSel |
(uint32_t)init->outMode |
init->outPen |
(uint32_t)init->resInMux |
(uint32_t)init->negSel |
(uint32_t)init->posSel |
( init->nextOut ? DAC_OPA0MUX_NEXTOUT : 0 ) |
( init->npEn ? DAC_OPA0MUX_NPEN : 0 ) |
( init->ppEn ? DAC_OPA0MUX_PPEN : 0 );
dac->CH0CTRL |= DAC_CH0CTRL_EN;
dac->OPACTRL = ( dac->OPACTRL
& ~( DAC_OPACTRL_OPA0SHORT |
_DAC_OPACTRL_OPA0LPFDIS_MASK |
DAC_OPACTRL_OPA0HCMDIS ) ) |
( init->shortInputs ? DAC_OPACTRL_OPA0SHORT : 0 ) |
( init->lpfPosPadDisable ?
DAC_OPACTRL_OPA0LPFDIS_PLPFDIS : 0 ) |
( init->lpfNegPadDisable ?
DAC_OPACTRL_OPA0LPFDIS_NLPFDIS : 0 ) |
( init->hcmDisable ? DAC_OPACTRL_OPA0HCMDIS : 0 ) |
( DAC_OPACTRL_OPA0EN );
}
else if ( opa == OPA1 )
{
EFM_ASSERT( ( init->outPen & ~_DAC_OPA1MUX_OUTPEN_MASK ) == 0 );
dac->BIASPROG = ( dac->BIASPROG
& ~( _DAC_BIASPROG_BIASPROG_MASK |
DAC_BIASPROG_HALFBIAS ) ) |
( init->bias << _DAC_BIASPROG_BIASPROG_SHIFT ) |
( init->halfBias ? DAC_BIASPROG_HALFBIAS : 0 );
if ( init->defaultOffset )
{
offset = SYSTEM_GetCalibrationValue( &dac->CAL );
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK ) |
( offset & _DAC_CAL_CH1OFFSET_MASK );
}
else
{
EFM_ASSERT( init->offset <= ( _DAC_CAL_CH1OFFSET_MASK >>
_DAC_CAL_CH1OFFSET_SHIFT ) );
dac->CAL = ( dac->CAL & ~_DAC_CAL_CH1OFFSET_MASK ) |
( init->offset << _DAC_CAL_CH1OFFSET_SHIFT );
}
dac->OPA1MUX = (uint32_t)init->resSel |
(uint32_t)init->outMode |
init->outPen |
(uint32_t)init->resInMux |
(uint32_t)init->negSel |
(uint32_t)init->posSel |
( init->nextOut ? DAC_OPA1MUX_NEXTOUT : 0 ) |
( init->npEn ? DAC_OPA1MUX_NPEN : 0 ) |
( init->ppEn ? DAC_OPA1MUX_PPEN : 0 );
dac->CH1CTRL |= DAC_CH1CTRL_EN;
dac->OPACTRL = ( dac->OPACTRL
& ~( DAC_OPACTRL_OPA1SHORT |
_DAC_OPACTRL_OPA1LPFDIS_MASK |
DAC_OPACTRL_OPA1HCMDIS ) ) |
( init->shortInputs ? DAC_OPACTRL_OPA1SHORT : 0 ) |
( init->lpfPosPadDisable ?
DAC_OPACTRL_OPA1LPFDIS_PLPFDIS : 0 ) |
( init->lpfNegPadDisable ?
DAC_OPACTRL_OPA1LPFDIS_NLPFDIS : 0 ) |
( init->hcmDisable ? DAC_OPACTRL_OPA1HCMDIS : 0 ) |
( DAC_OPACTRL_OPA1EN );
}
else /* OPA2 */
{
EFM_ASSERT( ( init->posSel == DAC_OPA2MUX_POSSEL_DISABLE ) ||
( init->posSel == DAC_OPA2MUX_POSSEL_POSPAD ) ||
( init->posSel == DAC_OPA2MUX_POSSEL_OPA1INP ) ||
( init->posSel == DAC_OPA2MUX_POSSEL_OPATAP ) );
EFM_ASSERT( ( init->outMode & ~DAC_OPA2MUX_OUTMODE ) == 0 );
EFM_ASSERT( ( init->outPen & ~_DAC_OPA2MUX_OUTPEN_MASK ) == 0 );
dac->BIASPROG = ( dac->BIASPROG
& ~( _DAC_BIASPROG_OPA2BIASPROG_MASK |
DAC_BIASPROG_OPA2HALFBIAS ) ) |
( init->bias << _DAC_BIASPROG_OPA2BIASPROG_SHIFT ) |
( init->halfBias ? DAC_BIASPROG_OPA2HALFBIAS : 0 );
if ( init->defaultOffset )
{
offset = SYSTEM_GetCalibrationValue( &dac->OPAOFFSET );
dac->OPAOFFSET = ( dac->OPAOFFSET & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK ) |
( offset & _DAC_OPAOFFSET_OPA2OFFSET_MASK );
}
else
{
EFM_ASSERT( init->offset <= ( _DAC_OPAOFFSET_OPA2OFFSET_MASK >>
_DAC_OPAOFFSET_OPA2OFFSET_SHIFT ) );
dac->CAL = ( dac->CAL & ~_DAC_OPAOFFSET_OPA2OFFSET_MASK ) |
( init->offset << _DAC_OPAOFFSET_OPA2OFFSET_SHIFT );
}
dac->OPA2MUX = (uint32_t)init->resSel |
(uint32_t)init->outMode |
init->outPen |
(uint32_t)init->resInMux |
(uint32_t)init->negSel |
(uint32_t)init->posSel |
( init->nextOut ? DAC_OPA2MUX_NEXTOUT : 0 ) |
( init->npEn ? DAC_OPA2MUX_NPEN : 0 ) |
( init->ppEn ? DAC_OPA2MUX_PPEN : 0 );
dac->OPACTRL = ( dac->OPACTRL
& ~( DAC_OPACTRL_OPA2SHORT |
_DAC_OPACTRL_OPA2LPFDIS_MASK |
DAC_OPACTRL_OPA2HCMDIS ) ) |
( init->shortInputs ? DAC_OPACTRL_OPA2SHORT : 0 ) |
( init->lpfPosPadDisable ?
DAC_OPACTRL_OPA2LPFDIS_PLPFDIS : 0 ) |
( init->lpfNegPadDisable ?
DAC_OPACTRL_OPA2LPFDIS_NLPFDIS : 0 ) |
( init->hcmDisable ? DAC_OPACTRL_OPA2HCMDIS : 0 ) |
( DAC_OPACTRL_OPA2EN );
}
}
/** @} (end addtogroup OPAMP) */
/** @} (end addtogroup EFM32_Library) */
#endif /* defined( OPAMP_PRESENT ) && ( OPAMP_COUNT == 1 ) */

View File

@ -0,0 +1,654 @@
/***************************************************************************//**
* @file
* @brief Pulse Counter (PCNT) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_pcnt.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup PCNT
* @brief Pulse Counter (PCNT) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of PCNT register block pointer reference for assert statements. */
#if (PCNT_COUNT == 1)
#define PCNT_REF_VALID(ref) ((ref) == PCNT0)
#elif (PCNT_COUNT == 2)
#define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1))
#elif (PCNT_COUNT == 3)
#define PCNT_REF_VALID(ref) (((ref) == PCNT0) || ((ref) == PCNT1) || \
((ref) == PCNT2))
#else
#error Undefined number of pulse counters (PCNT).
#endif
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Map PCNT structure into instance number.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block
*
* @return
* Instance number.
******************************************************************************/
static __INLINE unsigned int PCNT_Map(PCNT_TypeDef *pcnt)
{
return(((uint32_t)pcnt - PCNT0_BASE) / 0x400);
}
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
static __INLINE void PCNT_Sync(PCNT_TypeDef *pcnt, uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is
* activated. */
if (pcnt->FREEZE & PCNT_FREEZE_REGFREEZE)
{
return;
}
/* Wait for any pending previous write operation to have been completed in low
* frequency domain. */
while (pcnt->SYNCBUSY & mask)
;
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Reset PCNT counters and TOP register.
*
* @note
* Notice that special SYNCBUSY handling is not applicable for the RSTEN
* bit of the control register, so we don't need to wait for it when only
* modifying RSTEN. (It would mean undefined wait time if clocked by external
* clock.) The SYNCBUSY bit will however be set, leading to a synchronization
* in the LF domain, with in reality no changes.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
******************************************************************************/
void PCNT_CounterReset(PCNT_TypeDef *pcnt)
{
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Enable reset of CNT and TOP register */
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
/* Disable reset of CNT and TOP register */
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
}
/***************************************************************************//**
* @brief
* Set counter and top values.
*
* @details
* The pulse counter is disabled while changing these values, and reenabled
* (if originally enabled) when values have been set.
*
* @note
* This function will stall until synchronization to low frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module, since stall time may be
* undefined in that case. The counter should normally only be set when
* operating in (or about to enable) #pcntModeOvsSingle mode.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] count
* Value to set in counter register.
*
* @param[in] top
* Value to set in top register.
******************************************************************************/
void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top)
{
uint32_t ctrl;
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Keep current control setting, must be restored */
ctrl = pcnt->CTRL;
/* If enabled, disable pulse counter before changing values */
if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
pcnt->CTRL = (ctrl & ~_PCNT_CTRL_MODE_MASK) | PCNT_CTRL_MODE_DISABLE;
}
/* Load into TOPB */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
pcnt->TOPB = count;
/* Load TOPB value into TOP */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
/* This bit has no effect on rev. C and onwards parts - for compatibility */
pcnt->CMD = PCNT_CMD_LTOPBIM;
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
/* Load TOP into CNT */
pcnt->CMD = PCNT_CMD_LCNTIM;
/* Restore TOP? ('count' setting has been loaded into pcnt->TOP, better
* to use 'top' than pcnt->TOP in compare, since latter may in theory not
* be visible yet.) */
if (top != count)
{
/* Wait for command to sync LCNTIM before setting TOPB */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
/* Load into TOPB, we don't need to check for TOPB sync complete here,
* it has been ensured above. */
pcnt->TOPB = top;
/* Load TOPB value into TOP */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
pcnt->CMD = PCNT_CMD_LTOPBIM;
}
/* Reenable if it was enabled */
if ((ctrl & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL | PCNT_SYNCBUSY_CMD);
pcnt->CTRL = ctrl;
}
}
/***************************************************************************//**
* @brief
* Set PCNT operational mode.
*
* @details
* Notice that this function does not do any configuration. Setting operational
* mode is normally only required after initialization is done, and if not
* done as part of initialization. Or if requiring to disable/reenable pulse
* counter.
*
* @note
* This function may stall until synchronization to low frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module, since stall time may be
* undefined in that case.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] mode
* Operational mode to use for PCNT.
******************************************************************************/
void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode)
{
uint32_t tmp;
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Set as specified */
tmp = pcnt->CTRL & ~_PCNT_CTRL_MODE_MASK;
tmp |= (uint32_t)mode << _PCNT_CTRL_MODE_SHIFT;
/* LF register about to be modified require sync. busy check */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
pcnt->CTRL = tmp;
}
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
/***************************************************************************//**
* @brief
* Enable/disable the selected PRS input of PCNT.
*
* @details
* Notice that this function does not do any configuration.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] prsInput
* PRS input (S0 or S1) of the selected PCNT module.
*
* @param[in] enable
* Set to true to enable, false to disable the selected PRS input.
******************************************************************************/
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
PCNT_PRSInput_TypeDef prsInput,
bool enable)
{
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Enable/disable the selected PRS input on the selected PCNT module. */
switch (prsInput)
{
/* Enable/disable PRS input S0. */
case pcntPRSInputS0:
{
BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S0PRSEN_SHIFT, (uint32_t)enable);
}
break;
/* Enable/disable PRS input S1. */
case pcntPRSInputS1:
{
BITBAND_Peripheral(&(pcnt->INPUT), _PCNT_INPUT_S1PRSEN_SHIFT, (uint32_t)enable);
}
break;
/* Invalid parameter, asserted. */
default:
{
EFM_ASSERT(0);
}
break;
}
}
#endif
/***************************************************************************//**
* @brief
* PCNT register synchronization freeze control.
*
* @details
* Some PCNT registers require synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing PCNT synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disables freeze, modified registers are propagated to LF
* domain
******************************************************************************/
void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable)
{
EFM_ASSERT(PCNT_REF_VALID(pcnt));
if (enable)
{
/* Wait for any ongoing LF synchronization to complete. This is just to
* protect against the rare case when a user:
* - modifies a register requiring LF sync
* - then enables freeze before LF sync completed
* - then modifies the same register again
* since modifying a register while it is in sync progress should be
* avoided. */
while (pcnt->SYNCBUSY)
;
pcnt->FREEZE = PCNT_FREEZE_REGFREEZE;
}
else
{
pcnt->FREEZE = 0;
}
}
/***************************************************************************//**
* @brief
* Init pulse counter.
*
* @details
* This function will configure the pulse counter. The clock selection is
* configured as follows, depending on operational mode:
*
* @li #pcntModeOvsSingle - Use LFACLK.
* @li #pcntModeExtSingle - Use external PCNTn_S0 pin.
* @li #pcntModeExtQuad - Use external PCNTn_S0 pin.
*
* Notice that the LFACLK must be enabled in all modes, since some basic setup
* is done with this clock even if external pin clock usage mode is chosen.
* The pulse counter clock for the selected instance must also be enabled
* prior to init.
*
* Notice that pins used by the PCNT module must be properly configured
* by the user explicitly through setting the ROUTE register, in order for
* the PCNT to work as intended.
*
* Writing to CNT will not occur in external clock modes (EXTCLKQUAD and
* EXTCLKSINGLE) because the external clock rate is unknown. The user should
* handle it manually depending on the application
*
* TOPB is written for all modes but in external clock mode it will take
* 3 external clock cycles to sync to TOP
*
*
* @note
* Initializing requires synchronization into the low frequency domain. This
* may cause some delay.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] init
* Pointer to initialization structure used to initialize.
******************************************************************************/
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init)
{
unsigned int inst;
uint32_t tmp;
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Map pointer to instance */
inst = PCNT_Map(pcnt);
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
/* Selecting the PRS channels for the PRS input sources of the PCNT. These are
* written with a Read-Modify-Write sequence in order to keep the value of the
* input enable bits which can be modified using PCNT_PRSInputEnable(). */
tmp = pcnt->INPUT & ~(_PCNT_INPUT_S0PRSSEL_MASK | _PCNT_INPUT_S1PRSSEL_MASK);
tmp |= ((uint32_t)init->s0PRS << _PCNT_INPUT_S0PRSSEL_SHIFT) |
((uint32_t)init->s1PRS << _PCNT_INPUT_S1PRSSEL_SHIFT);
pcnt->INPUT = tmp;
#endif
/* Build CTRL setting, except for mode */
tmp = 0;
if (init->negEdge)
{
tmp |= PCNT_CTRL_EDGE_NEG;
}
if (init->countDown)
{
tmp |= PCNT_CTRL_CNTDIR_DOWN;
}
if (init->filter)
{
tmp |= PCNT_CTRL_FILT;
}
#if (defined (_EFM32_TINY_FAMILY) || defined (_EFM32_GIANT_FAMILY))
if (init->hyst)
{
tmp |= PCNT_CTRL_HYST;
}
if (init->s1CntDir)
{
tmp |= PCNT_CTRL_S1CDIR;
}
/* Configure counter events for regular and auxiliary counter. */
tmp |= init->cntEvent << _PCNT_CTRL_CNTEV_SHIFT;
tmp |= init->auxCntEvent << _PCNT_CTRL_AUXCNTEV_SHIFT;
#endif
/* Reset pulse counter while changing clock source. The reset bit */
/* is asynchronous, we don't have to check for SYNCBUSY. */
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
/* Select LFACLK to clock in control setting */
CMU_PCNTClockExternalSet(inst, false);
/* Handling depends on whether using external clock or not. */
switch (init->mode)
{
case pcntModeExtSingle:
case pcntModeExtQuad:
tmp |= init->mode << _PCNT_CTRL_MODE_SHIFT;
/* In most cases, the SYNCBUSY bit is set due to reset bit set, and waiting
* for asynchronous reset bit is strictly not necessary.
* But in theory, other operations on CTRL register may have been done
* outside this function, so wait. */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
/* Enable PCNT Clock Domain Reset. The PCNT must be in reset before changing
* the clock source to an external clock */
pcnt->CTRL = PCNT_CTRL_RSTEN;
/* Wait until CTRL write synchronized into LF domain. */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
/* Change to external clock BEFORE disabling reset */
CMU_PCNTClockExternalSet(inst, true);
/* Write to TOPB. If using external clock TOPB will sync to TOP at the same
* time as the mode. This will insure that if the user chooses to count
* down, the first "countable" pulse will make CNT go to TOP and not 0xFF
* (default TOP value). */
pcnt->TOPB = init->top;
/* This bit has no effect on rev. C and onwards parts - for compatibility */
pcnt->CMD = PCNT_CMD_LTOPBIM;
/* Write the CTRL register with the configurations.
* This should be written after TOPB in the eventuality of a pulse between
* these two writes that would cause the CTRL register to be synced one
* clock cycle earlier than the TOPB. */
pcnt->CTRL = tmp;
/* There are no syncs for TOP, CMD or CTRL because the clock rate is unknown
* and the program could stall
* These will be synced within 3 clock cycles of the external clock /
* For the same reason CNT cannot be written here. */
break;
/* pcntModeDisable */
/* pcntModeOvsSingle */
default:
/* No need to set disabled mode if already disabled. */
if ((pcnt->CTRL & _PCNT_CTRL_MODE_MASK) != PCNT_CTRL_MODE_DISABLE)
{
/* Set control to disabled mode, leave reset on until ensured disabled.
* We don't need to wait for CTRL SYNCBUSY completion here, it was
* triggered by reset bit above, which is asynchronous. */
pcnt->CTRL = tmp | PCNT_CTRL_MODE_DISABLE | PCNT_CTRL_RSTEN;
/* Wait until CTRL write synchronized into LF domain before proceeding
* to disable reset. */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
}
/* Disable reset bit, counter should now be in disabled mode. */
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
/* Set counter and top values as specified. */
PCNT_CounterTopSet(pcnt, init->counter, init->top);
/* Enter oversampling mode if selected. */
if (init->mode == pcntModeOvsSingle)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
pcnt->CTRL = tmp | (init->mode << _PCNT_CTRL_MODE_SHIFT);
}
break;
}
}
/***************************************************************************//**
* @brief
* Reset PCNT to same state as after a HW reset.
*
* @details
* Notice the LFACLK must be enabled, since some basic reset is done with
* this clock. The pulse counter clock for the selected instance must also
* be enabled prior to init.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
******************************************************************************/
void PCNT_Reset(PCNT_TypeDef *pcnt)
{
unsigned int inst;
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* Map pointer to instance and clock info */
inst = PCNT_Map(pcnt);
pcnt->IEN = _PCNT_IEN_RESETVALUE;
/* Notice that special SYNCBUSY handling is not applicable for the RSTEN
* bit of the control register, so we don't need to wait for it when only
* modifying RSTEN. The SYNCBUSY bit will be set, leading to a
* synchronization in the LF domain, with in reality no changes to LF domain.
* Enable reset of CNT and TOP register. */
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 1);
/* Select LFACLK as default */
CMU_PCNTClockExternalSet(inst, false);
PCNT_TopBufferSet(pcnt, _PCNT_TOPB_RESETVALUE);
/* Reset CTRL leaving RSTEN set */
pcnt->CTRL = _PCNT_CTRL_RESETVALUE | PCNT_CTRL_RSTEN;
/* Disable reset after CTRL reg has been synchronized */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CTRL);
BITBAND_Peripheral(&(pcnt->CTRL), _PCNT_CTRL_RSTEN_SHIFT, 0);
/* Clear pending interrupts */
pcnt->IFC = _PCNT_IFC_MASK;
/* Do not reset route register, setting should be done independently */
}
/***************************************************************************//**
* @brief
* Set top buffer value.
*
* @note
* This function may stall until synchronization to low frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module, since stall time may be
* undefined in that case.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] val
* Value to set in top buffer register.
******************************************************************************/
void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val)
{
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* LF register about to be modified require sync. busy check */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
pcnt->TOPB = val;
}
/***************************************************************************//**
* @brief
* Set top value.
*
* @note
* This function will stall until synchronization to low frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module, since stall time may be
* undefined in that case.
*
* @param[in] pcnt
* Pointer to PCNT peripheral register block.
*
* @param[in] val
* Value to set in top register.
******************************************************************************/
void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val)
{
EFM_ASSERT(PCNT_REF_VALID(pcnt));
/* LF register about to be modified require sync. busy check */
/* Load into TOPB */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB);
pcnt->TOPB = val;
/* Load TOPB value into TOP */
PCNT_Sync(pcnt, PCNT_SYNCBUSY_TOPB | PCNT_SYNCBUSY_CMD);
pcnt->CMD = PCNT_CMD_LTOPBIM;
}
/** @} (end addtogroup PCNT) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,122 @@
/***************************************************************************//**
* @file
* @brief Peripheral Reflex System (PRS) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_prs.h"
#include "efm32_assert.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup PRS
* @brief Peripheral Reflex System (PRS) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Set source and signal to be used for a channel.
*
* @param[in] ch
* Channel to define signal and source for.
*
* @param[in] source
* Source to select for channel. Use one of PRS_CH_CTRL_SOURCESEL_x defines.
*
* @param[in] signal
* Signal (for selected @p source) to use. Use one of PRS_CH_CTRL_SIGSEL_x
* defines.
*
* @param[in] edge
* Edge (for selected source/signal) to generate pulse for.
******************************************************************************/
void PRS_SourceSignalSet(unsigned int ch,
uint32_t source,
uint32_t signal,
PRS_Edge_TypeDef edge)
{
EFM_ASSERT(ch < 8);
PRS->CH[ch].CTRL = (source & _PRS_CH_CTRL_SOURCESEL_MASK) |
(signal & _PRS_CH_CTRL_SIGSEL_MASK) |
(uint32_t)edge;
}
#if ((defined _EFM32_TINY_FAMILY) || (defined _EFM32_GIANT_FAMILY))
/***************************************************************************//**
* @brief
* Set source and asynchronous signal to be used for a channel.
*
* @details
* Asynchronous reflexes are not clocked on HFPERCLK, and can be used even in
* EM2/EM3.
* There is a limitation to reflexes operating in asynchronous mode: they can
* only be used by a subset of the reflex consumers. Please refer to PRS
* chapter in the reference manual for the complete list of supported
* asynchronous signals and consumers.
*
* @note
* This function is only supported on the following device families:
* @li Tiny Gecko (EFM32TGxxxFxx)
* @li Giant Gecko (EFM32GGxxxFxxx)
* In asynchronous mode, the edge detector only works in EM0, hence it shall
* not be used. The EDSEL parameter in PRS_CHx_CTRL register is set to 0 (OFF)
* by default.
*
* @param[in] ch
* Channel to define source and asynchronous signal for.
*
* @param[in] source
* Source to select for channel. Use one of PRS_CH_CTRL_SOURCESEL_x defines.
*
* @param[in] signal
* Asynchronous signal (for selected @p source) to use. Use one of the
* PRS_CH_CTRL_SIGSEL_x defines that support asynchronous operation.
******************************************************************************/
void PRS_SourceAsyncSignalSet(unsigned int ch,
uint32_t source,
uint32_t signal)
{
EFM_ASSERT(ch < 8);
PRS->CH[ch].CTRL = PRS_CH_CTRL_ASYNC |
(source & _PRS_CH_CTRL_SOURCESEL_MASK) |
(signal & _PRS_CH_CTRL_SIGSEL_MASK) |
PRS_CH_CTRL_EDSEL_OFF;
}
#endif
/** @} (end addtogroup PRS) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,175 @@
/***************************************************************************//**
* @file
* @brief Reset Management Unit (RMU) peripheral module peripheral API
* for EFM32.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_rmu.h"
#include "efm32_emu.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RMU
* @brief Reset Management Unit (RMU) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Disable/enable the lockup signal from the Cortex M-3.
*
* @param[in] disable
* @li false - Allow lockup signal to reset.
* @li true - Do not allow lockup signal to reset.
******************************************************************************/
void RMU_LockupResetDisable(bool disable)
{
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_LOCKUPRDIS_SHIFT, (unsigned int)disable);
}
/***************************************************************************//**
* @brief
* Clear the reset cause register.
******************************************************************************/
void RMU_ResetCauseClear(void)
{
uint32_t locked;
RMU->CMD = RMU_CMD_RCCLR;
/* Clear some reset causes not cleared with RMU CMD register */
/* (If EMU registers locked, they must be unlocked first) */
locked = EMU->LOCK & EMU_LOCK_LOCKKEY_LOCKED;
if (locked)
{
EMU_Unlock();
}
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 1);
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 0);
if (locked)
{
EMU_Lock();
}
}
/***************************************************************************//**
* @brief
* Get the cause of the last reset.
*
* @details
* In order to be useful, the reset cause must be cleared by SW before a new
* reset occurs, otherwise reset causes may accumulate. See
* RMU_ResetCauseClear().
*
* @return
* The reset cause, a bit mask of (typically, but not always, only one) of:
* @li RMU_RSTCAUSE_PORST - Power on reset
* @li RMU_RSTCAUSE_BODUNREGRST - Brown out detector, unregulated power
* @li RMU_RSTCAUSE_BODREGRST - Brown out detector, regulated power
* @li RMU_RSTCAUSE_EXTRST - External reset
* @li RMU_RSTCAUSE_WDOGRST - Watchdog reset
* @li RMU_RSTCAUSE_LOCKUPRST - Cortex-M3 lockup reset
* @li RMU_RSTCAUSE_SYSREQRST - Cortex-M3 system request reset
******************************************************************************/
uint32_t RMU_ResetCauseGet(void)
{
uint32_t ret = RMU->RSTCAUSE;
/* Inspect and decode bits. The decoding must be done in correct order, */
/* since some reset causes may trigger other reset causes due to internal */
/* design. We are only interested in the main cause. */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY)
/* Clear "stray" bits if EM4 bit is set, they will always be active */
if (ret & RMU_RSTCAUSE_EM4RST)
{
ret &= ~(RMU_RSTCAUSE_BODREGRST|
RMU_RSTCAUSE_BODUNREGRST|
RMU_RSTCAUSE_LOCKUPRST|
RMU_RSTCAUSE_SYSREQRST);
}
if (ret == RMU_RSTCAUSE_BODAVDD0)
{
ret = RMU_RSTCAUSE_BODAVDD0;
}
else if (ret == RMU_RSTCAUSE_BODAVDD1)
{
ret = RMU_RSTCAUSE_BODAVDD1;
}
else if (ret == (RMU_RSTCAUSE_EM4WURST|RMU_RSTCAUSE_EM4RST))
{
ret &= (RMU_RSTCAUSE_EM4WURST|RMU_RSTCAUSE_EM4RST);
}
else if (ret & (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST))
{
ret &= (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST);
}
else
#endif
if (ret & RMU_RSTCAUSE_PORST)
{
ret = RMU_RSTCAUSE_PORST;
}
else if (ret & RMU_RSTCAUSE_BODUNREGRST)
{
ret = RMU_RSTCAUSE_BODUNREGRST;
}
else if ((ret & 0x1f) == RMU_RSTCAUSE_BODREGRST)
{
ret = RMU_RSTCAUSE_BODREGRST;
}
/* Both external and watchdog reset may occur at the same time */
else if (ret & (RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST))
{
ret &= RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST;
}
/* Both lockup and system reset may occur at the same time */
else if (ret & (RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST))
{
ret &= RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST;
}
else
{
ret = 0;
}
return ret;
}
/** @} (end addtogroup RMU) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,355 @@
/***************************************************************************//**
* @file
* @brief Real Time Counter (RTC) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_rtc.h"
#include "efm32_assert.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RTC
* @brief Real Time Counter (RTC) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of valid comparator register for assert statements. */
#define RTC_COMP_REG_VALID(reg) (((reg) <= 1))
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#if defined(_EFM32_GECKO_FAMILY)
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @note
* This only applies to the Gecko Family, see the reference manual
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
* for details. For Tiny Gecko and Giant Gecko, the RTC supports immediate
* updates of registers, and will automatically hold the bus until the
* register has been updated.
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
static __INLINE void RTC_Sync(uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (RTC->FREEZE & RTC_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain. This is only required for the Gecko Family */
while (RTC->SYNCBUSY & mask)
;
}
#endif
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get RTC compare register value.
*
* @param[in] comp
* Compare register to get, either 0 or 1
*
* @return
* Compare register value, 0 if invalid register selected.
******************************************************************************/
uint32_t RTC_CompareGet(unsigned int comp)
{
uint32_t ret;
EFM_ASSERT(RTC_COMP_REG_VALID(comp));
/* Initialize selected compare value */
switch (comp)
{
case 0:
ret = RTC->COMP0;
break;
case 1:
ret = RTC->COMP1;
break;
default:
/* Unknown compare register selected */
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Set RTC compare register value.
*
* @note
* The setting of a compare register requires synchronization into the
* low frequency domain. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. This only applies to the Gecko Family, see
* comment in the RTC_Sync() internal function call.
*
* @param[in] comp
* Compare register to set, either 0 or 1
*
* @param[in] value
* Initialization value (<= 0x00ffffff)
******************************************************************************/
void RTC_CompareSet(unsigned int comp, uint32_t value)
{
volatile uint32_t *compReg;
#if defined(_EFM32_GECKO_FAMILY)
uint32_t syncbusy;
#endif
EFM_ASSERT(RTC_COMP_REG_VALID(comp) &&
((value & ~(_RTC_COMP0_COMP0_MASK >> _RTC_COMP0_COMP0_SHIFT)) == 0));
/* Initialize selected compare value */
switch (comp)
{
case 0:
compReg = &(RTC->COMP0);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = RTC_SYNCBUSY_COMP0;
#endif
break;
case 1:
compReg = &(RTC->COMP1);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = RTC_SYNCBUSY_COMP1;
#endif
break;
default:
/* Unknown compare register selected, abort */
return;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(syncbusy);
#endif
*compReg = value;
}
/***************************************************************************//**
* @brief
* Enable/disable RTC.
*
* @note
* The enabling/disabling of the RTC modifies the RTC CTRL register which
* requires synchronization into the low frequency domain. If this register is
* modified before a previous update to the same register has completed, this
* function will stall until the previous synchronization has completed. This
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
* function call.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void RTC_Enable(bool enable)
{
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(RTC_SYNCBUSY_CTRL);
#endif
BITBAND_Peripheral(&(RTC->CTRL), _RTC_CTRL_EN_SHIFT, (unsigned int) enable);
}
/***************************************************************************//**
* @brief
* RTC register synchronization freeze control.
*
* @details
* Some RTC registers require synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing RTC synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling. This only applies to the Gecko Family, see the reference manual
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
* for details.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disables freeze, modified registers are propagated to LF
* domain
******************************************************************************/
void RTC_FreezeEnable(bool enable)
{
if (enable)
{
#if defined(_EFM32_GECKO_FAMILY)
/* Wait for any ongoing LF synchronization to complete. This is just to */
/* protect against the rare case when a user */
/* - modifies a register requiring LF sync */
/* - then enables freeze before LF sync completed */
/* - then modifies the same register again */
/* since modifying a register while it is in sync progress should be */
/* avoided. */
while (RTC->SYNCBUSY)
;
#endif
RTC->FREEZE = RTC_FREEZE_REGFREEZE;
}
else
{
RTC->FREEZE = 0;
}
}
/***************************************************************************//**
* @brief
* Initialize RTC.
*
* @details
* Note that the compare values must be set separately with RTC_CompareSet().
* That should probably be done prior to the use of this function if
* configuring the RTC to start when initialization is completed.
*
* @note
* The initialization of the RTC modifies the RTC CTRL register which requires
* synchronization into the low frequency domain. If this register is
* modified before a previous update to the same register has completed, this
* function will stall until the previous synchronization has completed. This
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
* function call.
*
* @param[in] init
* Pointer to RTC initialization structure.
******************************************************************************/
void RTC_Init(const RTC_Init_TypeDef *init)
{
uint32_t tmp;
if (init->enable)
{
tmp = RTC_CTRL_EN;
}
else
{
tmp = 0;
}
/* Configure DEBUGRUN flag, sets whether or not counter should be
* updated when debugger is active */
if (init->debugRun)
{
tmp |= RTC_CTRL_DEBUGRUN;
}
/* Configure COMP0TOP, this will use the COMP0 compare value as an
* overflow value, instead of default 24-bit 0x00ffffff */
if (init->comp0Top)
{
tmp |= RTC_CTRL_COMP0TOP;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(RTC_SYNCBUSY_CTRL);
#endif
RTC->CTRL = tmp;
}
/***************************************************************************//**
* @brief
* Restore RTC to reset state
******************************************************************************/
void RTC_Reset(void)
{
/* Restore all essential RTC register to default config */
RTC->FREEZE = _RTC_FREEZE_RESETVALUE;
RTC->CTRL = _RTC_CTRL_RESETVALUE;
RTC->COMP0 = _RTC_COMP0_RESETVALUE;
RTC->COMP1 = _RTC_COMP1_RESETVALUE;
RTC->IEN = _RTC_IEN_RESETVALUE;
RTC->IFC = _RTC_IFC_RESETVALUE;
}
/***************************************************************************//**
* @brief
* Restart RTC counter from zero
******************************************************************************/
void RTC_CounterReset(void)
{
/* A disable/enable sequnce will start the counter at zero */
RTC_Enable(false);
RTC_Enable(true);
}
/** @} (end addtogroup RTC) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,106 @@
/***************************************************************************//**
* @file
* @brief System Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32.h"
#include "efm32_system.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @brief System Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
tmp = (ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK);
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Address of register to get a calibration value for.
*
* @return
* Calibration value for the requested register.
******************************************************************************/
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
int regCount;
CALIBRATE_TypeDef *p;
regCount = 1;
p = CALIBRATE;
for (;; )
{
if ((regCount > CALIBRATE_MAX_REGISTERS) ||
(p->VALUE == 0xFFFFFFFF))
{
EFM_ASSERT(false);
return 0; /* End of device calibration table reached. */
}
if (p->ADDRESS == (uint32_t)regAddress)
{
return p->VALUE; /* Calibration value found ! */
}
p++;
regCount++;
}
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,295 @@
/***************************************************************************//**
* @file
* @brief Timer/counter (TIMER) Peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_timer.h"
#include "efm32_cmu.h"
#include "efm32_assert.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @brief Timer/Counter (TIMER) Peripheral API for EFM32
* @details
* The timer module consists of three main parts:
* @li General timer config and enable control.
* @li Compare/capture control.
* @li Dead time insertion control (may not be available for all timers).
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of TIMER register block pointer reference for assert statements. */
#if (TIMER_COUNT == 1)
#define TIMER_REF_VALID(ref) ((ref) == TIMER0)
#elif (TIMER_COUNT == 2)
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || ((ref) == TIMER1))
#elif (TIMER_COUNT == 3)
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || \
((ref) == TIMER1) || \
((ref) == TIMER2))
#elif (TIMER_COUNT == 4)
#define TIMER_REF_VALID(ref) (((ref) == TIMER0) || \
((ref) == TIMER1) || \
((ref) == TIMER2) || \
((ref) == TIMER3))
#else
#error Undefined number of timers.
#endif
/** Validation of TIMER compare/capture channel number */
#define TIMER_CH_VALID(ch) ((ch) < 3)
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Start/stop TIMER.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void TIMER_Enable(TIMER_TypeDef *timer, bool enable)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
if (enable)
{
timer->CMD = TIMER_CMD_START;
}
else
{
timer->CMD = TIMER_CMD_STOP;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER.
*
* @details
* Notice that counter top must be configured separately with for instance
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
* init must be initialized separately if used. That should probably
* be done prior to the use of this function if configuring the TIMER to
* start when initialization is completed.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
if (!(init->enable))
{
timer->CMD = TIMER_CMD_STOP;
}
/* Reset counter */
timer->CNT = _TIMER_CNT_RESETVALUE;
timer->CTRL =
((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT) |
((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT) |
((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT) |
((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT) |
((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT) |
(init->debugRun ? TIMER_CTRL_DEBUGRUN : 0) |
(init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0) |
(init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0) |
(init->oneShot ? TIMER_CTRL_OSMEN : 0) |
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
(init->count2x ? TIMER_CTRL_X2CNT : 0) |
(init->ati ? TIMER_CTRL_ATI : 0) |
#endif
(init->sync ? TIMER_CTRL_SYNC : 0);
/* Start timer if specified to be enabled (dosn't hurt if already started) */
if (init->enable)
{
timer->CMD = TIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER compare/capture channel.
*
* @details
* Notice that if operating channel in compare mode, the CCV and CCVB register
* must be set separately as required.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to init for.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
EFM_ASSERT(TIMER_CH_VALID(ch));
timer->CC[ch].CTRL =
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT) |
((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT) |
((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT) |
((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT) |
((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT) |
((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT) |
((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT) |
(init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0) |
(init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0) |
(init->coist ? TIMER_CC_CTRL_COIST : 0) |
(init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
}
#ifdef TIMER_DTLOCK_LOCKKEY_LOCK
/***************************************************************************//**
* @brief
* Lock the TIMER in order to protect some of its registers against unintended
* modification.
*
* @details
* Please refer to the reference manual for TIMER registers that will be
* locked.
*
* @note
* If locking the TIMER registers, they must be unlocked prior to using any
* TIMER API functions modifying TIMER registers protected by the lock.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Lock(TIMER_TypeDef *timer)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_LOCK;
}
#endif
/***************************************************************************//**
* @brief
* Reset TIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Reset(TIMER_TypeDef *timer)
{
int i;
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Make sure disabled first, before resetting other registers */
timer->CMD = TIMER_CMD_STOP;
timer->CTRL = _TIMER_CTRL_RESETVALUE;
timer->IEN = _TIMER_IEN_RESETVALUE;
timer->IFC = _TIMER_IFC_MASK;
timer->TOP = _TIMER_TOP_RESETVALUE;
timer->TOPB = _TIMER_TOPB_RESETVALUE;
timer->CNT = _TIMER_CNT_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* (Note: ROUTE register may be locked by DTLOCK register.) */
for (i = 0; TIMER_CH_VALID(i); i++)
{
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
}
/* Reset dead time insertion module, no effect on timers without DTI */
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
/* Unlock DTI registers first in case locked */
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
timer->DTFC = _TIMER_DTFC_RESETVALUE;
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
#endif
}
#ifdef TIMER_DTLOCK_LOCKKEY_UNLOCK
/***************************************************************************//**
* @brief
* Unlock the TIMER so that writing to locked registers again is possible.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Unlock(TIMER_TypeDef *timer)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
}
#endif
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,176 @@
/***************************************************************************//**
* @file
* @brief Voltage Comparator (VCMP) peripheral API for EFM32
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_assert.h"
#include "efm32_vcmp.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup VCMP
* @brief Voltage Comparator (VCMP) Peripheral API for EFM32
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Configure and enable Voltage Comparator
*
* @param[in] vcmpInit
* VCMP Initialization structure
******************************************************************************/
void VCMP_Init(const VCMP_Init_TypeDef *vcmpInit)
{
/* Verify input */
EFM_ASSERT((vcmpInit->inactive == 0) || (vcmpInit->inactive == 1));
EFM_ASSERT((vcmpInit->biasProg >= 0) && (vcmpInit->biasProg < 16));
/* Configure Half Bias setting */
if (vcmpInit->halfBias)
{
VCMP->CTRL |= VCMP_CTRL_HALFBIAS;
}
else
{
VCMP->CTRL &= ~(VCMP_CTRL_HALFBIAS);
}
/* Configure bias prog */
VCMP->CTRL &= ~(_VCMP_CTRL_BIASPROG_MASK);
VCMP->CTRL |= (vcmpInit->biasProg << _VCMP_CTRL_BIASPROG_SHIFT);
/* Configure sense for falling edge */
if (vcmpInit->irqFalling)
{
VCMP->CTRL |= VCMP_CTRL_IFALL;
}
else
{
VCMP->CTRL &= ~(VCMP_CTRL_IFALL);
}
/* Configure sense for rising edge */
if (vcmpInit->irqRising)
{
VCMP->CTRL |= VCMP_CTRL_IRISE;
}
else
{
VCMP->CTRL &= ~(VCMP_CTRL_IRISE);
}
/* Configure warm-up time */
VCMP->CTRL &= ~(_VCMP_CTRL_WARMTIME_MASK);
VCMP->CTRL |= (vcmpInit->warmup << _VCMP_CTRL_WARMTIME_SHIFT);
/* Configure hysteresis */
switch (vcmpInit->hyst)
{
case vcmpHyst20mV:
VCMP->CTRL |= VCMP_CTRL_HYSTEN;
break;
case vcmpHystNone:
VCMP->CTRL &= ~(VCMP_CTRL_HYSTEN);
break;
default:
break;
}
/* Configure inactive output value */
VCMP->CTRL |= (vcmpInit->inactive << _VCMP_CTRL_INACTVAL_SHIFT);
/* Configure trigger level */
VCMP_TriggerSet(vcmpInit->triggerLevel);
/* Enable or disable VCMP */
if (vcmpInit->enable)
{
VCMP->CTRL |= VCMP_CTRL_EN;
}
else
{
VCMP->CTRL &= ~(VCMP_CTRL_EN);
}
/* If Low Power Reference is enabled, wait until VCMP is ready */
/* before enabling it, see reference manual for deatils */
/* Configuring Low Power Ref without enable has no effect */
if(vcmpInit->lowPowerRef && vcmpInit->enable)
{
/* Poll for VCMP ready */
while(!VCMP_Ready());
VCMP_LowPowerRefSet(vcmpInit->lowPowerRef);
}
/* Clear edge interrupt */
VCMP_IntClear(VCMP_IF_EDGE);
}
/***************************************************************************//**
* @brief
* Enable or disable Low Power Reference setting
*
* @param[in] enable
* If true, enables low power reference, if false disable low power reference
******************************************************************************/
void VCMP_LowPowerRefSet(bool enable)
{
if (enable)
{
VCMP->INPUTSEL |= VCMP_INPUTSEL_LPREF;
}
else
{
VCMP->INPUTSEL &= ~(VCMP_INPUTSEL_LPREF);
}
}
/***************************************************************************//**
* @brief
* Configure trigger level of voltage comparator
*
* @param[in] level
* Trigger value, in range 0-63
******************************************************************************/
void VCMP_TriggerSet(int level)
{
/* Trigger range is 6 bits, value from 0-63 */
EFM_ASSERT((level > 0) && (level < 64));
/* Set trigger level */
VCMP->INPUTSEL = (VCMP->INPUTSEL & ~(_VCMP_INPUTSEL_TRIGLEVEL_MASK)) |
(level << _VCMP_INPUTSEL_TRIGLEVEL_SHIFT);
}
/** @} (end addtogroup VCMP) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,205 @@
/***************************************************************************//**
* @file
* @brief Watchdog (WDOG) peripheral API for EFM32
* devices.
* @author Energy Micro AS
* @version 2.3.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2010 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* This source code is the property of Energy Micro AS. The source and compiled
* code may only be used on Energy Micro "EFM32" microcontrollers.
*
* This copyright notice may not be removed from the source code nor changed.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "efm32_wdog.h"
#include "efm32_bitband.h"
/***************************************************************************//**
* @addtogroup EFM32_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup WDOG
* @brief Watchdog (WDOG) Peripheral API for EFM32
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enable/disable the watchdog timer.
*
* @note
* This function modifies the WDOG CTRL register which requires
* synchronization into the low frequency domain. If this register is modified
* before a previous update to the same register has completed, this function
* will stall until the previous synchronization has completed.
*
* @param[in] enable
* true to enable watchdog, false to disable. Watchdog cannot be disabled if
* watchdog has been locked.
******************************************************************************/
void WDOG_Enable(bool enable)
{
if (!enable)
{
/* Wait for any pending previous write operation to have been completed in */
/* low frequency domain */
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
;
}
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_EN_SHIFT, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Feed the watchdog.
*
* @details
* When the watchdog is activated, it must be fed (ie clearing the counter)
* before it reaches the defined timeout period. Otherwise, the watchdog
* will generate a reset.
******************************************************************************/
void WDOG_Feed(void)
{
/* If a previous clearing is being synchronized to LF domain, then there */
/* is no point in waiting for it to complete before clearing over again. */
/* This avoids stalling the core in the typical use case where some idle loop */
/* keeps clearing the watchdog. */
if (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CMD)
return;
WDOG->CMD = WDOG_CMD_CLEAR;
}
/***************************************************************************//**
* @brief
* Initialize watchdog (assuming the watchdog configuration has not been
* locked).
*
* @note
* This function modifies the WDOG CTRL register which requires
* synchronization into the low frequency domain. If this register is modified
* before a previous update to the same register has completed, this function
* will stall until the previous synchronization has completed.
*
* @param[in] init
* Structure holding watchdog configuration. A default setting
* #WDOG_INIT_DEFAULT is available for init.
******************************************************************************/
void WDOG_Init(const WDOG_Init_TypeDef *init)
{
uint32_t setting;
if (init->enable)
{
setting = WDOG_CTRL_EN;
}
else
{
setting = 0;
}
if (init->debugRun)
{
setting |= WDOG_CTRL_DEBUGRUN;
}
if (init->em2Run)
{
setting |= WDOG_CTRL_EM2RUN;
}
if (init->em3Run)
{
setting |= WDOG_CTRL_EM3RUN;
}
if (init->em4Block)
{
setting |= WDOG_CTRL_EM4BLOCK;
}
if (init->swoscBlock)
{
setting |= WDOG_CTRL_SWOSCBLOCK;
}
setting |= ((uint32_t)(init->clkSel) << _WDOG_CTRL_CLKSEL_SHIFT) |
((uint32_t)(init->perSel) << _WDOG_CTRL_PERSEL_SHIFT);
/* Wait for any pending previous write operation to have been completed in */
/* low frequency domain */
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
;
WDOG->CTRL = setting;
/* Optional register locking */
if (init->lock)
{
if (init->enable)
{
WDOG_Lock();
}
else
{
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
}
}
}
/***************************************************************************//**
* @brief
* Lock the watchdog configuration.
*
* @details
* This prevents errors from overwriting the watchdog configuration, possibly
* disabling it. Only a reset can unlock the watchdog config, once locked.
*
* If the LFRCO or LFXO clocks are used to clock the watchdog, one should
* consider using the option of inhibiting those clocks to be disabled,
* please see the WDOG_Enable() init structure.
*
* @note
* This function modifies the WDOG CTRL register which requires
* synchronization into the low frequency domain. If this register is modified
* before a previous update to the same register has completed, this function
* will stall until the previous synchronization has completed.
******************************************************************************/
void WDOG_Lock(void)
{
/* Wait for any pending previous write operation to have been completed in */
/* low frequency domain */
while (WDOG->SYNCBUSY & WDOG_SYNCBUSY_CTRL)
;
/* Disable writing to the control register */
BITBAND_Peripheral(&(WDOG->CTRL), _WDOG_CTRL_LOCK_SHIFT, 1);
}
/** @} (end addtogroup WDOG) */
/** @} (end addtogroup EFM32_Library) */

View File

@ -0,0 +1,108 @@
/****************************************************************************************
| Description: bootloader application source file
| File Name: main.c
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "boot.h" /* bootloader generic header */
#include "efm32.h" /* EFM32 registers */
#include "efm32_chip.h" /* EFM32 chip initialization */
#include "efm32_cmu.h" /* EFM32 clock management */
#include "efm32_gpio.h"
/****************************************************************************************
* Function prototypes
****************************************************************************************/
static void Init(void);
/****************************************************************************************
** NAME: main
** PARAMETER: none
** RETURN VALUE: program return code
** DESCRIPTION: This is the entry point for the bootloader application and is called
** by the reset interrupt vector after the C-startup routines executed.
**
****************************************************************************************/
int main(void)
{
/* initialize the microcontroller */
Init();
/* initialize the bootloader */
BootInit();
/* start the infinite program loop */
while (1)
{
/* run the bootloader task */
BootTask();
}
/* program should never get here */
return 0;
} /*** end of main ***/
/****************************************************************************************
** NAME: Init
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Initializes the microcontroller. The interrupts are disabled, the
** clocks are configured and the flash wait states are configured.
**
****************************************************************************************/
static void Init(void)
{
/* initialize the system and its clocks */
SystemInit();
/* handle chip errate workarounds */
CHIP_Init();
/* enable the low frequency crystal oscillator */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
/* turn on clocking of all the modules */
CMU->HFCORECLKEN0 |= 0x0F;
CMU->HFPERCLKEN0 |= 0xFFFF;
/* disable clocking of the modules that are not in use */
CMU_ClockEnable(cmuClock_AES | cmuClock_DMA | cmuClock_EBI | cmuClock_PRS, false);
CMU_ClockEnable(cmuClock_USART0 | cmuClock_USART1 | cmuClock_USART2, false);
CMU_ClockEnable(cmuClock_UART0 | cmuClock_ACMP0 | cmuClock_ACMP1, false);
CMU_ClockEnable(cmuClock_DAC0 | cmuClock_ADC0 | cmuClock_I2C0 | cmuClock_VCMP, false);
#if (BOOT_COM_UART_ENABLE > 0)
/* enable power to U2 (RS232_PWR_E) */
GPIO_PinModeSet(gpioPortB, 9, gpioModePushPullDrive, 1);
/* set port B outputs to drive up to 20 mA */
GPIO_DriveModeSet(gpioPortB, gpioDriveModeHigh);
#endif
} /*** end of Init ***/
/*********************************** end of main.c *************************************/

View File

@ -0,0 +1,693 @@
S02B0000443A2F7573722F6665617365722F736F6674776172652F4F70656E424C542F5461726765742F44657D
S1134000F001002071410000DD480000DD4800009F
S1134010DD480000DD480000DD480000DD48000008
S1134020DD480000DD480000DD480000DD480000F8
S1134030DD480000DD480000DD480000B94800000C
S1134040DD480000DD480000DD480000DD480000D8
S1134050DD480000DD480000DD480000DD480000C8
S1134060DD480000DD480000DD480000DD480000B8
S1134070DD480000DD480000DD480000DD480000A8
S1134080DD480000DD480000DD480000DD48000098
S1134090DD480000DD480000DD480000DD48000088
S11340A0DD480000DD480000DD48000081590000C3
S10F40B0DD480000DD480000EE11AA55B8
S11340BC2E498D462E492F480A1A04D081F30988BB
S11340CC022282F314882C482C492D4A00F039F82A
S11340DC2C482D492D4A00F034F82D482D492E4AF0
S11340EC00F02FF82D482E492E4A00F02AF82E48BD
S11340FC2E492F4A00F025F82E482F492F4A00F05C
S113410C20F82F482F49002200F026F82E482F497A
S113411C091A082903DB00220260043001602048DC
S113412C2049884205D00268043003B4904703BC8C
S113413CF7E700208646EC4600200021244A9047ED
S113414CFEE7884207D0521A05D0037801300B7071
S113415C0131013AF9D17047884202D00270013022
S113416CFAE770471B481C490160A1E7F0010020E5
S113417CF0010020F0010020086B0000000000207A
S113418C08000020E8410000E8410000D06A00006B
S113419C086B00000000002000000020D06A000022
S11341ACD06A0000D06A0000D06A0000D06A000017
S11341BCD06A0000D06A0000D06A0000086B0000CE
S11341CC080000207000002070000020F000002087
S10F41DCB946000008ED00E000400000BF
S11341E880B482B000AF786039607B683A685A63FB
S11341F807F10807BD4680BC704700BF80B581B091
S113420800AF4FF0B9033B603B68984707F10407D8
S1134218BD4680BDB0B586B000AF46F6D023C0F227
S113422800033C461D460FCD0FC495E8030084E8FF
S113423803004FF44240C0F202004FF0010100F0C5
S113424837FE4FF002004FF006014FF004024FF022
S1134258010301F08BF94FF002004FF007014FF012
S113426801024FF0000301F081F94FF40C50C0F241
S113427804004FF0010100F01BFE4FF00300C0F2F0
S113428812004FF0020100F0FDFF4FF4AA50C0F2F3
S113429816004FF0010100F013FD4FF4AA50C0F2CC
S11342A816004FF0010100F003FE4FF000033B60DD
S11342B83B464FF48840C4F20800194601F0C8FA96
S11342C84FF48840C4F208004FF000014FF416522E
S11342D801F03CFA4FF48843C4F208034FF0030298
S11342E85A654FF48840C4F208004FF00401FFF700
S11342F877FF4FF48840C4F208004FF0050101F03D
S113430869FA07F11807BD46B0BD00BF80B500AF14
S113431840F20803C2F200031B78002B17D140F2C5
S11343280C00C2F2000000F055F80346012B50D1EE
S113433840F20803C2F200034FF001021A7040F27F
S11343485003C2F200034FF000021A7041E040F239
S11343585003C2F200031B7803F1010240F20C037C
S1134368C2F20003D318184600F034F80346012BB0
S11343782FD140F25003C2F200031B7803F101036A
S1134388DAB240F25003C2F200031A7040F20C038E
S1134398C2F200031A7840F25003C2F200031B78F9
S11343A89A4216D140F20803C2F200034FF0000209
S11343B81A7040F20C03C2F200035B78FF2B08D199
S11343C840F20C03C2F200039B78002B01D1FFF7E3
S11343D815FF80BD80B581B000AF38604FF48843C5
S11343E8C4F20803DB6A03F00403002B0CD04FF477
S11343F88840C4F2080001F063FA03461A463B6891
S11344081A704FF0010301E04FF00003184607F15A
S11344180407BD4680BD00BF80B400AF62B6BD4688
S113442880BC704780B500AF4FF42040C4F2080048
S113443801F060FC80BD00BF80B581B000AF00F022
S11344482BFA03463B6040F25403C2F200031B6894
S11344583A68D21A40F2F3139A4230D940F2580318
S1134468C2F200031B78002B11D140F25803C2F2A8
S113447800034FF001021A704FF42040C4F2080000
S11344884FF000014FF0010201F0AAFB10E040F2E6
S11344985803C2F200034FF000021A704FF4204090
S11344A8C4F208004FF000014FF0000201F098FB3D
S11344B840F25403C2F200033A681A6000E000BFF5
S11344C807F10407BD4680BD80B584B000AF48F24B
S11344D8FC13C0F6E0731B68FB60FB684FEA1363C8
S11344E8002B1BD14AF20C03C4F20C03BB60BB685B
S11344F81B6823F07002BB681A6046F22003C4F2FA
S11345080C03BB60BB681B6823F06042BB681A607D
S1134518BB681B6863F06062BB681A60FB684FEA9B
S11345281363032B37D846F22003C4F20C03BB6091
S1134538BB681B6823F4FC52BB681A6048F240034A
S1134548C4F20C03BB60BB684FF000021A6048F267
S11345584403C4F20C03BB60BB684FF000021A604A
S113456848F25803C4F20C03BB60BB684FF0000266
S11345781A6048F26003C4F20C03BB60BB684FF0D6
S113458800021A6048F27803C4F20C03BB60BB68EB
S11345984FF000021A603B46184601F0A5F93B7833
S11345A8012B1BD17B78002B0AD148F24003C4F2BB
S11345B80C03BB60BB681B6843F00202BB681A604B
S11345C87B78012B0AD848F24403C4F20C03BB607D
S11345D8BB681B6843F00102BB681A6048F2F01319
S11345E8C0F6E0731B68FB60FA684BF6FF13C4F669
S11345F88A439A4257D848F24403C4F20C03BB6076
S1134608BB681B6843F49042BB681A6048F2B41351
S1134618C0F6E0731B6803F4FE434FEA13234FEA22
S113462803637B6048F2B413C0F6E0731B6803F0BD
S11346387F034FEA03437A6813437B6048F2B41359
S1134648C0F6E0731B6803F4FE437A6813437B6087
S113465848F2B413C0F6E0731B6803F07F037A686A
S113466813437B6042F23403C4F20003BB60BB68AB
S11346787A681A6044F22C03C4F20003BB6048F25F
S1134688C813C0F6E0731B687B60BB687A681A605D
S113469848F24403C4F20C03BB60BB681B6823F4F0
S11346A89042BB681A6007F11007BD4680BD00BF81
S11346B880B500AF00F008F8FFF7ACFDFFF7BCFECB
S11346C8FFF724FEFAE700BF80B500AF00F098F9C1
S11346D8FFF7FAFE4FF000004FF001014FF001021E
S11346E800F09AFE4FF40043C4F20C034FF4004266
S11346F8C4F20C02126C42F00F021A644FF4004325
S1134708C4F20C034FF40042C4F20C02526C6FEA78
S113471812426FEA02425A644FF43340C0F2060070
S11347284FF0000100F0C4FB4FF44850C0F20200FF
S11347384FF0000100F0BCFB4FF47240C0F20200DD
S11347484FF0000100F0B4FB4FF47240C0F20200D5
S11347584FF0000100F0ACFB4FF001004FF00901ED
S11347684FF005024FF0010300F000FF4FF0010085
S11347784FF0020100F0D0FEFFF754FE00F062F89B
S1134788FFF74AFE80BD00BF80B482B000AF7860F6
S113479839607B68002B10DA4FF46D43CEF20003C6
S11347A87A6802F00F02A2F104013A68D2B24FEA21
S11347B84212D2B25B181A760CE04FF46143CEF27F
S11347C8000379683A68D2B24FEA4212D2B25B184F
S11347D883F8002307F10807BD4680BC704700BF73
S11347E880B581B000AF38603A686FF07F439A4271
S11347F802D94FF001031FE04EF21003CEF200037A
S11348083A6822F07F4202F1FF325A604FF0FF30DB
S11348184FF00701FFF7B8FF4EF21003CEF2000382
S11348284FF000029A604EF21003CEF200034FF0EC
S113483807021A604FF00003184607F10407BD4643
S113484880BD00BF80B500AF4FF02000C0F2040067
S113485800F092FB024644F6D353C1F26203A3FB71
S113486802134FEA93131846FFF7BAFF4FF00000FC
S113487800F002F880BD00BF80B481B000AF38609A
S113488840F25C03C2F200033A681A6007F10407B5
S1134898BD4680BC704700BF80B400AF40F25C03E3
S11348A8C2F200031B681846BD4680BC704700BFAF
S11348B880B400AF40F25C03C2F200031B6803F14A
S11348C8010240F25C03C2F200031A60BD4680BCD8
S11348D8704700BF80B400AFFEE700BF80B581B069
S11348E800AF00F019F803463B604FF40043C4F2EC
S11348F80C035B6803F00F033A6822FA03F33B6086
S113490840F26003C2F200033A681A603B68184632
S113491807F10407BD4680BD80B481B000AF4FF4F1
S11349280043C4F20C03DB6A03F47053B3F5805FED
S11349380DD0B3F5005F03D0B3F5006F0BD011E0D1
S113494840F20403C2F200031B683B6050E04FF4DA
S113495800433B604CE040F20003C2F200031B68D2
S11349683B6045E04FF40043C4F20C03DB6803F4F6
S1134978E063B3F5007F24D0B3F5007F05D8002B9E
S11349882BD0B3F5807F22D02DE0B3F5806F0CD007
S1134998B3F5A06F03D0B3F5407F0CD023E04FF4F8
S11349A87C53C0F2AB133B6021E046F64073C0F27F
S11349B840133B601BE049F68073C0F2D5033B60AB
S11349C815E04DF6C003C0F2A7033B600FE04CF6B8
S11349D8C073C0F26A033B6009E044F24023C0F2AA
S11349E80F033B6003E04FF000033B6000BF00BFD0
S11349F83B68184607F10407BD4680BC704700BFF2
S1134A0880B400AFBD4680BC704700BF80B400AF1F
S1134A184FF400431846BD4680BC704780B400AFCD
S1134A2840F20403C2F200031B681846BD4680BC6A
S1134A38704700BF80B484B000AFB86079603A6052
S1134A48BB6803F104734FEAC3027B68D3184FEAC7
S1134A588303FB60FB683A681A6007F11007BD46D8
S1134A6880BC704780B481B000AF4FF00003C4F23B
S1134A780C035B683B603B6803F00703032B19D8FE
S1134A8801A252F823F000BFA14A0000A14A000085
S1134A98AF4A0000AF4A00003B6823F0070343F025
S1134AA801033B6006E03B6823F0070343F003037C
S1134AB83B6000BF4FF00003C4F20C033A685A602D
S1134AC807F10407BD4680BC704700BF90B484B0AA
S1134AD800AF38603B68BB60BB68B3FA83F4FC7111
S1134AE8FB79C3F11F03FB60FB68184607F1100745
S1134AF8BD4690BC704700BF80B482B000AF386038
S1134B084FF00003C4F20C035B687B603A684FF40F
S1134B181053C0F2F4039A421BD93A684FF49043F5
S1134B28C0F2E8139A4214D87B6803F00703A3F190
S1134B380203012B06D87B6823F0070343F0030321
S1134B487B6006E07B6823F0070343F001037B6086
S1134B5800BF3A684FF41053C0F2F4039A4212D8D3
S1134B687B6803F00703A3F10203012B06D87B68D3
S1134B7823F0070343F002037B6004E07B6823F01F
S1134B8807037B6000BF4FF00003C4F20C037A688C
S1134B985A6007F10807BD4680BC704780B481B0ED
S1134BA800AF49F68073C0F2D5033B603B681846F2
S1134BB807F10407BD4680BC704700BF80B582B0CA
S1134BC800AF4FF00400C0F2180000F0D1FA034619
S1134BD83B603B68072B06D0082B09D1FFF79CFEE6
S1134BE803467B6008E0FFF7D9FF03467B6003E0D8
S1134BF84FF000037B6000BF7B68184607F1080785
S1134C08BD4680BD80B582B000AF38604FF4004324
S1134C18C4F20C039A6A3B684FEA430322FA03F38B
S1134C2803F00303032B20D801A252F823F000BF9A
S1134C386B4C0000494C0000534C00005D4C0000D4
S1134C48FFF7E4FE03467B6013E0FFF7E7FE034645
S1134C587B600EE0FFF742FE03464FEA53037B6096
S1134C6807E04FF000037B6003E04FF000037B6034
S1134C7800BF7B68184607F10807BD4680BD00BF22
S1134C8880B481B000AF38604FF40043C4F20C0321
S1134C985B6D03F00103DBB2002B0AD100BF4FF4B4
S1134CA80043C4F20C031A6D3B681340002BF6D181
S1134CB800E000BF07F10407BD4680BC704700BF91
S1134CC880B584B000AF786039607B684FEA13130D
S1134CD803F00F03FB60FB6803F1FF33032B00F2BF
S1134CE8E18001A252F823F0014D0000294D000093
S1134CF8634D0000294E00003868FFF7E7FE0346BD
S1134D083B604FF40043C4F20C034FF40042C4F276
S1134D180C02926822F00F013A680A439A60C2E0D2
S1134D28FFF7A0FE3868FFF7D1FE03463B604FF457
S1134D380043C4F20C034FF40042C4F20C0252685C
S1134D4822F00F013A680A435A60FFF7C7FD034689
S1134D58BB60B868FFF7D0FEA5E07A6841F230433B
S1134D68C0F20A039A4223D04FF03003C0F20C0376
S1134D789A4237D04FF48663C0F208039A424DD161
S1134D884FF00400FFF77CFF3868FFF79FFE0346E7
S1134D983B604FF40043C4F20C034FF40042C4F2E6
S1134DA80C02926E22F00F013A680A439A6636E0C2
S1134DB84FF00400FFF764FF3868FFF787FE0346E7
S1134DC83B604FF40043C4F20C034FF40042C4F2B6
S1134DD80C02926E22F0F0013A684FEA02120A437A
S1134DE89A661CE04FF00400FFF74AFF3868FFF7A3
S1134DF86DFE03463B604FF40043C4F20C034FF4CA
S1134E080042C4F20C02926E22F440713A68A2F194
S1134E1810024FEA02220A439A6600E000BF42E009
S1134E287A684FF4A863C0F214039A4206D04FF488
S1134E38AA53C0F216039A4218D031E04FF040004A
S1134E48FFF71EFF3868FFF741FE03463B604FF447
S1134E580043C4F20C034FF40042C4F20C02126F74
S1134E6822F003013A680A431A671AE04FF0400037
S1134E78FFF706FF3868FFF729FE03463B604FF447
S1134E880043C4F20C034FF40042C4F20C02126F44
S1134E9822F030013A684FEA02120A431A6700E026
S1134EA800BF00E000BF07F11007BD4680BD00BF8A
S1134EB880B585B000AF78600B463B704FF00003B7
S1134EC8FB607B684FEA132303F00F0303F1FF33FE
S1134ED8052B4CD801A252F823F000BFFD4E000068
S1134EE8094F0000154F0000214F0000334F000008
S1134EF8454F000048F20803C4F20C033B6123E069
S1134F0848F24403C4F20C033B611DE048F2400339
S1134F18C4F20C033B6117E048F25803C4F20C03D3
S1134F283B614FF00103FB600EE048F26003C4F2FA
S1134F380C033B614FF01003FB6005E048F2780373
S1134F48C4F20C033B6100BF7B684FEA133303F0E0
S1134F581F03BB60FB68002B02D0F868FFF790FEC4
S1134F683B783869B9681A46FFF764FD00E000BF6A
S1134F7807F11407BD4680BD80B582B000AF386024
S1134F883B6803F47813B3F5402F7BD0B3F5402F77
S1134F9815D8B3F5802F43D0B3F5802F05D8002B4F
S1134FA829D0B3F5003F2BD0D8E0B3F5002F43D078
S1134FB8B3F5202F52D0B3F5C02F36D0CEE0B3F5D9
S1134FC8A01F00F09B80B3F5A01F07D8B3F5602F8E
S1134FD86CD0B3F5901F00F08A80BFE0B3F5C01F12
S1134FE800F0B280B3F5D01F00F0B380B3F5B01F62
S1134FF800F09680B2E0FFF78FFC03467B60B1E0D7
S1135008FFF78AFC03467B604FF40043C4F20C03A9
S11350189B6803F00F037A6822FA03F37B60A1E02C
S1135028FFF75CFC03467B609CE04FF00000FFF751
S1135038E9FD03467B6095E04FF00000FFF7E2FDD1
S113504803467B604FF40043C4F20C039B6E03F0E9
S11350580F037A6822FA03F37B6083E04FF00000C1
S1135068FFF7D0FD03467B604FF40043C4F20C0302
S11350789B6E03F0F0034FEA13137A6822FA03F3E2
S11350887B606FE04FF00000FFF7BCFD03467B60D8
S11350984FF40043C4F20C039B6E03F440734FEACD
S11350A813237A6822FA03F37B605BE04FF0000075
S11350B8FFF7A8FD03467B604FF40043C4F20C03DA
S11350C89B6E03F440734FEA13237A6822FA03F3BE
S11350D87B604FF40043C4F20C03DB6F03F0070357
S11350E803F101037A68B2FBF3F37B603AE04FF013
S11350F80100FFF787FD03467B6033E04FF00100B2
S1135108FFF780FD03467B604FF40043C4F20C03B1
S11351181B6F03F003037A6822FA03F37B6021E030
S11351284FF00100FFF76EFD03467B604FF4004328
S1135138C4F20C031B6F03F030034FEA13137A68AD
S113514822FA03F37B600DE0FFF738FD03467B602A
S113515808E0FFF723FD03467B6003E04FF00003FC
S11351687B6000BF7B68184607F10807BD4680BD11
S113517880B483B000AF38604FF00103BB603B6874
S113518803F00F037B607B6803F1FF33032B6DD8B7
S113519801A252F823F000BFB1510000F5510000FC
S11351A8315200006D5200004FF40043C4F20C0366
S11351B8DB6A03F47053B3F5805F0AD0B3F5005F7C
S11351C803D0B3F5006F08D00BE04FF00203BB60C7
S11351D80BE04FF00303BB6007E04FF00403BB6030
S11351E803E04FF00503BB6000BF43E04FF4004306
S11351F8C4F20C039B6A03F00303022B07D0032BAE
S113520809D0012B0BD14FF00303BB600BE04FF027
S11352180203BB6007E04FF00603BB6003E04FF0F6
S11352280103BB6000BF25E04FF40043C4F20C0344
S11352389B6A03F00C03022B07D0032B09D0012B24
S11352480BD14FF00303BB600BE04FF00203BB60CC
S113525807E04FF00603BB6003E04FF00103BB60B7
S113526800BF07E04FF00703BB6003E04FF0000303
S1135278BB6000BFBB68184607F10C07BD4680BC7D
S1135288704700BF80B588B000AF786039604FF0D0
S11352980303FB614FF00303BB617B6803F00F0357
S11352A8FB60FB68012B06D0012BC0F0AB80032BFD
S11352B800F2A88045E03B68A3F10203032B00F247
S11352C8A38001A252F823F0E1520000EF5200003B
S11352D8FD5200000B5300004FF00403FB614FF034
S11352E80003BB6114E04FF00303FB614FF00103BB
S11352F8BB610DE04FF00203FB614FF00203BB6199
S113530806E04FF00103FB614FF00303BB6100BFEC
S1135318B8694FF001014FF0010200F07DF8FFF782
S1135328A1FB4FF40043C4F20C03FA695A6200F07B
S1135338E3F8FFF7D3FA0346BB60B868FFF7DCFB72
S113534865E0FB68022B03D14FF000037B6102E0A8
S11353584FF002037B613B6803F1FF33052B55D8FB
S113536801A252F823F000BF8953000091530000B2
S1135378A95300001554000015540000C15300003F
S11353884FF000033B6125E04FF000004FF00101AE
S11353984FF0010200F040F84FF002033B6119E0BE
S11353A84FF001004FF001014FF0010200F034F812
S11353B84FF001033B610DE048F24000C4F20C00D9
S11353C84FF002014FF00102FFF734FB4FF00303E3
S11353D83B6100BF4FF40043C4F20C034FF4004296
S11353E8C4F20C02916A7A694FF0030000FA02F2DF
S11353F86FEA020211407A69386900FA02F20A4334
S11354089A6204E000BF02E000BF00E000BF07F1B9
S11354182007BD4680BD00BF80B586B000AFB86028
S113542813460A463A713B70BB68042B5ED801A246
S113543852F823F0A15400008D5400006554000074
S113544851540000795400004FF001033B614FF0C0
S11354580203FB604FF002037B6127E04FF0040373
S11354683B614FF00803FB604FF008037B611DE0CC
S11354784FF010033B614FF02003FB604FF0200313
S11354887B6113E04FF040033B614FF08003FB6006
S11354984FF080037B6109E04FF480733B614FF464
S11354A80073FB604FF400737B6100BF3B79002BF2
S11354B813D04FF40043C4F20C033A691A623B78E0
S11354C8002B10D000BF4FF40043C4F20C03DA6A77
S11354D87B691340002BF6D005E04FF40043C4F277
S11354E80C03FA681A6200F007F800E000BF07F13D
S11354F81807BD4680BD00BF80B400AF4FF4004319
S1135508C4F20C03DB6A9AB240F26403C2F20003E9
S11355181A80BD4680BC704780B482B000AF786002
S113552839604FF4C042C4F200024FF4C041C4F2DF
S11355380001786803464FEAC3031B184FEA830344
S1135548CB181B6823F003013B6841EA0300796820
S11355580B464FEAC3035B184FEA8303D31818605A
S113556807F10807BD4680BC704700BF80B484B00B
S113557800AFF860B9607A603B607B68002B2DD07F
S11355883B68002B15D04FF4C042C4F20002BB683C
S11355984FF0010101FA03F31846F9680B464FEA84
S11355A8C3035B184FEA8303D31803F1100318608D
S11355B814E04FF4C042C4F20002BB684FF001018A
S11355C801FA03F31846F9680B464FEAC3035B185C
S11355D84FEA8303D31803F114031860BB68072B3D
S11355E830D84FF4C042C4F200024FF4C041C4F2B0
S11355F80001F86803464FEAC3031B184FEA830304
S1135608CB1803F104031968BB684FEA83034FF00E
S11356180F0000FA03F36FEA03031940BB684FEA6B
S11356288303786800FA03F341EA0300F9680B4638
S11356384FEAC3035B184FEA8303D31803F1040347
S1135648186033E04FF4C042C4F200024FF4C04182
S1135658C4F20001F86803464FEAC3031B184FEA73
S11356688303CB1803F108031968BB684FEA830363
S1135678A3F120034FF00F0000FA03F36FEA0303CA
S11356881940BB684FEA8303A3F12003786800FA42
S113569803F341EA0300F9680B464FEAC3035B18B6
S11356A84FEA8303D31803F1080318607B68002BBF
S11356B82DD13B68002B15D04FF4C042C4F2000230
S11356C8BB684FF0010101FA03F31846F9680B4669
S11356D84FEAC3035B184FEA8303D31803F110039B
S11356E8186014E04FF4C042C4F20002BB684FF0E3
S11356F8010101FA03F31846F9680B464FEAC3039C
S11357085B184FEA8303D31803F11403186007F1F5
S11357181007BD4680BC704780B482B000AF786083
S113572839607B681B6C03F00103DBB2002B07D1E3
S113573800BF7B685A6C3B681340002BF9D100E02A
S113574800BF07F10807BD4680BC704780B585B027
S113575800AFB86079603A607B68002B1DD1BA68E5
S11357684FF48043C4F208039A4205D14FF4A86366
S1135778C0F214033B610BE0BA684FF48843C4F2E7
S113578808039A4221D14FF4AA53C0F216033B618D
S11357983869FFF7F1FB03467B607B684FEA4312E5
S11357A83B68B2FBF3F3FB60FB68A3F12003FB60E7
S11357B8FB684FEAC303FB60B8684FF00401FFF7C6
S11357C8ABFFBB68FA68DA6000E000BF07F11407B2
S11357D8BD4680BD80B583B000AF786039603B6852
S11357E86FEA0303BB60BB6803F00503BB60BB68D7
S11357F84FEA4303BB60BA683B681343BB607868ED
S11358084FF00201FFF788FF7B68BA685A6007F116
S11358180C07BD4680BD00BF80B482B000AF78607D
S11358280B463B703B78002B09D000BF7B685B6C50
S1135838002BFBD17B684FF001021A6403E07B68FC
S11358484FF000021A6407F10807BD4680BC704790
S113585880B582B000AF7860396078684FF0020193
S1135868FFF75AFF7B684FF00A025A6078684FF0D6
S11358780101FFF7D1FF7B681B6823F01C023B681A
S1135888DB681A433B681B691A433B685B691A4324
S11358987B681A603B685A683B689B68786811465D
S11358A81A46FFF753FF3B681A687B685A607868A2
S11358B84FF00001FFF7B0FF07F10807BD4680BDB0
S11358C880B481B000AF386000BF3B689B6803F0C8
S11358D82003002BF9D03B68DB69DBB2184607F1DB
S11358E80407BD4680BC704780B482B000AF3860FE
S11358F84FF6D073CEF20F031B69DBB203F03F03FC
S1135908DAB23B681A704FF6D073CEF20F039B6974
S1135918DBB223F00F03FB714FF6D073CEF20F0303
S1135928DB6903F0F0034FEA1313DAB2FB7913438C
S1135938FB713B68FA795A7007F10807BD4680BCC9
S1135948704700BF80B481B000AF38604FF4614342
S1135958CEF200033A684FEA5212396801F01F0187
S11359684FF0010000FA01F143F8221007F104078F
S1135978BD4680BC704700BF80B481B000AF4FF40F
S11359882043C4F208033B603B684FF0FF325A627D
S113599840F26803C2F200031B6803F1010240F2FB
S11359A86803C2F200031A6007F10407BD4680BC0D
S11359B8704700BF80B483B000AFB86079603A60C4
S11359C83B681F2B07DD3B68A3F120033B607B6822
S11359D803F104037B604FF001023B6802FA03F30E
S11359E83B607B68072B4BD801A252F823F000BF19
S11359F8195A0000275A0000355A0000435A00007B
S1135A08515A00005F5A00006D5A00007B5A00008A
S1135A18BB681A6C3B681A43BB681A6430E0BB68FD
S1135A285A6C3B681A43BB685A6429E0BB689A6C91
S1135A383B681A43BB689A6422E0BB68DA6C3B682B
S1135A481A43BB68DA641BE0BB681A6D3B681A43E7
S1135A58BB681A6514E0BB685A6D3B681A43BB6897
S1135A685A650DE0BB689A6D3B681A43BB689A6532
S1135A7806E0BB68DA6D3B681A43BB68DA6500BFA9
S1135A8807F10C07BD4680BC704700BF80B483B0E3
S1135A9800AFB86079603A603B681F2B07DD3B684C
S1135AA8A3F120033B607B6803F104037B604FF0A0
S1135AB801023B6802FA03F33B607B68072B5BD85F
S1135AC801A252F823F000BFF15A0000035B000062
S1135AD8155B0000275B0000395B00004B5B00008E
S1135AE85D5B00006F5B0000BB681A6C3B686FEA83
S1135AF803031A40BB681A643EE0BB685A6C3B68EF
S1135B086FEA03031A40BB685A6435E0BB689A6CB1
S1135B183B686FEA03031A40BB689A642CE0BB68CD
S1135B28DA6C3B686FEA03031A40BB68DA6423E063
S1135B38BB681A6D3B686FEA03031A40BB681A65B1
S1135B481AE0BB685A6D3B686FEA03031A40BB68E6
S1135B585A6511E0BB689A6D3B686FEA03031A4003
S1135B68BB689A6508E0BB68DA6D3B686FEA0303B3
S1135B781A40BB68DA6500BF07F10C07BD4680BC54
S1135B88704700BF80B481B000AF38603B684FF005
S1135B9800021A643B684FF000021A653B684FF034
S1135BA800025A643B684FF000025A653B684FF0A4
S1135BB800029A643B684FF000029A653B684FF014
S1135BC80002DA643B684FF00002DA6500BF3B6804
S1135BD85B6E002BFBD107F10407BD4680BC704700
S1135BE880B585B000AFB86079603A607B680B2BEC
S1135BF86ED801A252F823F0315C00003F5C00002B
S1135C084D5C00005B5C0000695C0000775C000090
S1135C18855C0000935C0000A15C0000AF5C0000A0
S1135C28BD5C0000CB5C00004FF003033B614FF008
S1135C380F03FB604CE04FF001033B614FF003039B
S1135C48FB6045E04FF003033B614FF00303FB6047
S1135C583EE04FF000033B614FF00303FB6037E085
S1135C684FF002033B614FF00303FB6030E04FF059
S1135C7800033B614FF02703FB6029E04FF0030367
S1135C883B614FF02703FB6022E04FF003033B61C5
S1135C984FF00103FB601BE04FF002033B614FF040
S1135CA80103FB6014E04FF001033B614FF0010373
S1135CB8FB600DE04FF001033B614FF00103FB6013
S1135CC806E04FF003033B614FF00703FB6000BF9E
S1135CD83B68002B05D0B8683969FA68FFF76AFE93
S1135CE804E0B8683969FA68FFF7D0FE07F11407C9
S1135CF8BD4680BD80B582B000AF38604FF4004324
S1135D08C4F20C037B607B689B6A23F003027B6804
S1135D189A627B689B6A43F002027B689A627B689A
S1135D289B6D43F004027B689A657B689B6E23F441
S1135D3840727B689A667B689B6E43F440727B680A
S1135D489A663B684FF000029A6200BF3B685B6E3C
S1135D58002BFBD13B684FF0FF325A624FF01B0017
S1135D68FFF7F0FD3B684FF001029A623B6841F689
S1135D780B725A607B684FF00002DA673868FFF7E5
S1135D8801FF3B6840F2FF329A603B684FF005021E
S1135D981A6000BF3B685B6E002BFBD13A684FF476
S1135DA88073C0F21C03D36000BF3B685B6E002B9A
S1135DB8FBD13B684FF001025A623B684FF0010285
S1135DC89A6207F10807BD4680BD00BF00B50346C7
S1135DD802783AB14268107840B102F101025A607F
S1135DE85DF804FB436898475DF804FB4FF0FF3007
S1135DF85DF804FB30B50446C8B2A16849B123680C
S1135E08626803F10105954208BF0020934238BF38
S1135E18C854E3682BB121686268914201D22146D3
S1135E289847236803F10103236030BDF0B5154694
S1135E3801290BD40E464FF00004C7B22846394650
S1135E48FFF7D8FF04F10104B442F7D1F0BD00BF55
S1135E5800B510F0100F07D100F4007000280CBF33
S1135E6820203020FFF7E2FF5DF804FBA0F1410099
S1135E7819288CBF00200120704700BFA0F16100E1
S1135E8819288CBF00200120704700BFA0F1300002
S1135E9809288CBF00200120704700BF30B5044694
S1135EA80D46FFF7F3FF10B1A4F130000FE02046D0
S1135EB8FFF7E4FF10B1A4F1570008E02046FFF70C
S1135EC8D5FF10B1A4F1370001E04FF0FF30A8422C
S1135ED8A8BF4FF0FF3030BDA0F10903202814BF3C
S1135EE800200120042B98BF40F00100704700BF38
S1135EF800F1010110F0030F11D010F8012B002A52
S1135F0823D010F0030F0AD010F8012B002A1CD05C
S1135F1810F0030F03D010F8012B002A15D02DE937
S1135F2870004FF001324FF0803350F8044BA4EB6B
S1135F38020525EA04051D4000D1F6E7A0F1040096
S1135F4870BC10F8012B002AFBD1A0EB01007047AC
S1135F582DE9F04F87B007460C4603924FF0000333
S1135F68036046F6E82BC0F2000B46F6F823C0F2AD
S1135F7800030293C1E204F10104252904BF234666
S1135F88002603D03846FFF735FFB6E2194613F862
S1135F98010B1C46A0F12002102A1CD8DFE802F0ED
S1135FA8091B1B0C1B1B1B0F1B1B1B121B151B1B71
S1135FB8180046F04006E9E746F08006E6E746F4AE
S1135FC80046E3E746F02006E0E746F01006DDE782
S1135FD846F40076DAE72A2808D0A0F13002D2B2D3
S1135FE8092A88BF4FF0000A11D920E0039B03F166
S1135FF804000390D3F800A0BAF1000FBCBFCAF1A3
S1136008000A46F01006487801F102040FE04FF048
S1136018000A0AEB8A0AA0F1300000EB4A0A13F8D6
S1136028010B1C46A0F13002D2B2092AF1D92AEA9E
S1136038EA7A2E2818BF4FF000082DD120782A2894
S11360480AD004F10104A0F13003DBB2092B88BFA4
S11360584FF000080AD91DE0039B03F104020392E0
S1136068D3F80080607804F1020410E023464FF06E
S1136078000808EB8808A0F1300000EB480813F882
S1136088010B1C46A0F13002D2B2092AF1D9B8F1A9
S1136098000F01DB46F4807668280AD12078682846
S11360A803BF46F0080660780234013418BF46F08E
S11360B8040678287AD8DFE810F02E0279007900EF
S11360C879007900790079007900790079007900FC
S11360D879007900790079007900790079007900EC
S11360E879007900790079007900790079007900DC
S11360F879007900790079007900790079007900CC
S1136108790079008A0079007900790079007900AA
S113611879007900790079007900790079007900AB
S1136128790079007900790079007900790079009B
S1136138790079007900790079007900790079008B
S1136148790079007900790079007900790079007B
S1136158790079007900790079007900790079006B
S113616879007900790079007900EE0079007900E6
S1136178790079007900790079007900790079004B
S113618890001A0179007900790079001A017900E0
S1136198790079007900AB000201DB00790079000D
S11361A8B7007900110179007900F00040F26C031E
S11361B8C2F200031D68002D00F09F81CDF8008015
S11361C803AB0193394632465346A84795E138460E
S11361D84FF02501FFF70EFE8FE1039B03F1040244
S11361E803921D780AF1FF3A304651463A46FFF7C2
S11361F82FFE38462946FFF7FDFD16F0100F00F074
S11362087C814FF0200051463A46FFF70FFE74E1B7
S113621816F0080F039B03F1040203921B683A6803
S113622814BF1A701A6068E1039B03F10402039215
S1136238D3F800904846FFF75BFE05468045ACBF9F
S11362480023012303EA1623002B18BF4546C5EB98
S11362580A0A304651463A46FFF7FAFD002DCCD0DB
S113626819F8011B3846FFF7C5FD013DF8D1C4E70D
S1136278039B03F1040203921B6806F08009B9F139
S1136288000F14BF4FF023094FF0000946F480763D
S11362984FF0080869E046F4005643F2780343F2E5
S11362A85809782808BF994616F0800F08BF4FF0A0
S11362B8000916F4807F18BF26F400761EE006F065
S11362C88009B9F1000F14BF4FF030094FF00009ED
S11362D816F4807F18BF26F400760FE016F4807F4A
S11362E81CBF26F400764FF0000907D104E046F4F9
S11362F880464FF0000901E04FF0000916F4804F82
S11363081DD0039B03F1040203921B6816F0040FCB
S113631818BF1BB203D116F0080F18BFDBB2002B4D
S1136328BCBF5B424FF02D091ADB06F04002002A7D
S113633818BF4FF0200916F0200F11D00EE0039B70
S113634803F1040203921B6816F0040F18BF9BB2F2
S113635806D116F0080F18BFDBB201E04FF02B0985
S113636816F4807F04D026F4007616F4807F01D1D9
S11363784FF00108A0F15800202870D8DFE800F099
S1136388196F6F6F6F6F6F6F6F6F6F6F156F6F6FC1
S11363986F156F6F6F6F6F11196F6F6F6F156F6F69
S11363A819004FF000050BBB5BE04FF0000553BB31
S11363B857E04FF00005002B53D04FF0000506F4CA
S11363C80052DDF808E032B103F00F011EF80100B5
S11363D804A9685405E003F00F011BF8010004A99F
S11363E8685405F101051B09EDD13AE04FF00005A9
S11363F803F0070101F1300104AAA95405F10105CC
S1136408DB08F5D12DE04FF0000506F4004C4CF6FE
S1136418CD4ECCF6CC4E6246A446144654B105F093
S11364280302032A01BF07A842192C2102F80C1CF5
S113643808BF013507AA5119AEFB03024FEAD2027D
S113644802EB8200A3EB400303F1300301F80C3C98
S113645805F101051346002AE0D1644601E04FF036
S11364680005C5EB080828EAE878C8EB0A0AC5EB72
S11364780A0AB9F1FF0F88BF0AF1FF3AB9F1000F10
S113648801D00AF1FF3A16F4007F06D1304651468E
S11364983A46FFF7DDFC4FF0000AB9F1FF0F04D9C3
S11364A8C9F307213846FFF7A5FCB9F1000F04D05A
S11364B85FFA89F13846FFF79DFC304651463A4663
S11364C8FFF7C6FC4FF0300041463A46FFF7AEFCF2
S11364D8012D09D40DF11008454415F8011D38465D
S11364E8FFF788FC4545F8D116F0100F05D04FF09A
S11364F8200051463A46FFF799FC217800297FF499
S11365083AADBB682BB13A6879688A423CBF00212E
S11365189954386801E04FF0FF3007B0BDE8F08FB8
S113652810B504460B783BB1B0F1FF3F06D04B6879
S113653803F1FF334B6001E08B689847204610BD98
S11365482DE9F04F82468B4617469846099E4FF030
S1136558FF3900E0A94609F101055046FFF736FC6A
S11365680446FFF7B9FC0028F4D12346B4F1FF3FF1
S113657808BF4FF0FF3500F09C8027F4C067002E59
S11365884EDD17F0800F0DD02B2C03D02D2C09D104
S113659847F4806709F102055046FFF717FC0446E3
S11365A806F1FF36302C14BF00230123002ED4BF7C
S11365B8002303F00103002B32D047F4007706F1DF
S11365C8FF3605F101095046FFF700FC0446002E8A
S11365D820DD582814BF00230123782808BF43F07E
S11365E80103BBB1B8F1100F14BF00230123B8F1A4
S11365F8000F08BF43F0010363B127F4007706F1E5
S1136608FF3605F102095046FFF7E0FB04464FF058
S1136618100851E0B8F1000F08BF4FF008084BE02C
S1136628B8F1000F08BF4FF00A08002ED8BF4FF08A
S113663800090EDC15E047F4007706F1FF3608FB85
S1136648090905F101055046FFF7C0FB044616B9D0
S113665807E04FF0000920464146FFF71FFC0028D9
S1136668E9DA20465146FFF75BFF17F4007F08BFBD
S11366786FF001051DD017F0010F1AD1DBF80030B7
S113668803F10402CBF800201B6807F49062B2F50A
S1136698906F08BFC9F1000917F0100F18BF83F8ED
S11366A8009006D117F0080F14BFA3F80090C3F8A0
S11366B800902846BDE8F08F4D46B6E72DE9F04F27
S11366C885B001908A4604924FF0000BCDF808B0CB
S11366D84CF6CC49C0F6CC49544614F8015B002D5D
S11366E800F0DE81252D3BD02846FFF7F5FB08B9DD
S11366F818E02C4604F101052078FFF7EDFB00288B
S1136708F7D101E00BF1010B0198FFF75FFB054698
S1136718FFF7E2FB0028F5D128460199FFF700FFAF
S1136728A246D9E70198FFF751FB0646A84203D1D0
S11367380BF1010BA246CFE70199FFF7F1FE029A8C
S1136748D2F1010338BF0023B6F1FF3F14BF00267E
S113675803F00106002E18BF4FF0FF3202929FE1AA
S11367689AF801302A2B06BF0AF102044FF00108F7
S11367784FF000084FF000050CE04D4500F3908100
S113678805EB8505A6F1300616EB450500F1888171
S113679848F02008274604F101043E78A246304612
S11367A8FFF774FB0028E8D1414608F02002002ACC
S11367B808BF6FF000454C2E05D17E7807F1020A18
S11367C848F044080EE0682E0CD17E78682E03BF8A
S11367D848F01008BE7807F1030A07F1020A18BF47
S11367E841F00808A6F12506532E00F25981DFE886
S11367F816F0540057015701570157015701570123
S113680857015701570157015701570157015701BC
S113681857015701570157015701570157015701AC
S1136828570157015701570157015701570157019C
S1136838570157015701570157015701570157018C
S1136848570157015701570157015701570157017C
S11368585701570157015701330157015701570190
S11368685701570157015701570157015701700044
S11368789F005701570157015701AA0057015701B3
S113688857015701B500CD00D80057015701E3005F
S1136898570128015701570133010198FFF796FA68
S11368A80446252802D10BF1010B15E70199FFF7DE
S11368B837FE029A131C18BF0123B4F1FF3F0CBF23
S11368C81C4643F00104002C08BF4FF0FF3202922B
S11368D8E6E008F02003002B08BF012518F00104A6
S11368E801BF049B1A1D04921E6818BF0026002DC0
S11368F800F0D680002D13DD0198FFF767FAB0F198
S1136908FF3F06D1029B002B08BF4FF0FF330293D1
S1136918C6E00CB906F8010B0BF1010B013DEBD1F4
S1136928002C7FF4D9AE029B03F101030293D3E652
S113693848F080020095019804A94FF00A03FFF774
S1136948FFFD044692E048F080020095019804A9EE
S11369584FF00003FFF7F4FD044687E018F0010F39
S11369687FF4BAAE049B03F1040204921B6818F086
S1136978100F18BF83F800B07FF4AEAE18F0080FFC
S113698814BFA3F800B0C3F800B0A5E648F080022D
S11369980095019804A94FF00803FFF7D1FD0446B8
S11369A864E028F01E020095019804A94FF0100332
S11369B8FFF7C6FD044659E04FF0FF3404F1010423
S11369C80198FFF703FA0646FFF786FA0028F5D17F
S11369D8B6F1FF3F08BF4FF0FF3447D018F0010766
S11369E801BF049B1A1D04921B680EBF0393002267
S11369F80392002D16DC1AE005F1FF351FB9039B3D
S1136A0803F8016B039304F101040198FFF7DEF91D
S1136A180646431C18BF0123002DD4BF002303F0EE
S1136A28010323B13046FFF757FA0028E4D0304673
S1136A380199FFF775FDCFB94FF00002039B1A7057
S1136A4814E048F080020095019804A94FF00A0365
S1136A58FFF776FD044609E048F0800200950198A6
S1136A6804A94FF01003FFF76BFD0446002C0FDA5E
S1136A78029A131C18BF0123B4F1FF3F0CBF1C4634
S1136A8843F00104002C08BF4FF0FF32029207E0E4
S1136A9818F0010F02BF029B01330293A3441BE6C3
S1136AA8029805B0BDE8F08F00B503B400F008F80B
S1136AB803BC02B4694609BE00F004F801BC00BD79
S10B6AC8704700BF704700BFD6
S1136AD00500000000000000802500000000000008
S1136AE00000000000000000303132333435363706
S1136AF03839616263646566303132333435363730
S10B6B00383941424344454683
S10B6B080048E80100800000D0
S90341714A

View File

@ -0,0 +1,181 @@
/****************************************************************************************
| Description: demo program bootloader interface source file
| File Name: boot.c
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "header.h" /* generic header */
/****************************************************************************************
** NAME: BootActivate
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Bootloader activation function.
**
****************************************************************************************/
static void BootActivate(void)
{
void (*pEntryFromProgFnc)(void);
/* set pointer to the address of function EntryFromProg in the bootloader. note that
* 1 is added to this address to enable a switch from Thumb2 to Thumb mode
*/
pEntryFromProgFnc = (void*)0x000000B8 + 1;
/* call EntryFromProg to activate the bootloader. */
pEntryFromProgFnc();
} /*** end of BootActivate ***/
#if (BOOT_COM_UART_ENABLE > 0)
/****************************************************************************************
* U N I V E R S A L A S Y N C H R O N O U S R X T X I N T E R F A C E
****************************************************************************************/
/****************************************************************************************
* Function prototypes
****************************************************************************************/
static unsigned char UartReceiveByte(unsigned char *data);
/****************************************************************************************
** NAME: BootComInit
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Initializes the UART communication interface
**
****************************************************************************************/
void BootComInit(void)
{
LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
/* configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true);
/* to avoid false start, configure output as high */
GPIO_PinModeSet(gpioPortC, 6, gpioModePushPull, 1);
GPIO_PinModeSet(gpioPortC, 7, gpioModeInput, 0);
/* enable CORE LE clock in order to access LE modules */
CMU_ClockEnable(cmuClock_CORELE, true);
/* select LFXO for LEUARTs (and wait for it to stabilize) */
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
/* do not prescale clock */
CMU_ClockDivSet(cmuClock_LEUART1, cmuClkDiv_1);
/* enable LEUART1 clock */
CMU_ClockEnable(cmuClock_LEUART1, true);
/* configure LEUART */
init.enable = leuartDisable;
LEUART_Init(LEUART1, &init);
LEUART_BaudrateSet(LEUART1, 0, BOOT_COM_UART_BAUDRATE);
/* enable pins at default location */
LEUART1->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN;
/* clear previous RX interrupts */
LEUART_IntClear(LEUART1, LEUART_IF_RXDATAV);
/* finally enable it */
LEUART_Enable(LEUART1, leuartEnable);
} /*** end of BootComInit ***/
/****************************************************************************************
** NAME: BootComCheckActivationRequest
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Receives the CONNECT request from the host, which indicates that the
** bootloader should be activated and, if so, activates it.
**
****************************************************************************************/
void BootComCheckActivationRequest(void)
{
static unsigned char xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1];
static unsigned char xcpCtoRxLength;
static unsigned char xcpCtoRxInProgress = 0;
/* start of cto packet received? */
if (xcpCtoRxInProgress == 0)
{
/* store the message length when received */
if (UartReceiveByte(&xcpCtoReqPacket[0]) == 1)
{
/* indicate that a cto packet is being received */
xcpCtoRxInProgress = 1;
/* reset packet data count */
xcpCtoRxLength = 0;
}
}
else
{
/* store the next packet byte */
if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == 1)
{
/* increment the packet data count */
xcpCtoRxLength++;
/* check to see if the entire packet was received */
if (xcpCtoRxLength == xcpCtoReqPacket[0])
{
/* done with cto packet reception */
xcpCtoRxInProgress = 0;
/* check if this was an XCP CONNECT command */
if ((xcpCtoReqPacket[1] == 0xff) && (xcpCtoReqPacket[2] == 0x00))
{
/* connection request received so start the bootloader */
BootActivate();
}
}
}
}
} /*** end of BootComCheckActivationRequest ***/
/****************************************************************************************
** NAME: UartReceiveByte
** PARAMETER: data pointer to byte where the data is to be stored.
** RETURN VALUE: 1 if a byte was received, 0 otherwise.
** DESCRIPTION: Receives a communication interface byte if one is present.
**
****************************************************************************************/
static unsigned char UartReceiveByte(unsigned char *data)
{
/* check to see if a new bytes was received */
if ((LEUART1->IF & LEUART_IF_RXDATAV) != 0)
{
/* store the received data byte and set return value to positive */
*data = LEUART_Rx(LEUART1);
return 1;
}
/* still here to no new byte received */
return 0;
} /*** end of UartReceiveByte ***/
#endif /* BOOT_COM_UART_ENABLE > 0 */
/*********************************** end of boot.c *************************************/

View File

@ -0,0 +1,42 @@
/****************************************************************************************
| Description: demo program bootloader interface header file
| File Name: boot.h
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
#ifndef BOOT_H
#define BOOT_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void BootComInit(void);
void BootComCheckActivationRequest(void);
#endif /* BOOT_H */
/*********************************** end of boot.h *************************************/

View File

@ -0,0 +1,302 @@
/*****************************************************************************
* Copyright (c) 2009 Rowley Associates Limited. *
* *
* This file may be distributed under the terms of the License Agreement *
* provided with this software. *
* *
* THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE *
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
*****************************************************************************/
/*****************************************************************************
* Preprocessor Definitions
* ------------------------
* APP_ENTRY_POINT
*
* Defines the application entry point function, if undefined this setting
* defaults to "main".
*
* USE_PROCESS_STACK
*
* If defined, thread mode will be configured to use the process stack if
* the size of the process stack is greater than zero bytes in length.
*
* INITIALIZE_STACK
*
* If defined, the contents of the stack will be initialized to a the
* value 0xCC.
*
* INITIALIZE_SECONDARY_SECTIONS
*
* If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
*
* FULL_LIBRARY
*
* If defined then
* - argc, argv are setup by the debug_getargs.
* - the exit symbol is defined and executes on return from main.
* - the exit symbol calls destructors, atexit functions and then debug_exit.
*
* If not defined then
* - argc and argv are zero.
* - the exit symbol is defined, executes on return from main and loops
*****************************************************************************/
#ifndef APP_ENTRY_POINT
#define APP_ENTRY_POINT main
#endif
#ifndef ARGSSPACE
#define ARGSSPACE 128
#endif
.global _start
.extern APP_ENTRY_POINT
.global exit
.global reset_handler
.section .init, "ax"
.code 16
.align 2
.thumb_func
_start:
ldr r1, =__stack_end__
#ifdef __ARM_EABI__
mov r2, #0x7
bic r1, r2
#endif
mov sp, r1
#ifdef INITIALIZE_STACK
mov r2, #0xCC
ldr r0, =__stack_start__
bl memory_set
#endif
#ifdef USE_PROCESS_STACK
/* Set up process stack if size > 0 */
ldr r1, =__stack_process_end__
ldr r0, =__stack_process_start__
sub r2, r1, r0
beq 1f
#ifdef __ARM_EABI__
mov r2, #0x7
bic r1, r2
#endif
msr psp, r1
mov r2, #2
msr control, r2
#ifdef INITIALIZE_STACK
mov r2, #0xCC
bl memory_set
#endif
1:
#endif
/* Copy initialised memory sections into RAM (if necessary). */
ldr r0, =__data_load_start__
ldr r1, =__data_start__
ldr r2, =__data_end__
bl memory_copy
ldr r0, =__text_load_start__
ldr r1, =__text_start__
ldr r2, =__text_end__
bl memory_copy
ldr r0, =__fast_load_start__
ldr r1, =__fast_start__
ldr r2, =__fast_end__
bl memory_copy
ldr r0, =__ctors_load_start__
ldr r1, =__ctors_start__
ldr r2, =__ctors_end__
bl memory_copy
ldr r0, =__dtors_load_start__
ldr r1, =__dtors_start__
ldr r2, =__dtors_end__
bl memory_copy
ldr r0, =__rodata_load_start__
ldr r1, =__rodata_start__
ldr r2, =__rodata_end__
bl memory_copy
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__data2_load_start__
ldr r1, =__data2_start__
ldr r2, =__data2_end__
bl memory_copy
ldr r0, =__text2_load_start__
ldr r1, =__text2_start__
ldr r2, =__text2_end__
bl memory_copy
ldr r0, =__rodata2_load_start__
ldr r1, =__rodata2_start__
ldr r2, =__rodata2_end__
bl memory_copy
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
/* Zero the bss. */
ldr r0, =__bss_start__
ldr r1, =__bss_end__
mov r2, #0
bl memory_set
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__bss2_start__
ldr r1, =__bss2_end__
mov r2, #0
bl memory_set
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
/* Initialise the heap */
ldr r0, = __heap_start__
ldr r1, = __heap_end__
sub r1, r1, r0
cmp r1, #8
blt 1f
mov r2, #0
str r2, [r0]
add r0, r0, #4
str r1, [r0]
1:
/* Call constructors */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0]
add r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b ctor_loop
ctor_end:
/* Setup initial call frame */
mov r0, #0
mov lr, r0
mov r12, sp
start:
/* Jump to application entry point */
#ifdef FULL_LIBRARY
mov r0, #ARGSSPACE
ldr r1, =args
ldr r2, =debug_getargs
blx r2
ldr r1, =args
#else
mov r0, #0
mov r1, #0
#endif
ldr r2, =APP_ENTRY_POINT
blx r2
.thumb_func
exit:
#ifdef FULL_LIBRARY
mov r5, r0 // save the exit parameter/return result
/* Call destructors */
ldr r0, =__dtors_start__
ldr r1, =__dtors_end__
dtor_loop:
cmp r0, r1
beq dtor_end
ldr r2, [r0]
add r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b dtor_loop
dtor_end:
/* Call atexit functions */
ldr r2, =_execute_at_exit_fns
blx r2
/* Call debug_exit with return result/exit parameter */
mov r0, r5
ldr r2, =debug_exit
blx r2
#endif
/* Returned from application entry point, loop forever. */
exit_loop:
b exit_loop
.thumb_func
memory_copy:
cmp r0, r1
beq 2f
sub r2, r2, r1
beq 2f
1:
ldrb r3, [r0]
add r0, r0, #1
strb r3, [r1]
add r1, r1, #1
sub r2, r2, #1
bne 1b
2:
bx lr
.thumb_func
memory_set:
cmp r0, r1
beq 1f
strb r2, [r0]
add r0, r0, #1
b memory_set
1:
bx lr
.thumb_func
reset_handler:
#ifdef VECTORS_IN_RAM
ldr r0, =__vectors_load_start__
ldr r1, =__vectors_load_end__
ldr r2, =_vectors_ram
l0:
cmp r0, r1
beq l1
ldr r3, [r0], #4
str r3, [r2], #4
b l0
l1:
#endif
#ifdef __TARGET_F4XX
#ifndef __NO_FPU
movw r0, 0xED88
movt r0, 0xE000
ldr r1, [r0]
orrs r1, r1, #(0xf << 20)
str r1, [r0]
#endif
#endif
/* Configure vector table offset register */
ldr r0, =0xE000ED08
#ifdef VECTORS_IN_RAM
ldr r1, =_vectors_ram
#else
ldr r1, =_vectors
#endif
str r1, [r0]
b _start
#ifdef FULL_LIBRARY
.bss
args:
.space ARGSSPACE
#endif
/* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
.section .stack, "wa", %nobits
.section .stack_process, "wa", %nobits
.section .heap, "wa", %nobits

View File

@ -0,0 +1,50 @@
/****************************************************************************************
| Description: generic header file
| File Name: header.h
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
#ifndef HEADER_H
#define HEADER_H
/****************************************************************************************
* Include files
****************************************************************************************/
#include "../Boot/config.h" /* bootloader configuration */
#include "efm32.h" /* EFM32 registers */
#include "efm32_chip.h" /* EFM32 chip initialization */
#include "efm32_cmu.h" /* EFM32 clock management */
#include "efm32_gpio.h" /* EFM32 GPIO management */
#include "efm32_leuart.h" /* EFM32 LEUART management */
#include "boot.h" /* bootloader interface driver */
#include "irq.h" /* IRQ driver */
#include "led.h" /* LED driver */
#include "timer.h" /* Timer driver */
#endif /* HEADER_H */
/*********************************** end of header.h ***********************************/

View File

@ -0,0 +1,119 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="EFM32G880_crossworks" target="8" version="2">
<project Name="demoprog_olimex_efm32g880">
<configuration Name="Common" Target="EFM32G880F128" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_heap_size="128" arm_linker_process_stack_size="0" arm_linker_stack_size="128" arm_simulator_memory_simulation_filename="$(TargetsDir)/EFM32/EFM32SimulatorMemory.dll" arm_simulator_memory_simulation_parameter="EFM32G880F128;FLASH=0x00000000:0x20000;RAM=0x20000000:0x4000" arm_target_debug_interface_type="ADIv5" arm_target_interface_type="SWD" arm_target_loader_parameter="16000000" build_intermediate_directory="$(Configuration)/../../obj" build_output_directory="$(Configuration)/../../bin" c_preprocessor_definitions="USE_PROCESS_STACK" c_user_include_directories="$(ProjectDir)/../src;$(ProjectDir)/../lib/CMSIS/CM3/CoreSupport;$(ProjectDir)/../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32;$(ProjectDir)/../lib/efm32lib/inc;$(ProjectDir)/../lib/lcd" gcc_optimization_level="None" link_include_startup_code="No" linker_additional_files="" linker_memory_map_file="$(TargetsDir)/EFM32/EFM32G880F128_MemoryMap.xml" linker_output_format="srec" oscillator_frequency="Other" project_directory="" project_type="Executable" property_groups_file_path="$(TargetsDir)/EFM32/EFM32_propertyGroups.xml"/>
<configuration Name="Flash" Placement="Flash" arm_target_flash_loader_file_path="$(TargetsDir)/EFM32/Release/Loader_rpc.elf" arm_target_flash_loader_type="LIBMEM RPC Loader" linker_section_placement_file="$(StudioDir)/targets/Cortex_M/flash_placement.xml" target_reset_script="FLASHReset()"/>
<configuration Name="RAM" Placement="RAM" linker_section_placement_file="$(StudioDir)/targets/Cortex_M/ram_placement.xml" target_reset_script="SRAMReset()"/>
<folder Name="Source Files">
<configuration Name="Common" filter="c;cpp;cxx;cc;h;s;asm;inc"/>
<folder Name="Demo">
<folder Name="Prog">
<file file_name="../boot.c"/>
<file file_name="../boot.h"/>
<file file_name="../cstart.s"/>
<file file_name="../header.h"/>
<file file_name="../irq.c"/>
<file file_name="../irq.h"/>
<file file_name="../led.c"/>
<file file_name="../led.h"/>
<file file_name="../main.c"/>
<file file_name="../timer.c"/>
<file file_name="../timer.h"/>
<file file_name="../vectors.c"/>
</folder>
</folder>
</folder>
<folder Name="System Files">
<file file_name="$(TargetsDir)/EFM32/EFM32_Target.js">
<configuration Name="Common" file_type="Reset Script"/>
</file>
<file file_name="../memory.x">
<configuration Name="Common" file_type="Linker Script"/>
</file>
</folder>
<folder Name="Library Files">
<folder Name="Cmsis">
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cm3.c"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cm3.h"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cmFunc.h"/>
<file file_name="../lib/CMSIS/CM3/CoreSupport/core_cmInstr.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/efm32g880f128.h"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c"/>
<file file_name="../lib/CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.h"/>
</folder>
<folder Name="Efm32lib">
<file file_name="../lib/efm32lib/inc/efm32_acmp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_adc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_aes.h"/>
<file file_name="../lib/efm32lib/inc/efm32_assert.h"/>
<file file_name="../lib/efm32lib/inc/efm32_bitband.h"/>
<file file_name="../lib/efm32lib/inc/efm32_chip.h"/>
<file file_name="../lib/efm32lib/inc/efm32_cmu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_common.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dac.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dbg.h"/>
<file file_name="../lib/efm32lib/inc/efm32_dma.h"/>
<file file_name="../lib/efm32lib/inc/efm32_ebi.h"/>
<file file_name="../lib/efm32lib/inc/efm32_emu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_gpio.h"/>
<file file_name="../lib/efm32lib/inc/efm32_i2c.h"/>
<file file_name="../lib/efm32lib/inc/efm32_int.h"/>
<file file_name="../lib/efm32lib/inc/efm32_lcd.h"/>
<file file_name="../lib/efm32lib/inc/efm32_lesense.h"/>
<file file_name="../lib/efm32lib/inc/efm32_letimer.h"/>
<file file_name="../lib/efm32lib/inc/efm32_leuart.h"/>
<file file_name="../lib/efm32lib/inc/efm32_mpu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_msc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_opamp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_pcnt.h"/>
<file file_name="../lib/efm32lib/inc/efm32_prs.h"/>
<file file_name="../lib/efm32lib/inc/efm32_rmu.h"/>
<file file_name="../lib/efm32lib/inc/efm32_rtc.h"/>
<file file_name="../lib/efm32lib/inc/efm32_system.h"/>
<file file_name="../lib/efm32lib/inc/efm32_timer.h"/>
<file file_name="../lib/efm32lib/inc/efm32_usart.h"/>
<file file_name="../lib/efm32lib/inc/efm32_vcmp.h"/>
<file file_name="../lib/efm32lib/inc/efm32_wdog.h"/>
<file file_name="../lib/efm32lib/src/efm32_acmp.c"/>
<file file_name="../lib/efm32lib/src/efm32_adc.c"/>
<file file_name="../lib/efm32lib/src/efm32_aes.c"/>
<file file_name="../lib/efm32lib/src/efm32_assert.c"/>
<file file_name="../lib/efm32lib/src/efm32_cmu.c"/>
<file file_name="../lib/efm32lib/src/efm32_dac.c"/>
<file file_name="../lib/efm32lib/src/efm32_dbg.c"/>
<file file_name="../lib/efm32lib/src/efm32_dma.c"/>
<file file_name="../lib/efm32lib/src/efm32_ebi.c"/>
<file file_name="../lib/efm32lib/src/efm32_emu.c"/>
<file file_name="../lib/efm32lib/src/efm32_gpio.c"/>
<file file_name="../lib/efm32lib/src/efm32_i2c.c"/>
<file file_name="../lib/efm32lib/src/efm32_int.c"/>
<file file_name="../lib/efm32lib/src/efm32_lcd.c"/>
<file file_name="../lib/efm32lib/src/efm32_lesense.c"/>
<file file_name="../lib/efm32lib/src/efm32_letimer.c"/>
<file file_name="../lib/efm32lib/src/efm32_leuart.c"/>
<file file_name="../lib/efm32lib/src/efm32_mpu.c"/>
<file file_name="../lib/efm32lib/src/efm32_msc.c"/>
<file file_name="../lib/efm32lib/src/efm32_opamp.c"/>
<file file_name="../lib/efm32lib/src/efm32_pcnt.c"/>
<file file_name="../lib/efm32lib/src/efm32_prs.c"/>
<file file_name="../lib/efm32lib/src/efm32_rmu.c"/>
<file file_name="../lib/efm32lib/src/efm32_rtc.c"/>
<file file_name="../lib/efm32lib/src/efm32_system.c"/>
<file file_name="../lib/efm32lib/src/efm32_timer.c"/>
<file file_name="../lib/efm32lib/src/efm32_usart.c"/>
<file file_name="../lib/efm32lib/src/efm32_vcmp.c"/>
<file file_name="../lib/efm32lib/src/efm32_wdog.c"/>
</folder>
<folder Name="Lcd">
<file file_name="../lib/lcd/lcdcontroller.c"/>
<file file_name="../lib/lcd/lcdcontroller.h"/>
<file file_name="../lib/lcd/lcddisplay.h"/>
</folder>
</folder>
</project>
<configuration Name="THUMB Flash Debug" inherited_configurations="THUMB;Flash;Debug"/>
<configuration Name="THUMB" Platform="ARM" arm_instruction_set="THUMB" arm_library_instruction_set="THUMB" c_preprocessor_definitions="__THUMB" hidden="Yes"/>
<configuration Name="Flash" c_preprocessor_definitions="__FLASH_BUILD" hidden="Yes"/>
<configuration Name="Debug" build_debug_information="Yes" c_preprocessor_definitions="DEBUG" gcc_optimization_level="None" hidden="Yes" link_include_startup_code="No"/>
</solution>

View File

@ -0,0 +1,62 @@
<!DOCTYPE CrossStudio_for_ARM_Session_File>
<session>
<Bookmarks/>
<Breakpoints/>
<ETMWindow>
<ETMRegister number="0" value="800" />
<ETMRegister number="8" value="6f" />
<ETMRegister number="9" value="1000000" />
</ETMWindow>
<ExecutionCountWindow/>
<Memory1>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory1>
<Memory2>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory2>
<Memory3>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory3>
<Memory4>
<MemoryWindow autoEvaluate="0" addressText="" numColumns="8" sizeText="" dataSize="1" radix="16" addressSpace="" />
</Memory4>
<Project>
<ProjectSessionItem path="EFM32G880_crossworks" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;demoprog_olimex_efm32g880" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;demoprog_olimex_efm32g880;Source Files" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;demoprog_olimex_efm32g880;Source Files;Demo" name="unnamed" />
<ProjectSessionItem path="EFM32G880_crossworks;demoprog_olimex_efm32g880;Source Files;Demo;Prog" name="unnamed" />
</Project>
<Register1>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register1>
<Register2>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register2>
<Register3>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register3>
<Register4>
<RegisterWindow openNodes="" binaryNodes="" hiddenNodes="" unsignedNodes="" visibleGroups="" decimalNodes="" octalNodes="" asciiNodes="" />
</Register4>
<TargetWindow programAction="" uploadFileType="" programLoadAddress="" programSize="" uploadFileName="" uploadMemoryInterface="" programFileName="" uploadStartAddress="" programFileType="" uploadSize="" programMemoryInterface="" />
<TraceWindow>
<Trace enabled="Yes" />
</TraceWindow>
<Watch1>
<Watches active="1" update="Never" />
</Watch1>
<Watch2>
<Watches active="0" update="Never" />
</Watch2>
<Watch3>
<Watches active="0" update="Never" />
</Watch3>
<Watch4>
<Watches active="0" update="Never" />
</Watch4>
<Files>
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="D:\usr\feaser\software\OpenBLT\Target\Demo\ARMCM3_EFM32_Olimex_EM32G880F128STK_Crossworks\Prog\main.c" y="101" path="D:\usr\feaser\software\OpenBLT\Target\Demo\ARMCM3_EFM32_Olimex_EM32G880F128STK_Crossworks\Prog\main.c" left="0" selected="1" name="unnamed" top="51" />
</Files>
<ARMCrossStudioWindow activeProject="demoprog_olimex_efm32g880" autoConnectTarget="Olimex ARM-USB-TINY" debugSearchFileMap="" fileDialogInitialDirectory="D:\usr\feaser\software\OpenBLT\Target\Demo\ARMCM3_EFM32_Olimex_EM32G880F128STK_Crossworks\Prog" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
</session>

View File

@ -0,0 +1,4 @@
Integrated Development Environment
----------------------------------
Rowleys CrossWorks was used as the editor during the development of this software program. This directory contains
the CrossWorks project and solution files. More info is available at: http://www.rowley.co.uk/

View File

@ -0,0 +1,97 @@
/****************************************************************************************
| Description: IRQ driver source file
| File Name: irq.c
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "header.h" /* generic header */
/****************************************************************************************
* Local data definitions
****************************************************************************************/
static unsigned char interruptNesting = 0; /* used for global interrupt en/disable */
/****************************************************************************************
** NAME: IrqInterruptEnable
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Enables the generation IRQ interrupts. Typically called once during
** software startup after completion of the initialization.
**
****************************************************************************************/
void IrqInterruptEnable(void)
{
__enable_irq();
} /*** end of IrqInterruptEnable ***/
/****************************************************************************************
** NAME: HwInterruptDisable
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Disables the generation IRQ interrupts and stores information on
** whether or not the interrupts were already disabled before explicitly
** disabling them with this function. Normally used as a pair together
** with IrqInterruptRestore during a critical section.
**
****************************************************************************************/
void IrqInterruptDisable(void)
{
if (interruptNesting == 0)
{
__disable_irq();
}
interruptNesting++;
} /*** end of IrqInterruptDisable ***/
/****************************************************************************************
** NAME: IrqInterruptRestore
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Restore the generation IRQ interrupts to the setting it had prior to
** calling IrqInterruptDisable. Normally used as a pair together with
** IrqInterruptDisable during a critical section.
**
****************************************************************************************/
void IrqInterruptRestore(void)
{
interruptNesting--;
if (interruptNesting == 0)
{
__enable_irq();
}
} /*** end of IrqInterruptRestore ***/
/*********************************** end of irq.c **************************************/

View File

@ -0,0 +1,43 @@
/****************************************************************************************
| Description: IRQ driver header file
| File Name: irq.h
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
#ifndef IRQ_H
#define IRQ_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void IrqInterruptEnable(void);
void IrqInterruptDisable(void);
void IrqInterruptRestore(void);
#endif /* IRQ_H */
/*********************************** end of irq.h **************************************/

View File

@ -0,0 +1,99 @@
/****************************************************************************************
| Description: LED driver source file
| File Name: led.c
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
/****************************************************************************************
* Include files
****************************************************************************************/
#include "header.h" /* generic header */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
#define LED_TOGGLE_MS (500) /* toggle interval time in millisecodns */
/****************************************************************************************
** NAME: LedInit
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Initializes the LED. The board doesn't have a dedicted LED so an
** inidicator on the LCD is used instead.
**
****************************************************************************************/
void LedInit(void)
{
/* initialize the LCD */
LCD_Init(LCD);
} /*** end of LedInit ***/
/****************************************************************************************
** NAME: LedToggle
** PARAMETER: none
** RETURN VALUE: none
** DESCRIPTION: Toggles the LED at a fixed time interval.
**
****************************************************************************************/
void LedToggle(void)
{
static unsigned char led_toggle_state = 0;
static unsigned long timer_counter_last = 0;
unsigned long timer_counter_now;
/* check if toggle interval time passed */
timer_counter_now = TimerGet();
if ( (timer_counter_now - timer_counter_last) < LED_TOGGLE_MS)
{
/* not yet time to toggle */
return;
}
/* determine toggle action */
if (led_toggle_state == 0)
{
led_toggle_state = 1;
/* turn the LED on */
LCD_Symbol(LCD, LCD_SYMBOL_OLIMEX, 1);
}
else
{
led_toggle_state = 0;
/* turn the LED off */
LCD_Symbol(LCD, LCD_SYMBOL_OLIMEX, 0);
}
/* store toggle time to determine next toggle interval */
timer_counter_last = timer_counter_now;
} /*** end of LedToggle ***/
/*********************************** end of led.c **************************************/

View File

@ -0,0 +1,48 @@
/****************************************************************************************
| Description: LED driver header file
| File Name: led.h
|
|----------------------------------------------------------------------------------------
| C O P Y R I G H T
|----------------------------------------------------------------------------------------
| Copyright (c) 2012 by Feaser http://www.feaser.com All rights reserved
|
|----------------------------------------------------------------------------------------
| L I C E N S E
|----------------------------------------------------------------------------------------
| This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
| modify it under the terms of the GNU General Public License as published by the Free
| Software Foundation, either version 3 of the License, or (at your option) any later
| version.
|
| OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
| PURPOSE. See the GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License along with OpenBLT.
| If not, see <http://www.gnu.org/licenses/>.
|
| A special exception to the GPL is included to allow you to distribute a combined work
| that includes OpenBLT without being obliged to provide the source code for any
| proprietary components. The exception text is included at the bottom of the license
| file <license.html>.
|
****************************************************************************************/
#ifndef LED_H
#define LED_H
/****************************************************************************************
* Include files
****************************************************************************************/
#include "lcdcontroller.h"
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void LedInit(void);
void LedToggle(void);
#endif /* LED_H */
/*********************************** end of led.h **************************************/

View File

@ -0,0 +1,339 @@
/**************************************************************************//**
* @file core_cm3.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V2.00
* @date 13. September 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ########################## Core Instruction Access ######################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __CLREX(void)
{
clrex
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
/* ########################### Core Function Access ########################### */
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_IPSR(void)
{
mrs r0, ipsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_APSR(void)
{
mrs r0, apsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_xPSR(void)
{
mrs r0, xpsr
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask Register.
\return Fault Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Set the Fault Mask
This function assigns the given value to the Fault Mask Register.
\param [in] faultMask Fault Mask value value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif

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