ready to alpha

подготовка к альфа-тестированию
This commit is contained in:
khristolyubov 2024-08-19 22:44:04 +07:00
commit e36b851783
164 changed files with 27352 additions and 0 deletions

23
boards.txt Normal file
View File

@ -0,0 +1,23 @@
# See: https://arduino.github.io/arduino-cli/latest/platform-specification/
##############################################################
aceUno8Mb.name=Elbear Ace-Uno 8Mb
# tool for firmware update
aceUno8Mb.upload.tool=elbear_uploader
aceUno8Mb.upload.protocol=elbear_uploader
aceUno8Mb.upload.maximum_size=8388608
aceUno8Mb.upload.maximum_data_size=16384
# tool for bootloader update
aceUno8Mb.bootloader.tool=mik32_upload
aceUno8Mb.bootloader.tool.default=mik32_upload
aceUno8Mb.bootloader.file=ace-uno/bootloader.hex
# build options
aceUno8Mb.build.mcu=MIK32_Amur
aceUno8Mb.build.f_cpu=32000000UL
aceUno8Mb.build.board=ACE_UNO_8Mb
aceUno8Mb.build.core=arduino
aceUno8Mb.build.variant=standart
aceUno8Mb.build.extra_flags=
aceUno8Mb.build.flags=

View File

@ -0,0 +1,247 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505F137160001130606F4B706A3
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB7150001938505F415
:1000500037160001130606F4B7060002938606263B
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7008E
:1000A0000001E780007273005010F5BF82800000ED
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78
:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28
:10010000FADCFEDE970000009380E00482909240CB
:100110002241B2414242D2426243F24302549254DB
:100120002255B2554256D2566257F2570648964863
:100130002649B649464AD64A664BF64B065C965C5B
:10014000265DB65D465ED65E665FF65F096173004A
:10015000203001A03D432A876373C3029377F700E1
:10016000BDEFADE5937606FF3D8ABA960CC34CC34E
:100170000CC74CC74107E36BD7FE11E28280B30680
:10018000C3408A069702000096966780A600230760
:10019000B700A306B7002306B700A305B7002305E1
:1001A000B700A304B7002304B700A303B7002303D9
:1001B000B700A302B7002302B700A301B7002301D1
:1001C000B700A300B7002300B700828093F5F50FB6
:1001D00093968500D58D93960501D58D61B793963D
:1001E00027009702000096968682E78086FA96801E
:1001F000C1171D8F3E96E374C3F8A5B7B707050076
:100200000947D8CFB7170500938707C0984385667D
:1002100093860640558F98C3B71708009387074009
:1002200023A0070023A2070023A407001307A008A8
:10023000D8C77D57D8CF354798C3D84F9356570165
:100240008D8AE5DE8280B71708009387074023A0D8
:10025000070023A2070023A4070023A607007D5759
:10026000D8CF23A40702B7170500938707C0984388
:10027000F1769386F63F758F98C3B7070500D84F80
:1002800023AE07008280B71708009387074088D7FE
:10029000D84F137707046DDF828037070002B71548
:1002A000080037460F0023200704814781469385C5
:1002B000054013061624C84D137505020DC991CECD
:1002C0002320F70437470F00130707246397E7003D
:1002D000B707000205472383E700B7170800938795
:1002E0000740C8534205418182808546E9B78507AA
:1002F000E39DC7FEFDD2B7470F0093870724232055
:10030000F704F9B74111B707000222C413870700A9
:1003100006C6834667000547138407006390E6021C
:100320001305000F8D37B717080093870740D84F84
:10033000218B09C7D84F13678700D8CF2303040048
:10034000B240224441018280411106C622C426C225
:10035000AA84EF009013E1689388086A01488147F6
:10036000014781460146B70520C726853794980086
:10037000EF000077130414687D1419E40D45B240B2
:10038000224492444101828085452685EF00501128
:1003900005897DF10145E5B7411122C4370400020A
:1003A000930704008C43B70700804AC0BE95B70787
:1003B000000223ACB70206C626C293974501130478
:1003C00004003709000289E713058900EF00701A5D
:1003D0000C40B70400029386440413060010130572
:1003E0008900EF0050141C40370700028356470372
:1003F000938707101CC013060010B68763F4C6006D
:1004000093070010138444041305F400938707F046
:100410001306100F814513040410231AF7021D3B25
:10042000A285138544043D46EF00F0182320040004
:1004300023220400232404002316040023070400BD
:10044000B240224492440249410182805D71130608
:1004500080028145280886C6F539BD47230CF10086
:100460008947230EF1003ED2E177938707082C08D5
:100470000A85231AF1021923B640616182805D71F9
:10048000A2C4370400021305840086C6A6C2652BE9
:1004900013058400E525894513058400EF0050000D
:1004A0009377250085E3AA84854513058400EF0032
:1004B000207F13E62400AA851376F60F1305840027
:1004C000EF007001E1689388086A0148814701479D
:1004D00081460146B7052038130584001125E168DF
:1004E00038009388086A1308000285468147014650
:1004F000B70599EB1305840023040100D523B71534
:10050000000151469385C5EF6800EF00D00A9304BF
:1005100084009C406C0051463ED085473ED2681016
:10052000C1673ED4EF003009B70607009C42370789
:10053000F1FF7D17F98F08109CC2812BB64026442D
:10054000964461618280411106C6F5390D3FB707B7
:10055000008073905730B70000808290B240410114
:100560008280411106C622C426C24AC08347350094
:1005700005476383E70811472A846389E7008DCF25
:10058000B24022449244024941018280B7070002EE
:1005900083D7470391C30935834744000347540079
:1005A000E2074207BA9737070002232EF702370700
:1005B00000022320F700E9B73709000283544903FA
:1005C0000346050093054500370500021305450461
:1005D0002695EF00407E83470400BE94C204C1808C
:1005E000231A99029307F00FE3FC97F82244B240D4
:1005F0009244024941014DB33D457131B7070002B4
:1006000083D7470391C3493B2244B24092440249F5
:10061000410115BF3707000293070700B705000225
:1006200003DE470083A705043716080037450F008F
:1006300037480F00B708000201438146130707003F
:10064000130606401305152413080824938848153B
:1006500063EEC6016304030023A0F504834767002B
:10066000A9E73705000213054515E5BD81470323BA
:10067000C60113730302631F03008507E399A7FEF6
:10068000B7470F009387072423A0F504854723036A
:10069000F7008280E38607FF832E46023383D8006B
:1006A00085062300D301054365B78280011122CC62
:1006B0003704000226CA4AC84EC652C406CE1304E6
:1006C0000400930400061309E00FB7090002130A9F
:1006D0000003E136834764001375F50FA303A400FC
:1006E00099C30D31FDB7630F950063042503E31231
:1006F00045FF3D45493E553605052312A4003D45BD
:100700005936C1BF3D454136313783476400F1FB5F
:10071000FDB7138589000D397DD11305000FCDB7C5
:10072000011106CE22CC1D333704000213058400CC
:10073000192E130584009921E1689388086A0148FD
:100740008147780085460146B705D9EB130584003B
:10075000230601007126E168814701478146014671
:10076000B70538FF9388086A0148130584008D2E69
:10077000713437070002B715080037460F002320F1
:100780000704814781469385054013061624C84D0A
:100790001375050211CD85CA2320F70437470F00D2
:1007A000130707246391E702793B01A08546C5B78B
:1007B0008507E39DC7FE81CAB7470F0093870724CB
:1007C0002320F704D5B7DD350547AA876305E50281
:1007D00009476300E506054591EBB7060600DC4ACC
:1007E0007D771307F73FF98FDCCA014582807D17BB
:1007F00019EB0D4582809306004037A707001307C9
:100800000712B7050500905D7D8E75D2370606008C
:100810005C4A7D771307F73FF98FD58F41115CCA8A
:1008200002C613073006B2476359F700014541017C
:100830008280856693860680C9B7B24785073EC623
:10084000DDB791476307F50263EAA7008547630AAE
:10085000F50489476309F50405458280A147E31D36
:10086000F5FE0947094501A8FD1781EFC8D20D45DE
:10087000828005470D45B7A7070093870712B70683
:100880000500905E798E6DD28A05C98D4111CCD25A
:1008900002C613073006B247635AF700014541010B
:1008A00082801147C9BF21470145F1B7B24785078B
:1008B0003EC6D5B70547AA876305E5020947630227
:1008C000E506054591EBB70606009C4A7D771307C0
:1008D000F73FF98F9CCA014582807D1719EB0D45C2
:1008E00082809306004037A7070013070712B70559
:1008F0000500905D7D8E75D2370706001C4B7D7616
:100900001306F63FF18FD58F1CCB85471CCF4111C5
:1009100002C613073006B2476359F700014541018B
:1009200082808566938606807DBFB24785073EC676
:10093000DDB711C98547630DF50205458280FD17B6
:1009400091EB0D4582800946B7A7070093870712F0
:10095000B7060500985E718F7DD34111C8D602C6D7
:1009600013073006B2476357F70001454101828003
:100970000546D9BFB24785073EC6EDB7011126CA65
:10098000B7040600DC4806CE22CC4AC84EC652C484
:1009900056C2F19BDCC89C482A89C845F19B9CC87B
:1009A00083C7C5012E848A07DCC883C7D5018A079F
:1009B0009CC8193D0C44AA8A03454400593518487F
:1009C000B70705002A8A98C358480850D8C3184C5E
:1009D00098C7CD35AA894850A93F834704002A8784
:1009E00093F6170089E6D44893E62600D4C893F618
:1009F000270099E637060600544A93E6160054CAC3
:100A000093F6470099E637060600144A93E6260057
:100A100014CAA18B99E7B70606009C4A93E7170012
:100A20009CCAF24062442320590123224901232415
:100A300039012326E900D244B249224A924A4A8522
:100A4000424905618280011106CE22CC02C402C651
:100A50002147B707050037550800D8C705448D471B
:100A60008A85130505803EC022C2292A3755080011
:100A70009307C0038A851305058022C222C43EC0A5
:100A80001122F240624405618280411122C406C6EF
:100A90002A84553F18405C4F93E707015CCF1C4404
:100AA0001CCB5C4085CB1C43B7061000D58F1CC304
:100AB000144C5C48B240D606CE07D58F834604015D
:100AC000C206D58F8346C4012244E206D58F1CCFCF
:100AD000410182801C43B706F0FFFD16F58FC1BFB0
:100AE000032305002A8E0325C30113650502232E67
:100AF000A3002324C3001396260149824D8E23268A
:100B000003012322C300139605016354060299C210
:100B10000545B1CB01476346D700639C08020D45EC
:100B200082803386E700034606000507230AC300D8
:100B3000DDB799C2054505CB8147E3D0D7FE032633
:100B40000E00034546013306F70085072300A60083
:100B5000EDB783270E00FD18DC4F93F70702D5DFB2
:100B600011656D8D11E18280B707070083C74701CA
:100B700013F585001D8D3335A00082801C4141474F
:100B8000D8CF8280B7470800938707402A8863043C
:100B9000F508B7570800938707806304F50A3747BD
:100BA0000800630DE50A05458280331E1F01337678
:100BB000DE0129C683A345008843139318003396AA
:100BC0006F001346F6FF13F43300718D3314640085
:100BD000418D88C3638B5302638C0302084303AEC9
:100BE000C500718D331E6E003365C50108C3884290
:100BF000698E884533156500498E90C2850833D5C6
:100C00001E0145F53244410182802326C801F9B70F
:100C10002324C801E1B7B716050037170500B71739
:100C20000500938646C1130707C19387C7C083AEEB
:100C300005008148054F8D4F914233D51E0105EDCA
:100C40008280B716050037170500B7170500938691
:100C500006C21307C7C1938787C1D1BFB716050066
:100C600037170500B7170500938686C0130747C0DE
:100C7000938707C06DBF331E1F013376DE0119E273
:100C8000850865BF411122C635B7E1689388086AB7
:100C900001488147014781460146B705200689B5CD
:100CA000011106CEA307010089476393F502B7053A
:100CB0002035E1681307F1009388086A01488147ED
:100CC00085460146313DF2400345F10005618280D1
:100CD000B7052005F9BF011106CE22CC26CA23068E
:100CE000B100AA84A306C1004D37E1689388086A61
:100CF00001487C00014789460146B78520012685C9
:100D00000964F93B130414717D1419E40D45F24094
:100D10006244D24405618280854526855137058924
:100D200065F50145EDB7011106CE22CC26CA2E8409
:100D30004AC8AA84328936C6893FB247E16822860A
:100D40009388086A01480147CA86B78580022685CC
:100D5000616479331304146A7D1411C485452685B2
:100D60008137058975F9F2406244D24442490561F0
:100D70008280011106CE22CC26CA2EC6AA84313723
:100D80003246E1689388086A0148814701478146F5
:100D9000B705802026856164A1331304146A7D148D
:100DA00011C485452685ED3D058975F9F2406244FB
:100DB000D24405618280B3C7A5008D8BB308C500FE
:100DC000B1E78D4763F4C704937735002A87B9EB01
:100DD00013F6C8FFB306E6409307000263C8D706C0
:100DE000AE86BA876371C70203A806009107910611
:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47
:100E000091073E97BE956366170182802A87637EAD
:100E1000150383C7050005078505A30FF7FEE39AB1
:100E2000E8FE828083C60500050793773700A30F8D
:100E3000D7FE8505D1DF83C6050005079377370008
:100E4000A30FD7FE8505F9FF61B78280411122C645
:100E50001304000283A3050083A2450083AF85002D
:100E600003AFC50083AE050103AE450103A38501B1
:100E700003A8C501945113074702B307E640232E88
:100E800077FC232057FE2322F7FF2324E7FF2326A6
:100E9000D7FF2328C7FF232A67FE232C07FF232E13
:100EA000D7FE93854502E347F4FAAE86BA876371AD
:100EB000C70203A806009107910623AE07FFE3EAE5
:100EC000C7FE9307F6FF998FF19B91073E97BE955A
:100ED0006365170132444101828083C7050005071D
:100EE0008505A30FF7FEE387E8FE83C70500050726
:100EF0008505A30FF7FEE392E8FEE9BF200000009E
:100F0000010000000300000006000000EB000000EC
:100F10000000008000010000000007000000000049
:100F200000000000000000000000000000000000C1
:100F300000000000000000000000000000000000B1
:0400000501000000F6
:00000001FF

View File

@ -0,0 +1,247 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505F137160001130606F4B706A3
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB7150001938505F415
:1000500037160001130606F4B7060002938606263B
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7008E
:1000A0000001E780007273005010F5BF82800000ED
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78
:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28
:10010000FADCFEDE970000009380E00482909240CB
:100110002241B2414242D2426243F24302549254DB
:100120002255B2554256D2566257F2570648964863
:100130002649B649464AD64A664BF64B065C965C5B
:10014000265DB65D465ED65E665FF65F096173004A
:10015000203001A03D432A876373C3029377F700E1
:10016000BDEFADE5937606FF3D8ABA960CC34CC34E
:100170000CC74CC74107E36BD7FE11E28280B30680
:10018000C3408A069702000096966780A600230760
:10019000B700A306B7002306B700A305B7002305E1
:1001A000B700A304B7002304B700A303B7002303D9
:1001B000B700A302B7002302B700A301B7002301D1
:1001C000B700A300B7002300B700828093F5F50FB6
:1001D00093968500D58D93960501D58D61B793963D
:1001E00027009702000096968682E78086FA96801E
:1001F000C1171D8F3E96E374C3F8A5B7B707050076
:100200000947D8CFB7170500938707C0984385667D
:1002100093860640558F98C3B71708009387074009
:1002200023A0070023A2070023A407001307A008A8
:10023000D8C77D57D8CF354798C3D84F9356570165
:100240008D8AE5DE8280B71708009387074023A0D8
:10025000070023A2070023A4070023A607007D5759
:10026000D8CF23A40702B7170500938707C0984388
:10027000F1769386F63F758F98C3B7070500D84F80
:1002800023AE07008280B71708009387074088D7FE
:10029000D84F137707046DDF828037070002B71548
:1002A000080037460F0023200704814781469385C5
:1002B000054013061624C84D137505020DC991CECD
:1002C0002320F70437470F00130707246397E7003D
:1002D000B707000205472383E700B7170800938795
:1002E0000740C8534205418182808546E9B78507AA
:1002F000E39DC7FEFDD2B7470F0093870724232055
:10030000F704F9B74111B707000222C413870700A9
:1003100006C6834667000547138407006390E6021C
:100320001305000F8D37B717080093870740D84F84
:10033000218B09C7D84F13678700D8CF2303040048
:10034000B240224441018280411106C622C426C225
:10035000AA84EF009013E1689388086A01488147F6
:10036000014781460146B70520C726853794980086
:10037000EF000077130414687D1419E40D45B240B2
:10038000224492444101828085452685EF00501128
:1003900005897DF10145E5B7411122C4370400020A
:1003A000930704008C43B70700804AC0BE95B70787
:1003B000000223ACB70206C626C293974501130478
:1003C00004003709000289E713058900EF00701A5D
:1003D0000C40B70400029386440413060010130572
:1003E0008900EF0050141C40370700028356470372
:1003F000938707101CC013060010B68763F4C6006D
:1004000093070010138444041305F400938707F046
:100410001306100F814513040410231AF7021D3B25
:10042000A285138544043D46EF00F0182320040004
:1004300023220400232404002316040023070400BD
:10044000B240224492440249410182805D71130608
:1004500080028145280886C6F539BD47230CF10086
:100460008947230EF1003ED2E177938707082C08D5
:100470000A85231AF1021923B640616182805D71F9
:10048000A2C4370400021305840086C6A6C2652BE9
:1004900013058400E525894513058400EF0050000D
:1004A0009377250085E3AA84854513058400EF0032
:1004B000207F13E62400AA851376F60F1305840027
:1004C000EF007001E1689388086A0148814701479D
:1004D00081460146B7052038130584001125E168DF
:1004E00038009388086A1308000285468147014650
:1004F000B70599EB1305840023040100D523B71534
:10050000000151469385C5EF6800EF00D00A9304BF
:1005100084009C406C0051463ED085473ED2681016
:10052000C1673ED4EF003009B70607009C42370789
:10053000F1FF7D17F98F08109CC2812BB64026442D
:10054000964461618280411106C6F5390D3FB707B7
:10055000008073905730B70000808290B240410114
:100560008280411106C622C426C24AC08347350094
:1005700005476383E70811472A846389E7008DCF25
:10058000B24022449244024941018280B7070002EE
:1005900083D7470391C30935834744000347540079
:1005A000E2074207BA9737070002232EF702370700
:1005B00000022320F700E9B73709000283544903FA
:1005C0000346050093054500370500021305450461
:1005D0002695EF00407E83470400BE94C204C1808C
:1005E000231A99029307F00FE3FC97F82244B240D4
:1005F0009244024941014DB33D457131B7070002B4
:1006000083D7470391C3493B2244B24092440249F5
:10061000410115BF3707000293070700B705000225
:1006200003DE470083A705043716080037450F008F
:1006300037480F00B708000201438146130707003F
:10064000130606401305152413080824938848153B
:1006500063EEC6016304030023A0F504834767002B
:10066000A9E73705000213054515E5BD81470323BA
:10067000C60113730302631F03008507E399A7FEF6
:10068000B7470F009387072423A0F504854723036A
:10069000F7008280E38607FF832E46023383D8006B
:1006A00085062300D301054365B78280011122CC62
:1006B0003704000226CA4AC84EC652C406CE1304E6
:1006C0000400930400061309E00FB7090002130A9F
:1006D0000003E136834764001375F50FA303A400FC
:1006E00099C30D31FDB7630F950063042503E31231
:1006F00045FF3D45493E553605052312A4003D45BD
:100700005936C1BF3D454136313783476400F1FB5F
:10071000FDB7138589000D397DD11305000FCDB7C5
:10072000011106CE22CC1D333704000213058400CC
:10073000192E130584009921E1689388086A0148FD
:100740008147780085460146B705D9EB130584003B
:10075000230601007126E168814701478146014671
:10076000B70538FF9388086A0148130584008D2E69
:10077000713437070002B715080037460F002320F1
:100780000704814781469385054013061624C84D0A
:100790001375050211CD85CA2320F70437470F00D2
:1007A000130707246391E702793B01A08546C5B78B
:1007B0008507E39DC7FE81CAB7470F0093870724CB
:1007C0002320F704D5B7DD350547AA876305E50281
:1007D00009476300E506054591EBB7060600DC4ACC
:1007E0007D771307F73FF98FDCCA014582807D17BB
:1007F00019EB0D4582809306004037A707001307C9
:100800000712B7050500905D7D8E75D2370606008C
:100810005C4A7D771307F73FF98FD58F41115CCA8A
:1008200002C613073006B2476359F700014541017C
:100830008280856693860680C9B7B24785073EC623
:10084000DDB791476307F50263EAA7008547630AAE
:10085000F50489476309F50405458280A147E31D36
:10086000F5FE0947094501A8FD1781EFC8D20D45DE
:10087000828005470D45B7A7070093870712B70683
:100880000500905E798E6DD28A05C98D4111CCD25A
:1008900002C613073006B247635AF700014541010B
:1008A00082801147C9BF21470145F1B7B24785078B
:1008B0003EC6D5B70547AA876305E5020947630227
:1008C000E506054591EBB70606009C4A7D771307C0
:1008D000F73FF98F9CCA014582807D1719EB0D45C2
:1008E00082809306004037A7070013070712B70559
:1008F0000500905D7D8E75D2370706001C4B7D7616
:100900001306F63FF18FD58F1CCB85471CCF4111C5
:1009100002C613073006B2476359F700014541018B
:1009200082808566938606807DBFB24785073EC676
:10093000DDB711C98547630DF50205458280FD17B6
:1009400091EB0D4582800946B7A7070093870712F0
:10095000B7060500985E718F7DD34111C8D602C6D7
:1009600013073006B2476357F70001454101828003
:100970000546D9BFB24785073EC6EDB7011126CA65
:10098000B7040600DC4806CE22CC4AC84EC652C484
:1009900056C2F19BDCC89C482A89C845F19B9CC87B
:1009A00083C7C5012E848A07DCC883C7D5018A079F
:1009B0009CC8193D0C44AA8A03454400593518487F
:1009C000B70705002A8A98C358480850D8C3184C5E
:1009D00098C7CD35AA894850A93F834704002A8784
:1009E00093F6170089E6D44893E62600D4C893F618
:1009F000270099E637060600544A93E6160054CAC3
:100A000093F6470099E637060600144A93E6260057
:100A100014CAA18B99E7B70606009C4A93E7170012
:100A20009CCAF24062442320590123224901232415
:100A300039012326E900D244B249224A924A4A8522
:100A4000424905618280011106CE22CC02C402C651
:100A50002147B707050037550800D8C705448D471B
:100A60008A85130505803EC022C2292A3755080011
:100A70009307C0038A851305058022C222C43EC0A5
:100A80001122F240624405618280411122C406C6EF
:100A90002A84553F18405C4F93E707015CCF1C4404
:100AA0001CCB5C4085CB1C43B7061000D58F1CC304
:100AB000144C5C48B240D606CE07D58F834604015D
:100AC000C206D58F8346C4012244E206D58F1CCFCF
:100AD000410182801C43B706F0FFFD16F58FC1BFB0
:100AE000032305002A8E0325C30113650502232E67
:100AF000A3002324C3001396260149824D8E23268A
:100B000003012322C300139605016354060299C210
:100B10000545B1CB01476346D700639C08020D45EC
:100B200082803386E700034606000507230AC300D8
:100B3000DDB799C2054505CB8147E3D0D7FE032633
:100B40000E00034546013306F70085072300A60083
:100B5000EDB783270E00FD18DC4F93F70702D5DFB2
:100B600011656D8D11E18280B707070083C74701CA
:100B700013F585001D8D3335A00082801C4141474F
:100B8000D8CF8280B7470800938707402A8863043C
:100B9000F508B7570800938707806304F50A3747BD
:100BA0000800630DE50A05458280331E1F01337678
:100BB000DE0129C683A345008843139318003396AA
:100BC0006F001346F6FF13F43300718D3314640085
:100BD000418D88C3638B5302638C0302084303AEC9
:100BE000C500718D331E6E003365C50108C3884290
:100BF000698E884533156500498E90C2850833D5C6
:100C00001E0145F53244410182802326C801F9B70F
:100C10002324C801E1B7B716050037170500B71739
:100C20000500938646C1130707C19387C7C083AEEB
:100C300005008148054F8D4F914233D51E0105EDCA
:100C40008280B716050037170500B7170500938691
:100C500006C21307C7C1938787C1D1BFB716050066
:100C600037170500B7170500938686C0130747C0DE
:100C7000938707C06DBF331E1F013376DE0119E273
:100C8000850865BF411122C635B7E1689388086AB7
:100C900001488147014781460146B705200689B5CD
:100CA000011106CEA307010089476393F502B7053A
:100CB0002035E1681307F1009388086A01488147ED
:100CC00085460146313DF2400345F10005618280D1
:100CD000B7052005F9BF011106CE22CC26CA23068E
:100CE000B100AA84A306C1004D37E1689388086A61
:100CF00001487C00014789460146B78520012685C9
:100D00000964F93B130414717D1419E40D45F24094
:100D10006244D24405618280854526855137058924
:100D200065F50145EDB7011106CE22CC26CA2E8409
:100D30004AC8AA84328936C6893FB247E16822860A
:100D40009388086A01480147CA86B78580022685CC
:100D5000616479331304146A7D1411C485452685B2
:100D60008137058975F9F2406244D24442490561F0
:100D70008280011106CE22CC26CA2EC6AA84313723
:100D80003246E1689388086A0148814701478146F5
:100D9000B705802026856164A1331304146A7D148D
:100DA00011C485452685ED3D058975F9F2406244FB
:100DB000D24405618280B3C7A5008D8BB308C500FE
:100DC000B1E78D4763F4C704937735002A87B9EB01
:100DD00013F6C8FFB306E6409307000263C8D706C0
:100DE000AE86BA876371C70203A806009107910611
:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47
:100E000091073E97BE956366170182802A87637EAD
:100E1000150383C7050005078505A30FF7FEE39AB1
:100E2000E8FE828083C60500050793773700A30F8D
:100E3000D7FE8505D1DF83C6050005079377370008
:100E4000A30FD7FE8505F9FF61B78280411122C645
:100E50001304000283A3050083A2450083AF85002D
:100E600003AFC50083AE050103AE450103A38501B1
:100E700003A8C501945113074702B307E640232E88
:100E800077FC232057FE2322F7FF2324E7FF2326A6
:100E9000D7FF2328C7FF232A67FE232C07FF232E13
:100EA000D7FE93854502E347F4FAAE86BA876371AD
:100EB000C70203A806009107910623AE07FFE3EAE5
:100EC000C7FE9307F6FF998FF19B91073E97BE955A
:100ED0006365170132444101828083C7050005071D
:100EE0008505A30FF7FEE387E8FE83C70500050726
:100EF0008505A30FF7FEE392E8FEE9BF200000009E
:100F0000010000000300000006000000EB000000EC
:100F10000000008000010000000007000000000049
:100F200000000000000000000000000000000000C1
:100F300000000000000000000000000000000000B1
:0400000501000000F6
:00000001FF

57
cores/arduino/Arduino.h Normal file
View File

@ -0,0 +1,57 @@
/*
Arduino.h - Main include file for the Arduino SDK
Copyright (c) 2005-2013 Arduino Team. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Arduino_h
#define Arduino_h
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#endif
#if GCC_VERSION < 60300
#error "GCC version 6.3 or higher is required"
#endif
#ifdef __IN_ECLIPSE__
// #include "SrcWrapper.h"
#endif
#include "wiring.h"
// void ErrorMsgHandler(const char * msg);
/* sketch */
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
extern void setup(void) ;
extern void loop(void) ;
// void yield(void)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
// Include pins variant
#include "pins_arduino.h"
#endif // Arduino_h

View File

@ -0,0 +1,186 @@
/*
HardwareSerial.cpp - Hardware serial library for Wiring
*/
#include "HardwareSerial.h"
#include <uart_lib.h>
#include "mik32_hal_irq.h"
// объект класса HardwareSerial для использования в arduino ide
HardwareSerial Serial;
void serialEvent() __attribute__((weak));
bool Serial0_available() __attribute__((weak));
void serialEventRun(void)
{
if (Serial0_available && serialEvent && Serial0_available())
serialEvent();
}
// Public Methods
void HardwareSerial::begin(unsigned long baud, uint8_t config)
{
// find the frequency divider (F_CPU is in the preprocessor defines)
uint32_t brr = (uint32_t)(F_CPU/baud);
if (brr < 16) // the driver says that the divisor must be at least 16
brr = 16;
// parse config
uint32_t reg1config = UART_CONTROL1_RE_M | UART_CONTROL1_TE_M | UART_CONTROL1_RXNEIE_M;
uint32_t reg2config = 0;
uint32_t reg3config = 0;
// first look at parity, because the parity bit is included in the data length
bool useParity = true;
if ((config >> 4) == 0) // no - everything is zero, don't set anything in reg1config
useParity = false;
else if ((config >> 4) == 2) // even
reg1config |= UART_CONTROL1_PCE_M;
else if ((config >> 4) == 3) // odd
reg1config |= (UART_CONTROL1_PCE_M | UART_CONTROL1_PS_M);
// data length
if (((config & 0x07) == 4) && (useParity == false)) // 7 bit + no parity
// 7 bits without parity - configure 7 bits
reg1config |= UART_CONTROL1_M_7BIT_M;
else if (((config & 0x07) == 6) && (useParity == true)) // 8 bit + parity
// 8 bits with parity - configure 9 bits
reg1config |= UART_CONTROL1_M_9BIT_M;
// if 7 bits with parity or 8 bits without parity - do not change anything,
// leaving the data length selected as 8 bits
// stop bit // stop bit = 1 - everything is zero, don't set anything
if ((config >> 3) & (0x01 == 1)) // stop bit = 2
reg2config |= UART_CONTROL2_STOP_1_M;
// turn on the receiver and transmitter, apply the parsed config
UART_Init(UART_0, brr, reg1config, reg2config, reg3config);
// Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled
HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK);
isInited = true;
}
void HardwareSerial::end()
{
if (isInited)
{
// wait for the data to be sent if necessary
flush();
// disable clock
__HAL_PCC_UART_0_CLK_DISABLE();
HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK);
// reconfigure pins to z state
GPIO_InitTypeDef GPIO_InitStruct;
memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)(GPIO_PIN_5 | GPIO_PIN_6);
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
// reset buffer indices
_rx_buffer_head = _rx_buffer_tail = 0;
isInited = false;
}
}
int HardwareSerial::available(void)
{
// free space in buffer
return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
}
int HardwareSerial::availableForWrite(void)
{
// don't use buffer
return -1;
}
void HardwareSerial::rx_complete_irq(void)
{
// find next index in buffer with upper limit
uint8_t i = (uint8_t)(_rx_buffer_head + 1)%SERIAL_RX_BUFFER_SIZE;
unsigned char c;
// while there is something to receive, put the data into the buffer
// and edit the buffer index
while (!UART_IsRxFifoEmpty(UART_0))
{
c = UART_ReadByte(UART_0);
if (i != _rx_buffer_tail)
{
// write if there is space in the buffer
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
}
}
// wrapper for use in С-files
extern "C" void serial_handler_wrapper(void)
{
Serial.rx_complete_irq();
}
int HardwareSerial::peek(void)
{
if (_rx_buffer_head == _rx_buffer_tail) // nothing to read
return -1;
else
return _rx_buffer[_rx_buffer_tail]; // return first element
}
int HardwareSerial::read(void)
{
// if there is nothing to read, return -1
if (_rx_buffer_head == _rx_buffer_tail)
return -1;
else
{
// return first element and edit the buffer index
unsigned char c = _rx_buffer[_rx_buffer_tail];
_rx_buffer_tail = (uint8_t)(_rx_buffer_tail + 1)%SERIAL_RX_BUFFER_SIZE;
return (int)c;
}
}
// write byte
size_t HardwareSerial::write(uint8_t c)
{
if (isInited)
{
UART_WriteByte(UART_0, c);
UART_WaitTransmission(UART_0);
return 1;
}
else
return 0;
}
// write bytes buffer
size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
{
if (isInited)
{
size_t n = 0;
while (size--)
{
if (HardwareSerial::write(*buffer++))
n++;
else
break;
}
return n;
}
else
return 0;
}
void HardwareSerial::flush()
{
// wait for the data transfer complete
while((UART_0->FLAGS & UART_FLAGS_TC_M) == 0)
;
}

View File

@ -0,0 +1,103 @@
/*
HardwareSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "stdint.h"
#include "Stream.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
// NOTE: a "power of 2" buffer size is recommended to dramatically
// optimize all the modulo operations for ring buffers.
// WARNING: When buffer sizes are increased to > 256, the buffer index
// variables are automatically increased in size, but the extra
// atomicity guards needed for that are not implemented. This will
// often work, but occasionally a race condition can occur that makes
// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405
#define SERIAL_RX_BUFFER_SIZE 64
// Define config for Serial.begin(baud, config);
// parity: 7...4 bits = 0 (no), 2 (even), 3 (odd)
// stop bit: 3 bit = 0 (1 bit), 1 (2 bits)
// data width: 2...0 bits = 4 (7 bit), 6 (8 bit)
// ------- No parity (N) -------
// 1stop bit
#define SERIAL_7N1 0x04 // 00000100
#define SERIAL_8N1 0x06 // 00000110
// 2stop bits
#define SERIAL_7N2 0x0C // 00001100
#define SERIAL_8N2 0x0E // 00001110
// ------- Even parity -------
#define SERIAL_7E1 0x24 // 00100100
#define SERIAL_8E1 0x26 // 00100110
#define SERIAL_7E2 0x2C // 00101100
#define SERIAL_8E2 0x2E // 00101110
// ------- Odd parity -------
#define SERIAL_7O1 0x34 // 00110100
#define SERIAL_8O1 0x36 // 00110110
#define SERIAL_7O2 0x3C // 00111100
#define SERIAL_8O2 0x3E // 00111110
class HardwareSerial : public Stream
{
protected:
volatile uint8_t _rx_buffer_head;
volatile uint8_t _rx_buffer_tail;
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
private:
bool isInited = false;
public:
inline HardwareSerial(){};
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint8_t);
void end();
virtual int available(void);
virtual int availableForWrite(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
size_t write(uint8_t) override;
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
size_t write(const uint8_t *buffer, size_t size);
using Print::write; // pull in write(str)
operator bool() { return isInited; }
void rx_complete_irq(void);
};
extern HardwareSerial Serial;
extern void serialEventRun(void) __attribute__((weak));
#endif

267
cores/arduino/Print.cpp Normal file
View File

@ -0,0 +1,267 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
Modified 03 August 2015 by Chuck Todd
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Arduino.h"
#include "Print.h"
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--)
{
if (write(*buffer++)) n++;
else break;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
if (write(c)) n++;
else break;
}
return n;
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
} else {
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0) return write(n);
else return printNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
return write("\r\n");
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
// Private Methods /////////////////////////////////////////////////////////////
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2) base = 10;
do {
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
return write(str);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}

96
cores/arduino/Print.h Normal file
View File

@ -0,0 +1,96 @@
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#include "WString.h"
#include "string.h"
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
#undef BIN
#endif
#define BIN 2
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
size_t write(const char *str)
{
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overridden by subclasses with buffering
virtual int availableForWrite() { return 0; }
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ }
};
#endif

39
cores/arduino/Printable.h Normal file
View File

@ -0,0 +1,39 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include <stdlib.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable {
public:
virtual size_t printTo(Print &p) const = 0;
};
#endif

318
cores/arduino/Stream.cpp Normal file
View File

@ -0,0 +1,318 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
findMulti/findUntil routines written by Jim Leonard/Xuth
*/
#include "Arduino.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
// protected method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
do {
c = read();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// protected method to peek stream with timeout
int Stream::timedPeek()
{
int c;
_startMillis = millis();
do {
c = peek();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
{
int c;
while (1) {
c = timedPeek();
if( c < 0 ||
c == '-' ||
(c >= '0' && c <= '9') ||
(detectDecimal && c == '.')) return c;
switch( lookahead ){
case SKIP_NONE: return -1; // Fail code.
case SKIP_WHITESPACE:
switch( c ){
case ' ':
case '\t':
case '\r':
case '\n': break;
default: return -1; // Fail code.
}
case SKIP_ALL:
break;
}
read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, strlen(target), NULL, 0);
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
if (terminator == NULL) {
MultiTarget t[1] = {{target, targetLen, 0}};
return findMulti(t, 1) == 0 ? true : false;
} else {
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
return findMulti(t, 2) == 0 ? true : false;
}
}
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == ignore)
; // ignore this character
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == ignore );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
bool isFraction = false;
long value = 0;
int c;
float fraction = 1.0;
c = peekNextDigit(lookahead, true);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if(c == ignore)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1;
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length) {
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;
count++;
}
return count;
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c < 0 || c == terminator) break;
*buffer++ = (char)c;
index++;
}
return index; // return number of characters, not including null terminator
}
String Stream::readString()
{
String ret;
int c = timedRead();
while (c >= 0)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
String Stream::readStringUntil(char terminator)
{
String ret;
int c = timedRead();
while (c >= 0 && c != terminator)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
if (t->len <= 0)
return t - targets;
}
while (1) {
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
// the simple case is if we match, deal with that first.
if (c == t->str[t->index]) {
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do {
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0) {
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i) {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index) {
t->index++;
break;
}
// otherwise we just try the next index
} while (t->index);
}
}
// unreachable
return -1;
}

129
cores/arduino/Stream.h Normal file
View File

@ -0,0 +1,129 @@
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/
#ifndef Stream_h
#define Stream_h
#include <inttypes.h>
#include "Print.h"
// compatibility macros for testing
/*
#define getInt() parseInt()
#define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
// This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input.
enum LookaheadMode{
SKIP_ALL, // All invalid characters are ignored.
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{
protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // read stream with timeout
int timedPeek(); // peek stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
Stream() {_timeout=1000;}
// parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); }
// returns true if target string is found, false if timed out (see setTimeout)
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
// returns true if target string is found, false if timed out
bool find(char target) { return find (&target, 1); }
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
String readStringUntil(char terminator);
protected:
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
struct MultiTarget {
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#undef NO_IGNORE_CHAR
#endif

158
cores/arduino/Tone.cpp Normal file
View File

@ -0,0 +1,158 @@
#include "Arduino.h"
#include "pins_arduino.h"
#include "mik32_hal_timer16.h"
#include "mik32_hal_irq.h"
#define PRESCALERS_QTY 7
typedef struct
{
unsigned int frequency;
uint8_t prescaler;
uint32_t period_ticks;
}FrequencyParams_t;
FrequencyParams_t frequencyParams = {0, 0, 0};
// timer handler
Timer16_HandleTypeDef htimer16_1;
// timer_toggle_count:
// > 0 - duration specified
// = 0 - stopped
// < 0 - infinitely (until noTone() called)
volatile long timer_toggle_count;
// tone pin params
volatile int8_t timer_pin = -1;
volatile GPIO_TypeDef* timer_pin_port = 0;
volatile HAL_PinsTypeDef timer_pin_mask = (HAL_PinsTypeDef)0;
bool timerIsOn = false;
static void Timer16_Init(uint8_t prescaler)
{
htimer16_1.Instance = TIMER16_1;
htimer16_1.Clock.Source = TIMER16_SOURCE_INTERNAL_SYSTEM;
// prescaler depends on required frequency
htimer16_1.Clock.Prescaler = prescaler;
htimer16_1.CountMode = TIMER16_COUNTMODE_INTERNAL;
htimer16_1.ActiveEdge = TIMER16_ACTIVEEDGE_RISING;
htimer16_1.Preload = TIMER16_PRELOAD_AFTERWRITE;
htimer16_1.Trigger.Source = 0;
// timer triggers by software
htimer16_1.Trigger.ActiveEdge = TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE;
htimer16_1.Trigger.TimeOut = TIMER16_TIMEOUT_DISABLE;
htimer16_1.Filter.ExternalClock = TIMER16_FILTER_NONE;
htimer16_1.Filter.Trigger = TIMER16_FILTER_NONE;
htimer16_1.Waveform.Enable = TIMER16_WAVEFORM_GENERATION_ENABLE;
htimer16_1.Waveform.Polarity = TIMER16_WAVEFORM_POLARITY_NONINVERTED;
htimer16_1.EncoderMode = TIMER16_ENCODER_DISABLE;
HAL_Timer16_Init(&htimer16_1);
}
// calculate prescaler and period in timer ticks for required frequancy
static void calcFrequencyParams(FrequencyParams_t* params, unsigned int newFrequency)
{
// limit the frequency to an acceptable range
if (newFrequency < TONE_MIN_FREQUENCY_HZ) newFrequency = TONE_MIN_FREQUENCY_HZ;
if (newFrequency > TONE_MAX_FREQUENCY_HZ) newFrequency = TONE_MAX_FREQUENCY_HZ;
// go through the prescalers possible values to find the appropriate one.
// prescaler is set to a value from 0 to 7
uint32_t tempPeriod;
for (uint8_t prescaler = 0; prescaler < PRESCALERS_QTY; prescaler++)
{
// timer frequency is 2 times greater than the required signal frequency
tempPeriod = F_CPU / ((1 << prescaler) * 2 * newFrequency);
if (tempPeriod <= UINT16_MAX)
{
// if period is suitable save the current prescaler and period
params->frequency = newFrequency;
params->prescaler = prescaler;
params->period_ticks = tempPeriod;
break;
}
}
}
// start tone with frequency (in hertz) and duration (in milliseconds)
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
{
if (!timerIsOn) // if tone is not generated at the moment
{
// calculate the parameters necessary to ensure a given frequency if the frequency has changed
if (frequencyParams.frequency != frequency)
calcFrequencyParams(&frequencyParams, frequency);
// Calculate the toggle count
if (duration > 0)
timer_toggle_count = (duration * (F_CPU/(frequencyParams.period_ticks*(1<<frequencyParams.prescaler))))/1000 - 1;
else
timer_toggle_count = -1;
// save info about the selected tone pin
timer_pin = pin;
timer_pin_port = digitalPinToPort(pin);
timer_pin_mask = digitalPinToBitMask(pin);
// initialize the timer and pin, enable timer interrupt and start the count
Timer16_Init(frequencyParams.prescaler);
HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER16_1_MASK);
pinMode(pin, OUTPUT);
timer_pin_port->CLEAR = timer_pin_mask;
HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks);
timerIsOn = true;
}
// if tone is generated, but the same pin that works now is specified
else if (timerIsOn && (pin == timer_pin))
{
// change frequency if necessary
if (frequency != frequencyParams.frequency)
{
calcFrequencyParams(&frequencyParams, frequency);
htimer16_1.Clock.Prescaler = frequencyParams.prescaler; // update value in common structure
HAL_Timer16_SetPrescaler(&htimer16_1, frequencyParams.prescaler); // the timer is turned off inside the function
HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks); // start with a new period
}
}
}
// stop tone
void noTone(uint8_t pin)
{
if (timerIsOn)
{
timer_pin_port->CLEAR = timer_pin_mask; // pin to 0
htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer
HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK);
pinMode(pin, INPUT); // deinit pin
timer_pin = -1; // reset to default
timerIsOn = false;
}
}
// irq handler
extern "C" void tone_interrupt_handler(void)
{
if ((htimer16_1.Instance->ISR & htimer16_1.Instance->IER) & TIMER16_ISR_ARR_MATCH_M)
{
// timer period has passed, change the pin state
if (timer_toggle_count != 0)
{
timer_pin_port->OUTPUT_ ^= timer_pin_mask;
if (timer_toggle_count > 0)
timer_toggle_count--;
}
else
{
// turn off if the specified duration has passed
timer_pin_port->CLEAR = timer_pin_mask;
noTone(timer_pin);
}
}
// reset timer interrupt flags
htimer16_1.Instance->ICR = 0xFFFFFFFF;
}

23
cores/arduino/Tone.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _TONE_H_
#define _TONE_H_
#include "stdint.h"
#define TONE_MIN_FREQUENCY_HZ 4
#define TONE_MAX_FREQUENCY_HZ 40000
/*
* \brief
* Start tone on specified pin with frequency in range
* TONE_MIN_FREQUENCY_HZ...TONE_MAX_FREQUENCY_HZ.
* If duration = 0, tone won't stop until noTone() has called
*/
void tone(uint8_t pin, unsigned int frequency, unsigned long duration = 0);
/*
* \brief
* Stop tone on specified pin
*/
void noTone(uint8_t pin);
#endif /* _TONE_H_ */

168
cores/arduino/WCharacter.h Normal file
View File

@ -0,0 +1,168 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Character_h
#define Character_h
#include <ctype.h>
// WCharacter.h prototypes
inline bool isAlphaNumeric(int c) __attribute__((always_inline));
inline bool isAlpha(int c) __attribute__((always_inline));
inline bool isAscii(int c) __attribute__((always_inline));
inline bool isWhitespace(int c) __attribute__((always_inline));
inline bool isControl(int c) __attribute__((always_inline));
inline bool isDigit(int c) __attribute__((always_inline));
inline bool isGraph(int c) __attribute__((always_inline));
inline bool isLowerCase(int c) __attribute__((always_inline));
inline bool isPrintable(int c) __attribute__((always_inline));
inline bool isPunct(int c) __attribute__((always_inline));
inline bool isSpace(int c) __attribute__((always_inline));
inline bool isUpperCase(int c) __attribute__((always_inline));
inline bool isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline bool isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline bool isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline bool isAscii(int c)
{
return ( isascii (c) == 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline bool isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline bool isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline bool isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline bool isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline bool isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline bool isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline bool isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline bool isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline bool isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline bool isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
return toascii (c);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
#endif

132
cores/arduino/WInterrupts.c Normal file
View File

@ -0,0 +1,132 @@
#include <inttypes.h>
#include "mik32_hal_irq.h"
#include "pins_arduino.h"
#include "wiring_digital.h"
#include "WInterrupts.h"
extern void ErrorMsgHandler(const char * msg);
typedef void (*voidFuncPtr)(void);
// empty irq handler
static void nothing(void)
{
;
}
// enable global interrupts
void interrupts(void)
{
HAL_IRQ_EnableInterrupts();
}
// disable global interrupts
void noInterrupts(void)
{
HAL_IRQ_DisableInterrupts();
}
// we can provide no more than 8 interrupts on gpio at the same time
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] =
{
#if EXTERNAL_NUM_INTERRUPTS > 7
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 6
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 5
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 4
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 3
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 2
nothing,
#endif
nothing,
nothing,
};
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
{
// if the interrupt number does not exceed the total number
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
intFunc[interruptNum] = userFunc; // save pointer to irq handler
// init pin as input without pullups
pinMode(interruptToDigitalPin(interruptNum), INPUT);
// interrupt line initialization
HAL_GPIO_InterruptMode halMode;
if (mode == LOW) halMode = GPIO_INT_MODE_LOW;
else if (mode == HIGH) halMode = GPIO_INT_MODE_HIGH;
else if (mode == CHANGE) halMode = GPIO_INT_MODE_CHANGE;
else if (mode == FALLING) halMode = GPIO_INT_MODE_FALLING;
else if (mode == RISING) halMode = GPIO_INT_MODE_RISING;
else return;
HAL_GPIO_InitInterruptLine(interruptToGpioIntMux(interruptNum), halMode);
// turn on the mask in EPIC
if ((halMode == GPIO_INT_MODE_LOW) || (halMode == GPIO_INT_MODE_HIGH))
// by level
HAL_EPIC_MaskLevelSet(HAL_EPIC_GPIO_IRQ_MASK);
else
// by edge
HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK);
}
else
ErrorMsgHandler("attachInterrupt(): incorrect interrupt number\n\r");
}
void detachInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
// disable the interrupt in line
HAL_GPIO_DeInitInterruptLine(interruptToGpioIntLine(interruptNum));
intFunc[interruptNum] = nothing;
// we don't change anything in the EPIC controller, in case there are still configured lines left
}
}
// disable single interrupt
void disableInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
// disable gpio interrupt line
GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num);
}
}
// enable single interrupt
void enableInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
// enable gpio interrupt line
GPIO_IRQ->ENABLE_SET = (1 << irq_line_num);
}
}
// common gpio interrupt handler
void gpio_interrupts_handler(void)
{
// go through all the interrupts and call the handler for the triggered line
for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++)
{
if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i)))
intFunc[i]();
}
HAL_GPIO_ClearInterrupts();
}

View File

@ -0,0 +1,26 @@
#ifndef _WIRING_INTERRUPTS_
#define _WIRING_INTERRUPTS_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// enable/disable interrupts
void interrupts(void);
void noInterrupts(void);
// attach/detach interrupt to pin
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode);
void detachInterrupt(uint8_t interruptNum);
// enable/disable single external interrupt by it's number
void disableInterrupt(uint8_t interruptNum);
void enableInterrupt(uint8_t interruptNum);
#ifdef __cplusplus
}
#endif
#endif /* _WIRING_INTERRUPTS_ */

65
cores/arduino/WMath.cpp Normal file
View File

@ -0,0 +1,65 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
extern "C" {
#include "stdlib.h"
#include "stdint.h"
}
#include "WMath.h"
void randomSeed(uint32_t dwSeed)
{
if (dwSeed != 0) {
srand(dwSeed) ;
}
}
long random(long howbig)
{
if (howbig == 0) {
return 0 ;
}
return rand() % howbig;
}
long random(long howsmall, long howbig)
{
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
return random(diff) + howsmall;
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
uint16_t makeWord(uint16_t w)
{
return w ;
}
uint16_t makeWord(uint8_t h, uint8_t l)
{
return (h << 8) | l ;
}

33
cores/arduino/WMath.h Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _WIRING_MATH_
#define _WIRING_MATH_
long random(long);
long random(long, long);
void randomSeed(uint32_t dwSeed);
long map(long, long, long, long, long);
uint16_t makeWord(uint16_t w);
uint16_t makeWord(uint8_t h, uint8_t l);
#define word(...) makeWord(__VA_ARGS__)
#endif /* _WIRING_MATH_ */

751
cores/arduino/WString.cpp Normal file
View File

@ -0,0 +1,751 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "WString.h"
#include "itoa.h"
/*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
String::String(const String &value)
{
init();
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
String::String(unsigned char value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base);
*this = buf;
}
String::String(int value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base);
*this = buf;
}
String::String(unsigned int value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base);
*this = buf;
}
String::String(long value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base);
*this = buf;
}
String::String(unsigned long value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base);
*this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::String(double value, unsigned char decimalPlaces)
{
init();
char buf[33];
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::~String()
{
if (buffer) free(buffer);
}
/*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
void String::invalidate(void)
{
if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (PGM_P)pstr);
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void String::move(String &rhs)
{
if (buffer) {
if (rhs && capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}
String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{
return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
strcpy(buffer + len, cstr);
len = newlen;
return 1;
}
unsigned char String::concat(const char *cstr)
{
if (!cstr) return 0;
return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return concat(buf, 1);
}
unsigned char String::concat(unsigned char num)
{
char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10);
return concat(buf, strlen(buf));
}
unsigned char String::concat(float num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(double num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string, strlen(string));
}
unsigned char String::concat(const __FlashStringHelper * str)
{
if (!str) return 0;
int length = strlen_P((const char *) str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy_P(buffer + len, (const char *) str);
len = newlen;
return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}
char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}
/*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{
return indexOf(c, 0);
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) return -1;
const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
return temp - buffer;
}
int String::indexOf(const String &s2) const
{
return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
buffer[fromIndex + 1] = tempchar;
if (temp == NULL) return -1;
return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left >= len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}
/*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
}
void String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
}
void String::remove(unsigned int index){
// Pass the biggest integer as the count. The remove method
// below will take care of truncating it at the end of the
// string.
remove(index, (unsigned int)-1);
}
void String::remove(unsigned int index, unsigned int count){
if (index >= len) { return; }
if (count <= 0) { return; }
if (count > len - index) { count = len - index; }
char *writeTo = buffer + index;
len = len - count;
strncpy(writeTo, buffer + index + count,len - index);
buffer[len] = 0;
}
void String::toLowerCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
}
void String::toUpperCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
}
void String::trim(void)
{
if (!buffer || len == 0) return;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}
float String::toFloat(void) const
{
return float(toDouble());
}
double String::toDouble(void) const
{
if (buffer) return atof(buffer);
return 0;
}

230
cores/arduino/WString.h Normal file
View File

@ -0,0 +1,230 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/dtostrf.h>
#include <avr/pgmspace.h>
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String
{
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base=10);
explicit String(int, unsigned char base=10);
explicit String(unsigned int, unsigned char base=10);
explicit String(long, unsigned char base=10);
explicit String(unsigned long, unsigned char base=10);
explicit String(float, unsigned char decimalPlaces=2);
explicit String(double, unsigned char decimalPlaces=2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsuccessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
String & operator += (const char *cstr) {concat(cstr); return (*this);}
String & operator += (char c) {concat(c); return (*this);}
String & operator += (unsigned char num) {concat(num); return (*this);}
String & operator += (int num) {concat(num); return (*this);}
String & operator += (unsigned int num) {concat(num); return (*this);}
String & operator += (long num) {concat(num); return (*this);}
String & operator += (unsigned long num) {concat(num); return (*this);}
String & operator += (float num) {concat(num); return (*this);}
String & operator += (double num) {concat(num); return (*this);}
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character access
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{ getBytes((unsigned char *)buf, bufsize, index); }
const char* c_str() const { return buffer; }
char* begin() { return buffer; }
char* end() { return buffer + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
double toDouble(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void move(String &rhs);
#endif
};
class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num) : String(num) {}
StringSumHelper(double num) : String(num) {}
};
#endif // __cplusplus
#endif // String_class_h

36
cores/arduino/abi.cpp Normal file
View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
namespace std {
[[gnu::weak, noreturn]] void terminate() {
abort();
}
}
void __cxa_pure_virtual(void) {
std::terminate();
}
void __cxa_deleted_virtual(void) {
std::terminate();
}

View File

@ -0,0 +1,91 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@arduino.cc>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
//Commented code is the original version
/*char fmt[20];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(sout, fmt, val);
return sout;*/
// Handle negative numbers
unsigned int negative = 0;
if (val < 0.0)
{
negative = 1;
val = -val;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (int i=0; i<prec; ++i)
rounding /= 10.0;
val += rounding;
// Extract the integer part of the number
unsigned long int_part = (unsigned long)val;
double remainder = val - (double)int_part;
if(negative)
int_part = -int_part;
// Extract digits from the remainder
unsigned long dec_part = 0;
double decade = 1.0;
for(int i=0; i < prec; i++)
decade *= 10.0;
remainder *= decade;
dec_part = (int)remainder;
sprintf(sout, "%ld.%ld", int_part, dec_part);
// Handle minimum field width of the output string
// width is signed value, negative for left adjustment.
// Range -128,127
char fmt[129] = "";
unsigned int w = width;
if (width < 0) {
negative = 1;
w = -width;
} else {
negative = 0;
}
if(strlen(sout) < w) {
memset(fmt, ' ', 128);
fmt[w-strlen(sout)] = '\0';
if(negative == 0) {
char *tmp = strdup(sout);
strcpy(sout,fmt);
strcat(sout, tmp);
free(tmp);
} else {
// left adjustment
strcat(sout, fmt);
}
}
return sout;
}

View File

@ -0,0 +1,33 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2013 Arduino. All rights reserved.
Written by Cristian Maglie <c.maglie@arduino.cc>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __DTOSTRF_H_
#define __DTOSTRF_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,130 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1
#include <inttypes.h>
#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)
#define _SFR_BYTE(n) (n)
typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t;
#define memchr_P(str, c, len) memchr((str), (c), (len))
#define memcmp_P(a, b, n) memcmp((a), (b), (n))
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen))
#define memrchr_P(str, val, len) memrchr((str), (val), (len))
#define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(str, c) strchr((str), (c))
#define strchrnul_P(str, c) strchrnul((str), (c))
#define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(a, b) strcasecmp((a), (b))
#define strcasestr_P(a, b) strcasestr((a), (b))
#define strlcat_P(dest, src, len) strlcat((dest), (src), (len))
#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len))
#define strlen_P(s) strlen((const char *)(s))
#define strnlen_P(str, len) strnlen((str), (len))
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
#define strncat_P(a, b, n) strncat((a), (b), (n))
#define strncpy_P(a, b, n) strncpy((a), (b), (n))
#define strpbrk_P(str, chrs) strpbrk((str), (chrs))
#define strrchr_P(str, c) strrchr((str), (c))
#define strsep_P(strp, delim) strsep((strp), (delim))
#define strspn_P(str, chrs) strspn((str), (chrs))
#define strstr_P(a, b) strstr((a), (b))
#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__)
#define vfprintf_P(fp, s, ...) vfprintf((fp), (s), __VA_ARGS__)
#define printf_P(...) printf(__VA_ARGS__)
#define snprintf_P(s, n, ...) snprintf((s), (n), __VA_ARGS__)
#define vsprintf_P(s, ...) vsprintf((s), __VA_ARGS__)
#define vsnprintf_P(s, n, ...) vsnprintf((s), (n), __VA_ARGS__)
#define fprintf_P(fp, ...) fprintf((fp), __VA_ARGS__)
#define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#if 0
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#else
#define pgm_read_word(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned short *)(_addr); \
})
#define pgm_read_dword(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned long *)(_addr); \
})
#define pgm_read_float(addr) ({ \
typeof(addr) _addr = (addr); \
*(const float *)(_addr); \
})
#define pgm_read_ptr(addr) ({ \
typeof(addr) _addr = (addr); \
*(void * const *)(_addr); \
})
#endif
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#endif

541
cores/arduino/binary.h Normal file
View File

@ -0,0 +1,541 @@
/*
binary.h - Definitions for binary constants
Copyright (c) 2006 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Binary_h
#define Binary_h
#ifdef __cplusplus
extern "C" {
#endif
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
#define B11 3
#define B011 3
#define B0011 3
#define B00011 3
#define B000011 3
#define B0000011 3
#define B00000011 3
#define B100 4
#define B0100 4
#define B00100 4
#define B000100 4
#define B0000100 4
#define B00000100 4
#define B101 5
#define B0101 5
#define B00101 5
#define B000101 5
#define B0000101 5
#define B00000101 5
#define B110 6
#define B0110 6
#define B00110 6
#define B000110 6
#define B0000110 6
#define B00000110 6
#define B111 7
#define B0111 7
#define B00111 7
#define B000111 7
#define B0000111 7
#define B00000111 7
#define B1000 8
#define B01000 8
#define B001000 8
#define B0001000 8
#define B00001000 8
#define B1001 9
#define B01001 9
#define B001001 9
#define B0001001 9
#define B00001001 9
#define B1010 10
#define B01010 10
#define B001010 10
#define B0001010 10
#define B00001010 10
#define B1011 11
#define B01011 11
#define B001011 11
#define B0001011 11
#define B00001011 11
#define B1100 12
#define B01100 12
#define B001100 12
#define B0001100 12
#define B00001100 12
#define B1101 13
#define B01101 13
#define B001101 13
#define B0001101 13
#define B00001101 13
#define B1110 14
#define B01110 14
#define B001110 14
#define B0001110 14
#define B00001110 14
#define B1111 15
#define B01111 15
#define B001111 15
#define B0001111 15
#define B00001111 15
#define B10000 16
#define B010000 16
#define B0010000 16
#define B00010000 16
#define B10001 17
#define B010001 17
#define B0010001 17
#define B00010001 17
#define B10010 18
#define B010010 18
#define B0010010 18
#define B00010010 18
#define B10011 19
#define B010011 19
#define B0010011 19
#define B00010011 19
#define B10100 20
#define B010100 20
#define B0010100 20
#define B00010100 20
#define B10101 21
#define B010101 21
#define B0010101 21
#define B00010101 21
#define B10110 22
#define B010110 22
#define B0010110 22
#define B00010110 22
#define B10111 23
#define B010111 23
#define B0010111 23
#define B00010111 23
#define B11000 24
#define B011000 24
#define B0011000 24
#define B00011000 24
#define B11001 25
#define B011001 25
#define B0011001 25
#define B00011001 25
#define B11010 26
#define B011010 26
#define B0011010 26
#define B00011010 26
#define B11011 27
#define B011011 27
#define B0011011 27
#define B00011011 27
#define B11100 28
#define B011100 28
#define B0011100 28
#define B00011100 28
#define B11101 29
#define B011101 29
#define B0011101 29
#define B00011101 29
#define B11110 30
#define B011110 30
#define B0011110 30
#define B00011110 30
#define B11111 31
#define B011111 31
#define B0011111 31
#define B00011111 31
#define B100000 32
#define B0100000 32
#define B00100000 32
#define B100001 33
#define B0100001 33
#define B00100001 33
#define B100010 34
#define B0100010 34
#define B00100010 34
#define B100011 35
#define B0100011 35
#define B00100011 35
#define B100100 36
#define B0100100 36
#define B00100100 36
#define B100101 37
#define B0100101 37
#define B00100101 37
#define B100110 38
#define B0100110 38
#define B00100110 38
#define B100111 39
#define B0100111 39
#define B00100111 39
#define B101000 40
#define B0101000 40
#define B00101000 40
#define B101001 41
#define B0101001 41
#define B00101001 41
#define B101010 42
#define B0101010 42
#define B00101010 42
#define B101011 43
#define B0101011 43
#define B00101011 43
#define B101100 44
#define B0101100 44
#define B00101100 44
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51
#define B00110011 51
#define B110100 52
#define B0110100 52
#define B00110100 52
#define B110101 53
#define B0110101 53
#define B00110101 53
#define B110110 54
#define B0110110 54
#define B00110110 54
#define B110111 55
#define B0110111 55
#define B00110111 55
#define B111000 56
#define B0111000 56
#define B00111000 56
#define B111001 57
#define B0111001 57
#define B00111001 57
#define B111010 58
#define B0111010 58
#define B00111010 58
#define B111011 59
#define B0111011 59
#define B00111011 59
#define B111100 60
#define B0111100 60
#define B00111100 60
#define B111101 61
#define B0111101 61
#define B00111101 61
#define B111110 62
#define B0111110 62
#define B00111110 62
#define B111111 63
#define B0111111 63
#define B00111111 63
#define B1000000 64
#define B01000000 64
#define B1000001 65
#define B01000001 65
#define B1000010 66
#define B01000010 66
#define B1000011 67
#define B01000011 67
#define B1000100 68
#define B01000100 68
#define B1000101 69
#define B01000101 69
#define B1000110 70
#define B01000110 70
#define B1000111 71
#define B01000111 71
#define B1001000 72
#define B01001000 72
#define B1001001 73
#define B01001001 73
#define B1001010 74
#define B01001010 74
#define B1001011 75
#define B01001011 75
#define B1001100 76
#define B01001100 76
#define B1001101 77
#define B01001101 77
#define B1001110 78
#define B01001110 78
#define B1001111 79
#define B01001111 79
#define B1010000 80
#define B01010000 80
#define B1010001 81
#define B01010001 81
#define B1010010 82
#define B01010010 82
#define B1010011 83
#define B01010011 83
#define B1010100 84
#define B01010100 84
#define B1010101 85
#define B01010101 85
#define B1010110 86
#define B01010110 86
#define B1010111 87
#define B01010111 87
#define B1011000 88
#define B01011000 88
#define B1011001 89
#define B01011001 89
#define B1011010 90
#define B01011010 90
#define B1011011 91
#define B01011011 91
#define B1011100 92
#define B01011100 92
#define B1011101 93
#define B01011101 93
#define B1011110 94
#define B01011110 94
#define B1011111 95
#define B01011111 95
#define B1100000 96
#define B01100000 96
#define B1100001 97
#define B01100001 97
#define B1100010 98
#define B01100010 98
#define B1100011 99
#define B01100011 99
#define B1100100 100
#define B01100100 100
#define B1100101 101
#define B01100101 101
#define B1100110 102
#define B01100110 102
#define B1100111 103
#define B01100111 103
#define B1101000 104
#define B01101000 104
#define B1101001 105
#define B01101001 105
#define B1101010 106
#define B01101010 106
#define B1101011 107
#define B01101011 107
#define B1101100 108
#define B01101100 108
#define B1101101 109
#define B01101101 109
#define B1101110 110
#define B01101110 110
#define B1101111 111
#define B01101111 111
#define B1110000 112
#define B01110000 112
#define B1110001 113
#define B01110001 113
#define B1110010 114
#define B01110010 114
#define B1110011 115
#define B01110011 115
#define B1110100 116
#define B01110100 116
#define B1110101 117
#define B01110101 117
#define B1110110 118
#define B01110110 118
#define B1110111 119
#define B01110111 119
#define B1111000 120
#define B01111000 120
#define B1111001 121
#define B01111001 121
#define B1111010 122
#define B01111010 122
#define B1111011 123
#define B01111011 123
#define B1111100 124
#define B01111100 124
#define B1111101 125
#define B01111101 125
#define B1111110 126
#define B01111110 126
#define B1111111 127
#define B01111111 127
#define B10000000 128
#define B10000001 129
#define B10000010 130
#define B10000011 131
#define B10000100 132
#define B10000101 133
#define B10000110 134
#define B10000111 135
#define B10001000 136
#define B10001001 137
#define B10001010 138
#define B10001011 139
#define B10001100 140
#define B10001101 141
#define B10001110 142
#define B10001111 143
#define B10010000 144
#define B10010001 145
#define B10010010 146
#define B10010011 147
#define B10010100 148
#define B10010101 149
#define B10010110 150
#define B10010111 151
#define B10011000 152
#define B10011001 153
#define B10011010 154
#define B10011011 155
#define B10011100 156
#define B10011101 157
#define B10011110 158
#define B10011111 159
#define B10100000 160
#define B10100001 161
#define B10100010 162
#define B10100011 163
#define B10100100 164
#define B10100101 165
#define B10100110 166
#define B10100111 167
#define B10101000 168
#define B10101001 169
#define B10101010 170
#define B10101011 171
#define B10101100 172
#define B10101101 173
#define B10101110 174
#define B10101111 175
#define B10110000 176
#define B10110001 177
#define B10110010 178
#define B10110011 179
#define B10110100 180
#define B10110101 181
#define B10110110 182
#define B10110111 183
#define B10111000 184
#define B10111001 185
#define B10111010 186
#define B10111011 187
#define B10111100 188
#define B10111101 189
#define B10111110 190
#define B10111111 191
#define B11000000 192
#define B11000001 193
#define B11000010 194
#define B11000011 195
#define B11000100 196
#define B11000101 197
#define B11000110 198
#define B11000111 199
#define B11001000 200
#define B11001001 201
#define B11001010 202
#define B11001011 203
#define B11001100 204
#define B11001101 205
#define B11001110 206
#define B11001111 207
#define B11010000 208
#define B11010001 209
#define B11010010 210
#define B11010011 211
#define B11010100 212
#define B11010101 213
#define B11010110 214
#define B11010111 215
#define B11011000 216
#define B11011001 217
#define B11011010 218
#define B11011011 219
#define B11011100 220
#define B11011101 221
#define B11011110 222
#define B11011111 223
#define B11100000 224
#define B11100001 225
#define B11100010 226
#define B11100011 227
#define B11100100 228
#define B11100101 229
#define B11100110 230
#define B11100111 231
#define B11101000 232
#define B11101001 233
#define B11101010 234
#define B11101011 235
#define B11101100 236
#define B11101101 237
#define B11101110 238
#define B11101111 239
#define B11110000 240
#define B11110001 241
#define B11110010 242
#define B11110011 243
#define B11110100 244
#define B11110101 245
#define B11110110 246
#define B11110111 247
#define B11111000 248
#define B11111001 249
#define B11111010 250
#define B11111011 251
#define B11111100 252
#define B11111101 253
#define B11111110 254
#define B11111111 255
#ifdef __cplusplus
}
#endif
#endif

36
cores/arduino/board.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "board.h"
#include "mik32_hal_pcc.h"
#include "Arduino.h"
// --------------------- init --------------------- //
// called before setup()
void pre_init(void)
{
HAL_Init();
// gpio clock
__HAL_PCC_GPIO_0_CLK_ENABLE();
__HAL_PCC_GPIO_1_CLK_ENABLE();
__HAL_PCC_GPIO_2_CLK_ENABLE();
__HAL_PCC_GPIO_IRQ_CLK_ENABLE();
// for delays
SysTick_Init();
}
// called after setup()
void post_init(void)
{
// enable global interrupts by default
interrupts();
}
// --------------------- other --------------------- //
// print text if Serial is enabled
extern "C" void ErrorMsgHandler(const char * msg)
{
if(Serial)
Serial.println(msg);
}

8
cores/arduino/board.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _BOARD_H_
#define _BOARD_H_
// functions for init called before and after setup()
void pre_init(void) ;
void post_init(void);
#endif /* _BOARD_H_ */

174
cores/arduino/itoa.cpp Normal file
View File

@ -0,0 +1,174 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "itoa.h"
#include <string.h>
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
#if 0
/* reverse: reverse string s in place */
static void reverse( char s[] )
{
int i, j ;
char c ;
for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- )
{
c = s[i] ;
s[i] = s[j] ;
s[j] = c ;
}
}
/* itoa: convert n to characters in s */
extern void itoa( int n, char s[] )
{
int i, sign ;
if ( (sign = n) < 0 ) /* record sign */
{
n = -n; /* make n positive */
}
i = 0;
do
{ /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0) ; /* delete it */
if (sign < 0 )
{
s[i++] = '-';
}
s[i] = '\0';
reverse( s ) ;
}
#else
extern char* itoa( int value, char *string, int radix )
{
return ltoa( value, string, radix ) ;
}
extern char* ltoa( long value, char *string, int radix )
{
char tmp[33];
char *tp = tmp;
long i;
unsigned long v;
int sign;
char *sp;
if ( string == NULL )
{
return 0 ;
}
if (radix > 36 || radix <= 1)
{
return 0 ;
}
sign = (radix == 10 && value < 0);
if (sign)
{
v = -value;
}
else
{
v = (unsigned long)value;
}
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
sp = string;
if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
extern char* utoa( unsigned value, char *string, int radix )
#else
extern char* utoa( unsigned long value, char *string, int radix )
#endif
{
return ultoa( value, string, radix ) ;
}
extern char* ultoa( unsigned long value, char *string, int radix )
{
char tmp[33];
char *tp = tmp;
long i;
unsigned long v = value;
char *sp;
if ( string == NULL )
{
return 0;
}
if (radix > 36 || radix <= 1)
{
return 0;
}
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
sp = string;
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}
#endif /* 0 */
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

47
cores/arduino/itoa.h Normal file
View File

@ -0,0 +1,47 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _ITOA_
#define _ITOA_
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
#if 0
extern void itoa( int n, char s[] ) ;
#else
extern char* itoa( int value, char *string, int radix ) ;
extern char* ltoa( long value, char *string, int radix ) ;
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 9 || \
(__GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ > 2)))
extern char* utoa( unsigned value, char *string, int radix ) ;
#else
extern char* utoa( unsigned long value, char *string, int radix ) ;
#endif
extern char* ultoa( unsigned long value, char *string, int radix ) ;
#endif /* 0 */
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // _ITOA_

17
cores/arduino/main.cpp Normal file
View File

@ -0,0 +1,17 @@
#define ARDUINO_MAIN
#include "Arduino.h"
int main()
{
pre_init();
setup();
post_init();
while (1)
{
loop();
}
}

1
cores/arduino/mik32/hal/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode

View File

@ -0,0 +1 @@
# mcu32-hal

View File

@ -0,0 +1,105 @@
#ifndef MIK32_HAL_SCR1_TIMER
#define MIK32_HAL_SCR1_TIMER
#ifdef __cplusplus
extern "C" {
#endif
#include "mcu32_memory_map.h"
#include "power_manager.h"
#include "inttypes.h"
// #include "csr.h"
// #include "scr1_csr_encoding.h"
#include "scr1_timer.h"
#define MIK32_FREQ 32000000 /* Входная частота, Гц */
#define MIK32_FREQ_MHZ 32 /* Входная частота, МГц */
/* Источник тактированя */
#define SCR1_TIMER_CLKSRC_INTERNAL 0 /* Тактирование от ядра */
#define SCR1_TIMER_CLKSRC_EXTERNAL_RTC 1 /* Тактирование от внешнего RTC */
typedef struct
{
SCR1_TIMER_TypeDef *Instance; /* Базовый адрес регистров SCR1_TIMER */
uint8_t ClockSource; /* Источник тактирования */
uint16_t Divider; /* Делитель частоты 10-битное число */
} SCR1_TIMER_HandleTypeDef;
void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer);
void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer);
void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource);
void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider);
void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer);
void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds);
int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer);
uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer);
/* Время задержки должено быть не больше 134217 мс */
void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds);
#ifdef __cplusplus
}
#endif
#endif
/*
* uint32_t TIMER_CTRL;
* uint32_t TIMER_DIV;
* uint32_t MTIME;
* uint32_t MTIMEH;
* uint32_t MTIMECMP;
* uint32_t MTIMECMPH;
*/
/*
Регистр TIMER_CTRL
------------------------------------------------------------------------------------------------
Обозначение | Биты | По умолчанию | Описание | Доступ
------------------------------------------------------------------------------------------------
ENABLE | 0 | X | Включение таймера | RW
------------------------------------------------------------------------------------------------
CLKSRC | 1 | 0x0 | Источник тактирования | RW
| | | 0 - Тактирования ядра |
| | | 1 - Внешний RTC |
------------------------------------------------------------------------------------------------
Reserved | 31:2 | | RZ
------------------------------------------------------------------------------------------------
Регистр TIMER_DIV
------------------------------------------------------------------------------------------------
Обозначение | Биты | По умолчанию | Описание | Доступ
------------------------------------------------------------------------------------------------
DIV | 9:0 | X | Делитель | RW
| Счет идет каждые DIV+1 |
| такта частоты |
------------------------------------------------------------------------------------------------
Reserved | 31:10 | X | RZ
------------------------------------------------------------------------------------------------
По умолчанию, MTIME и MTIMEH равны нулю после перезагрузки ядра (которая также
начинает подсчет). Другим вариантом начала счета для MTIME/MTIMEH является запись некоторого значения в
MTIME/MTIMEH.
MTIME - Счетчик таймера. 64-битне число. MTIMEH - старшее слово, MTIME - младшее слово.
MTIMECMP - Регистр сравнения. 64-битное число. MTIMECMPH - старшее слово, MTIMECMP - младшее слово.
Прерывание машинного таймера становится ожидающим всякий раз, когда mtime содержит значение, большее или равное mtimecmp,
обрабатывая значения как целые числа без знака. Прерывание сохраняется до тех пор, пока mtimecmp не станет больше
mtime (обычно в результате записи mtimecmp). Прерывание будет принято только в том случае, если
включены прерывания и бит MTIE установлен в регистре mie.
*/

View File

@ -0,0 +1,125 @@
#include "mik32_hal_scr1_timer.h"
#include "mik32_hal.h"
void HAL_SCR1_Timer_Enable(SCR1_TIMER_HandleTypeDef *hscr1_timer)
{
hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_ENABLE_M;
}
void HAL_SCR1_Timer_Disable(SCR1_TIMER_HandleTypeDef *hscr1_timer)
{
hscr1_timer->Instance->TIMER_CTRL &= ~SCR1_TIMER_CTRL_ENABLE_M;
hscr1_timer->Instance->MTIME = 0;
hscr1_timer->Instance->MTIMEH = 0;
}
void HAL_SCR1_Timer_SetClockSource(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint8_t ClockSource)
{
hscr1_timer->ClockSource = ClockSource;
switch (ClockSource)
{
case SCR1_TIMER_CLKSRC_INTERNAL:
hscr1_timer->Instance->TIMER_CTRL &= SCR1_TIMER_CTRL_CLKSRC_INTERNAL_M;
break;
case SCR1_TIMER_CLKSRC_EXTERNAL_RTC:
hscr1_timer->Instance->TIMER_CTRL |= SCR1_TIMER_CTRL_CLKSRC_RTC_M;
break;
}
}
void HAL_SCR1_Timer_SetDivider(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint16_t Divider)
{
/* Divider 10-битное число */
if(Divider > 1023)
{
Divider = 1023;
}
hscr1_timer->Divider = Divider;
hscr1_timer->Instance->TIMER_DIV = Divider;
}
void HAL_SCR1_Timer_Init(SCR1_TIMER_HandleTypeDef *hscr1_timer)
{
hscr1_timer->Instance->TIMER_CTRL = 0;
/* Настройка источника тактирования */
HAL_SCR1_Timer_SetClockSource(hscr1_timer, hscr1_timer->ClockSource);
/* Настройка делителя */
HAL_SCR1_Timer_SetDivider(hscr1_timer, hscr1_timer->Divider);
HAL_SCR1_Timer_Start(hscr1_timer, 134217);
}
void HAL_SCR1_Timer_Start(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds)
{
uint8_t AHBMDivider = PM->DIV_AHB; /* Делитель частоты */
uint32_t Milliseconds_max_32bit = 134217; /* 134217 - максимальное число миллисекунд для того чтобы при расчете количества тактов не превысить 32 бита */
if (Milliseconds > Milliseconds_max_32bit)
{
Milliseconds = Milliseconds_max_32bit; /* Задержка равна предельному значению 134217, мс */
}
uint32_t Ticks = Milliseconds * (MIK32_FREQ/1000); /* Количество тактов системного таймера для достижения значения Milliseconds */
Ticks = Ticks / (AHBMDivider + 1);
Ticks = Ticks / (hscr1_timer->Divider + 1);
#ifdef MIK32_SCR1_TIMER_DEBUG
xprintf("Milliseconds = %u\n", Milliseconds);
xprintf("Ticks = %u\n", Ticks);
#endif
hscr1_timer->Instance->MTIME = 0;
hscr1_timer->Instance->MTIMEH = 0;
hscr1_timer->Instance->MTIMECMP = Ticks;
hscr1_timer->Instance->MTIMECMPH = 0;
HAL_SCR1_Timer_Enable(hscr1_timer);
}
uint64_t HAL_SCR1_Timer_Get_Ticks(SCR1_TIMER_HandleTypeDef *hscr1_timer)
{
return ((uint64_t)hscr1_timer->Instance->MTIMEH)<<32 | hscr1_timer->Instance->MTIME;
}
int HAL_SCR1_Timer_GetFlagCMP(SCR1_TIMER_HandleTypeDef *hscr1_timer)
{
uint32_t MTIME = hscr1_timer->Instance->MTIME;
uint32_t MTIMEH = hscr1_timer->Instance->MTIMEH;
uint32_t MTIMECMP = hscr1_timer->Instance->MTIMECMP;
uint32_t MTIMECMPH = hscr1_timer->Instance->MTIMECMPH;
if( ((MTIMEH == MTIMECMPH) && (MTIME > MTIMECMP)) || (MTIMEH > MTIMECMPH) )
{
HAL_SCR1_Timer_Disable(hscr1_timer);
return 1;
}
else
{
return 0;
}
}
void HAL_DelayMs(SCR1_TIMER_HandleTypeDef *hscr1_timer, uint32_t Milliseconds)
{
HAL_SCR1_Timer_Start(hscr1_timer, Milliseconds);
while (HAL_SCR1_Timer_GetFlagCMP(hscr1_timer) == 0);
HAL_SCR1_Timer_Disable(hscr1_timer);
}

View File

@ -0,0 +1,34 @@
#ifndef MIK32_HAL
#define MIK32_HAL
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_def.h"
#include "mik32_hal_pcc.h"
#ifndef OSC_SYSTEM_VALUE
#define OSC_SYSTEM_VALUE ((uint32_t)32000000U) // Значение частоты основного внешнего источника по умолчанию.
#endif
#ifndef OSC_CLOCK_VALUE
#define OSC_CLOCK_VALUE ((uint32_t)32768U) // Значение частоты часового внешнего источника по умолчанию.
#endif
#ifndef HSI_VALUE
#define HSI_VALUE ((uint32_t)32000000U) // Значение частоты основного внутреннего источника по умолчанию.
#endif
#ifndef LSI_VALUE
#define LSI_VALUE ((uint32_t)32768U) // Значение частоты часового внутреннего источника по умолчанию.
#endif
void HAL_MspInit();
HAL_StatusTypeDef HAL_Init();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,360 @@
#ifndef MIK32_HAL_ADC
#define MIK32_HAL_ADC
#ifdef __cplusplus
extern "C" {
#endif
#include "analog_reg.h"
#include "pad_config.h"
#include "stdbool.h"
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "mcu32_memory_map.h"
/* Title: Макросы */
/*
* Defines: Каналы АЦП
*
* ADC_CHANNEL0 - Канал АЦП0 (PORT_1_5)
* ADC_CHANNEL1 - Канал АЦП1 (PORT_1_7)
* ADC_CHANNEL2 - Канал АЦП2 (PORT_0_2)
* ADC_CHANNEL3 - Канал АЦП3 (PORT_0_4)
* ADC_CHANNEL4 - Канал АЦП4 (PORT_0_7)
* ADC_CHANNEL5 - Канал АЦП5 (PORT_0_9)
* ADC_CHANNEL6 - Канал АЦП6 (PORT_0_11)
* ADC_CHANNEL7 - Канал АЦП7 (PORT_0_13)
*
*/
#define ADC_CHANNEL0 0 /* Канал АЦП0 - PORT_1_5 */
#define ADC_CHANNEL1 1 /* Канал АЦП1 - PORT_1_7 */
#define ADC_CHANNEL2 2 /* Канал АЦП2 - PORT_0_2 */
#define ADC_CHANNEL3 3 /* Канал АЦП3 - PORT_0_4 */
#define ADC_CHANNEL4 4 /* Канал АЦП4 - PORT_0_7 */
#define ADC_CHANNEL5 5 /* Канал АЦП5 - PORT_0_9 */
#define ADC_CHANNEL6 6 /* Канал АЦП6 - PORT_0_11 */
#define ADC_CHANNEL7 7 /* Канал АЦП7 - PORT_0_13 */
/*
* Defines: Выбор ИОН
*
* Выбор источника опорного напряжения.
*
* ADC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В
* ADC_EXTREF_ON - Внешний источник опорного напряжения
*
*/
#define ADC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */
#define ADC_EXTREF_ON 1 /* Внешний источник опорного напряжения */
/*
* Defines: Выбор внешнего ИОН
*
* Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН.
*
* ADC_EXTCLB_CLBREF - Настраиваемый ОИН
* ADC_EXTCLB_ADCREF - Внешний вывод
*
*/
#define ADC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */
#define ADC_EXTCLB_ADCREF 1 /* Внешний вывод */
/*
* Defines: Входы АЦП
*
* Номера выводов каналов АЦП и ADC_REF
*
* ADC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал)
* ADC_CHANNEL0_PORT_1_5 - Канал АЦП0 - PORT_1_5
* ADC_CHANNEL1_PORT_1_7 - Канал АЦП1 - PORT_1_7
* ADC_CHANNEL2_PORT_0_2 - Канал АЦП2 - PORT_0_2
* ADC_CHANNEL3_PORT_0_4 - Канал АЦП3 - PORT_0_4
* ADC_CHANNEL4_PORT_0_7 - Канал АЦП4 - PORT_0_7
* ADC_CHANNEL5_PORT_0_9 - Канал АЦП5 - PORT_0_9
* ADC_CHANNEL6_PORT_0_11 - Канал АЦП6 - PORT_0_11
* ADC_CHANNEL7_PORT_0_13 - Канал АЦП7 - PORT_0_13
* ADC_REF_PORT_1_10 - Внешний опорный сигнал - PORT_1_10
*
*/
#define ADC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */
#define ADC_CHANNEL0_PORT_1_5 5 /* Канал АЦП0 - PORT_1_5 */
#define ADC_CHANNEL1_PORT_1_7 7 /* Канал АЦП1 - PORT_1_7 */
#define ADC_CHANNEL2_PORT_0_2 2 /* Канал АЦП2 - PORT_0_2 */
#define ADC_CHANNEL3_PORT_0_4 4 /* Канал АЦП3 - PORT_0_4 */
#define ADC_CHANNEL4_PORT_0_7 7 /* Канал АЦП4 - PORT_0_7 */
#define ADC_CHANNEL5_PORT_0_9 9 /* Канал АЦП5 - PORT_0_9 */
#define ADC_CHANNEL6_PORT_0_11 11 /* Канал АЦП6 - PORT_0_11 */
#define ADC_CHANNEL7_PORT_0_13 13 /* Канал АЦП7 - PORT_0_13 */
#define ADC_REF_PORT_1_10 10 /* Внешний опорный сигнал - PORT_1_10 */
/* Title: Структуры */
/*
* Struct: ADC_InitTypeDef
*
* Настройки АЦП при инициализации
*
*/
typedef struct
{
/*
* Variable: Sel
* Выбор канала АЦП
*
* Этот параметр должен быть одним из значений:
*
* - <ADC_CHANNEL0>;
* - <ADC_CHANNEL1>;
* - <ADC_CHANNEL2>;
* - <ADC_CHANNEL3>;
* - <ADC_CHANNEL4>;
* - <ADC_CHANNEL5>;
* - <ADC_CHANNEL6>;
* - <ADC_CHANNEL7>.
*
*/
uint8_t Sel;
/*
* Variable: EXTRef
* Выбор источника опорного напряжения
*
* Этот параметр должен быть одним из значений:
*
* - <ADC_EXTREF_OFF>;
* - <ADC_EXTREF_ON>.
*
*/
uint8_t EXTRef;
/*
* Variable: EXTClb
* Выбор внешнего источника опорного напряжения
*
* Этот параметр должен быть одним из значений:
*
* - <ADC_EXTCLB_CLBREF>;
* - <ADC_EXTCLB_ADCREF>.
*
*/
uint8_t EXTClb;
} ADC_InitTypeDef;
/*
* Struct: ADC_HandleTypeDef
* Настройки АЦП
*
*/
typedef struct
{
/*
* Variable: Instance
* Базоый адрес регистров ADC.
*
*/
ANALOG_REG_TypeDef *Instance;
/*
* Variable: Init
* Настройки АЦП при инициализации
*
*/
ADC_InitTypeDef Init;
} ADC_HandleTypeDef;
/* Сменить канал АЦП */
#ifdef MIK32V0
#define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | ((channel_selection) << ADC_CONFIG_SEL_S)))
#else // MIK32V2
#define ADC_SEL_CHANNEL(adc_instance, channel_selection) ((adc_instance)->ADC_CONFIG = (((adc_instance)->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) | (((adc_instance)->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) | ((channel_selection) << ADC_CONFIG_SEL_S))
#endif // MIK32V0
/* Запустить однократное преобразование */
#define HAL_ADC_SINGLE(adc_instance) ((adc_instance)->ADC_SINGLE = 1)
#define HAL_ADC_SINGLE_AND_SET_CH(adc_instance, adc_channel) ({(adc_instance)->ADC_SINGLE = 1; ADC_SEL_CHANNEL((adc_instance), (adc_channel));}) /* Запустить однократное преобразование */
/* Title: Функции */
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
/*
* Включить калибруемый ИОН
*/
void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc);
/*
* Выключить калибруемый ИОН
*/
void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc);
/*
* Задать коэфициент настройки ОИН
*/
void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef);
/*
* Задать коэфициент настройки опорного источника тока
*/
void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef);
/*
* Function: HAL_ADC_ResetEnable
* Установить бит Rn, управление сбросом АЦП, в 1.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_ResetDisable
* Сбросить бит Rn, управление сбросом АЦП, в 0.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_Disable
* Выключть питание АЦП
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_Disable(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_Enable
* Включть питание АЦП
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_Enable(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_ChannelSet
* Задать активный канал АЦП и перевести соответсвующий вывод в аналоговую функцию.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_Init
* Инициализировать АЦП в соответсвии с настройками в hadc.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_Init(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_Single
* Запустить однократное измерение АЦП.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void.
*/
void HAL_ADC_Single(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_ContiniusDisabled
* Выключить непрерывное измерение АЦП.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_ContiniusEnable
* Выключить непрерывное измерение АЦП.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_WaitValid
* Ожидать установку флага актуальных данных.
*
* Флаг VALID - Признак наличия актуальных данных.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* void
*/
void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_GetValue
* Получить результат преобразовния АЦП.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* (uint16_t ) - Результат преобразования АЦП.
*
*/
uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc);
/*
* Function: HAL_ADC_WaitAndGetValue
* Ожидать актуальный результат преобразования АЦП и получить его значение.
*
* Parameters:
* hadc - Указатель на структуру с настройками ADC.
*
* Returns:
* (uint16_t ) - Результат преобразования АЦП.
*
*/
uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,347 @@
#ifndef MIK32_HAL_CRC32
#define MIK32_HAL_CRC32
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "crc.h"
#include "mcu32_memory_map.h"
/* Title: Макросы */
/*
* Defines: Перестановка битов/байтов данных
*
* CRC_REVERSE_OFF - Перестановка выключена
* CRC_REVERSE_BITS - Биты в байтах перестанавливаются, байты не перестанавливаются
* CRC_REVERSE_BITS_BYTES - Перестанавливаются и биты, и байты
* CRC_REVERSE_BYTES - Биты в байтах не перестанавливаются, байты перестанавливаются
*
*/
#define CRC_REVERSE_OFF 0 // Перестановка выключена
#define CRC_REVERSE_BITS 1 // Биты в байтах перестанавливаются, байты не перестанавливаются
#define CRC_REVERSE_BITS_BYTES 2 // Перестанавливаются и биты, и байты
#define CRC_REVERSE_BYTES 3 // Биты в байтах не перестанавливаются, байты перестанавливаются
/* Модификаторы */
/*
* Defines: Флаг RefIn
*
* Флаг RefIn, указывающий на начало и направление вычислений.
*
* Перестановка битов/байтов входных данных.
*
* Существует два варианта:
*
* - CRC_REFIN_FALSE начиная со старшего значащего бита (MSB-first);
* - CRC_REFIN_TRUE с младшего (LSB-first).
*
* CRC_REFIN_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются
* CRC_REFIN_TRUE - Перестанавливаются и биты, и байты
*
*/
#define CRC_REFIN_FALSE CRC_REVERSE_BYTES // RefIn = false - CRC_REVERSE_BYTES
#define CRC_REFIN_TRUE CRC_REVERSE_BITS_BYTES // RefIn = true - CRC_REVERSE_BITS_BYTES
/*
* Defines: Флаг RefOut
*
* Флаг RefOut, определяющий, инвертируется ли порядок битов регистра при входе на элемент XOR.
*
* Перестановки битов/байтов выходных данных.
*
* CRC_REFOUT_FALSE - Биты в байтах не перестанавливаются, байты перестанавливаются
* CRC_REFOUT_TRUE - Перестанавливаются и биты, и байты
*
*/
#define CRC_REFOUT_FALSE CRC_REVERSE_OFF // RefOut = false - CRC_REVERSE_OFF
#define CRC_REFOUT_TRUE CRC_REVERSE_BITS_BYTES // RefOUT = true - CRC_REVERSE_BITS_BYTES
/*
* Defines: Флаг XorOut
*
* Инверсия контрольной суммы.
* Число XorOut = 0xFFFFFFFF, с которым складывается по модулю 2 полученный результат. Побитовая инверсия результата.
*
* CRC_OUTPUTINVERSION_OFF - Инверсия выключена.
* CRC_OUTPUTINVERSION_ON - Инверсия включена (операция XOR выполняется)
*
*/
#define CRC_OUTPUTINVERSION_OFF 0 // Инверсия выключена
#define CRC_OUTPUTINVERSION_ON 1 // Инверсия включена (операция XOR выполняется)
/*
* Defines: Размер буфера
*
* CRC_MAX_WORDS - Максимальное количество слов в буфере.
* CRC_MAX_BYTES - Максимальное количество байтов в буфере.
*
*/
#define CRC_MAX_WORDS 16
#define CRC_MAX_BYTES 64
/* Title: Структуры */
/*
* Struct: CRC_HandleTypeDef
* Настройки CRC
*
*/
typedef struct
{
/*
* Variable: Instance
* Базоый адрес регистров CRC
*
*/
CRC_TypeDef *Instance;
/*
* Variable: Poly
* Значение порождающего многочлена.
*
* Этот параметр может быть 32-битным значением.
*
*/
uint32_t Poly;
/*
* Variable: Init
* Стартовое значение данных.
*
* Этот параметр может быть 32-битным значением.
*
*/
uint32_t Init;
/*
* Variable: InputReverse
* Перестановка битов/байтов входных данных.
*
* Этот параметр должен быть одним из значений:
*
* - <CRC_REFIN_FALSE>;
* - <CRC_REFIN_TRUE>.
*
*/
uint8_t InputReverse;
/*
* Variable: OutputReverse
* Перестановка битов/байтов выходных данных.
*
* Этот параметр должен быть одним из значений:
*
* - <CRC_REFOUT_FALSE>;
* - <CRC_REFOUT_TRUE>.
*
*/
uint8_t OutputReverse;
/*
* Variable: OutputInversion
* Инверсия контрольной суммы.
*
* Этот параметр должен быть одним из значений:
*
* - <CRC_OUTPUTINVERSION_OFF>;
* - <CRC_OUTPUTINVERSION_ON>.
*
*/
uint8_t OutputInversion;
} CRC_HandleTypeDef;
/* Title: Функции */
void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc);
/*
* Function: HAL_CRC_SetInputReverse
* Задать перестановка битов/байтов входных данных в соответствии со значением <CRC_HandleTypeDef.InputReverse> (RefIn).
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_SetOutputInversion
* Инверсия контрольной суммы в соответсвии со значением <CRC_HandleTypeDef.OutputInversion> (XorOut).
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_SetOutputReverse
* Перестановки битов/байтов выходных данных в соответствии со значением <CRC_HandleTypeDef.OutputReverse> (RefOut).
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_SetInit
* Задать начальное значение данных в соответсвии с <CRC_HandleTypeDef.Init>
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_Init
* Инициализировать CRC в соответствии с настройками <CRC_HandleTypeDef> *hcrc.
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_Init(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_WaitBusy
* Ожидать сброса флага BUSY. Если флаг равен 0, то автомат закончил вычисления.
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* void
*/
void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc);
/*
* Function: HAL_CRC_WaitBusy
* Записать данные по байтам в буфер CRC.
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
* message - Массив с данными.
* message_length - Количество передаваемых байтов.
*
* Returns:
* void
*/
void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length);
/*
* Function: HAL_RTC_WriteData32
* Записать данные по словам в буфер CRC.
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
* message - Массив с данными.
* message_length - Количество передаваемых байтов.
*
* Returns:
* void
*/
void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length);
/*
* Function: HAL_RTC_ReadCRC
* Получить значение CRC.
*
* Parameters:
* hcrc - Указатель на структуру с настройками CRC.
*
* Returns:
* (uint32_t ) - Значение CRC.
*
*/
uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc);
#ifdef __cplusplus
}
#endif
#endif
/**************************************CRC-32**************************************/
// hcrc.Poly = 0x04C11DB7;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_TRUE;
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
/**************************************CRC-32/BZIP2**************************************/
// hcrc.Poly = 0x04C11DB7;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_FALSE;
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
/*******************************************CRC-32C*******************************************/
// hcrc.Poly = 0x1EDC6F41;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_TRUE;
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
/*******************************************CRC-32D*******************************************/
// hcrc.Poly = 0xA833982B;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_TRUE;
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
/****************************************CRC-32/JAMCRC****************************************/
// hcrc.Poly = 0x04C11DB7;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_TRUE;
// hcrc.OutputReverse = CRC_REFOUT_TRUE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
/****************************************CRC-32/MPEG-2****************************************/
// hcrc.Poly = 0x04C11DB7;
// hcrc.Init = 0xFFFFFFFF;
// hcrc.InputReverse = CRC_REFIN_FALSE;
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
/*****************************************CRC-32/POSIX*****************************************/
// hcrc.Poly = 0x04C11DB7;
// hcrc.Init = 0x00000000;
// hcrc.InputReverse = CRC_REFIN_FALSE;
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_ON;
/*******************************************CRC-32Q*******************************************/
// hcrc.Poly = 0x814141AB;
// hcrc.Init = 0x00000000;
// hcrc.InputReverse = CRC_REFIN_FALSE;
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;
/*****************************************CRC-32/XFER*****************************************/
// hcrc.Poly = 0x000000AF;
// hcrc.Init = 0x00000000;
// hcrc.InputReverse = CRC_REFIN_FALSE;
// hcrc.OutputReverse = CRC_REFOUT_FALSE;
// hcrc.OutputInversion = CRC_OUTPUTINVERSION_OFF;

View File

@ -0,0 +1,120 @@
#ifndef MIK32_HAL_CRYPTO
#define MIK32_HAL_CRYPTO
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "crypto.h"
#include "pad_config.h"
#include "mcu32_memory_map.h"
/**
* @name Длина вектора инициализации
* @{
*/
#define IV_LENGTH_KUZNECHIK_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Кузнечик). */
#define IV_LENGTH_MAGMA_CBC 4 /**< Количество слов вектора инициализации в режиме шифрования CBC (Магма). */
#define IV_LENGTH_AES_CBC 2 /**< Количество слов вектора инициализации в режиме шифрования CBC (AES). */
#define IV_LENGTH_KUZNECHIK_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Кузнечик). */
#define IV_LENGTH_MAGMA_CTR 2 /**< Количество слов вектора инициализации в режиме шифрования CTR (Магма). */
#define IV_LENGTH_AES_CTR 1 /**< Количество слов вектора инициализации в режиме шифрования CTR (AES). */
/** @} */
/**
* @name Длина ключа
* @{
*/
#define CRYPTO_KEY_KUZNECHIK 8 /**< Длина ключа Кузнечик. */
#define CRYPTO_KEY_MAGMA 8 /**< Длина ключа Магма. */
#define CRYPTO_KEY_AES 4 /**< Длина ключа AES. */
/** @} */
/**
* @name Длина блока
* @{
*/
#define CRYPTO_BLOCK_KUZNECHIK 4 /**< Длина блока Кузнечик. */
#define CRYPTO_BLOCK_MAGMA 2 /**< Длина блока Магма. */
#define CRYPTO_BLOCK_AES 4 /**< Длина блока AES. */
/** @} */
/**
* @name Алгоритм шифрования
* @{
*/
#define CRYPTO_ALG_KUZNECHIK 0 /**< Алгоритм шифрования Кузнечик. */
#define CRYPTO_ALG_MAGMA 1 /**< Алгоритм шифрования Магма. */
#define CRYPTO_ALG_AES 2 /**< Алгоритм шифрования AES. */
/** @} */
/**
* @name Режим шифрования
* @{
*/
#define CRYPTO_CIPHER_MODE_ECB 0 /**< Режим шифрования ECB (Electronic Codebook). */
#define CRYPTO_CIPHER_MODE_CBC 1 /**< Режим шифрования CBC (Cipher Block Chaining). */
#define CRYPTO_CIPHER_MODE_CTR 2 /**< Режим шифрования CTR (Counter mode). */
/** @} */
/**
* @name Перестановка слова
* @{
*/
#define CRYPTO_SWAP_MODE_NONE 0 /**< Нет перестановки. */
#define CRYPTO_SWAP_MODE_HALFWORD 1 /**< Перестановка по полуслову. */
#define CRYPTO_SWAP_MODE_BYTE 2 /**< Перестановки по байтам. */
#define CRYPTO_SWAP_MODE_BIT 3 /**< Перестановка по битам. */
/** @} */
/**
* @name Порядок загрузки/выгрузки
* @{
*/
#define CRYPTO_ORDER_MODE_LSW 0 /**< Порядка загрузки/выгрузки от младшего слова к старшему. */
#define CRYPTO_ORDER_MODE_MSW 1 /**< Порядка загрузки/выгрузки от старшего слова к младшему. */
/** @} */
#define MAXIMUM_KEY_LENGTH 8 /**< Максимальная длина ключа. */
/**
* @brief Настройки Crypto.
*
*/
typedef struct __Crypto_HandleTypeDef
{
CRYPTO_TypeDef *Instance; /**< Базовый адрес регистров Crypto */
uint8_t Algorithm; /**< Выбор алгоритма шифрования. Этот параметр должен быть одним из значений: #CRYPTO_ALG_KUZNECHIK, #CRYPTO_ALG_MAGMA, #CRYPTO_ALG_AES.*/
uint8_t CipherMode; /**< Выбор режима шифрования. Этот параметр должен быть одним из значений: #CRYPTO_CIPHER_MODE_ECB, #CRYPTO_CIPHER_MODE_CBC, #CRYPTO_CIPHER_MODE_CTR. */
uint8_t SwapMode; /**< Перестановка слова. Этот параметр должен быть одним из значений: #CRYPTO_SWAP_MODE_NONE, #CRYPTO_SWAP_MODE_HALFWORD, #CRYPTO_SWAP_MODE_BYTE, #CRYPTO_SWAP_MODE_BIT. */
uint8_t OrderMode; /**< Выбор порядка загрузки/выгрузки. Этот параметр должен быть одним из значений: #CRYPTO_ORDER_MODE_LSW, #CRYPTO_ORDER_MODE_MSW. */
} Crypto_HandleTypeDef;
void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto);
void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto);
void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto);
void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm);
void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode);
void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode);
void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode);
void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength);
void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[]);
void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto);
void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length);
void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,251 @@
#ifndef MIK32_HAL_DAC
#define MIK32_HAL_DAC
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "analog_reg.h"
#include "pad_config.h"
#include "stdbool.h"
#include "mcu32_memory_map.h"
/* Title: Макросы */
/*
* Defines: Каналы ЦАП
*
* HAL_DAC1 - Канал ЦАП1 (PORT_1_12)
* HAL_DAC2 - Канал ЦАП2 (PORT_1_13)
*
*/
#define HAL_DAC1 &(ANALOG_REG->DAC0) /* Канал DAC1 - PORT_1_12 */
#define HAL_DAC2 &(ANALOG_REG->DAC1) /* Канал DAC2 - PORT_1_13 */
/*
* Defines: Выбор ИОН
*
* Выбор источника опорного напряжения.
*
* DAC_EXTREF_OFF - Встроенный источник опорного напряжения 1,2 В
* DAC_EXTREF_ON - Внешний источник опорного напряжения
*
*/
#define DAC_EXTREF_OFF 0 /* Встроенный источник опорного напряжения 1,2 В */
#define DAC_EXTREF_ON 1 /* Внешний источник опорного напряжения */
/*
* Defines: Выбор внешнего ИОН
*
* Выбор внешнего источника опорного напряжения по отношению к встроенному в АЦП ИОН.
*
* DAC_EXTCLB_CLBREF - Настраиваемый ОИН
* DAC_EXTCLB_DACREF - Внешний вывод
*
*/
#define DAC_EXTCLB_CLBREF 0 /* Настраиваемый ОИН */
#define DAC_EXTCLB_DACREF 1 /* Внешний вывод */
/* Выводы ЦАП */
/*
* Defines: Входы АЦП
*
* Номера выводов каналов ЦАП и DAC_REF
*
* DAC_PORT_AS_FUNC3 - Четвертая функция вывода (аналоговый сигнал)
* DAC1_PORT_1_12 - ЦАП1 - PORT_1_12
* DAC2_PORT_1_13 - ЦАП2 - PORT_1_13
* DAC_REF_PORT_1_11 - Внешний опорный сигнал DAC_REF - PORT_1_11
*
*/
#define DAC_PORT_AS_FUNC3 0b11 /* Четвертая функция вывода (аналоговый сигнал) */
#define DAC1_PORT_1_12 12 /* DAC1 - PORT_1_12 */
#define DAC2_PORT_1_13 13 /* DAC2 - PORT_1_13 */
#define DAC_REF_PORT_1_11 11 /* Внешний опорный сигнал - PORT_1_11 */
/* Title: Структуры */
/*
* Struct: DAC_InitTypeDef
*
* Настройки ЦАП при инициализации
*
*/
typedef struct
{
/*
* Variable: EXTRef
* Выбор источника опорного напряжения
*
* Этот параметр должен быть одним из значений:
*
* - <DAC_EXTREF_OFF>;
* - <DAC_EXTREF_ON>.
*
*/
uint8_t EXTRef;
/*
* Variable: EXTClb
* Выбор внешнего источника опорного напряжения
*
* Этот параметр должен быть одним из значений:
*
* - <DAC_EXTCLB_CLBREF>;
* - <DAC_EXTCLB_DACREF>.
*
*/
uint8_t EXTClb;
/*
* Variable: DIV
* Значение делителя тактового сигнала.
*
* Частота определяется как F_ЦАП = F_IN/(Div+1).
*
* Значением может быть 8-битное число в пределах от 0 до 255
*
*/
uint8_t DIV;
} DAC_InitTypeDef;
/*
* Struct: DAC_HandleTypeDef
*
* Настройки ЦАП
*
*/
typedef struct
{
/*
* Variable: Instance
* Базоый адрес регистров ANALOG_REG.
*
*/
ANALOG_REG_TypeDef *Instance;
/*
* Variable: Instance_dac
* Базоый адрес регистров DAC
*
*/
volatile DAC_TypeDef *Instance_dac;
/*
* Variable: Init
* Настройки ЦАП при инициализации
*
*/
DAC_InitTypeDef Init;
} DAC_HandleTypeDef;
/* Title: Функции */
void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);
void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac);
void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac);
void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef);
void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef);
/*
* Function: HAL_DAC_SetDiv
* Установить значение делителя тактового сигнала ЦАП.
*
* Частота определяется как F_ЦАП = F_IN/(Div+1).
*
* Значением может быть 8-битное число в пределах от 0 до 255
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
* div - Делитель частоты.
*
* Returns:
* void
*/
void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div);
/*
* Function: HAL_DAC_ResetEnable
* Установить бит Rn, управление сбросом ЦАП, в 1.
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
*
* Returns:
* void
*/
void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac);
/*
* Function: HAL_DAC_ResetDisable
* Сбросить бит Rn, управление сбросом ЦАП, в 0.
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
*
* Returns:
* void
*/
void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac);
/*
* Function: HAL_DAC_Disable
* Выключть питание ЦАП
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
*
* Returns:
* void
*/
void HAL_DAC_Disable(DAC_HandleTypeDef *hdac);
/*
* Function: HAL_ADC_Enable
* Включть питание ЦАП
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
*
* Returns:
* void
*/
void HAL_DAC_Enable(DAC_HandleTypeDef *hdac);
/*
* Function: HAL_DAC_Init
* Инициализировать ЦАП в соответсвии с настройками в hdac.
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
*
* Returns:
* void
*/
void HAL_DAC_Init(DAC_HandleTypeDef *hdac);
/*
* Function: HAL_DAC_SetValue
* Задать входные данные для преобразования ЦАП.
*
* Входные данные могут быть в пределах от 0 до 4 095.
*
* Parameters:
* hdac - Указатель на структуру с настройками ЦАП.
* DAC_Value - Входные данные для преобразования ЦАП.
*
* Returns:
* void
*
*/
void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
#ifndef MIK32_HAL_DEF
#define MIK32_HAL_DEF
#ifdef __cplusplus
extern "C" {
#endif
#define HAL_PIN_MASK 0xFFFF
#define HAL_PORT_S 16
typedef enum HAL_StatusTypeDef
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,210 @@
#ifndef MIK32_HAL_DMA
#define MIK32_HAL_DMA
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "stddef.h"
#include "dma_config.h"
#include "mcu32_memory_map.h"
#include "mik32_hal_def.h"
#define DMA_TIMEOUT_DEFAULT 1000000 /**< Стандартная задержка для ожидания timeout. */
/**
* @brief Разрешить или запретить читать текущий статус канала.
*
* При разрешении чтения текущего статуса канала регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения,
* а в CHx_CFG при считывании меняются битовые поля.
*/
typedef enum __HAL_DMA_CurrentValueTypeDef
{
DMA_CURRENT_VALUE_ENABLE = 0, /**< Текущие значения. */
DMA_CURRENT_VALUE_DISABLE = 1 /**< Значения при настройке. */
} HAL_DMA_CurrentValueTypeDef;
/**
* @brief Номер канала.
*
* При совпадении приоритетов каналов меньший номер канала является более приоритетным.
*/
typedef enum __HAL_DMA_ChannelIndexTypeDef
{
DMA_CHANNEL_0 = 0,
DMA_CHANNEL_1 = 1,
DMA_CHANNEL_2 = 2,
DMA_CHANNEL_3 = 3
} HAL_DMA_ChannelIndexTypeDef;
/**
* @brief Приоритет канала.
*
* Арбитраж выбора канала происходит за два такта удержания линии запроса.
* Если одновременно поступают несколько запросов ПДП, то схема арбитража выбирает наиболее
* приоритетную линию запроса в соответствии с программной установкой каждого из каналов.
* При совпадении приоритетов каналов меньший номер канала является более приоритетным.
*/
typedef enum __HAL_DMA_ChannelPriorityTypeDef
{
DMA_CHANNEL_PRIORITY_LOW = 0b00, /**< Низкий приоритет. */
DMA_CHANNEL_PRIORITY_MEDIUM = 0b01, /**< Средний приоритет. */
DMA_CHANNEL_PRIORITY_HIGH = 0b10, /**< Высокий приоритет. */
DMA_CHANNEL_PRIORITY_VERY_HIGH = 0b11 /**< Высший приоритет. */
} HAL_DMA_ChannelPriorityTypeDef;
/**
* @brief Режим адресации источника или назначения.
*/
typedef enum __HAL_DMA_ChannelModeTypeDef
{
DMA_CHANNEL_MODE_PERIPHERY = 0, /**< Режим адреса - периферия. */
DMA_CHANNEL_MODE_MEMORY = 1 /**< Режим адреса - память. */
} HAL_DMA_ChannelModeTypeDef;
/**
* @brief Наличие инкремента адреса источника или назначения.
*/
typedef enum __HAL_DMA_ChannelIncTypeDef
{
DMA_CHANNEL_INC_DISABLE = 0, /* Адрес не инкрементируется. */
DMA_CHANNEL_INC_ENABLE = 1 /* Адрес инкрементируется. */
} HAL_DMA_ChannelIncTypeDef;
/**
* @brief Разрядность адреса источника или назначения.
* @warning Разрядность должна быть кратна количеству байт пересылки (LEN).
*/
typedef enum __HAL_DMA_ChannelSizeTypeDef
{
DMA_CHANNEL_SIZE_BYTE = 0, /**< Байт. */
DMA_CHANNEL_SIZE_HALFWORD = 1, /**< Полуслово. */
DMA_CHANNEL_SIZE_WORD = 2 /**< Слово. */
} HAL_DMA_ChannelSizeTypeDef;
/**
* @brief Периферийные линии источника или назначения.
*/
typedef enum __HAL_DMA_ChannelRequestTypeDef
{
DMA_CHANNEL_USART_0_REQUEST = 0,
DMA_CHANNEL_USART_1_REQUEST = 1,
DMA_CHANNEL_CRYPTO_REQUEST = 2,
DMA_CHANNEL_SPI_0_REQUEST = 3,
DMA_CHANNEL_SPI_1_REQUEST = 4,
DMA_CHANNEL_I2C_0_REQUEST = 5,
DMA_CHANNEL_I2C_1_REQUEST = 6,
DMA_CHANNEL_SPIFI_REQUEST = 7,
DMA_CHANNEL_TIMER32_1_REQUEST = 8,
DMA_CHANNEL_TIMER32_2_REQUEST = 9,
#ifdef MIK32V0
DMA_CHANNEL_TIMER32_0_REQUEST = 10
#else // MIK32V2
DMA_CHANNEL_DAC_0_REQUEST = 10,
DMA_CHANNEL_DAC_1_REQUEST = 11,
DMA_CHANNEL_TIMER32_0_REQUEST = 12
#endif // MIK32V0
} HAL_DMA_ChannelRequestTypeDef;
/**
* @brief Разрешение работы логики с откликом для адресата источника и назначения.
*
* Используется при работе с Timer32. При работе логики с откликом пакет данных передается
* каждый раз при переполнении таймера. Если работа с откликом запрещена, то все пакеты передаются сразу после
* первого переполнения таймера.
*/
typedef enum
{
DMA_CHANNEL_ACK_DISABLE = 0, /**< Работа логики с откликом запрещена. */
DMA_CHANNEL_ACK_ENABLE = 1 /**< Работа логики с откликом разрешена. */
} HAL_DMA_ChannelACKTypeDef;
/**
* @brief Разрешение прерываний.
*
* Используется при настройке глобального прерывания DMA, прерывания DMA при возникновении ошибки и
* локального прерывания при завершении работы канала.
*/
typedef enum
{
DMA_IRQ_DISABLE = 0, /* Прерывание запрещено. */
DMA_IRQ_ENABLE = 1 /* Прерывание разрешено. */
} HAL_DMA_IRQTypeDef;
/**
* @brief Настройки канала DMA.
*/
typedef struct __DMA_ChannelInitHandleTypeDef
{
HAL_DMA_ChannelIndexTypeDef Channel; /**< Номер канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelIndexTypeDef. */
HAL_DMA_ChannelPriorityTypeDef Priority; /**< Приоритет канала. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelPriorityTypeDef. */
HAL_DMA_ChannelModeTypeDef ReadMode; /**< Режим адресации источника. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */
HAL_DMA_ChannelIncTypeDef ReadInc; /**< Наличие инкремента адреса источника. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */
HAL_DMA_ChannelSizeTypeDef ReadSize; /**< Разрядность адреса источника. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */
HAL_DMA_ChannelACKTypeDef ReadAck; /**< Разрешение работы логики с откликом для адресата источника. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */
uint32_t ReadBurstSize; /**< Количество байт в пакете. Определяется как 2^{ReadBurstSize}. @warning Количество байт в пакете должно быть кратно ReadSize. */
HAL_DMA_ChannelRequestTypeDef ReadRequest; /**< Выбор периферийной линии источника при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */
HAL_DMA_ChannelModeTypeDef WriteMode; /**< Режим адресации назначения. Данный параметр может иметь значение #DMA_CHANNEL_MODE_PERIPHERY или #DMA_CHANNEL_MODE_MEMORY. */
HAL_DMA_ChannelIncTypeDef WriteInc; /**< Наличие инкремента адреса назначения. Данный параметр может иметь значение #DMA_CHANNEL_INC_DISABLE или #DMA_CHANNEL_INC_ENABLE. */
HAL_DMA_ChannelSizeTypeDef WriteSize; /**< Разрядность адреса назначения. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelSizeTypeDef. @warning Разрядность должна быть кратна количеству байт пересылки (LEN + 1). */
HAL_DMA_ChannelACKTypeDef WriteAck; /**< Разрешение работы логики с откликом для адресата назначения. Данный параметр может иметь значение #DMA_CHANNEL_ACK_DISABLE или #DMA_CHANNEL_ACK_ENABLE */
uint32_t WriteBurstSize; /**< Количество байт в пакете. Определяется как 2^{WriteBurstSize}. @warning Количество байт в пакете должно быть кратно WriteSize. */
HAL_DMA_ChannelRequestTypeDef WriteRequest; /**< Выбор периферийной линии назначения при ReadMode = DMA_CHANNEL_MODE_PERIPHERY. Данный параметр может быть одним из значений перечисления @ref HAL_DMA_ChannelRequestTypeDef. */
} DMA_ChannelInitHandleTypeDef;
/**
* @brief Структура для инициализации DMA.
*/
typedef struct __DMA_InitTypeDef
{
DMA_CONFIG_TypeDef *Instance; /**< Базовый адрес регистров DMA. Этот параметр может иметь значение #DMA_CONFIG. */
HAL_DMA_CurrentValueTypeDef CurrentValue; /**< Разрешить или запретить читать текущий статус канала. При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения, а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке. */
} DMA_InitTypeDef;
/**
* @brief Структура для инициализации канала DMA.
*/
typedef struct __DMA_ChannelHandleTypeDef
{
DMA_InitTypeDef *dma; /**< Указатель на структуру для инициализации DMA. */
DMA_ChannelInitHandleTypeDef ChannelInit; /**< Настройки канала DMA. */
} DMA_ChannelHandleTypeDef;
void HAL_DMA_MspInit(DMA_InitTypeDef* hdma);
void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex);
void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma);
void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma);
void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma);
void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma);
void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue);
int HAL_DMA_GetChannelCurrentValue(DMA_InitTypeDef *hdma);
void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission);
void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission);
void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission);
HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma);
HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout);
int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel);
int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel);
int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel);
void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel);
void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel);
void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* Source, void* Destination, uint32_t Len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,118 @@
#ifndef MIK32_HAL_EEPROM_H_INCLUDED
#define MIK32_HAL_EEPROM_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_def.h"
#include <mcu32_memory_map.h>
#include <eeprom.h>
#include <power_manager.h>
#ifndef HAL_EEPROM_TIMEOUT
#define HAL_EEPROM_TIMEOUT 10000
#endif
typedef enum
{
HAL_EEPROM_OP_READ = 0b00,
HAL_EEPROM_OP_CLEAR = 0b01,
HAL_EEPROM_OP_PROGRAM = 0b10,
} HAL_EEPROM_OperationTypeDef;
typedef enum
{
HAL_EEPROM_WRITE_SINGLE = 0b00,
HAL_EEPROM_WRITE_EVEN = 0b01,
HAL_EEPROM_WRITE_ODD = 0b10,
HAL_EEPROM_WRITE_ALL = 0b11,
} HAL_EEPROM_WriteBehaviourTypeDef;
typedef enum
{
HAL_EEPROM_MODE_TWO_STAGE = 0b00,
HAL_EEPROM_MODE_THREE_STAGE = 0b01,
} HAL_EEPROM_ModeTypeDef;
typedef enum
{
HAL_EEPROM_ECC_ENABLE = 0b00,
HAL_EEPROM_ECC_DISABLE = 0b01,
} HAL_EEPROM_ErrorCorrectionTypeDef;
typedef enum
{
HAL_EEPROM_SERR_DISABLE = 0b00,
HAL_EEPROM_SERR_ENABLE = 0b01,
} HAL_EEPROM_EnableInterruptTypeDef;
typedef struct
{
uint8_t N_LD;
uint8_t N_R_1;
uint8_t N_R_2;
uint32_t N_EP_1;
uint16_t N_EP_2;
} HAL_EEPROM_TimingsTypeDef;
typedef struct
{
EEPROM_REGS_TypeDef *Instance;
HAL_EEPROM_TimingsTypeDef Timings;
HAL_EEPROM_ModeTypeDef Mode;
HAL_EEPROM_ErrorCorrectionTypeDef ErrorCorrection;
HAL_EEPROM_EnableInterruptTypeDef EnableInterrupt;
} HAL_EEPROM_HandleTypeDef;
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_EEPROM_WaitBusy(HAL_EEPROM_HandleTypeDef *eeprom, uint32_t timeout)
{
while (timeout)
{
timeout--;
if (!(eeprom->Instance->EESTA & EEPROM_EESTA_BSY_M))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
#define HAL_EEPROM_INTERRUPT_GET(eeprom) ((*eeprom).Instance->EESTA & EEPROM_EESTA_SERR_M)
#define HAL_EEPROM_INTERRUPT_FLAG_CLEAR(eeprom) (*eeprom).Instance->EESTA &= ~EEPROM_EESTA_SERR_M;
HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom);
HAL_StatusTypeDef HAL_EEPROM_Erase(
HAL_EEPROM_HandleTypeDef *eeprom,
uint16_t address,
uint8_t erasedWordsCount,
HAL_EEPROM_WriteBehaviourTypeDef erasedPages,
uint32_t timeout);
HAL_StatusTypeDef HAL_EEPROM_Write(
HAL_EEPROM_HandleTypeDef *eeprom,
uint16_t address,
uint32_t *data,
uint8_t length,
HAL_EEPROM_WriteBehaviourTypeDef writedPages,
uint32_t timeout);
HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout);
void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode);
void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection);
void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt);
void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency);
HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout);
#ifdef __cplusplus
}
#endif
#endif // MIK32_HAL_EEPROM_H_INCLUDED

View File

@ -0,0 +1,391 @@
#ifndef MIK32_HAL_GPIO_NEW
#define MIK32_HAL_GPIO_NEW
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_def.h"
#include "pad_config.h"
#include "gpio.h"
#include "gpio_irq.h"
#include "mcu32_memory_map.h"
#include "mik32_hal_pcc.h"
#define GPIO_MODE_BIT_LEVEL_S 0 /**< Позиция бита для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_MODE_BIT_EDGE_S 1 /**< Позиция бита для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_MODE_BIT_ANYEDGE_S 2 /**< Позиция бита для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_MODE_BIT_LEVEL_M (1 << GPIO_MODE_BIT_LEVEL_S) /**< Маска для режима LEVEL_SET (тип прерывания по уровню низкий/высокий или по событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_MODE_BIT_EDGE_M (1 << GPIO_MODE_BIT_EDGE_S) /**< Маска для режима EDGE (тип прерывания уровень или событие) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_MODE_BIT_ANYEDGE_M (1 << GPIO_MODE_BIT_ANYEDGE_S) /**< Маска для режима ANYEDGE (режим прерывания по любому событию фронт/спад) в перечислении @ref HAL_GPIO_InterruptMode. */
#define GPIO_IRQ_LINE_S 4 /**< Позиция номера канала в перечислении @ref HAL_GPIO_Line @ref и @ref HAL_GPIO_Line_Config. */
#define __LOW GPIO_PIN_LOW /**< Псевдоним @ref GPIO_PIN_LOW. Низкий выходной уровень GPIO. */
#define __HIGH GPIO_PIN_HIGH /**< Псевдоним @ref GPIO_PIN_HIGH. Высокий выходной уровень GPIO. */
#define __INPUT HAL_GPIO_MODE_GPIO_INPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_INPUT. Режим вывода - GPIO. Вход. */
#define __OUTPUT HAL_GPIO_MODE_GPIO_OUTPUT /**< Псевдоним @ref HAL_GPIO_MODE_GPIO_OUTPUT. Режим вывода - GPIO. Выход. */
#define __PULL_NONE HAL_GPIO_PULL_NONE /**< Псевдоним @ref HAL_GPIO_PULL_NONE. Подтяжка не подключаются. */
#define __PULL_UP HAL_GPIO_PULL_UP /**< Псевдоним @ref HAL_GPIO_PULL_UP. Подтяжка к питанию. */
#define __PULL_DOWN HAL_GPIO_PULL_DOWN /**< Псевдоним @ref HAL_GPIO_PULL_DOWN. Подтяжка к земле. */
#define __DS_2MA HAL_GPIO_DS_2MA /**< Псевдоним @ref HAL_GPIO_DS_2MA. Режим драйвера 2мА. */
#define __DS_4MA HAL_GPIO_DS_4MA /**< Псевдоним @ref HAL_GPIO_DS_4MA. Режим драйвера 4мА. */
#define __DS_8MA HAL_GPIO_DS_8MA /**< Псевдоним @ref HAL_GPIO_DS_8MA. Режим драйвера 8мА. */
/**
* @brief Маска выводов.
*/
typedef enum __HAL_PinsTypeDef
{
GPIO_PIN_0 = (1 << 0), /**< Выбран пин 0. */
GPIO_PIN_1 = (1 << 1), /**< Выбран пин 1. */
GPIO_PIN_2 = (1 << 2), /**< Выбран пин 2. */
GPIO_PIN_3 = (1 << 3), /**< Выбран пин 3. */
GPIO_PIN_4 = (1 << 4), /**< Выбран пин 4. */
GPIO_PIN_5 = (1 << 5), /**< Выбран пин 5. */
GPIO_PIN_6 = (1 << 6), /**< Выбран пин 6. */
GPIO_PIN_7 = (1 << 7), /**< Выбран пин 7. */
GPIO_PIN_8 = (1 << 8), /**< Выбран пин 8. */
GPIO_PIN_9 = (1 << 9), /**< Выбран пин 9. */
GPIO_PIN_10 = (1 << 10), /**< Выбран пин 10. */
GPIO_PIN_11 = (1 << 11), /**< Выбран пин 11. */
GPIO_PIN_12 = (1 << 12), /**< Выбран пин 12. */
GPIO_PIN_13 = (1 << 13), /**< Выбран пин 13. */
GPIO_PIN_14 = (1 << 14), /**< Выбран пин 14. */
GPIO_PIN_15 = (1 << 15), /**< Выбран пин 15. */
GPIO_PIN_ALL = 0xFFFF /**< Выбраны все пины порта. */
} HAL_PinsTypeDef;
/**
* @brief Перечисление состояний выходного уровня GPIO.
*/
typedef enum __GPIO_PinState
{
GPIO_PIN_LOW = 0, /**< Низкий выходной уровень GPIO. */
GPIO_PIN_HIGH = 1 /**< Высокий выходной уровень GPIO.*/
} GPIO_PinState;
/**
* @brief Перечисление режимов вывода.
*/
typedef enum __HAL_GPIO_ModeTypeDef
{
#ifdef MIK32V0
HAL_GPIO_MODE_GPIO_INPUT = 0b101, /**< Режим вывода - GPIO. Вход. */
HAL_GPIO_MODE_GPIO_OUTPUT = 0b001, /**< Режим вывода - GPIO. Выход. */
HAL_GPIO_MODE_SERIAL = 0b00, /**< Режим вывода - последовательный интерфейс. */
#else // MIK32V2
HAL_GPIO_MODE_GPIO_INPUT = 0b100, /**< Режим вывода - GPIO. Вход. */
HAL_GPIO_MODE_GPIO_OUTPUT = 0b000, /**< Режим вывода - GPIO. Выход. */
HAL_GPIO_MODE_SERIAL = 0b01, /**< Режим вывода - последовательный интерфейс. */
#endif // MIK32V0
HAL_GPIO_MODE_TIMER_SERIAL = 0b10, /**< Режим вывода - последовательный интерфейс или таймер. */
HAL_GPIO_MODE_ANALOG = 0b11 /**< Аналоговый сигнал. */
} HAL_GPIO_ModeTypeDef;
/**
* @brief Перечисление режимов подтяжки.
*/
typedef enum __HAL_GPIO_PullTypeDef
{
HAL_GPIO_PULL_NONE = 0b00, /**< Подтяжка не подключаются. */
HAL_GPIO_PULL_UP = 0b01, /**< Подтяжка к питанию. */
HAL_GPIO_PULL_DOWN = 0b10 /**< Подтяжка к земле. */
} HAL_GPIO_PullTypeDef;
/**
* @brief Перечисление режимов нагрузочной способности.
*/
typedef enum __HAL_GPIO_DSTypeDef
{
HAL_GPIO_DS_2MA = 0b00, /**< Режим драйвера 2мА. */
HAL_GPIO_DS_4MA = 0b01, /**< Режим драйвера 4мА. */
HAL_GPIO_DS_8MA = 0b10 /**< Режим драйвера 8мА. */
} HAL_GPIO_DSTypeDef;
/**
* @brief Настройки для конфигурации выводов.
*/
typedef struct __GPIO_InitTypeDef
{
/**
* @brief Маска выводов, к которым применяется инициализация..
*
* Этот параметр является маской из значений @ref HAL_PinsTypeDef.
*/
HAL_PinsTypeDef Pin;
/**
* @brief Режим выводов или направление GPIO.
*
* Этот параметр должен быть одним из значений:
* - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода - GPIO. Вход
* - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода - GPIO. Выход
* - @ref HAL_GPIO_MODE_SERIAL - режим вывода - последовательный интерфейс
* - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода - последовательный интерфейс или таймер
* - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал
*/
/**
* @brief Режим выводов или направление GPIO.
*
* Этот параметр должен быть одним из значений:
* - @ref HAL_GPIO_MODE_GPIO_INPUT - режим вывода GPIO. Направление вывода как вход;
* - @ref HAL_GPIO_MODE_GPIO_OUTPUT - режим вывода GPIO. Направление вывода как выход;
* - @ref HAL_GPIO_MODE_SERIAL - режим вывода последовательный интерфейс;
* - @ref HAL_GPIO_MODE_TIMER_SERIAL - режим вывода последовательный интерфейс или таймер;
* - @ref HAL_GPIO_MODE_ANALOG - режим вывода аналоговый сигнал.
*/
HAL_GPIO_ModeTypeDef Mode;
/**
* @brief Режим подтяжки.
*
* Этот параметр должен быть одним из значений:
* - @ref HAL_GPIO_PULL_NONE подтяжка не подключаются
* - @ref HAL_GPIO_PULL_UP подтяжка к питанию
* - @ref HAL_GPIO_PULL_DOWN подтяжка к земле
*/
HAL_GPIO_PullTypeDef Pull;
/**
* @brief Нагрузочная способность выводов.
*
* Этот параметр должен быть одним из значений:
* - @ref HAL_GPIO_DS_2MA режим драйвера 2мА
* - @ref HAL_GPIO_DS_4MA режим драйвера 4мА
* - @ref HAL_GPIO_DS_8MA режим драйвера 8мА
*/
HAL_GPIO_DSTypeDef DS;
} GPIO_InitTypeDef;
/**
* @brief Перечисление масок для линий внешних прерываний.
*/
typedef enum __HAL_GPIO_Line
{
GPIO_LINE_0 = 0 << GPIO_IRQ_LINE_S, /**< Линия прерываний 0.*/
GPIO_LINE_1 = 1 << GPIO_IRQ_LINE_S, /**< Линия прерываний 1.*/
GPIO_LINE_2 = 2 << GPIO_IRQ_LINE_S, /**< Линия прерываний 2.*/
GPIO_LINE_3 = 3 << GPIO_IRQ_LINE_S, /**< Линия прерываний 3.*/
GPIO_LINE_4 = 4 << GPIO_IRQ_LINE_S, /**< Линия прерываний 4.*/
GPIO_LINE_5 = 5 << GPIO_IRQ_LINE_S, /**< Линия прерываний 5.*/
GPIO_LINE_6 = 6 << GPIO_IRQ_LINE_S, /**< Линия прерываний 6.*/
GPIO_LINE_7 = 7 << GPIO_IRQ_LINE_S, /**< Линия прерываний 7.*/
} HAL_GPIO_Line;
/**
* @brief Конфигурация линии прерывания.
*
* @note значение представляется в виде 0b0LLLMMMM, где L - биты номера линии, M - биты выбранного входа мультиплексора линии.
*/
typedef enum __HAL_GPIO_Line_Config
{
GPIO_MUX_LINE_0_PORT0_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT0_8 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT1_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT1_8 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT2_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT0_4 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT0_12 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT1_4 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT1_12 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */
GPIO_MUX_LINE_0_PORT2_4 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */
GPIO_MUX_PORT0_0_LINE_0 = 0 | GPIO_LINE_0, /**< PORT0_0 как вход для линии прерывания 0. */
GPIO_MUX_PORT0_8_LINE_0 = 1 | GPIO_LINE_0, /**< PORT0_8 как вход для линии прерывания 0. */
GPIO_MUX_PORT1_0_LINE_0 = 2 | GPIO_LINE_0, /**< PORT1_0 как вход для линии прерывания 0. */
GPIO_MUX_PORT1_8_LINE_0 = 3 | GPIO_LINE_0, /**< PORT1_8 как вход для линии прерывания 0. */
GPIO_MUX_PORT2_0_LINE_0 = 4 | GPIO_LINE_0, /**< PORT2_0 как вход для линии прерывания 0. */
GPIO_MUX_PORT0_4_LINE_0 = 5 | GPIO_LINE_0, /**< PORT0_4 как вход для линии прерывания 0. */
GPIO_MUX_PORT0_12_LINE_0 = 6 | GPIO_LINE_0, /**< PORT0_12 как вход для линии прерывания 0. */
GPIO_MUX_PORT1_4_LINE_0 = 7 | GPIO_LINE_0, /**< PORT1_4 как вход для линии прерывания 0. */
GPIO_MUX_PORT1_12_LINE_0 = 8 | GPIO_LINE_0, /**< PORT1_12 как вход для линии прерывания 0. */
GPIO_MUX_PORT2_4_LINE_0 = 9 | GPIO_LINE_0, /**< PORT2_4 как вход для линии прерывания 0. */
GPIO_MUX_LINE_1_PORT0_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT0_9 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT1_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT1_9 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT2_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT0_5 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT0_13 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT1_5 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT1_13 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */
GPIO_MUX_LINE_1_PORT2_5 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */
GPIO_MUX_PORT0_1_LINE_1 = 0 | GPIO_LINE_1, /**< PORT0_1 как вход для линии прерывания 1. */
GPIO_MUX_PORT0_9_LINE_1 = 1 | GPIO_LINE_1, /**< PORT0_9 как вход для линии прерывания 1. */
GPIO_MUX_PORT1_1_LINE_1 = 2 | GPIO_LINE_1, /**< PORT1_1 как вход для линии прерывания 1. */
GPIO_MUX_PORT1_9_LINE_1 = 3 | GPIO_LINE_1, /**< PORT1_9 как вход для линии прерывания 1. */
GPIO_MUX_PORT2_1_LINE_1 = 4 | GPIO_LINE_1, /**< PORT2_1 как вход для линии прерывания 1. */
GPIO_MUX_PORT0_5_LINE_1 = 5 | GPIO_LINE_1, /**< PORT0_5 как вход для линии прерывания 1. */
GPIO_MUX_PORT0_13_LINE_1 = 6 | GPIO_LINE_1, /**< PORT0_13 как вход для линии прерывания 1. */
GPIO_MUX_PORT1_5_LINE_1 = 7 | GPIO_LINE_1, /**< PORT1_5 как вход для линии прерывания 1. */
GPIO_MUX_PORT1_13_LINE_1 = 8 | GPIO_LINE_1, /**< PORT1_13 как вход для линии прерывания 1. */
GPIO_MUX_PORT2_5_LINE_1 = 9 | GPIO_LINE_1, /**< PORT2_5 как вход для линии прерывания 1. */
GPIO_MUX_LINE_2_PORT0_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT0_10 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT1_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT1_10 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT2_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT0_6 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT0_14 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT1_6 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT1_14 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */
GPIO_MUX_LINE_2_PORT2_6 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */
GPIO_MUX_PORT0_2_LINE_2 = 0 | GPIO_LINE_2, /**< PORT0_2 как вход для линии прерывания 2. */
GPIO_MUX_PORT0_10_LINE_2 = 1 | GPIO_LINE_2, /**< PORT0_10 как вход для линии прерывания 2. */
GPIO_MUX_PORT1_2_LINE_2 = 2 | GPIO_LINE_2, /**< PORT1_2 как вход для линии прерывания 2. */
GPIO_MUX_PORT1_10_LINE_2 = 3 | GPIO_LINE_2, /**< PORT1_10 как вход для линии прерывания 2. */
GPIO_MUX_PORT2_2_LINE_2 = 4 | GPIO_LINE_2, /**< PORT2_2 как вход для линии прерывания 2. */
GPIO_MUX_PORT0_6_LINE_2 = 5 | GPIO_LINE_2, /**< PORT0_6 как вход для линии прерывания 2. */
GPIO_MUX_PORT0_14_LINE_2 = 6 | GPIO_LINE_2, /**< PORT0_14 как вход для линии прерывания 2. */
GPIO_MUX_PORT1_6_LINE_2 = 7 | GPIO_LINE_2, /**< PORT1_6 как вход для линии прерывания 2. */
GPIO_MUX_PORT1_14_LINE_2 = 8 | GPIO_LINE_2, /**< PORT1_14 как вход для линии прерывания 2. */
GPIO_MUX_PORT2_6_LINE_2 = 9 | GPIO_LINE_2, /**< PORT2_6 как вход для линии прерывания 2. */
GPIO_MUX_LINE_3_PORT0_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT0_11 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT1_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT1_11 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT2_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT0_7 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT0_15 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT1_7 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT1_15 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */
GPIO_MUX_LINE_3_PORT2_7 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */
GPIO_MUX_PORT0_3_LINE_3 = 0 | GPIO_LINE_3, /**< PORT0_3 как вход для линии прерывания 3. */
GPIO_MUX_PORT0_11_LINE_3 = 1 | GPIO_LINE_3, /**< PORT0_11 как вход для линии прерывания 3. */
GPIO_MUX_PORT1_3_LINE_3 = 2 | GPIO_LINE_3, /**< PORT1_3 как вход для линии прерывания 3. */
GPIO_MUX_PORT1_11_LINE_3 = 3 | GPIO_LINE_3, /**< PORT1_11 как вход для линии прерывания 3. */
GPIO_MUX_PORT2_3_LINE_3 = 4 | GPIO_LINE_3, /**< PORT2_3 как вход для линии прерывания 3. */
GPIO_MUX_PORT0_7_LINE_3 = 5 | GPIO_LINE_3, /**< PORT0_7 как вход для линии прерывания 3. */
GPIO_MUX_PORT0_15_LINE_3 = 6 | GPIO_LINE_3, /**< PORT0_15 как вход для линии прерывания 3. */
GPIO_MUX_PORT1_7_LINE_3 = 7 | GPIO_LINE_3, /**< PORT1_7 как вход для линии прерывания 3. */
GPIO_MUX_PORT1_15_LINE_3 = 8 | GPIO_LINE_3, /**< PORT1_15 как вход для линии прерывания 3. */
GPIO_MUX_PORT2_7_LINE_3 = 9 | GPIO_LINE_3, /**< PORT2_7 как вход для линии прерывания 3. */
GPIO_MUX_LINE_4_PORT0_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT0_12 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT1_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT1_12 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT2_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT0_0 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT0_8 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT1_0 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT1_8 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */
GPIO_MUX_LINE_4_PORT2_0 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */
GPIO_MUX_PORT0_4_LINE_4 = 0 | GPIO_LINE_4, /**< PORT0_4 как вход для линии прерывания 4. */
GPIO_MUX_PORT0_12_LINE_4 = 1 | GPIO_LINE_4, /**< PORT0_12 как вход для линии прерывания 4. */
GPIO_MUX_PORT1_4_LINE_4 = 2 | GPIO_LINE_4, /**< PORT1_4 как вход для линии прерывания 4. */
GPIO_MUX_PORT1_12_LINE_4 = 3 | GPIO_LINE_4, /**< PORT1_12 как вход для линии прерывания 4. */
GPIO_MUX_PORT2_4_LINE_4 = 4 | GPIO_LINE_4, /**< PORT2_4 как вход для линии прерывания 4. */
GPIO_MUX_PORT0_0_LINE_4 = 5 | GPIO_LINE_4, /**< PORT0_0 как вход для линии прерывания 4. */
GPIO_MUX_PORT0_8_LINE_4 = 6 | GPIO_LINE_4, /**< PORT0_8 как вход для линии прерывания 4. */
GPIO_MUX_PORT1_0_LINE_4 = 7 | GPIO_LINE_4, /**< PORT1_0 как вход для линии прерывания 4. */
GPIO_MUX_PORT1_8_LINE_4 = 8 | GPIO_LINE_4, /**< PORT1_8 как вход для линии прерывания 4. */
GPIO_MUX_PORT2_0_LINE_4 = 9 | GPIO_LINE_4, /**< PORT2_0 как вход для линии прерывания 4. */
GPIO_MUX_LINE_5_PORT0_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT0_13 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT1_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT1_13 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT2_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT0_1 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT0_9 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT1_1 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT1_9 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */
GPIO_MUX_LINE_5_PORT2_1 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */
GPIO_MUX_PORT0_5_LINE_5 = 0 | GPIO_LINE_5, /**< PORT0_5 как вход для линии прерывания 5. */
GPIO_MUX_PORT0_13_LINE_5 = 1 | GPIO_LINE_5, /**< PORT0_13 как вход для линии прерывания 5. */
GPIO_MUX_PORT1_5_LINE_5 = 2 | GPIO_LINE_5, /**< PORT1_5 как вход для линии прерывания 5. */
GPIO_MUX_PORT1_13_LINE_5 = 3 | GPIO_LINE_5, /**< PORT1_13 как вход для линии прерывания 5. */
GPIO_MUX_PORT2_5_LINE_5 = 4 | GPIO_LINE_5, /**< PORT2_5 как вход для линии прерывания 5. */
GPIO_MUX_PORT0_1_LINE_5 = 5 | GPIO_LINE_5, /**< PORT0_1 как вход для линии прерывания 5. */
GPIO_MUX_PORT0_9_LINE_5 = 6 | GPIO_LINE_5, /**< PORT0_9 как вход для линии прерывания 5. */
GPIO_MUX_PORT1_1_LINE_5 = 7 | GPIO_LINE_5, /**< PORT1_1 как вход для линии прерывания 5. */
GPIO_MUX_PORT1_9_LINE_5 = 8 | GPIO_LINE_5, /**< PORT1_9 как вход для линии прерывания 5. */
GPIO_MUX_PORT2_1_LINE_5 = 9 | GPIO_LINE_5, /**< PORT2_1 как вход для линии прерывания 5. */
GPIO_MUX_LINE_6_PORT0_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT0_14 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT1_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT1_14 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT2_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT0_2 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT0_10 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT1_2 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT1_10 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */
GPIO_MUX_LINE_6_PORT2_2 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */
GPIO_MUX_PORT0_6_LINE_6 = 0 | GPIO_LINE_6, /**< PORT0_6 как вход для линии прерывания 6. */
GPIO_MUX_PORT0_14_LINE_6 = 1 | GPIO_LINE_6, /**< PORT0_14 как вход для линии прерывания 6. */
GPIO_MUX_PORT1_6_LINE_6 = 2 | GPIO_LINE_6, /**< PORT1_6 как вход для линии прерывания 6. */
GPIO_MUX_PORT1_14_LINE_6 = 3 | GPIO_LINE_6, /**< PORT1_14 как вход для линии прерывания 6. */
GPIO_MUX_PORT2_6_LINE_6 = 4 | GPIO_LINE_6, /**< PORT2_6 как вход для линии прерывания 6. */
GPIO_MUX_PORT0_2_LINE_6 = 5 | GPIO_LINE_6, /**< PORT0_2 как вход для линии прерывания 6. */
GPIO_MUX_PORT0_10_LINE_6 = 6 | GPIO_LINE_6, /**< PORT0_10 как вход для линии прерывания 6. */
GPIO_MUX_PORT1_2_LINE_6 = 7 | GPIO_LINE_6, /**< PORT1_2 как вход для линии прерывания 6. */
GPIO_MUX_PORT1_10_LINE_6 = 8 | GPIO_LINE_6, /**< PORT1_10 как вход для линии прерывания 6. */
GPIO_MUX_PORT2_2_LINE_6 = 9 | GPIO_LINE_6, /**< PORT2_2 как вход для линии прерывания 6. */
GPIO_MUX_LINE_7_PORT0_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT0_15 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT1_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT1_15 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT2_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT0_3 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT0_11 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT1_3 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT1_11 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */
GPIO_MUX_LINE_7_PORT2_3 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */
GPIO_MUX_PORT0_7_LINE_7 = 0 | GPIO_LINE_7, /**< PORT0_7 как вход для линии прерывания 7. */
GPIO_MUX_PORT0_15_LINE_7 = 1 | GPIO_LINE_7, /**< PORT0_15 как вход для линии прерывания 7. */
GPIO_MUX_PORT1_7_LINE_7 = 2 | GPIO_LINE_7, /**< PORT1_7 как вход для линии прерывания 7. */
GPIO_MUX_PORT1_15_LINE_7 = 3 | GPIO_LINE_7, /**< PORT1_15 как вход для линии прерывания 7. */
GPIO_MUX_PORT2_7_LINE_7 = 4 | GPIO_LINE_7, /**< PORT2_7 как вход для линии прерывания 7. */
GPIO_MUX_PORT0_3_LINE_7 = 5 | GPIO_LINE_7, /**< PORT0_3 как вход для линии прерывания 7. */
GPIO_MUX_PORT0_11_LINE_7 = 6 | GPIO_LINE_7, /**< PORT0_11 как вход для линии прерывания 7. */
GPIO_MUX_PORT1_3_LINE_7 = 7 | GPIO_LINE_7, /**< PORT1_3 как вход для линии прерывания 7. */
GPIO_MUX_PORT1_11_LINE_7 = 8 | GPIO_LINE_7, /**< PORT1_11 как вход для линии прерывания 7. */
GPIO_MUX_PORT2_3_LINE_7 = 9 | GPIO_LINE_7, /**< PORT2_3 как вход для линии прерывания 7. */
} HAL_GPIO_Line_Config;
/**
* @brief Режим прерывания линии GPIO.
* \note Функция инициализации @ref HAL_GPIO_InitInterruptLine не включает прерывания GPIO в EPIC.
*/
typedef enum __HAL_GPIO_InterruptMode
{
GPIO_INT_MODE_LOW = 0, /**< Режим прерывания по низкому уровню на выводе. */
GPIO_INT_MODE_HIGH = GPIO_MODE_BIT_LEVEL_M, /**< Режим прерывания по высокому уровню на выводе. */
GPIO_INT_MODE_FALLING = GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с высокого на низкий. */
GPIO_INT_MODE_RISING = GPIO_MODE_BIT_LEVEL_M | GPIO_MODE_BIT_EDGE_M, /**< Режим прерывания по смене уровня на выводе с низкого на высокий. */
GPIO_INT_MODE_CHANGE = GPIO_MODE_BIT_EDGE_M | GPIO_MODE_BIT_ANYEDGE_M, /**< Режим прерывания по изменению уровня на выводе. */
} HAL_GPIO_InterruptMode;
HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init);
HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode);
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine);
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine);
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine);
void HAL_GPIO_ClearInterrupts();
#ifdef __cplusplus
}
#endif
#endif // MIK32_HAL_GPIO

View File

@ -0,0 +1,615 @@
#ifndef MIK32_HAL_I2C
#define MIK32_HAL_I2C
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "mik32_hal_def.h"
#include "i2c.h"
#include "mcu32_memory_map.h"
#include "mik32_hal_dma.h"
/*
* Define: I2C_TIMEOUT
* Количество циклов ожидания установки флага TXIS или RXNE
*
*/
#define I2C_TIMEOUT_DEFAULT 1000000 /* Количество циклов ожидания установки флага TXIS или RXNE */
/*
* Define: I2C_NBYTE_MAX
* Максимальлное количество байт в посылке (NBYTES)
*
*/
#define I2C_NBYTE_MAX 255 /* Максимальное количество байт в посылке (NBYTES) */
#define I2C_ADDRESS_7BIT_MAX 0x7F /* Максимальный 7 битный адрес */
#define I2C_ADDRESS_10BIT_MAX 0x3FF /* Максимальный 10 битный адрес */
#define I2C_INTMASK 0b11111110 /* Маска для разрешенных прерываний */
/* I2C_error - номера ошибок I2C*/
/* Номер канала */
typedef enum
{
I2C_ERROR_NONE = 0, /* Ошибок нет */
I2C_ERROR_TIMEOUT = 1, /* Превышено ожидание установки флага TXIS или RXNE */
I2C_ERROR_NACK = 2, /* Во время передачи не получено подтверждение данных (NACK) */
I2C_ERROR_BERR = 3, /* Ошибка шины */
I2C_ERROR_ARLO = 4, /* Проигрыш арбитража */
I2C_ERROR_OVR = 5, /* Переполнение или недозагрузка */
I2C_ERROR_STOP = 6, /* Обнаружение STOP на линии */
} HAL_I2C_ErrorTypeDef;
/* I2C_addressing_mode - Режим адреса */
typedef enum
{
I2C_ADDRESSINGMODE_7BIT = 0, /* 7 битный адрес */
I2C_ADDRESSINGMODE_10BIT = 1 /* 10 битный адрес */
} HAL_I2C_AddressingModeTypeDef;
/* I2C_dual_addressing_mode - Режим дополнительного адреса 7 бит */
typedef enum
{
I2C_DUALADDRESS_DISABLE = 0, /* Выключить дополнительный адрес */
I2C_DUALADDRESS_ENABLE = 1 /* Включить дополнительный адрес */
} HAL_I2C_DualAddressTypeDef;
/* I2C_general_call_mode - Адрес общего вызова */
typedef enum
{
I2C_GENERALCALL_DISABLE = 0, /* Выключить адрес общего вызова */
I2C_GENERALCALL_ENABLE = 1 /* Включить адрес общего вызова */
} HAL_I2C_GeneralCallTypeDef;
/* I2C_nostretch_mode - Режим удержания SCL ведомым */
typedef enum
{
I2C_NOSTRETCH_DISABLE = 0, /* Растягивание активно */
I2C_NOSTRETCH_ENABLE = 1 /* растягивание выключено */
} HAL_I2C_NoStretchModeTypeDef;
/* I2C_sbc_mode - Режим аппаратного контроля байта ведомым */
typedef enum
{
I2C_SBC_DISABLE = 0, /* Аппаратный контроль выключен */
I2C_SBC_ENABLE = 1 /* Аппаратный контроль включен */
} HAL_I2C_SBCModeTypeDef;
/* I2C_reload_mode - Режим перезаписи NBYTES: */
typedef enum
{
I2C_RELOAD_DISABLE = 0, /* Транзакция завершена после пересылки NBYTES байт данных (на шине ожидаются STOP или RESTART) */
I2C_RELOAD_ENABLE = 1 /* Транзакция не завершена после пересылки NBYTES байт данных (значение NBYTES будет перезаписано) */
} HAL_I2C_ReloadModeTypeDef;
/* I2C_autoend_mode - Режим автоматического окончания */
typedef enum
{
I2C_AUTOEND_DISABLE = 0, /* Режим автоматического окончания отключен */
I2C_AUTOEND_ENABLE = 1 /* Режим автоматического окончания включен */
} HAL_I2C_AutoEndModeTypeDef;
/* I2C_transfer_direction - Направление передачи */
typedef enum
{
I2C_TRANSFER_WRITE = 0, /* Ведущий запрашивает транзакцию записи */
I2C_TRANSFER_READ = 1 /* Ведущий запрашивает транзакцию чтения */
} HAL_I2C_TransferDirectionTypeDef;
/* I2C_OwnAddress2_mask - Маска второго собственного адреса */
typedef enum
{
I2C_OWNADDRESS2_MASK_DISABLE = 0, /* Нет маски */
I2C_OWNADDRESS2_MASK_111111x = 1, /* Сравниваются только OA2[7:2] */
I2C_OWNADDRESS2_MASK_11111xx = 2, /* Сравниваются только OA2[7:3]; */
I2C_OWNADDRESS2_MASK_1111xxx = 3, /* Сравниваются только OA2[7:4]; */
I2C_OWNADDRESS2_MASK_111xxxx = 4, /* Сравниваются только OA2[7:5]; */
I2C_OWNADDRESS2_MASK_11xxxxx = 5, /* Сравниваются только OA2[7:6]; */
I2C_OWNADDRESS2_MASK_1xxxxxx = 6, /* Сравниваются только OA2[7]; */
I2C_OWNADDRESS2_MASK_1111111 = 7 /* OA2[7:1] маскируются, подтверждаются (ACK) все 7-битные адреса (кроме зарезервированных) */
} HAL_I2C_OwnAddress2MaskTypeDef;
/* I2C_digital_filter - Цифровой фильтр */
typedef enum
{
I2C_DIGITALFILTER_OFF = 0,
I2C_DIGITALFILTER_1CLOCKCYCLES = 1,
I2C_DIGITALFILTER_2CLOCKCYCLES = 2,
I2C_DIGITALFILTER_15CLOCKCYCLES = 15
} HAL_I2C_DigitalFilterTypeDef;
/* I2C_analog_filter - Цифровой фильтр */
typedef enum
{
I2C_ANALOGFILTER_ENABLE = 0,
I2C_ANALOGFILTER_DISABLE = 1
} HAL_I2C_AnalogFilterTypeDef;
typedef enum
{
HAL_I2C_MODE_MASTER = 0, /* Режим ведущего */
HAL_I2C_MODE_SLAVE = 1, /* Режим ведомого */
} HAL_I2C_ModeTypeDef;
typedef struct
{
HAL_I2C_ModeTypeDef Mode; /* Режим ведомый или ведущий */
/*
* Variable: OwnAddress1
* Основной собственный адрес.
*
* Когда включен дополнительный адрес, длинна основного адреса должна быть 7 бит.
*
* Этот параметр должен быть 7-битным или 10-битным числом
*
*/
uint32_t OwnAddress1;
/*
* Variable: DualAddressMode
* Активация дополнительного 7 битного адреса
*
* Можно использовать, если длина основного адреса 7 бит
*
* Этот параметр должен быть одним из значений:
*
* - <I2C_DUALADDRESS_DISABLE>;
* - <I2C_DUALADDRESS_ENABLE>.
*
*
*/
HAL_I2C_DualAddressTypeDef DualAddressMode;
/*
* Variable: OwnAddress2
* Дополнительный 7 битный адрес
*
* Можно использовать, если длина основного адреса 7 бит
*
* Этот параметр должен быть 7 битным числом.
*
*/
uint32_t OwnAddress2;
HAL_I2C_GeneralCallTypeDef GeneralCall;
/*
* Variable: OwnAddress2Mask
* Маска сравнения дополнительного 7 битного адреса
*
* Этот параметр должен быть одним из значений:
*
* - <I2C_OWNADDRESS2_MASK_DISABLE>
* - <I2C_OWNADDRESS2_MASK_111111x>
* - <I2C_OWNADDRESS2_MASK_11111xx>
* - <I2C_OWNADDRESS2_MASK_1111xxx>
* - <I2C_OWNADDRESS2_MASK_111xxxx>
* - <I2C_OWNADDRESS2_MASK_11xxxxx>
* - <I2C_OWNADDRESS2_MASK_1xxxxxx>
* - <I2C_OWNADDRESS2_MASK_1111111>
*
*/
HAL_I2C_OwnAddress2MaskTypeDef OwnAddress2Mask;
/*
* Variable: NoStretchMode
* Растягивания тактового сигнала в режиме "ведомый".
*
* Не совместим с режимом SBC
*
* В режиме ведущий значение всегда I2C_NOSTRETCH_DISABLE
*
* Этот параметр должен быть одним из значений:
*
* - <I2C_NOSTRETCH_DISABLE>
* - <I2C_NOSTRETCH_ENABLE>
*
*/
HAL_I2C_NoStretchModeTypeDef NoStretchMode;
/*
* Variable: SBCMode
* Режим аппаратного контроля передачи данных в режиме "ведомый"
*
* Не совместим с режимом NOSTRETCH
*
* Этот параметр должен быть одним из значений:
*
* - <I2C_SBC_DISABLE>
* - <I2C_SBC_ENABLE>
*
*/
HAL_I2C_SBCModeTypeDef SBCMode;
/*
* Variable: AutoEnd
* Управление режимом автоматического окончания в режиме "ведущий"
*
* Этот параметр должен быть одним из значений:
*
* - <AUTOEND_DISABLE>
* - <AUTOEND_ENABLE>
*
*/
HAL_I2C_AutoEndModeTypeDef AutoEnd;
/*
* Variable: Filter
* Цифровой фильтр
*
* Этот параметр должен быть одним из значений:
*
* - <I2C_FILTER_OFF>
* - <I2C_FILTER_1CLOCKCYCLES>
* - <I2C_FILTER_2CLOCKCYCLES>
* - <I2C_FILTER_15CLOCKCYCLES>
*
*/
HAL_I2C_DigitalFilterTypeDef DigitalFilter;
HAL_I2C_AnalogFilterTypeDef AnalogFilter;
} I2C_InitTypeDef;
/*
* Struct: I2C_ClockTypeDef
*
* Настройки временных ограничений
*
*/
typedef struct
{
/*
* Variable: PRESC
* Предварительный делитель частоты I2CCLK.
*
* Используется для вычисления значения t_PRESC используемого счетчиками предустановки, удержания, низкого и высокого уровней.
*
* Этот параметр может быть числом в пределах от 0 до 15
*
*/
uint32_t PRESC;
/*
* Variable: SCLDEL
* Длительность предустановки данных.
*
* Задержка между изменением SDA и фронтом SCL.
*
* Этот параметр может быть числом в пределах от 0 до 15.
*
*/
uint32_t SCLDEL;
/*
* Variable: SDADEL
* Длительность предустановки данных.
*
* Задержка между спадом SCL и изменением SDA в режиме ведущего и ведомого при NOSTRETCH = 0.
*
* Этот параметр может быть числом в пределах от 0 до 15.
*
*/
uint32_t SDADEL;
/*
* Variable: SCLH
* Длительность удержания SCL в состоянии логической "1" в режиме "ведущий".
*
* Этот параметр может быть от 0 до 255.
*
*/
uint32_t SCLH;
/*
* Variable: SCLL
* Длительность удержания SCL в состоянии логического "0" в режиме "ведущий".
*
* Этот параметр может быть от 0 до 255.
*
*/
uint32_t SCLL;
} I2C_ClockTypeDef;
typedef enum
{
HAL_I2C_STATE_READY, /* Готов к передаче */
HAL_I2C_STATE_BUSY, /* Идет передача */
HAL_I2C_STATE_END, /* Передача завершена */
HAL_I2C_STATE_ERROR /* Ошибка при передаче */
} HAL_I2C_StateTypeDef;
typedef struct
{
/*
* Variable: Instance
* Базовый адрес регистров I2C
*
*/
I2C_TypeDef *Instance;
/*
* Variable: Init
* Параметры инициализации I2C
*
*/
I2C_InitTypeDef Init;
/*
* Variable: Clock
* Параметры частоты I2C
*
*/
I2C_ClockTypeDef Clock;
/*
* Variable: ErrorCode
* Код ошибки I2C
*
*/
HAL_I2C_ErrorTypeDef ErrorCode;
/*
* Variable: hdmatx
* Канала DMA для отправки данных
*/
DMA_ChannelHandleTypeDef *hdmatx;
/*
* Variable: hdmarx
* Канала DMA для приема данных
*/
DMA_ChannelHandleTypeDef *hdmarx;
volatile HAL_I2C_StateTypeDef State;
uint8_t *pBuffPtr;
uint32_t TransferSize;
uint32_t TransferCount;
} I2C_HandleTypeDef;
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c);
void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c);
void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c);
void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter);
void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter);
void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c);
void HAL_I2C_NoStretchMode(I2C_HandleTypeDef *hi2c, HAL_I2C_NoStretchModeTypeDef NoStretchMode);
void HAL_I2C_OwnAddress1(I2C_HandleTypeDef *hi2c);
void HAL_I2C_OwnAddress2(I2C_HandleTypeDef *hi2c);
void HAL_I2C_GeneralCall(I2C_HandleTypeDef *hi2c, HAL_I2C_GeneralCallTypeDef GeneralCall);
void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode);
void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd);
HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
void HAL_I2C_Master_SlaveAddress(I2C_HandleTypeDef *hi2h, uint16_t SlaveAddress);
HAL_StatusTypeDef HAL_I2C_WaitBusy(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
void HAL_I2C_Master_NBYTES(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_WaitADDR(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_WaitTCR(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
void HAL_I2C_Slave_ACK(I2C_HandleTypeDef *hi2c);
void HAL_I2C_Slave_NACK(I2C_HandleTypeDef *hi2c);
extern HAL_StatusTypeDef HAL_I2C_Slave_SBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t ByteCount);
HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize, uint32_t Timeout);
void HAL_I2C_InterruptDisable(I2C_HandleTypeDef *hi2c, uint32_t IntDisMask);
void HAL_I2C_InterruptEnable(I2C_HandleTypeDef *hi2c, uint32_t IntEnMask);
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t SlaveAddress, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
{
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1);
}
/* Сброс флага ADDR */
hi2c->Instance->ICR |= I2C_ICR_ADDRCF_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_ERR_IRQ(I2C_HandleTypeDef *hi2c)
{
hi2c->State = HAL_I2C_STATE_ERROR;
/* Выключить все прерывания I2C */
hi2c->Instance->CR1 &= ~I2C_INTMASK;
/* Сброс I2C */
hi2c->ErrorCode = I2C_ERROR_NONE;
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_NACK_IRQ(I2C_HandleTypeDef *hi2c)
{
hi2c->State = HAL_I2C_STATE_ERROR;
/* Выключить все прерывания I2C */
hi2c->Instance->CR1 &= ~I2C_INTMASK;
/* Сброс I2C */
hi2c->ErrorCode = I2C_ERROR_NONE;
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_STOP_IRQ(I2C_HandleTypeDef *hi2c)
{
hi2c->State = HAL_I2C_STATE_END;
/* Сброс содержимого TXDR */
hi2c->Instance->ISR |= I2C_ISR_TXE_M;
/* Сброс флага детектирования STOP на шине */
hi2c->Instance->ICR |= I2C_ICR_STOPCF_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_TXIS_IRQ(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->TXDR = *((uint8_t *)hi2c->pBuffPtr);
hi2c->pBuffPtr++;
hi2c->TransferCount++;
if (hi2c->TransferCount == hi2c->TransferSize)
{
hi2c->State = HAL_I2C_STATE_END;
}
}
static inline __attribute__((always_inline)) void HAL_I2C_RXNE_IRQ(I2C_HandleTypeDef *hi2c)
{
*((uint8_t *)hi2c->pBuffPtr) = (uint8_t)hi2c->Instance->RXDR;
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
{
if (HAL_I2C_Slave_SBC(hi2c, hi2c->pBuffPtr - hi2c->TransferCount, hi2c->TransferSize, hi2c->TransferCount) != HAL_OK)
{
hi2c->State = HAL_I2C_STATE_END;
/* Выключить все прерывания I2C */
hi2c->Instance->CR1 &= ~I2C_INTMASK;
/* Сброс I2C */
hi2c->ErrorCode = I2C_ERROR_NONE;
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
}
hi2c->pBuffPtr++;
hi2c->TransferCount++;
if (hi2c->TransferCount == hi2c->TransferSize)
{
hi2c->State = HAL_I2C_STATE_END;
}
}
static inline __attribute__((always_inline)) void HAL_I2C_TCR_IRQ(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
{
if (hi2c->TransferCount < hi2c->TransferSize)
{
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(0x1);
}
else
{
hi2c->State = HAL_I2C_STATE_END;
}
}
else
{
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
/* Подготовка перед отправкой */
if ((hi2c->TransferSize - hi2c->TransferCount) <= I2C_NBYTE_MAX)
{
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(hi2c->TransferSize - hi2c->TransferCount);
hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M;
hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M;
hi2c->Instance->CR2 |= hi2c->Init.AutoEnd << I2C_CR2_AUTOEND_S;
}
else /* DataSize > 255 */
{
hi2c->Instance->CR2 &= ~I2C_CR2_NBYTES_M;
hi2c->Instance->CR2 |= I2C_CR2_NBYTES(I2C_NBYTE_MAX);
/* При RELOAD = 1 AUTOEND игнорируется */
hi2c->Instance->CR2 |= I2C_CR2_RELOAD_M;
}
}
}
static inline __attribute__((always_inline)) void HAL_I2C_TC_IRQ(I2C_HandleTypeDef *hi2c)
{
hi2c->State = HAL_I2C_STATE_END;
}
static inline __attribute__((always_inline)) void HAL_I2C_IRQHandler(I2C_HandleTypeDef *hi2c)
{
uint32_t int_mask = hi2c->Instance->CR1 & I2C_INTMASK; /* разрешенные прерывания */
uint32_t interrupt_status = hi2c->Instance->ISR; /* Флаги */
if ((interrupt_status & I2C_ISR_ADDR_M) && (int_mask & I2C_CR1_ADDRIE_M))
{
// xprintf("ADDR\n");
HAL_I2C_ADDR_IRQ(hi2c);
}
if ((interrupt_status & (I2C_ISR_BERR_M | I2C_ISR_ARLO_M | I2C_ISR_OVR_M)) && (int_mask & I2C_CR1_ERRIE_M))
{
// xprintf("Err, count %d, ISR %d\n", hi2c->TransferCount, hi2c->Instance->ISR);
HAL_I2C_ERR_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_NACKF_M) && (int_mask & I2C_CR1_NACKIE_M))
{
// xprintf("NACK\n");
HAL_I2C_NACK_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_STOPF_M) && (int_mask & I2C_CR1_STOPIE_M))
{
// xprintf("Stop\n");
HAL_I2C_STOP_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_TXIS_M) && (int_mask & I2C_CR1_TXIE_M))
{
// xprintf("TXIS %d (%d)\n", hi2c->TransferCount, *((uint8_t *)hi2c->pBuffPtr));
HAL_I2C_TXIS_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_RXNE_M) && (int_mask & I2C_CR1_RXIE_M))
{
// xprintf("RXNE %d\n", hi2c->TransferCount);
HAL_I2C_RXNE_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_TCR_M) && (int_mask & I2C_CR1_TCIE_M))
{
// xprintf("TCR\n");
HAL_I2C_TCR_IRQ(hi2c);
}
if ((interrupt_status & I2C_ISR_TC_M) && (int_mask & I2C_CR1_TCIE_M))
{
// xprintf("TC\n");
HAL_I2C_TC_IRQ(hi2c);
}
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,333 @@
#ifndef MIK32_HAL_IRQ
#define MIK32_HAL_IRQ
#ifdef __cplusplus
extern "C" {
#endif
#include "epic.h"
#include "csr.h"
#include "scr1_csr_encoding.h"
#include "mcu32_memory_map.h"
/* Title: Макросы */
#ifdef MIK32V0
/*
* Defines: Маска линии прерывания
*
*
* HAL_EPIC_TIMER32_0_MASK - Маска для линии прерывания Timer32_0
* HAL_EPIC_UART_0_MASK - Маска для линии прерывания USART_0
* HAL_EPIC_UART_1_MASK - Маска для линии прерывания USART_1
* HAL_EPIC_SPI_0_MASK - Маска для линии прерывания SPI_0
* HAL_EPIC_SPI_1_MASK - Маска для линии прерывания SPI_1
* HAL_EPIC_GPIO_IRQ_MASK - Маска для линии прерывания GPIO
* HAL_EPIC_I2C_0_MASK - Маска для линии прерывания I2C_0
* HAL_EPIC_I2C_1_MASK - Маска для линии прерывания I2C_1
* HAL_EPIC_WDT_MASK - Маска для линии прерывания Сторожевой таймер
* HAL_EPIC_TIMER16_0_MASK - Маска для линии прерывания Timer16_0
* HAL_EPIC_TIMER16_1_MASK - Маска для линии прерывания Timer16_1
* HAL_EPIC_TIMER16_2_MASK - Маска для линии прерывания Timer16_2
* HAL_EPIC_TIMER32_1_MASK - Маска для линии прерывания Timer32_1
* HAL_EPIC_TIMER32_2_MASK - Маска для линии прерывания Timer32_2
* HAL_EPIC_SPIFI_MASK - Маска для линии прерывания SPIFI
* HAL_EPIC_RTC_MASK - Маска для линии прерывания RTC
* HAL_EPIC_EEPROM_MASK - Маска для линии прерывания EEPROM
* HAL_EPIC_WDT_DOM3_MASK - Маска для линии прерывания Сторожевой таймер шины (периферийные устройства)
* HAL_EPIC_WDT_SPIFI_MASK - Маска для линии прерывания Сторожевой таймер шины (SPIFI)
* HAL_EPIC_WDT_EEPROM_MASK - Маска для линии прерывания Сторожевой таймер шины (EEPROM)
* HAL_EPIC_DMA_GLB_ERR_MASK - Маска для линии прерывания ПДП глобальное прерывание
* HAL_EPIC_DMA_CHANNELS_MASK - Маска для линии прерывания ПДП локальное прерывание
* HAL_EPIC_FREQ_MON_MASK - Маска для линии прерывания Монитор частоты
* HAL_EPIC_PVD_AVCC_UNDER - Маска для линии прерывания Монитор напряжения AVCC (ниже порога)
* HAL_EPIC_PVD_AVCC_OVER - Маска для линии прерывания Монитор напряжения AVCC (выше порога)
* HAL_EPIC_PVD_VCC_UNDER - Маска для линии прерывания Монитор напряжения VCC (ниже порога)
* HAL_EPIC_PVD_VCC_OVER - Маска для линии прерывания Монитор напряжения VCC (выше порога)
* HAL_EPIC_BATTERY_NON_GOOD - Маска для линии прерывания Недостаточное напряжение батареи
* HAL_EPIC_BOR_MASK - Маска для линии прерывания BrouwnOut детектор
* HAL_EPIC_TSENS_MASK - Маска для линии прерывания Монитор температуры
* HAL_EPIC_ADC_MASK - Маска для линии прерывания АЦП
*
*/
#define HAL_EPIC_TIMER32_0_MASK ( 1 << EPIC_TIMER32_0_INDEX )
#define HAL_EPIC_UART_0_MASK ( 1 << EPIC_UART_0_INDEX )
#define HAL_EPIC_UART_1_MASK ( 1 << EPIC_UART_1_INDEX )
#define HAL_EPIC_SPI_0_MASK ( 1 << EPIC_SPI_0_INDEX )
#define HAL_EPIC_SPI_1_MASK ( 1 << EPIC_SPI_1_INDEX )
#define HAL_EPIC_GPIO_IRQ_MASK ( 1 << EPIC_GPIO_IRQ_INDEX )
#define HAL_EPIC_I2C_0_MASK ( 1 << EPIC_I2C_0_INDEX )
#define HAL_EPIC_I2C_1_MASK ( 1 << EPIC_I2C_1_INDEX )
#define HAL_EPIC_WDT_MASK ( 1 << EPIC_WDT_INDEX )
#define HAL_EPIC_TIMER16_0_MASK ( 1 << EPIC_TIMER16_0_INDEX )
#define HAL_EPIC_TIMER16_1_MASK ( 1 << EPIC_TIMER16_1_INDEX )
#define HAL_EPIC_TIMER16_2_MASK ( 1 << EPIC_TIMER16_2_INDEX )
#define HAL_EPIC_TIMER32_1_MASK ( 1 << EPIC_TIMER32_1_INDEX )
#define HAL_EPIC_TIMER32_2_MASK ( 1 << EPIC_TIMER32_2_INDEX )
#define HAL_EPIC_SPIFI_MASK ( 1 << EPIC_SPIFI_INDEX )
#define HAL_EPIC_RTC_MASK ( 1 << EPIC_RTC_INDEX )
#define HAL_EPIC_EEPROM_MASK ( 1 << EPIC_EEPROM_INDEX )
#define HAL_EPIC_WDT_DOM3_MASK ( 1 << EPIC_WDT_DOM3_INDEX )
#define HAL_EPIC_WDT_SPIFI_MASK ( 1 << EPIC_WDT_SPIFI_INDEX )
#define HAL_EPIC_WDT_EEPROM_MASK ( 1 << EPIC_WDT_EEPROM_INDEX )
#define HAL_EPIC_DMA_GLB_ERR_MASK ( 1 << EPIC_DMA_GLB_ERR_INDEX )
#define HAL_EPIC_DMA_CHANNELS_MASK ( 1 << EPIC_DMA_CHANNELS_INDEX )
#define HAL_EPIC_FREQ_MON_MASK ( 1 << EPIC_FREQ_MON_INDEX )
#define HAL_EPIC_PVD_AVCC_UNDER ( 1 << EPIC_PVD_AVCC_UNDER )
#define HAL_EPIC_PVD_AVCC_OVER ( 1 << EPIC_PVD_AVCC_OVER )
#define HAL_EPIC_PVD_VCC_UNDER ( 1 << EPIC_PVD_VCC_UNDER )
#define HAL_EPIC_PVD_VCC_OVER ( 1 << EPIC_PVD_VCC_OVER )
#define HAL_EPIC_BATTERY_NON_GOOD ( 1 << EPIC_BATTERY_NON_GOOD )
#define HAL_EPIC_BOR_MASK ( 1 << EPIC_BOR_INDEX )
#define HAL_EPIC_TSENS_MASK ( 1 << EPIC_TSENS_INDEX )
#define HAL_EPIC_ADC_MASK ( 1 << EPIC_ADC_INDEX )
/*
* macros: Проверка флагов линий прерываний в EPIC
*
*
* EPIC_CHECK_Timer32_0 - Проверка флага Timer32_0
* EPIC_CHECK_UART_0 - Проверка флага USART_0
* EPIC_CHECK_UART_1 - Проверка флага USART_1
* EPIC_CHECK_SPI_0 - Проверка флага SPI_0
* EPIC_CHECK_SPI_1 - Проверка флага SPI_1
* EPIC_CHECK_GPIO - Проверка флага GPIO
* EPIC_CHECK_I2C_0 - Проверка флага I2C_0
* EPIC_CHECK_I2C_1 - Проверка флага I2C_1
* EPIC_CHECK_WDT - Проверка флага Сторожевой таймер
* EPIC_CHECK_TIMER16_0 - Проверка флага Timer16_0
* EPIC_CHECK_TIMER16_1 - Проверка флага Timer16_1
* EPIC_CHECK_TIMER16_2 - Проверка флага Timer16_2
* EPIC_CHECK_TIMER32_1 - Проверка флага Timer32_1
* EPIC_CHECK_TIMER32_2 - Проверка флага Timer32_2
* EPIC_CHECK_SPIFI - Проверка флага SPIFI
* EPIC_CHECK_RTC - Проверка флага RTC
* EPIC_CHECK_EEPROM - Проверка флага EEPROM
* EPIC_CHECK_WDT_DOM3 - Проверка флага Сторожевой таймер шины (периферийные устройства)
* EPIC_CHECK_WDT_SPIFI - Проверка флага Сторожевой таймер шины (SPIFI)
* EPIC_CHECK_WDT_EEPROM - Проверка флага Сторожевой таймер шины (EEPROM)
* EPIC_CHECK_DMA_GLB_ERR - Проверка флага ПДП глобальное прерывание
* EPIC_CHECK_DMA_CHANNELS - Проверка флага ПДП локальное прерывание
* EPIC_CHECK_FREQ_MON - Проверка флага Монитор частоты
* EPIC_CHECK_PVD_AVCC_UNDER - Проверка флага Монитор напряжения AVCC (ниже порога)
* EPIC_CHECK_PVD_AVCC_OVER - Проверка флага Монитор напряжения AVCC (выше порога)
* EPIC_CHECK_PVD_VCC_UNDER - Проверка флага Монитор напряжения VCC (ниже порога)
* EPIC_CHECK_PVD_VCC_OVER - Проверка флага Монитор напряжения VCC (выше порога)
* EPIC_CHECK_BATTERY_NON_GOOD - Проверка флага Недостаточное напряжение батареи
* EPIC_CHECK_BOR - Проверка флага BrouwnOut детектор
* EPIC_CHECK_TSENS - Проверка флага Монитор температуры
* EPIC_CHECK_ADC - Проверка флага АЦП
*
*/
#define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX))
#define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX))
#define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX))
#define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX))
#define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX))
#define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX))
#define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX))
#define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX))
#define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX))
#define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX))
#define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX))
#define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX))
#define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX))
#define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX))
#define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX))
#define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX))
#define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX))
#define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX))
#define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX))
#define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX))
#define EPIC_CHECK_DMA_GLB_ERR() (EPIC->RAW_STATUS & (1 << EPIC_DMA_GLB_ERR_INDEX))
#define EPIC_CHECK_DMA_CHANNELS() (EPIC->RAW_STATUS & (1 << EPIC_DMA_CHANNELS_INDEX))
#define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX))
#define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER))
#define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER))
#define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER))
#define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER))
#define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD))
#define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX))
#define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX))
#define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX))
#else // MIK32V2
#define HAL_EPIC_TIMER32_0_MASK (1 << EPIC_TIMER32_0_INDEX)
#define HAL_EPIC_UART_0_MASK (1 << EPIC_UART_0_INDEX)
#define HAL_EPIC_UART_1_MASK (1 << EPIC_UART_1_INDEX)
#define HAL_EPIC_SPI_0_MASK (1 << EPIC_SPI_0_INDEX)
#define HAL_EPIC_SPI_1_MASK (1 << EPIC_SPI_1_INDEX)
#define HAL_EPIC_GPIO_IRQ_MASK (1 << EPIC_GPIO_IRQ_INDEX)
#define HAL_EPIC_I2C_0_MASK (1 << EPIC_I2C_0_INDEX)
#define HAL_EPIC_I2C_1_MASK (1 << EPIC_I2C_1_INDEX)
#define HAL_EPIC_WDT_MASK (1 << EPIC_WDT_INDEX)
#define HAL_EPIC_TIMER16_0_MASK (1 << EPIC_TIMER16_0_INDEX)
#define HAL_EPIC_TIMER16_1_MASK (1 << EPIC_TIMER16_1_INDEX)
#define HAL_EPIC_TIMER16_2_MASK (1 << EPIC_TIMER16_2_INDEX)
#define HAL_EPIC_TIMER32_1_MASK (1 << EPIC_TIMER32_1_INDEX)
#define HAL_EPIC_TIMER32_2_MASK (1 << EPIC_TIMER32_2_INDEX)
#define HAL_EPIC_SPIFI_MASK (1 << EPIC_SPIFI_INDEX)
#define HAL_EPIC_RTC_MASK (1 << EPIC_RTC_INDEX)
#define HAL_EPIC_EEPROM_MASK (1 << EPIC_EEPROM_INDEX)
#define HAL_EPIC_WDT_DOM3_MASK (1 << EPIC_WDT_DOM3_INDEX)
#define HAL_EPIC_WDT_SPIFI_MASK (1 << EPIC_WDT_SPIFI_INDEX)
#define HAL_EPIC_WDT_EEPROM_MASK (1 << EPIC_WDT_EEPROM_INDEX)
#define HAL_EPIC_DMA_MASK (1 << EPIC_DMA_INDEX)
#define HAL_EPIC_FREQ_MON_MASK (1 << EPIC_FREQ_MON_INDEX)
#define HAL_EPIC_PVD_AVCC_MASK (1 << EPIC_PVD_AVCC_UNDER)
#define HAL_EPIC_PVD_AVCCMASK (1 << EPIC_PVD_AVCC_OVER)
#define HAL_EPIC_PVD_VCC_MASK (1 << EPIC_PVD_VCC_UNDER)
#define HAL_EPIC_PVD_VCCMASK (1 << EPIC_PVD_VCC_OVER)
#define HAL_EPIC_BATTERY_NONMASK (1 << EPIC_BATTERY_NON_GOOD)
#define HAL_EPIC_BOR_MASK (1 << EPIC_BOR_INDEX)
#define HAL_EPIC_TSENS_MASK (1 << EPIC_TSENS_INDEX)
#define HAL_EPIC_ADC_MASK (1 << EPIC_ADC_INDEX)
#define HAL_EPIC_DAC0_MASK (1 << EPIC_DAC0_INDEX)
#define HAL_EPIC_DAC1_MASK (1 << EPIC_DAC1_INDEX)
#define EPIC_CHECK_TIMER32_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_0_INDEX))
#define EPIC_CHECK_UART_0() (EPIC->RAW_STATUS & (1 << EPIC_UART_0_INDEX))
#define EPIC_CHECK_UART_1() (EPIC->RAW_STATUS & (1 << EPIC_UART_1_INDEX))
#define EPIC_CHECK_SPI_0() (EPIC->RAW_STATUS & (1 << EPIC_SPI_0_INDEX))
#define EPIC_CHECK_SPI_1() (EPIC->RAW_STATUS & (1 << EPIC_SPI_1_INDEX))
#define EPIC_CHECK_GPIO_IRQ() (EPIC->RAW_STATUS & (1 << EPIC_GPIO_IRQ_INDEX))
#define EPIC_CHECK_I2C_0() (EPIC->RAW_STATUS & (1 << EPIC_I2C_0_INDEX))
#define EPIC_CHECK_I2C_1() (EPIC->RAW_STATUS & (1 << EPIC_I2C_1_INDEX))
#define EPIC_CHECK_WDT() (EPIC->STATUS & (1 << EPIC_WDT_INDEX))
#define EPIC_CHECK_TIMER16_0() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_0_INDEX))
#define EPIC_CHECK_TIMER16_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_1_INDEX))
#define EPIC_CHECK_TIMER16_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER16_2_INDEX))
#define EPIC_CHECK_TIMER32_1() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_1_INDEX))
#define EPIC_CHECK_TIMER32_2() (EPIC->RAW_STATUS & (1 << EPIC_TIMER32_2_INDEX))
#define EPIC_CHECK_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_SPIFI_INDEX))
#define EPIC_CHECK_RTC() (EPIC->RAW_STATUS & (1 << EPIC_RTC_INDEX))
#define EPIC_CHECK_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_EEPROM_INDEX))
#define EPIC_CHECK_WDT_DOM3() (EPIC->RAW_STATUS & (1 << EPIC_WDT_DOM3_INDEX))
#define EPIC_CHECK_WDT_SPIFI() (EPIC->RAW_STATUS & (1 << EPIC_WDT_SPIFI_INDEX))
#define EPIC_CHECK_WDT_EEPROM() (EPIC->RAW_STATUS & (1 << EPIC_WDT_EEPROM_INDEX))
#define EPIC_CHECK_DMA() (EPIC->RAW_STATUS & (1 << EPIC_DMA_INDEX))
#define EPIC_CHECK_FREQ_MON() (EPIC->STATUS & (1 << EPIC_FREQ_MON_INDEX))
#define EPIC_CHECK_PVD_AVCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_UNDER))
#define EPIC_CHECK_PVD_AVCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_AVCC_OVER))
#define EPIC_CHECK_PVD_VCC_UNDER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_UNDER))
#define EPIC_CHECK_PVD_VCC_OVER() (EPIC->STATUS & (1 << EPIC_PVD_VCC_OVER))
#define EPIC_CHECK_BATTERY_NON_GOOD() (EPIC->STATUS & (1 << EPIC_BATTERY_NON_GOOD))
#define EPIC_CHECK_BOR() (EPIC->STATUS & (1 << EPIC_BOR_INDEX))
#define EPIC_CHECK_TSENS() (EPIC->RAW_STATUS & (1 << EPIC_TSENS_INDEX))
#define EPIC_CHECK_ADC() (EPIC->STATUS & (1 << EPIC_ADC_INDEX))
#define EPIC_CHECK_DAC0() (EPIC->STATUS & (1 << EPIC_DAC0_INDEX))
#define EPIC_CHECK_DAC1() (EPIC->STATUS & (1 << EPIC_DAC1_INDEX))
#endif // MIK32V0
/*
* Function: HAL_IRQ_EnableInterrupts
* Разрешить глобальные прерывания.
*
* Разрешается машинное программное прерывание.
*
* Returns:
* void.
*/
void HAL_IRQ_EnableInterrupts();
/*
* Function: HAL_IRQ_DisableInterrupts
* Запретить машинное программное прерывание.
*
* Глобальные прерывания не запрещаются.
*
* Returns:
* void.
*/
void HAL_IRQ_DisableInterrupts();
/* Прерывание по фронту */
/*
* Function: HAL_EPIC_MaskSet
* Задать маску разрешенных линий прерываний по фронту
*
* Parameters:
* InterruptMask - Маска разрешенных линий прерываний
*
* Returns:
* void.
*/
void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask);
/*
* Function: HAL_EPIC_MaskClear
* Сбросить маску разрешенный линий прерываний по фронту
*
* Parameters:
* InterruptMask - Маска сбрасываемых линий прерываний
*
* Returns:
* void.
*/
void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask);
/*
* Function: HAL_EPIC_MaskSet
* Задать маску разрешенных линий прерываний по уровню
*
* Parameters:
* InterruptMask - Маска разрешенных линий прерываний
*
* Returns:
* void.
*/
void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask);
/*
* Function: HAL_EPIC_MaskClear
* Сбросить маску разрешенный линий прерываний по уровню
*
* Parameters:
* InterruptMask - Маска сбрасываемых линий прерываний
*
* Returns:
* void.
*/
void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask);
/*
* Function: HAL_EPIC_Clear
* Сбросить прерывания
*
* Parameters:
* InterruptMask - Маска сбрасываемых линий прерываний
*
* Returns:
* void.
*/
static inline __attribute__((always_inline)) void HAL_EPIC_Clear(uint32_t InterruptMask)
{
EPIC->CLEAR = InterruptMask;
}
/*
* Function: HAL_EPIC_GetStatus
* Получить текущий статус прерываний в соответствии с маской разрешенных прерываний
*
* Returns:
* (uint32_t ) - Текущий статус прерываний в соответствии с маской разрешенных прерываний
*/
uint32_t HAL_EPIC_GetStatus();
/*
* Function: HAL_EPIC_GetRawStatus
* Получить текущий статус прерываний
*
* В данном статусе маска разрешенных прерываний не учитывается
*
* Returns:
* (uint32_t ) - текущий статус прерываний
*/
uint32_t HAL_EPIC_GetRawStatus();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,71 @@
#ifndef MIK32_HAL_OTP
#define MIK32_HAL_OTP
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "power_manager.h"
#include "otp.h"
#include "pad_config.h"
#include "stdbool.h"
#include "mcu32_memory_map.h"
/* Выбор напряжения на UPP матрицы. */
#define OTP_UPP_READ_2V 0b000 /**< 2 В. */
#define OTP_UPP_READ_2_5V 0b001 /**< 2,5 В. */
#define OTP_UPP_READ_3V 0b011 /**< 3 В. */
#define OTP_UPP_READ_VDD18 0b010 /**< VDD18. */
#define OTP_UPP_READ_VDD5 0b110 /**< VDD5. */
/* Выбор тока считывания. */
#define OTP_READ_CUR_2 0 /**< 2 мкА. */
#define OTP_READ_CUR_0_2 1 /**< 0,2 мкА. */
#define OTP_POWER_OFF 1 /**< Hard IP введен в режим пониженного энергопотребления, операции записи и чтения запрещены. */
#define OTP_POWER_ON 0 /**< Hard IP выведен из режима пониженного энергопотребления и может выполнять операции чтения и записи. */
/* Режим чтения. */
#define OPT_READ_2STAGES 0 /**< Чтение в 2 этапа. Вводятся такты ожидания APB. */
#define OPT_READ_3STAGES 1 /**< Чтение в 3 этапа. Опрос флага BSY. Нет тактов ожидания APB. */
/**
* @brief Настройки OTP.
*
*/
typedef struct __OTP_HandleTypeDef
{
OTP_TypeDef *Instance; /**< Базовый адрес регистров OTP. */
uint8_t ReadMode; /**< Режим чтения. */
} OTP_HandleTypeDef;
void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp);
void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff);
void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage);
void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur);
void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp);
void HAL_OTP_Init(OTP_HandleTypeDef *hotp);
void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp);
void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength);
void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data);
void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data);
void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength);
void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength);
uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp);
uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp);
void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,280 @@
#ifndef MIK32_HAL_PCC
#define MIK32_HAL_PCC
#ifdef __cplusplus
extern "C" {
#endif
#include "wakeup.h"
#include "power_manager.h"
#include "mik32_hal_def.h"
#include "mcu32_memory_map.h"
#include "mik32_hal.h"
#define CLOCKSWITCH_TIMEOUT_VALUE 500000 /**< Стандартная задержка для ожидания детектирования источника тактирования, на который происходит переключение */
/**
* @brief Источники тактирования.
*
* Используется как маска для включения источников частоты и
* для назначения приоритетного источника тактирования системы в мониторе частоты.
*/
typedef enum __HAL_PCC_OscillatorTypeTypeDef
{
PCC_OSCILLATORTYPE_NONE = 0b0000, /**< Автоматический выбор источника тактирования RTC */
PCC_OSCILLATORTYPE_HSI32M = 0b0001, /**< Внутренний источник тактирования 32МГц */
PCC_OSCILLATORTYPE_OSC32M = 0b0010, /**< Внешний источник тактирования 32МГц */
PCC_OSCILLATORTYPE_LSI32K = 0b0100, /**< Внутренний источник тактирования 32КГц */
PCC_OSCILLATORTYPE_OSC32K = 0b1000, /**< Внешний источник тактирования 32КГц */
PCC_OSCILLATORTYPE_ALL = 0b1111 /**< Все источники */
} HAL_PCC_OscillatorTypeTypeDef;
/**
* @brief Принудительный выбор источника тактирования системы.
*
* Используется для включения или отключения автоматического переключения источника тактирования системы.
*/
typedef enum __HAL_PCC_ForceOscSysTypeDef
{
PCC_FORCE_OSC_SYS_UNFIXED = 0, /**< Источник тактирования системы не выбирается принудительно */
PCC_FORCE_OSC_SYS_FIXED = 1 /**< Источник тактирования системы выбирается принудительно */
} HAL_PCC_ForceOscSysTypeDef;
/**
* @brief Опорный источник тактирования монитора частоты.
*
* Используется для назначения приоритетного опорного источника тактирования монитора частоты.
*/
typedef enum __HAL_PCC_FreqMonitorSourceTypeDef
{
PCC_FREQ_MONITOR_SOURCE_AUTO = 0b00, /**< Опорный источник частоты монитора частоты выбирается автоматически */
PCC_FREQ_MONITOR_SOURCE_LSI32K = 0b01, /**< Опорный источник частоты монитора частоты принудительно выбран как LSI32K */
PCC_FREQ_MONITOR_SOURCE_OSC32K = 0b10 /**< Опорный источник частоты монитора частоты принудительно выбран как OSC32K */
} HAL_PCC_FreqMonitorSourceTypeDef;
/**
* @brief Источники тактирования RTC.
*
* Используются для назначения приоритетного источника тактирования модуля RTC.
*/
typedef enum __HAL_PCC_RTCClockSourceTypeDef
{
PCC_RTC_CLOCK_SOURCE_AUTO = 0b00, /**< Источник тактирования RTC выбирается автоматически. Если присутствуют оба тактовых сигнала 32K, то выбирается LSI32K */
PCC_RTC_CLOCK_SOURCE_LSI32K = 0b01, /**< Приоритетный источник тактирования RTC - LSI32K */
PCC_RTC_CLOCK_SOURCE_OSC32K = 0b10 /**< Приоритетный источник тактирования RTC - OSC32K */
} HAL_PCC_RTCClockSourceTypeDef;
/**
* @brief Источники тактирования RTC в составе ядра.
*
* Используются для назначения приоритетного источника тактирования RTC в составе ядра.
*/
typedef enum __HAL_PCC_CPURTCClockSourceTypeDef
{
PCC_CPU_RTC_CLOCK_SOURCE_OSC32K = 0, /**< Источник тактирования RTC в составе ядра - OSC32K */
PCC_CPU_RTC_CLOCK_SOURCE_LSI32K = 1 /**< Источник тактирования RTC в составе ядра - LSI32K */
} HAL_PCC_CPURTCClockSourceTypeDef;
/**
* @name Шина AHB
* @brief Макросы для включения и отключения тактирования периферии на шине AHB
@{
*/
#define __HAL_PCC_CPU_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Включить тактирование CPU */
#define __HAL_PCC_CPU_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CPU_M) /**< Выключить тактирование CPU */
#define __HAL_PCC_EEPROM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Включить тактирование EEPROM */
#define __HAL_PCC_EEPROM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_EEPROM_M) /**< Выключить тактирование EEPROM */
#define __HAL_PCC_RAM_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Включить тактирование RAM */
#define __HAL_PCC_RAM_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_RAM_M) /**< Выключить тактирование SPIFI */
#define __HAL_PCC_SPIFI_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Включить тактирование SPIFI */
#define __HAL_PCC_SPIFI_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_SPIFI_M) /**< Выключить тактирование SPIFI */
#define __HAL_PCC_TCB_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Включить тактирование блока TCB */
#define __HAL_PCC_TCB_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_TCB_M) /**< Выключить тактирование блока TCB */
#define __HAL_PCC_DMA_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Включить тактирование DMA */
#define __HAL_PCC_DMA_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_DMA_M) /**< Выключить тактирование DMA */
#define __HAL_PCC_CRYPTO_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Включить тактирование крипто-блока */
#define __HAL_PCC_CRYPTO_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRYPTO_M) /**< Выключить тактирование крипто-блока */
#define __HAL_PCC_CRC32_CLK_ENABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Включить тактирование CRC */
#define __HAL_PCC_CRC32_CLK_DISABLE() (PM->CLK_AHB_SET = PM_CLOCK_AHB_CRC32_M) /**< Выключить тактирование CRC */
/** @} */
/**
* @name Шина APB_M
* @brief Макросы для включения и отключения тактирования периферии на шине APB_M
@{
*/
#define __HAL_PCC_PM_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PM_M) /**< Включить тактирование Power manager */
#define __HAL_PCC_PM_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PM_M) /**< Выключить тактирование Power manager */
#define __HAL_PCC_EPIC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_EPIC_M) /**< Включить тактирование контроллера прерываний */
#define __HAL_PCC_EPIC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_EPIC_M) /**< Выключить тактирование контроллера прерываний */
#define __HAL_PCC_TIMER32_0_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_TIMER32_0_M) /**< Включить тактирование TIMER32_0 */
#define __HAL_PCC_TIMER32_0_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_TIMER32_0_M) /**< Выключить тактирование TIMER32_0 */
#define __HAL_PCC_PAD_CONFIG_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Включить тактирование контроллера выводов */
#define __HAL_PCC_PAD_CONFIG_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PAD_CONFIG_M) /**< Выключить тактирование контроллера выводов */
#define __HAL_PCC_WDT_BUS_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WDT_BUS_M) /**< Включить тактирование сторожевого таймера шины */
#define __HAL_PCC_WDT_BUS_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WDT_BUS_M) /**< Выключить тактирование сторожевого таймера шины */
#define __HAL_PCC_OTP_CONTROLLER_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Включить тактирование OTP */
#define __HAL_PCC_OTP_CONTROLLER_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_OTP_CONTROLLER_M) /**< Выключить тактирование OTP */
#define __HAL_PCC_PVD_CONTROL_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Включить тактирование Монитора напряжения */
#define __HAL_PCC_PVD_CONTROL_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_PVD_CONTROL_M) /**< Выключить тактирование Монитора напряжения */
#define __HAL_PCC_WU_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_WU_M) /**< Включить тактирование Wake up */
#define __HAL_PCC_WU_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_WU_M) /**< Выключить тактирование Wake up */
#define __HAL_PCC_RTC_CLK_ENABLE() (PM->CLK_APB_M_SET = PM_CLOCK_APB_M_RTC_M) /**< Включить тактирование RTC */
#define __HAL_PCC_RTC_CLK_DISABLE() (PM->CLK_APB_M_CLEAR = PM_CLOCK_APB_M_RTC_M) /**< Выключить тактирование RTC */
/** @} */
/**
* @name Шина APB_P
* @brief Макросы для включения и отключения тактирования периферии на шине APB_P
@{
*/
#define __HAL_PCC_WDT_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_WDT_M) /**< Включить тактирование сторожевого таймера */
#define __HAL_PCC_WDT_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_WDT_M) /**< Выключить тактирование сторожевого таймера */
#define __HAL_PCC_UART_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_0_M) /**< Включить тактирование UART_0 */
#define __HAL_PCC_UART_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_0_M) /**< Выключить тактирование UART_0 */
#define __HAL_PCC_UART_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_UART_1_M) /**< Включить тактирование UART_1 */
#define __HAL_PCC_UART_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_UART_1_M) /**< Выключить тактирование UART_1 */
#define __HAL_PCC_TIMER16_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_0_M) /**< Включить тактирование Timer16_0 */
#define __HAL_PCC_TIMER16_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_0_M) /**< Выключить тактирование Timer16_0 */
#define __HAL_PCC_TIMER16_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_1_M) /**< Включить тактирование Timer16_1 */
#define __HAL_PCC_TIMER16_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_1_M) /**< Выключить тактирование Timer16_1 */
#define __HAL_PCC_TIMER16_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER16_2_M) /**< Включить тактирование Timer16_2 */
#define __HAL_PCC_TIMER16_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER16_2_M) /**< Выключить тактирование Timer16_2 */
#define __HAL_PCC_TIMER32_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_1_M) /**< Включить тактирование Timer32_1 */
#define __HAL_PCC_TIMER32_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_1_M) /**< Выключить тактирование Timer32_1 */
#define __HAL_PCC_TIMER32_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_TIMER32_2_M) /**< Включить тактирование Timer32_2 */
#define __HAL_PCC_TIMER32_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_TIMER32_2_M) /**< Выключить тактирование Timer32_2 */
#define __HAL_PCC_SPI_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_0_M) /**< Включить тактирование SPI_0 */
#define __HAL_PCC_SPI_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_0_M) /**< Выключить тактирование SPI_0 */
#define __HAL_PCC_SPI_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_SPI_1_M) /**< Включить тактирование SPI_1 */
#define __HAL_PCC_SPI_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_SPI_1_M) /**< Выключить тактирование SPI_1 */
#define __HAL_PCC_I2C_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_0_M) /**< Включить тактирование I2C_0 */
#define __HAL_PCC_I2C_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_0_M) /**< Выключить тактирование I2C_0 */
#define __HAL_PCC_I2C_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_I2C_1_M) /**< Включить тактирование I2C_1 */
#define __HAL_PCC_I2C_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_I2C_1_M) /**< Выключить тактирование I2C_1 */
#define __HAL_PCC_GPIO_0_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_0_M) /**< Включить тактирование GPIO_0 */
#define __HAL_PCC_GPIO_0_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_0_M) /**< Выключить тактирование GPIO_0 */
#define __HAL_PCC_GPIO_1_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_1_M) /**< Включить тактирование GPIO_1 */
#define __HAL_PCC_GPIO_1_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_1_M) /**< Выключить тактирование GPIO_1 */
#define __HAL_PCC_GPIO_2_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_2_M) /**< Включить тактирование GPIO_2 */
#define __HAL_PCC_GPIO_2_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_2_M) /**< Выключить тактирование GPIO_2 */
#define __HAL_PCC_ANALOG_REGS_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Включить тактирование аналоговых блоков */
#define __HAL_PCC_ANALOG_REGS_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_ANALOG_REGS_M) /**< Выключить тактирование аналоговых блоков */
#define __HAL_PCC_GPIO_IRQ_CLK_ENABLE() (PM->CLK_APB_P_SET = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Включить тактирование схемы формирования прерываний GPIO */
#define __HAL_PCC_GPIO_IRQ_CLK_DISABLE() (PM->CLK_APB_P_CLEAR = PM_CLOCK_APB_P_GPIO_IRQ_M) /**< Выключить тактирование схемы формирования прерываний GPIO */
/** @} */
/**
* @brief Структура с состояниями ошибок.
*
* Используется только как возвращаемое значение функции HAL_PCC_Config(PCC_InitTypeDef *PCC_Init).
*/
typedef struct __PCC_ConfigErrorsTypeDef
{
HAL_StatusTypeDef FreqMonRef; /**< Ошибка, возвращаемая функцией HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk) */
HAL_StatusTypeDef SetOscSystem; /**< Ошибка, возвращаемая функцией HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys) */
HAL_StatusTypeDef RTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator) */
HAL_StatusTypeDef CPURTCClock; /**< Ошибка, возвращаемая функцией HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator) */
} PCC_ConfigErrorsTypeDef;
/**
* @brief Настройки монитора частоты
*/
typedef struct __PCC_FreqMonTypeDef
{
uint8_t OscillatorSystem; /**< Источник тактирования системы. Может принимать одно из значений HAL_PCC_OscillatorTypeTypeDef. */
HAL_PCC_ForceOscSysTypeDef ForceOscSys; /**< Разрешение принудительного выбора источника тактирования системы. Может принимать одно из значений HAL_PCC_ForceOscSysTypeDef. */
HAL_PCC_FreqMonitorSourceTypeDef Force32KClk; /**< Опорный источник монитора частоты. Может принимать одно из значений HAL_PCC_FreqMonitorSourceTypeDef. */
} PCC_FreqMonTypeDef;
/**
* @brief Настройки тактирования и монитора частоты
*/
typedef struct __PCC_InitTypeDef
{
uint8_t OscillatorEnable; /**< Осциллятор, который должен быть включен. Этот параметр может быть маской из значений HAL_PCC_OscillatorTypeTypeDef. */
PCC_FreqMonTypeDef FreqMon; /**< Настройки монитора частоты. */
uint32_t AHBDivider; /**< Делитель частоты AHB. Этот параметр должен быть числом между Min = 0 и Max = 255 */
uint32_t APBMDivider; /**< Делитель частоты APB_M. Этот параметр должен быть числом между Min = 0 и Max = 255 */
uint32_t APBPDivider; /**< Делитель частоты APB_P. Этот параметр должен быть числом между Min = 0 и Max = 255 */
uint8_t HSI32MCalibrationValue; /**< Поправочный коэффициент HSI32M. Этот параметр должен быть числом между Min = 0 и Max = 255 */
uint8_t LSI32KCalibrationValue; /**< Поправочный коэффициент LSI32K. Этот параметр должен быть числом между Min = 0 и Max = 255 */
HAL_PCC_RTCClockSourceTypeDef RTCClockSelection; /**< Источник тактирования RTC. Может принимать одно из значений HAL_PCC_RTCClockSourceTypeDef. */
HAL_PCC_CPURTCClockSourceTypeDef RTCClockCPUSelection; /**< Источник тактирования RTC в составе ядра. Может принимать одно из значений HAL_PCC_CPURTCClockSourceTypeDef. */
} PCC_InitTypeDef;
void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator);
void HAL_PCC_OscDisable(uint32_t Oscillator);
HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk);
HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys);
HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator);
HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator);
void HAL_PCC_DividerAHB(uint32_t DividerAHB);
void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M);
void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P);
PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init);
uint32_t HAL_PCC_GetSysClockFreq();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,485 @@
#ifndef MIK32_HAL_RTC
#define MIK32_HAL_RTC
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "rtc.h"
#include "mcu32_memory_map.h"
/* Title: Макросы */
/*
* Defines: Месяц
*
*
* RTC_MONTH_JANUARY - Январь
* RTC_MONTH_FEBRUARY - Февраль
* RTC_MONTH_MARCH - Март
* RTC_MONTH_APRIL - Апрель
* RTC_MONTH_MAY - Май
* RTC_MONTH_JUNE - Июнь
* RTC_MONTH_JULY - Июль
* RTC_MONTH_AUGUST - Август
* RTC_MONTH_SEPTEMBER - Сентябрь
* RTC_MONTH_OCTOBER - Октябрь
* RTC_MONTH_NOVEMBER - Ноябрь
* RTC_MONTH_DECEMBER - Декабрь
*
*/
/* Месяц */
#define RTC_MONTH_JANUARY 1
#define RTC_MONTH_FEBRUARY 2
#define RTC_MONTH_MARCH 3
#define RTC_MONTH_APRIL 4
#define RTC_MONTH_MAY 5
#define RTC_MONTH_JUNE 6
#define RTC_MONTH_JULY 7
#define RTC_MONTH_AUGUST 8
#define RTC_MONTH_SEPTEMBER 9
#define RTC_MONTH_OCTOBER 10
#define RTC_MONTH_NOVEMBER 11
#define RTC_MONTH_DECEMBER 12
/* Title: Макросы */
/*
* Defines: День недели
*
*
* RTC_WEEKDAY_MONDAY - Понедельник
* RTC_WEEKDAY_TUESDAY - Вторник
* RTC_WEEKDAY_WEDNESDAY - Среда
* RTC_WEEKDAY_THURSDAY - Четверг
* RTC_WEEKDAY_FRIDAY - Пятница
* RTC_WEEKDAY_SATURDAY - Суббота
* RTC_WEEKDAY_SUNDAY - Воскресенье
*
*/
/* День недели */
#define RTC_WEEKDAY_MONDAY 1
#define RTC_WEEKDAY_TUESDAY 2
#define RTC_WEEKDAY_WEDNESDAY 3
#define RTC_WEEKDAY_THURSDAY 4
#define RTC_WEEKDAY_FRIDAY 5
#define RTC_WEEKDAY_SATURDAY 6
#define RTC_WEEKDAY_SUNDAY 7
/*
* Defines: Прерывание будильника Alarm
*
*
* RTC_ALARM_IRQ_DISABLE - Запретить прерывание Alarm
* RTC_ALARM_IRQ_ENABLE - Разрешить прерывание Alarm
*
*/
#define RTC_ALARM_IRQ_DISABLE 0 /* Запретить прерывание Alarm */
#define RTC_ALARM_IRQ_ENABLE 1 /* Разрешить прерывание Alarm */
/* Title: Структуры */
typedef struct
{
uint8_t Alarm; /* Разрешение прерывания при наличии установленного бита ALRM */
} RTC_IRQnTypeDef;
/*
* Struct: RTC_HandleTypeDef
* Настройки инициализации RTC
*
*/
typedef struct
{
/*
* Variable: Instance
* Базовый адрес регистров RTC
*
*/
RTC_TypeDef *Instance;
RTC_IRQnTypeDef Interrupts; /* Прерывания RTC */
} RTC_HandleTypeDef;
/*
* Struct: RTC_HandleTypeDef
* Время и день недели
*
*/
typedef struct
{
/*
* Variable: Dow
* День недели
*
* Этот параметр должен быть одним из значений:
*
* - <RTC_WEEKDAY_MONDAY>
* - <RTC_WEEKDAY_TUESDAY>
* - <RTC_WEEKDAY_WEDNESDAY>
* - <RTC_WEEKDAY_THURSDAY>
* - <RTC_WEEKDAY_FRIDAY>
* - <RTC_WEEKDAY_SATURDAY>
* - <RTC_WEEKDAY_SUNDAY>
*
*/
uint8_t Dow; /* Параметр RTC. День недели.
Этот параметр должен быть числом между Min = 1 и Max = 7 */
/*
* Variable: Hours
* Часы
*
* Этот параметр должен быть числом в диапазоне от 0 до 23.
*
*/
uint8_t Hours;
/*
* Variable: Minutes
* Минуты
*
* Этот параметр должен быть числом в диапазоне от 0 до 59.
*
*/
uint8_t Minutes;
/*
* Variable: Seconds
* Секунды
*
* Этот параметр должен быть числом в диапазоне от 0 до 59.
*
*/
uint8_t Seconds;
} RTC_TimeTypeDef;
/*
* Struct: RTC_DateTypeDef
* Дата
*
*/
typedef struct
{
/*
* Variable: Century
* Секунды
*
* Этот параметр должен быть числом в диапазоне от 0 до 99.
*
*/
uint8_t Century;
/*
* Variable: Day
* Число
*
* Этот параметр должен быть числом в диапазоне от 1 до 31.
*
*/
uint8_t Day;
/*
* Variable: Day
* Месяц
*
* Этот параметр должен быть числом в диапазоне от 1 до 12.
*
*/
uint8_t Month;
/*
* Variable: Day
* Год
*
* Этот параметр должен быть числом в диапазоне от 0 до 99.
*
*/
uint8_t Year;
} RTC_DateTypeDef;
/*
* Struct: RTC_DateTypeDef
* Дата и время будильника
*
*/
typedef struct
{
/*
* Variable: AlarmTime
* Время и день недели будильника
*
*/
RTC_TimeTypeDef AlarmTime;
/*
* Variable: AlarmDate
* Дата будильника
*
*/
RTC_DateTypeDef AlarmDate;
/*
* Variable: MaskAlarmTime
* Маска сравнений будильника по времени
*
*/
uint32_t MaskAlarmTime;
/*
* Variable: MaskAlarmDate
* Маска сравнений будильника по дате
*
*/
uint32_t MaskAlarmDate;
} RTC_AlarmTypeDef;
/* Title: Функции */
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc);
/*
* Function: HAL_RTC_WaitFlag
*
* Ожидать после записи в регистр RTC установку Flag в 0
*
* Сигнал проведения синхронизации между тактовыми доменами. После записи в любой регистр и пока данный флаг
* читается равным 1, запрещено выполнять любую новую запись.
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*
*/
void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_Disable
*
* Выключить модуль RTC
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_Disable
*
* Включить модуль RTC
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_SetTime
*
* Установить временя и день недели RTC в соответствии с параметрами sTime
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
* sTime - Указатель на структуру с настройками времени и дня недели.
*
* Returns:
* void.
*/
void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime);
/*
* Function: HAL_RTC_SetDate
*
* Установить дату в соответствии с параметрами sDate
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
* sDate - Указатель на структуру с настройками даты.
*
* Returns:
* void.
*/
void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate);
/*
* Function: HAL_RTC_Alarm_SetTime
*
* Установить время будильника в соответствии с параметрами sAlarm
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
* sAlarm - Указатель на структуру с настройками времени и дня недели будильника.
*
* Returns:
* void.
*/
void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
/*
* Function: HAL_RTC_Alarm_SetDate
*
* Установить время будильника в соответствии с параметрами sAlarm
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
* sAlarm - Указатель на структуру с настройками даты будильника.
*
* Returns:
* void.
*/
void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
/*
* Function: HAL_RTC_SetAlarm
*
* Установить дату и время будильника в соответствии с параметрами sAlarm
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
* sAlarm - Указатель на структуру с настройками даты и времени будильника.
*
* Returns:
* void.
*/
void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm);
/*
* Function: HAL_RTC_AlarmDisable
*
* Запретить все сравнения будильника
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_AlarmDisable
*
* Очистить флаг будильника Alrm
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_GetAlrmFlag
*
* Получить значение флага будильника Alrm
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_GetDate
*
* Получить текущую дату RTC
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* (RTC_DateTypeDef ) - Структура с текущей датой RTC
*/
RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_GetTime
*
* Получить текущее время RTC
*
* Parameters:
*
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* (RTC_DateTypeDef ) - Структура с текущей датой RTC
*/
RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_SetInterruptAlarm
* Задать разрешение на включение прерывания Alarm в соответствии с InterruptEnable
*
* Parameters:
* hrtc - Указатель на структуру с настройками RTC.
* InterruptEnable - Разрешение прерывания Alarm.
*
* Этот параметр должен быть одним из значений:
*
* - <RTC_ALARM_IRQ_DISABLE>
* - <RTC_ALARM_IRQ_ENABLE>
*
* Returns:
* void.
*/
void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable);
/*
* Function: HAL_RTC_InterruptInit
* Инициализировать прерывания RTC в соответствии с настройками hrtc
*
* Parameters:
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* void.
*/
void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc);
/*
* Function: HAL_RTC_GetINTE
* Получить текущее значение бита разрешения прерывания Alarm - INTE
*
* Parameters:
* hrtc - Указатель на структуру с настройками RTC.
*
* Returns:
* (int ) - Текущее значение бита разрешения прерывания Alarm - INTE
*
*/
int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,484 @@
#ifndef MIK32_HAL_SPI
#define MIK32_HAL_SPI
#ifdef __cplusplus
extern "C" {
#endif
#include "stddef.h"
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "power_manager.h"
#include "spi_.h"
#include "mik32_hal_def.h"
#include "mcu32_memory_map.h"
/** Значение timeout по умолчанию. */
#define SPI_TIMEOUT_DEFAULT 1000000
/* Ошибки SPI */
#define HAL_SPI_ERROR_NONE 0b00000000 /**< Значение при отсутствии ошибок. */
#define HAL_SPI_ERROR_MODF 0b00000001 /**< Маска для ошибки MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI. */
#define HAL_SPI_ERROR_OVR 0b00000010 /**< Маска для ошибки RX_OVERFLOW - прерывание при переполнении RX_FIFO. */
/* Выбор ведомых устройств. */
#define SPI_CS_NONE 0b1111 /**< Ведомое устройство не выбрано. */
#define SPI_CS_0 0b1110 /**< Ведомое устройство 1. */
#define SPI_CS_1 0b1101 /**< Ведомое устройство 2. */
#define SPI_CS_2 0b1011 /**< Ведомое устройство 3. */
#define SPI_CS_3 0b0111 /**< Ведомое устройство 4. */
/* Коэффициент деления частоты spi_ref_clk. */
#define SPI_BAUDRATE_DIV4 0b001 /**< Коэффициент деления частоты spi_ref_clk - 4. */
#define SPI_BAUDRATE_DIV8 0b010 /**< Коэффициент деления частоты spi_ref_clk - 8. */
#define SPI_BAUDRATE_DIV16 0b011 /**< Коэффициент деления частоты spi_ref_clk - 16. */
#define SPI_BAUDRATE_DIV32 0b100 /**< Коэффициент деления частоты spi_ref_clk - 32. */
#define SPI_BAUDRATE_DIV64 0b101 /**< Коэффициент деления частоты spi_ref_clk - 64. */
#define SPI_BAUDRATE_DIV128 0b110 /**< Коэффициент деления частоты spi_ref_clk - 128. */
#define SPI_BAUDRATE_DIV256 0b111 /**< Коэффициент деления частоты spi_ref_clk - 256. */
/* Режим управления сигналом выбора ведомого CS. */
#define SPI_MANUALCS_OFF 0 /**< Автоматический режим. */
#define SPI_MANUALCS_ON 1 /**< Ручной режим. */
/* Настройки фазы тактового сигнала. */
#define SPI_PHASE_OFF 0 /**< Тактовая частота SPI активна вне слова */
#define SPI_PHASE_ON 1 /**< Тактовая частота SPI неактивна вне слова */
/* Настройки полярности тактового сигнала вне слова. */
#define SPI_POLARITY_LOW 0 /**< Тактовый сигнал вне слова удерживается на низком уровне. */
#define SPI_POLARITY_HIGH 1 /**< Тактовый сигнал вне слова удерживается на высоком уровне. */
/* Использование внешнего декодера. */
#define SPI_DECODER_NONE 0 /**< Внешний декодер не используется. Выбор только 1 из 4 ведомых устройств. */
#define SPI_DECODER_USE 1 /**< Используется внешний декодер. */
/* Длина передаваемой посылки. */
#define SPI_DATASIZE_8BITS 0 /**< Длина передаваемой посылки - 8 бит. */
#define SPI_DATASIZE_16BITS 1 /**< Длина передаваемой посылки - 16 бит. */
#define SPI_DATASIZE_24BITS 2 /**< Длина передаваемой посылки - 24 бит. */
#define SPI_DATASIZE_32BITS 3 /**< Длина передаваемой посылки - 32 бит. */
/* Значения по умолчанию порогового значения TX_FIFO. */
#define SPI_THRESHOLD_DEFAULT 4 /* Значение Threshold_of_TX_FIFO по умолчанию*/
/* Прерывания. */
#define TX_FIFO_UNDERFLOW 6 /**< Регистр TX FIFO опустошен. */
#define RX_FIFO_FULL 5 /**< Регистр RX_FIFO заполнен. */
#define RX_FIFO_NOT_EMPTY 4 /**< Регистр RX_FIFO не пустой. */
#define TX_FIFO_FULL 3 /**< Регистр TX_FIFO заполнен. */
#define TX_FIFO_NOT_FULL 2 /**< Регистр TX_FIFO не заполнен. */
#define MODE_FAIL 1 /**< Напряжение на выводе n_ss_in не соответствую режиму работы SPI. */
#define RX_OVERFLOW 0 /**< Прерывание при переполнении RX_FIFO, значение сбрасывается при чтении. */
#define SPI_BUFFER_SIZE 8 /**< Размер буферов RX и TX. */
/** @brief Включить модуль SPI.
* @param __HANDLE__ Указатель SPI Handle.
*/
#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE = SPI_ENABLE_M)
/** @brief Выключить модуль SPI.
* @param __HANDLE__ Указатель SPI Handle.
*/
#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->ENABLE &= ~SPI_ENABLE_M)
/** @brief Проверить установлен ли указанный флаг SPI или нет.
* @param __HANDLE__ Указатель SPI Handle.
* @param __FLAG__ Флаг для проверки.
* Этот параметр должен быть одним из следующих значений:
* - @ref SPI_INT_STATUS_SPI_ACTIVE_M: Флаг статуса сеанса передачи
* - @ref SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M: Флаг опустошения буфера TX_FIFO в режиме ведомого перед началом обмена
* - @ref SPI_INT_STATUS_RX_FIFO_FULL_M: Флаг заполнения буфера RX_FIFO
* - @ref SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M: Флаг наличия данных в буфере RX_FIFO
* - @ref SPI_INT_STATUS_TX_FIFO_FULL_M: Флаг заполнения буфера TX_FIFO
* - @ref SPI_INT_STATUS_TX_FIFO_NOT_FULL_M: Флаг заполнения буфера TX_FIFO ниже порогового значения
* - @ref SPI_INT_STATUS_MODE_FAIL_M: Флаг детектирования напряжение на выводе n_ss_in не соответствую режиму работы SPI
* - @ref SPI_INT_STATUS_RX_OVERFLOW_M: Флаг переполнения буфера RX_FIFO
*
* @return Состояние флага @p __FLAG__ (TRUE или FALSE).
*/
#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->ENABLE) & (__FLAG__)) == (__FLAG__))
/**
* @brief Выбор режима ведущий/ведомый.
*/
typedef enum __HAL_SPI_ModeTypeDef
{
HAL_SPI_MODE_SLAVE = 0, /**< Режим ведомого. */
HAL_SPI_MODE_MASTER = 1, /**< Режим ведущего. */
} HAL_SPI_ModeTypeDef;
/**
* @brief Состояние модуля SPI.
*/
typedef enum __HAL_SPI_StateTypeDef
{
HAL_SPI_STATE_READY, /**< Готов к передаче. */
HAL_SPI_STATE_BUSY, /**< Идет передача. */
HAL_SPI_STATE_END, /**< Передача завершена. */
HAL_SPI_STATE_ERROR /**< Ошибка при передаче. */
} HAL_SPI_StateTypeDef;
/**
* @brief Определение структуры конфигурации SPI
*/
typedef struct __SPI_InitTypeDef
{
/**
* @brief Выбор режима ведущий/ведомый.
*
* Этот параметр должен быть одним из значений:
* - @ref HAL_SPI_MODE_SLAVE - режим ведомого
* - @ref HAL_SPI_MODE_MASTER - режим ведущего
*/
HAL_SPI_ModeTypeDef SPI_Mode;
/**
* @brief Коэффициент деления частоты.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_BAUDRATE_DIV4;
* - @ref SPI_BAUDRATE_DIV8;
* - @ref SPI_BAUDRATE_DIV16;
* - @ref SPI_BAUDRATE_DIV32;
* - @ref SPI_BAUDRATE_DIV64;
* - @ref SPI_BAUDRATE_DIV128;
* - @ref SPI_BAUDRATE_DIV256.
*/
uint8_t BaudRateDiv;
/**
* @brief Режим управления сигналом выбора ведомого CS.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_MANUALCS_OFF - сигнал выбора ведомого CS управляется автоматически
* - @ref SPI_MANUALCS_ON - сигнал выбора ведомого CS управляется вручную
*/
uint8_t ManualCS;
/**
* @brief Настройка фазы тактового сигнала.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_PHASE_OFF - тактовая частота SPI активна вне слова. Сигналы SS переводятся в неактивное состояние между словами.
* Длительность импульса всегда 1 период тактового сигнала шины APB_P
* - @ref SPI_PHASE_ON - тактовая частота SPI неактивна вне слова. Сигналы SS не переводятся в неактивное состояние между словами
*/
uint8_t CLKPhase;
/**
* @brief Настройка полярности тактового сигнала вне слова.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_POLARITY_LOW - тактовый сигнал вне слова удерживается на низком уровне
* - @ref SPI_POLARITY_HIGH - тактовый сигнал вне слова удерживается на высоком уровне
*/
uint8_t CLKPolarity;
/**
* @brief Использование внешнего декодера.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_DECODER_NONE - внешний декодер не используется. Выбирается один ведомый из четырех, подключенный к одному из выводов CS0 - CS3
* - @ref SPI_DECODER_USE - используется внешний декодер. Значение @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect"
* отображается на выводах CS0 - CS3
*
*/
uint8_t Decoder;
/**
* @brief Пороговое значение TX_FIFO.
*
* Уровень, при котором TX_FIFO считается незаполненным и формируется прерывание TX_FIFO_NOT_full (IXR_TXOW).
*/
uint8_t ThresholdTX;
/**
* @brief Выбранное ведомое устройство.
*
* Этот параметр должен быть одним из значений:
* - @ref SPI_CS_NONE - ведомое устройство не выбрано
* - @ref SPI_CS_0 - ведомое устройство 1
* - @ref SPI_CS_1 - ведомое устройство 2
* - @ref SPI_CS_2 - ведомое устройство 3
* - @ref SPI_CS_3 - ведомое устройство 4
*/
uint8_t ChipSelect;
} SPI_InitTypeDef;
/**
* @brief Определение структуры SPI Handle.
*/
typedef struct __SPI_HandleTypeDef
{
SPI_TypeDef *Instance; /**< Адрес регистров SPI. */
SPI_InitTypeDef Init; /**< Параметры SPI. */
uint8_t ErrorCode; /**< Код ошибки при работе SPI. */
HAL_SPI_StateTypeDef State; /**< Состояние модуля SPI. */
uint8_t *pTxBuffPtr; /**< Указатель на буфер для передачи данных по SPI. */
uint32_t TxCount; /**< Счетчик байт при передачи данных по SPI. */
uint8_t *pRxBuffPtr; /**< Указатель на буфер для считывания данных по SPI. */
uint32_t RxCount; /**< Счетчик байт при считывания данных по SPI. */
} SPI_HandleTypeDef;
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
void HAL_SPI_Enable(SPI_HandleTypeDef *hspi);
void HAL_SPI_Disable(SPI_HandleTypeDef *hspi);
void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn);
void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after);
void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init);
void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter);
void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold);
uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi);
void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi);
void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi);
void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M);
void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size);
/**
* @brief Разрешить прерывания в соответствии с маской.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param IntEnMask маска разрешенных прерываний.
*/
static inline __attribute__((always_inline)) void HAL_SPI_InterruptEnable(SPI_HandleTypeDef *hspi, uint32_t IntEnMask)
{
hspi->Instance->INT_ENABLE |= IntEnMask;
}
/**
* @brief Запретить прерывания в соответствии с маской.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param IntDisMask маска запрещенных прерываний.
*/
static inline __attribute__((always_inline)) void HAL_SPI_InterruptDisable(SPI_HandleTypeDef *hspi, uint32_t IntDisMask)
{
hspi->Instance->INT_DISABLE |= IntDisMask;
}
/**
* @brief Получить состояние флага прерывания с учетом маски разрешенных прерываний.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param Interrupt Флаг прерывания.
* Этот параметр должен быть одним из следующих значений:
* - @ref TX_FIFO_UNDERFLOW - регистр TX FIFO опустошен
* - @ref RX_FIFO_FULL - регистр RX_FIFO заполнен
* - @ref RX_FIFO_NOT_EMPTY - регистр RX_FIFO не пустой
* - @ref TX_FIFO_FULL - регистр TX_FIFO заполнен
* - @ref TX_FIFO_NOT_FULL - регистр TX_FIFO не заполнен
* - @ref MODE_FAIL - напряжение на выводе n_ss_in не соответствую режиму работы SPI
* - @ref RX_OVERFLOW - прерывание при переполнении RX_FIFO, значение сбрасывается при чтении
* @return Состояние флага.
*/
static inline __attribute__((always_inline)) uint8_t HAL_SPI_GetInterruptStatus(SPI_HandleTypeDef *hspi, uint32_t Interrupt)
{
uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK;
switch (Interrupt)
{
case TX_FIFO_UNDERFLOW:
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M) >> SPI_INT_STATUS_TX_FIFO_UNDERFLOW_S;
break;
case RX_FIFO_FULL:
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_FULL_M) >> SPI_INT_STATUS_RX_FIFO_FULL_S;
break;
case RX_FIFO_NOT_EMPTY:
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) >> SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_S;
break;
case TX_FIFO_FULL:
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_FULL_M) >> SPI_INT_STATUS_TX_FIFO_FULL_S;
break;
case TX_FIFO_NOT_FULL:
interrupt_status = (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) >> SPI_INT_STATUS_TX_FIFO_NOT_FULL_S;
break;
case MODE_FAIL:
interrupt_status = (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M) >> SPI_INT_STATUS_MODE_FAIL_S;
break;
case RX_OVERFLOW:
interrupt_status = (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M) >> SPI_INT_STATUS_RX_OVERFLOW_S;
break;
default:
break;
}
return interrupt_status;
}
/**
* @brief Обработчик прерывания RX_OVERFLOW (IXR_RXOVR) - переполнение буфера RX.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
static inline __attribute__((always_inline)) void HAL_SPI_RXOverflow_IRQ(SPI_HandleTypeDef *hspi)
{
hspi->State = HAL_SPI_STATE_ERROR;
hspi->ErrorCode |= HAL_SPI_ERROR_OVR;
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
SPI_INT_STATUS_MODE_FAIL_M |
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
SPI_INT_STATUS_TX_FIFO_FULL_M |
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
SPI_INT_STATUS_RX_FIFO_FULL_M |
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
}
/**
* @brief Обработчик прерывания MODE_FAIL (IXR_MODF) - напряжение на выводе n_ss_in не соответствую режиму работы SPI.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
static inline __attribute__((always_inline)) void HAL_SPI_ModeFail_IRQ(SPI_HandleTypeDef *hspi)
{
hspi->State = HAL_SPI_STATE_ERROR;
hspi->ErrorCode |= HAL_SPI_ERROR_MODF;
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
SPI_INT_STATUS_MODE_FAIL_M |
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
SPI_INT_STATUS_TX_FIFO_FULL_M |
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
SPI_INT_STATUS_RX_FIFO_FULL_M |
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
}
/**
* @brief Обработчик прерывания TX_FIFO_NOT_full (IXR_TXOW) - регистр TX_FIFO не заполнен (меньше значения ThresholdTX).
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
static inline __attribute__((always_inline)) void HAL_SPI_TXFifoNotFull_IRQ(SPI_HandleTypeDef *hspi)
{
uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */
for (volatile uint32_t i = 0; (i < write_read_bytes) && hspi->TxCount; i++)
{
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
hspi->pTxBuffPtr++;
hspi->TxCount--;
}
if (hspi->TxCount == 0)
{
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_TX_FIFO_NOT_FULL_M);
if (hspi->RxCount == 0)
{
hspi->State = HAL_SPI_STATE_END;
__HAL_SPI_DISABLE(hspi);
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
(void)unused;
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
SPI_INT_STATUS_MODE_FAIL_M |
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
SPI_INT_STATUS_TX_FIFO_FULL_M |
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
SPI_INT_STATUS_RX_FIFO_FULL_M |
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
}
}
}
/**
* @brief Обработчик прерывания RX_FIFO_NOT_EMPTY (IXR_RXNEMPTY) - Регистр RX_FIFO не пустой.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
static inline __attribute__((always_inline)) void HAL_SPI_RXFifoNotEmpty_IRQ(SPI_HandleTypeDef *hspi)
{
/* Чтение одного байта */
*(hspi->pRxBuffPtr) = hspi->Instance->RXDATA;
hspi->pRxBuffPtr++;
hspi->RxCount--;
if (hspi->RxCount == 0)
{
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M | SPI_INT_STATUS_RX_OVERFLOW_M);
if (hspi->TxCount == 0)
{
hspi->State = HAL_SPI_STATE_END;
__HAL_SPI_DISABLE(hspi);
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
(void)unused;
HAL_SPI_InterruptDisable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M |
SPI_INT_STATUS_MODE_FAIL_M |
SPI_INT_STATUS_TX_FIFO_NOT_FULL_M |
SPI_INT_STATUS_TX_FIFO_FULL_M |
SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M |
SPI_INT_STATUS_RX_FIFO_FULL_M |
SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M);
}
}
}
/**
* @brief Обработчик запроса прерывания SPI.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
static inline __attribute__((always_inline)) void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
{
uint32_t interrupt_status = hspi->Instance->INT_STATUS & hspi->Instance->INT_MASK;
if (!(interrupt_status & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M | SPI_INT_STATUS_TX_FIFO_UNDERFLOW_M)))
{
if (interrupt_status & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M)
{
HAL_SPI_RXFifoNotEmpty_IRQ(hspi);
}
if (interrupt_status & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)
{
HAL_SPI_TXFifoNotFull_IRQ(hspi);
}
return;
}
if (interrupt_status & SPI_INT_STATUS_RX_OVERFLOW_M)
{
HAL_SPI_RXOverflow_IRQ(hspi);
return;
}
if (interrupt_status & SPI_INT_STATUS_MODE_FAIL_M)
{
HAL_SPI_ModeFail_IRQ(hspi);
return;
}
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,234 @@
#ifndef MIK32_HAL_SPIFI
#define MIK32_HAL_SPIFI
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "mik32_hal_def.h"
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include <spifi.h>
#include <mcu32_memory_map.h>
#define HAL_SPIFI_TIMEOUT 100000
typedef enum __HAL_SPIFI_CacheEnableTypeDef
{
SPIFI_CACHE_DISABLE = 0,
SPIFI_CACHE_ENABLE = 1,
} HAL_SPIFI_CacheEnableTypeDef;
typedef enum __HAL_SPIFI_DataCacheEnableTypeDef
{
SPIFI_DATA_CACHE_ENABLE = 0,
SPIFI_DATA_CACHE_DISABLE = 1,
} HAL_SPIFI_DataCacheEnableTypeDef;
typedef enum __HAL_SPIFI_InterruptEnableTypeDef
{
SPIFI_INTERRUPT_DISABLE = 0,
SPIFI_INTERRUPT_ENABLE = 1,
} HAL_SPIFI_InterruptEnableTypeDef;
typedef enum __HAL_SPIFI_Mode3EnableTypeDef
{
SPIFI_MODE3_DISABLE = 0,
SPIFI_MODE3_ENABLE = 1,
} HAL_SPIFI_Mode3EnableTypeDef;
typedef enum __HAL_SPIFI_PrefetchEnableTypeDef
{
SPIFI_PREFETCH_ENABLE = 0,
SPIFI_PREFETCH_DISABLE = 1,
} HAL_SPIFI_PrefetchEnableTypeDef;
typedef enum __HAL_SPIFI_DualModeEnableTypeDef
{
SPIFI_DUAL_MODE_ENABLE = 0,
SPIFI_DUAL_MODE_DISABLE = 1,
} HAL_SPIFI_DualModeEnableTypeDef;
typedef enum __HAL_SPIFI_DMAEnableTypeDef
{
SPIFI_DMA_ENABLE = 0,
SPIFI_DMA_DISABLE = 1,
} HAL_SPIFI_DMAEnableTypeDef;
typedef enum __HAL_SPIFI_FieldFormTypeDef
{
SPIFI_FIELDFORM_ALL_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL,
SPIFI_FIELDFORM_DATA_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_DATA_PARALLEL,
SPIFI_FIELDFORM_OPCODE_SERIAL = SPIFI_CONFIG_CMD_FIELDFORM_OPCODE_SERIAL,
SPIFI_FIELDFORM_ALL_PARALLEL = SPIFI_CONFIG_CMD_FIELDFORM_ALL_PARALLEL,
} HAL_SPIFI_FieldFormTypeDef;
typedef enum __HAL_SPIFI_FrameFormTypeDef
{
SPIFI_FRAMEFORM_OPCODE = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_NOADDR,
SPIFI_FRAMEFORM_OPCODE_1ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_1ADDR,
SPIFI_FRAMEFORM_OPCODE_2ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_2ADDR,
SPIFI_FRAMEFORM_OPCODE_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR,
SPIFI_FRAMEFORM_OPCODE_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_4ADDR,
SPIFI_FRAMEFORM_3ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_3ADDR,
SPIFI_FRAMEFORM_4ADDR = SPIFI_CONFIG_CMD_FRAMEFORM_NOOPCODE_4ADDR,
} HAL_SPIFI_FrameFormTypeDef;
typedef enum __HAL_SPIFI_DirectionTypeDef
{
SPIFI_DIRECTION_INPUT = SPIFI_CONFIG_CMD_DOUT_M ^ (1 << SPIFI_CONFIG_CMD_DOUT_S),
SPIFI_DIRECTION_OUTPUT = SPIFI_CONFIG_CMD_DOUT_M
} HAL_SPIFI_DirectionTypeDef;
typedef struct __SPIFI_MemoryCommandTypeDef
{
uint32_t InterimData;
uint8_t InterimLength;
HAL_SPIFI_FieldFormTypeDef FieldForm;
HAL_SPIFI_FrameFormTypeDef FrameForm;
uint8_t OpCode;
} SPIFI_MemoryCommandTypeDef;
typedef struct __SPIFI_MemoryModeConfig_HandleTypeDef
{
SPIFI_CONFIG_TypeDef *Instance;
HAL_SPIFI_CacheEnableTypeDef CacheEnable;
uint32_t CacheLimit;
SPIFI_MemoryCommandTypeDef Command;
} SPIFI_MemoryModeConfig_HandleTypeDef;
typedef struct __SPIFI_HandleTypeDef
{
SPIFI_CONFIG_TypeDef *Instance;
uint16_t timeout;
uint8_t CS_High;
HAL_SPIFI_CacheEnableTypeDef cacheEnabled;
HAL_SPIFI_DataCacheEnableTypeDef dataCacheEnabled;
HAL_SPIFI_InterruptEnableTypeDef interruptEnabled;
HAL_SPIFI_Mode3EnableTypeDef mode3Enabled;
uint8_t divider;
HAL_SPIFI_PrefetchEnableTypeDef prefetchEnabled;
HAL_SPIFI_DualModeEnableTypeDef dualModeEnabled;
bool DMAEnabled;
} SPIFI_HandleTypeDef;
typedef struct __SPIFI_CommandTypeDef
{
HAL_SPIFI_DirectionTypeDef Direction;
uint32_t InterimData;
uint8_t InterimLength;
HAL_SPIFI_FieldFormTypeDef FieldForm;
HAL_SPIFI_FrameFormTypeDef FrameForm;
uint8_t OpCode;
} SPIFI_CommandTypeDef;
__attribute__((weak)) void HAL_SPIFI_MspInit();
void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi);
HAL_StatusTypeDef HAL_SPIFI_SendCommand(
SPIFI_HandleTypeDef *spifi,
SPIFI_CommandTypeDef *cmd,
uint32_t address,
uint16_t bufferSize,
uint8_t *readBuffer,
uint8_t *writeBuffer,
uint32_t timeout);
HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL(
SPIFI_HandleTypeDef *spifi,
uint32_t cmdRegCfg,
uint32_t address,
uint16_t bufferSize,
uint8_t *readBuffer,
uint8_t *writeBuffer,
uint32_t interimData,
uint32_t timeout);
bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi);
static inline __attribute__((always_inline)) bool HAL_SPIFI_IsCommandCompleted(SPIFI_HandleTypeDef *spifi)
{
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitCommandProcessing(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
while (timeout-- > 0)
{
if (HAL_SPIFI_IsCommandCompleted(spifi))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi);
bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi);
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
while (timeout-- != 0)
{
if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_WaitInterruptClear(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
while (timeout-- != 0)
{
if ((spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) == 0)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
static inline __attribute__((always_inline)) bool HAL_SPIFI_IsInterruptRequest(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_INTRQ_M) != 0;
}
#ifdef __cplusplus
}
#endif
#endif // MIK32_HAL_SPIFI

View File

@ -0,0 +1,318 @@
#ifndef MIK32_HAL_TIMER16
#define MIK32_HAL_TIMER16
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include "power_manager.h"
#include "timer16.h"
#include "pad_config.h"
#include "stdbool.h"
#include "mcu32_memory_map.h"
/**
* @brief Источник тактирования.
*/
typedef enum __HAL_Timer16_SourceTypeDef
{
TIMER16_SOURCE_INTERNAL_SYSTEM = 0x0, /**< Тактирование от системной частоты (sys_clk). */
TIMER16_SOURCE_INTERNAL_AHB = 0x1, /**< Тактирование от частоты шины AHB. */
TIMER16_SOURCE_INTERNAL_OSC32M = 0x2, /**< Тактирование от частоты внешнего осциллятора OSC32М. */
TIMER16_SOURCE_INTERNAL_HSI32M = 0x3, /**< Тактирование от частоты встроенного осциллятора HSI32M. */
TIMER16_SOURCE_INTERNAL_OSC32K = 0x4, /**< Тактирование от частоты внешнего осциллятора OSC32К. */
TIMER16_SOURCE_INTERNAL_LSI32K = 0x5, /**< Тактирование от частоты встроенного осциллятора LSI32K. */
TIMER16_SOURCE_EXTERNAL_INPUT1 = 0x6 /**< Тактирование от внешнего вывода Input1. */
} HAL_Timer16_SourceTypeDef;
/**
* @brief Делитель частоты.
*/
typedef enum __HAL_Timer16_PrescalerTypeDef
{
TIMER16_PRESCALER_1 = 0b000, /**< Делитель частоты 1. */
TIMER16_PRESCALER_2 = 0b001, /**< Делитель частоты 2. */
TIMER16_PRESCALER_4 = 0b010, /**< Делитель частоты 4. */
TIMER16_PRESCALER_8 = 0b011, /**< Делитель частоты 8. */
TIMER16_PRESCALER_16 = 0b100, /**< Делитель частоты 16. */
TIMER16_PRESCALER_32 = 0b101, /**< Делитель частоты 32. */
TIMER16_PRESCALER_64 = 0b110, /**< Делитель частоты 64. */
TIMER16_PRESCALER_128 = 0b111 /**< Делитель частоты 128. */
} HAL_Timer16_PrescalerTypeDef;
/**
* @brief Источник тактового сигнала таймера для синхронизации счетчика.
*/
typedef enum __HAL_Timer16_CountModeTypeDef
{
TIMER16_COUNTMODE_INTERNAL = 0, /**< Счетчик увеличивается после каждого внутреннего тактового импульса. */
TIMER16_COUNTMODE_EXTERNAL = 1 /**< Счетчик увеличивается после каждого действительного тактового импульса на внешнем выводе input1. */
} HAL_Timer16_CountModeTypeDef;
/**
* @brief Полярность синхронизации.
* Выбор активного фронта при тактировании от внешнего источника.
*
*/
typedef enum __HAL_Timer16_ActiveEdgeTypeDef
{
TIMER16_ACTIVEEDGE_RISING = 0b00, /**< Нарастающий фронт является активным фронтом, используемым для подсчета. */
TIMER16_ACTIVEEDGE_FOLLING = 0b01, /**< Спадающий фронт является активным фронтом, используемым для подсчета. */
TIMER16_ACTIVEEDGE_BOTH = 0b10 /**< Оба фронта являются активными фронтами. */
} HAL_Timer16_ActiveEdgeTypeDef;
/* Title: Источник триггера */
typedef enum __HAL_Timer16_TriggerTypeDef
{
TIMER16_TRIGGER_TIM0_GPIO0_7 = 0b000, /**< GPIO0_7 источник триггера для Timer16_0. */
TIMER16_TRIGGER_TIM0_GPIO0_4 = 0b001, /**< GPIO0_4 источник триггера для Timer16_0. */
TIMER16_TRIGGER_TIM0_GPIO0_15 = 0b010, /**< GPIO0_15 источник триггера для Timer16_0. */
TIMER16_TRIGGER_TIM0_GPIO0_14 = 0b011, /**< GPIO0_14 источник триггера для Timer16_0. */
TIMER16_TRIGGER_TIM1_GPIO1_9 = 0b000, /**< GPIO1_9 источник триггера для Timer16_1. */
TIMER16_TRIGGER_TIM1_GPIO1_8 = 0b001, /**< GPIO1_8 источник триггера для Timer16_1. */
TIMER16_TRIGGER_TIM1_GPIO1_7 = 0b010, /**< GPIO1_7 источник триггера для Timer16_1. */
TIMER16_TRIGGER_TIM1_GPIO1_6 = 0b011, /**< GPIO1_6 источник триггера для Timer16_1. */
TIMER16_TRIGGER_TIM2_GPIO2_3 = 0b000, /**< GPIO2_3 источник триггера для Timer16_2. */
TIMER16_TRIGGER_TIM2_GPIO2_2 = 0b001, /**< GPIO2_2 источник триггера для Timer16_2. */
TIMER16_TRIGGER_TIM2_GPIO2_1 = 0b010, /**< GPIO2_1 источник триггера для Timer16_2. */
TIMER16_TRIGGER_TIM2_GPIO2_0 = 0b011, /**< GPIO2_0 источник триггера для Timer16_2. */
TIMER16_TRIGGER_TEMPERATURE = 0b100, /**< Источник триггера - термосенсор. */
TIMER16_TRIGGER_ADC = 0b101, /**< Источник триггера - окончание преобразования АЦП. */
TIMER16_TRIGGER_RTC = 0b110, /**< Источник триггера - прерывание RTC. */
TIMER16_TRIGGER_AlARM = 0b111 /**< Источник триггера - Будильник. */
} HAL_Timer16_TriggerTypeDef;
/**
* @brief Полярность синхронизации.
* Выбор активного фронта при тактировании от внешнего источника.
*/
typedef enum __HAL_Timer16_Trigger_ActiveEdgeTypeDef
{
TIMER16_TRIGGER_ACTIVEEDGE_SOFTWARE = 0b00, /**< Программный триггер. Запускается при установленном CNTSTRT или SNGSTRT. */
TIMER16_TRIGGER_ACTIVEEDGE_RISING = 0b01, /**< Нарастающий фронт является активным фронтом. */
TIMER16_TRIGGER_ACTIVEEDGE_FOLLING = 0b10, /**< Спадающий фронт является активным фронтом. */
TIMER16_TRIGGER_ACTIVEEDGE_BOTH = 0b11 /**< Оба фронта являются активными фронтами. */
} HAL_Timer16_Trigger_ActiveEdgeTypeDef;
/**
* @brief Функция тайм-аут.
*/
typedef enum __HAL_Timer16_TimeoutTypeDef
{
TIMER16_TIMEOUT_DISABLE = 0, /**< Триггерное событие, поступающее, когда таймер уже запущен, будет проигнорировано. */
TIMER16_TIMEOUT_ENABLE = 1 /**< Триггерное событие, поступающее, когда таймер уже запущен, сбросит и перезапустит счетчик. */
} HAL_Timer16_TimeoutTypeDef;
/**
* @brief Режим обновления регистров ARR и CMP.
*/
typedef enum __HAL_Timer16_PreloadTypeDef
{
TIMER16_PRELOAD_AFTERWRITE = 0, /**< Регистры обновляются после каждого доступа к записи на шине APB. */
TIMER16_PRELOAD_ENDPERIOD = 1 /**< Регистры обновляются в конце текущего периода Timer16. */
} HAL_Timer16_PreloadTypeDef;
/**
* @brief Фильтр для внешнего тактового генератора/триггера.
*/
typedef enum __HAL_Timer16_FilterTypeDef
{
TIMER16_FILTER_NONE = 0b00, /**< Фильтр отключен. */
TIMER16_FILTER_2CLOCK = 0b01, /**< Фильтр на 2 такта. */
TIMER16_FILTER_4CLOCK = 0b10, /**< Фильтр на 4 такта. */
TIMER16_FILTER_8CLOCK = 0b11 /**< Фильтр на 8 тактов. */
} HAL_Timer16_FilterTypeDef;
/**
* @brief Режим энкодера.
*/
typedef enum __HAL_Timer16_EncoderTypeDef
{
TIMER16_ENCODER_DISABLE = 0, /**< Режим энкодера выключен. */
TIMER16_ENCODER_ENABLE = 1 /**< Режим энкодера включен. */
} HAL_Timer16_EncoderTypeDef;
/**
* @brief Генерация волновой формы.
*/
typedef enum __HAL_Timer16_WaveformGenTypeDef
{
TIMER16_WAVEFORM_GENERATION_ENABLE = 0, /**< Выключить генерацию волновой формы. */
TIMER16_WAVEFORM_GENERATION_DISABLE = 1 /**< Включить генерацию волновой формы. */
} HAL_Timer16_WaveformGenTypeDef;
/**
* @brief Полярность волновой формы.
*/
typedef enum __HAL_Timer16_WaveformPolarityTypeDef
{
TIMER16_WAVEFORM_POLARITY_NONINVERTED = 0, /**< Неинвертированная полярность волновой формы. */
TIMER16_WAVEFORM_POLARITY_INVERTED = TIMER16_CFGR_WAVPOL_M /**< Инвертированная полярность волновой формы. */
} HAL_Timer16_WaveformPolarityTypeDef;
/**
* @brief Настройки источника тактирования.
*/
typedef struct __Timer16_ClockConfigTypeDef
{
uint8_t Source; /**< Источник тактирования. */
uint8_t Prescaler; /**< Делитель частоты. */
} Timer16_ClockConfigTypeDef;
/**
* @brief Настройки генерации волновой формы.
*/
typedef struct __Timer16_WaveformConfigTypeDef
{
HAL_Timer16_WaveformGenTypeDef Enable; /**< Включить или выключить генерацию волновой формы. */
HAL_Timer16_WaveformPolarityTypeDef Polarity; /**< Полярность выходного сигнала. */
} Timer16_WaveformConfigTypeDef;
/**
* @brief Настройки триггера.
*/
typedef struct __Timer16_TriggerConfigTypeDef
{
uint8_t Source; /**< Источник триггера. */
uint8_t ActiveEdge; /**< Активный фронт. */
uint8_t TimeOut; /**< Функция тайм-аут. */
} Timer16_TriggerConfigTypeDef;
/**
* @brief Настройки фильтров.
*/
typedef struct __Timer16_FilterConfigTypeDef
{
uint8_t ExternalClock; /**< Фильтр для внешнего тактового генератора. */
uint8_t Trigger; /**< фильтр для триггера. */
} Timer16_FilterConfigTypeDef;
/**
* @brief Настройки Timer16
*/
typedef struct __Timer16_HandleTypeDef
{
TIMER16_TypeDef *Instance; /**< Базовый адрес регистров Timer16. #TIMER16_0, #TIMER16_1, #TIMER16_2. */
Timer16_ClockConfigTypeDef Clock; /**< Настройки тактирования. */
uint8_t CountMode; /**< Источник синхронизации. */
uint8_t ActiveEdge; /**< Активный фронт. */
uint8_t Preload; /**< Режим записи в ARR и CMP. */
Timer16_TriggerConfigTypeDef Trigger; /**< Настройки триггера. */
Timer16_FilterConfigTypeDef Filter; /**< Настройки фильтра. */
Timer16_WaveformConfigTypeDef Waveform; /**< Настройки генерации волновой формы. */
uint8_t EncoderMode; /**< Включить или выключить режим энкодера. */
} Timer16_HandleTypeDef;
/**
* @brief Запустить таймер16 в продолжительном режиме.
*/
#define __HAL_TIMER16_START_CONTINUOUS(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_CNTSTRT_M)
/**
* @brief Запустить таймер16 в однократном режиме.
*/
#define __HAL_TIMER16_START_SINGLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= TIMER16_CR_SNGSTRT_M)
void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16);
void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge);
void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock);
void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode);
void HAL_Timer16_ClockInit(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetPreload(Timer16_HandleTypeDef *htimer16, uint8_t Preload);
void HAL_Timer16_WaitARROK(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_WaitCMPOK(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetARR(Timer16_HandleTypeDef *htimer16, uint16_t Period);
void HAL_Timer16_SetCMP(Timer16_HandleTypeDef *htimer16, uint16_t Compare);
void HAL_Timer16_SelectTrigger(Timer16_HandleTypeDef *htimer16, uint8_t TriggerSource);
void HAL_Timer16_SetTriggerEdge(Timer16_HandleTypeDef *htimer16, uint8_t TriggerEdge);
void HAL_Timer16_SetTimeOut(Timer16_HandleTypeDef *htimer16, uint8_t TimeOut);
void HAL_Timer16_SetFilterExternalClock(Timer16_HandleTypeDef *htimer16, uint8_t FilterExternalClock);
void HAL_Timer16_SetFilterTrigger(Timer16_HandleTypeDef *htimer16, uint8_t FilterTrigger);
void HAL_Timer16_SetEncoderMode(Timer16_HandleTypeDef *htimer16, uint8_t EncoderMode);
void HAL_Timer16_WaveformPolarity(Timer16_HandleTypeDef *htimer16, HAL_Timer16_WaveformPolarityTypeDef WaveformPolarity);
void HAL_Timer16_SetPrescaler(Timer16_HandleTypeDef *htimer16, uint8_t Prescaler);
void HAL_Timer16_Init(Timer16_HandleTypeDef *htimer16);
uint16_t HAL_Timer16_GetCounterValue(Timer16_HandleTypeDef *htimer16);
uint8_t HAL_Timer16_CheckCMP(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_WaitCMP(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Counter_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period);
void HAL_Timer16_StartPWM(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_StartOneShot(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_StartSetOnes(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_Encoder_Start(Timer16_HandleTypeDef *htimer16, uint32_t Period);
void HAL_Timer16_Encoder_Stop(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Stop(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Counter_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period);
void HAL_Timer16_StartPWM_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_StartOneShot_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_StartSetOnes_IT(Timer16_HandleTypeDef *htimer16, uint16_t Period, uint16_t Compare);
void HAL_Timer16_Encoder_Start_IT(Timer16_HandleTypeDef *htimer16, uint32_t Period);
void HAL_Timer16_Encoder_Stop_IT(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Stop_IT(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_WaitTrigger(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask);
void HAL_Timer16_SetInterruptDOWN(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptUP(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptARROK(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptCMPOK(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptEXTTRIG(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16);
/**
* @brief Получить статус прерываний Timer16.
* Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний.
* @param htimer16 Указатель на структуру с настройками Timer16.
* @return Статус прерываний.
*/
static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptStatus(Timer16_HandleTypeDef *htimer16)
{
uint32_t interrupt_status = htimer16->Instance->ISR & htimer16->Instance->IER;
return interrupt_status;
}
/**
* @brief Очистить флаг прерывания.
* @param htimer16 Указатель на структуру с настройками Timer16.
* @param Interrupt Номер прерывания Timer16 в регистре ICR.
*/
static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptFlag(Timer16_HandleTypeDef *htimer16, uint32_t Interrupt)
{
htimer16->Instance->ICR = 1 << Interrupt;
}
/**
* @brief Очистить флаги прерываний по маске.
* @param htimer16 Указатель на структуру с настройками Timer16.
* @param InterruptMask Маска очищаемых флагов прерываний.
*/
static inline __attribute__((always_inline)) void HAL_Timer16_ClearInterruptMask(Timer16_HandleTypeDef *htimer16, uint32_t InterruptMask)
{
htimer16->Instance->ICR = InterruptMask;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,265 @@
#ifndef MIK32_HAL_TIMER32
#define MIK32_HAL_TIMER32
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mik32_hal_gpio.h"
#include <timer32.h>
#include <power_manager.h>
#include "mik32_hal_def.h"
#include <mcu32_memory_map.h>
#define TIMER32_TIMEOUT 10000000
#define TIMER32_INTERRUPT_CLEAR_MASK 0x3FF
/* Сдвиг настройки тактирования таймера в регистре Timer_CFG */
#define MUX_TIM32_0 0
#define MUX_TIM32_1 3
#define MUX_TIM32_2 6
/* Значение в регистре Timer_CFG при тактировании таймера от TIM1 или TIM2 */
#define TIMER32_TIM1_SYS_CLK 0b00
#define TIMER32_TIM1_HCLK 0b01
#define TIMER32_TIM2_OSC32K 0b00
#define TIMER32_TIM2_LSI32K 0b10
typedef enum
{
TIMER32_SOURCE_PRESCALER, /* Выход с делителя - частота шины AHB (hclk) */
TIMER32_SOURCE_TIM1_SYS_CLK, /* Системная частота */
TIMER32_SOURCE_TIM1_HCLK, /* частота шины AHB */
TIMER32_SOURCE_TIM2_OSC32K, /* Внешний источник 32кГц */
TIMER32_SOURCE_TIM2_LSI32K, /* Внутренний источник 32кГц */
TIMER32_SOURCE_TX_PAD, /* Внешний вывод TX_PAD */
} HAL_TIMER32_SourceTypeDef;
typedef enum
{
TIMER32_COUNTMODE_FORWARD = 0b00,
TIMER32_COUNTMODE_REVERSE = 0b01,
TIMER32_COUNTMODE_BIDIRECTIONAL = 0b10
} HAL_TIMER32_CountModeTypeDef;
typedef enum
{
TIMER32_STATE_DISABLE = 0b00,
TIMER32_STATE_ENABLE = 0b01
} HAL_TIMER32_StateTypeDef;
typedef enum
{
TIMER32_CHANNEL_STATE_DISABLE,
TIMER32_CHANNEL_STATE_ENABLE,
} HAL_TIMER32_CHANNEL_StateTypeDef;
typedef enum
{
TIMER32_CHANNEL_NON_INVERTED_PWM = 0,
TIMER32_CHANNEL_INVERTED_PWM = 1
} HAL_TIMER32_CHANNEL_PWMInvertTypeDef;
typedef enum
{
TIMER32_CHANNEL_MODE_COMPARE = 0b01, /* Режим сравнения */
TIMER32_CHANNEL_MODE_CAPTURE = 0b10, /* Режим захвата */
TIMER32_CHANNEL_MODE_PWM = 0b11, /* ШИМ */
} HAL_TIMER32_CHANNEL_ModeTypeDef;
typedef enum
{
TIMER32_CHANNEL_CAPTUREEDGE_RISING = 0,
TIMER32_CHANNEL_CAPTUREEDGE_FALLING = 1
} HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef;
typedef enum
{
TIMER32_CHANNEL_FILTER_OFF = 0,
TIMER32_CHANNEL_FILTER_ON = 1
} HAL_TIMER32_CHANNEL_NoiseTypeDef;
typedef enum
{
TIMER32_CHANNEL_0 = 0,
TIMER32_CHANNEL_1 = 1,
TIMER32_CHANNEL_2 = 2,
TIMER32_CHANNEL_3 = 3
} HAL_TIMER32_CHANNEL_IndexTypeDef;
typedef struct
{
/* Источник тактирования таймера для счета*/
HAL_TIMER32_SourceTypeDef Source;
/* Делитель частоты. Частота делится на Prescaler + 1 */
uint32_t Prescaler;
} TIMER32_ClockConfigTypeDef;
typedef struct
{
TIMER32_TypeDef *Instance;
/* Настройки тактирования */
TIMER32_ClockConfigTypeDef Clock;
/* Режим счета */
HAL_TIMER32_CountModeTypeDef CountMode;
/* Максимальное значение счета */
uint32_t Top;
HAL_TIMER32_StateTypeDef State;
uint32_t InterruptMask;
} TIMER32_HandleTypeDef;
typedef struct
{
TIMER32_TypeDef *TimerInstance;
TIMER32_CHANNEL_TypeDef *Instance;
HAL_TIMER32_CHANNEL_IndexTypeDef ChannelIndex;
/* Инверсия ГИМ */
HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert;
/* Режим канала */
HAL_TIMER32_CHANNEL_ModeTypeDef Mode;
/* Активный фронт в режиме захвата*/
HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef CaptureEdge;
/* Значение сравнения канала */
uint32_t OCR;
/* Фильтр */
HAL_TIMER32_CHANNEL_NoiseTypeDef Noise;
uint8_t State;
} TIMER32_CHANNEL_HandleTypeDef;
#define HAL_TIMER32_VALUE_GET(timer_instance) (*timer_instance).Instance->VALUE;
#define HAL_TIMER32_INTERRUPTFLAGS_CLEAR(timer_instance) (*timer_instance).Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK;
#define HAL_TIMER32_VALUE_CLEAR(timer_instance) (*timer_instance).Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M;
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Channel_ICR_Get(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
return timerChannel->Instance->ICR;
}
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_InterruptFlags_Get(TIMER32_HandleTypeDef *timer)
{
return timer->Instance->INT_FLAGS;
}
static inline __attribute__((always_inline)) uint32_t HAL_Timer32_Value_Get(TIMER32_HandleTypeDef *timer)
{
return timer->Instance->VALUE;
}
static inline __attribute__((always_inline)) void HAL_Timer32_InterruptFlags_Clear(TIMER32_HandleTypeDef *timer)
{
timer->Instance->INT_CLEAR = TIMER32_INTERRUPT_CLEAR_MASK;
}
static inline __attribute__((always_inline)) void HAL_Timer32_Value_Clear(TIMER32_HandleTypeDef *timer)
{
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_CLR_M;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCapture(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout)
{
while (timeout)
{
timeout--;
if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_IC_M(timerChannel->ChannelIndex))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_Channel_WaitFlagCompare(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t timeout)
{
while (timeout)
{
timeout--;
if (timerChannel->TimerInstance->INT_FLAGS & TIMER32_INT_OC_M(timerChannel->ChannelIndex))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagOverflow(TIMER32_HandleTypeDef *timer, uint32_t timeout)
{
while (timeout)
{
timeout--;
if (timer->Instance->INT_FLAGS & TIMER32_INT_OVERFLOW_M)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitFlagUnderflow(TIMER32_HandleTypeDef *timer, uint32_t timeout)
{
while (timeout)
{
timeout--;
if (timer->Instance->INT_FLAGS & TIMER32_INT_UNDERFLOW_M)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state);
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);
void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source);
void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask);
void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask);
void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode);
void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask);
HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert);
HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode);
HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge);
HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR);
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR);
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise);
void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer);
HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel);
void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask);
void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask);
#ifdef __cplusplus
}
#endif
#endif // MIK32_HAL_TIMER32

View File

@ -0,0 +1,158 @@
#ifndef MIK32_TSENS
#define MIK32_TSENS
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MIK32V0
#include "analog_reg.h"
#include "pad_config.h"
#include "mcu32_memory_map.h"
#include "power_manager.h"
#include "mik32_hal_def.h"
#include "mik32_hal_pcc.h"
#define TSENS_OPTIMAL_FREQUENCY 40000 /**< Рекомендуемая частота работы термосенсора. */
#define __HAL_TSENS_FORCE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG &= ~TSENS_CFG_NRST_M) /**< Установить состояние сброса термосенсора. */
#define __HAL_TSENS_RELEASE_RESET(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CFG |= TSENS_CFG_NRST_M) /**< Снять состояние сброса термосенсора. */
#define __HAL_TSENS_SINGLE_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_SINGLE = 1) /**< Запустить одиночное измерение температуры. */
#define __HAL_TSENS_CONTINUOUS_START(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 1) /**< Запуск непрерывного измерения температуры. */
#define __HAL_TSENS_CONTINUOUS_STOP(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CONTINUOUS = 0) /**< Остановка непрерывного измерения температуры. */
#define __HAL_TSENS_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_EOC_M) == TSENS_VALUE_EOC_M) /**< Получить состояние флага окончания преобразования (EOC). */
#define __HAL_TSENS_READ_MEASUREMENT(__HANDLE__) ((__HANDLE__)->Instance->TSENS_VALUE & TSENS_VALUE_VALUE_M) /**< Получить результат измерения термосенсора. */
#define __HAL_TSENS_IRQ_ENABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_LOW_MASK_M) /**< Разрешить прерывание по выходу за нижний порог температуры. */
#define __HAL_TSENS_IRQ_DISABLE_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_LOW_MASK_M) /**< Запретить прерывание по выходу за нижний порог температуры. */
#define __HAL_TSENS_IRQ_CLEAR_LOWIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_LOW_CLEAR_M) /**< Очистить флаг прерывания по выходу за нижний порог температуры (LOW_IRQ). */
#define __HAL_TSENS_IRQ_GET_LOWIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) == TSENS_IRQ_LOW_IRQ_M) /**< Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ). */
/** Получить состояние флага прерывания по выходу за нижний порог температуры (LOW_IRQ) с учетом маски разрешенных прерываний. */
#define __HAL_TSENS_IRQ_GET_LOWIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_LOW_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_LOW_IRQ_M)
#define __HAL_TSENS_IRQ_ENABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_HI_MASK_M) /**< Разрешить прерывание по выходу за верхний порог температуры. */
#define __HAL_TSENS_IRQ_DISABLE_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_HI_MASK_M) /**< Запретить прерывание по выходу за верхний порог температуры. */
#define __HAL_TSENS_IRQ_CLEAR_HIIRQ(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_HI_CLEAR_M) /**< Очистить флаг прерывания по выходу за верхний порог температуры (HI_IRQ). */
#define __HAL_TSENS_IRQ_GET_HIIRQ(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) == TSENS_IRQ_HI_IRQ_M) /**< Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ). */
/** Получить состояние флага прерывания по выходу за верхний порог температуры (HI_IRQ) с учетом маски разрешенных прерываний. */
#define __HAL_TSENS_IRQ_GET_HIIRQ_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_HI_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_HI_IRQ_M)
#define __HAL_TSENS_IRQ_ENABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ |= TSENS_IRQ_EOC_MASK_M) /**< Разрешить прерывание по окончанию преобразования. */
#define __HAL_TSENS_IRQ_DISABLE_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~TSENS_IRQ_EOC_MASK_M) /**< Запретить прерывание по окончанию преобразования. */
#define __HAL_TSENS_IRQ_CLEAR_EOC(__HANDLE__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = TSENS_CLEAR_IRQ_EOC_CLEAR_M) /**< Очистить флаг прерывания по окончанию преобразования (EOC_IRQ). */
#define __HAL_TSENS_IRQ_GET_EOC(__HANDLE__) (((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) == TSENS_IRQ_EOC_IRQ_M) /**< Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ). */
/** Получить состояние флага прерывания по окончанию преобразования (EOC_IRQ) с учетом маски разрешенных прерываний. */
#define __HAL_TSENS_IRQ_GET_EOC_MASK(__HANDLE__) ((((__HANDLE__)->Instance->TSENS_IRQ & TSENS_IRQ_EOC_IRQ_M) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == TSENS_IRQ_EOC_IRQ_M)
/**
* Разрешить прерывание . __INTERRUPT__ может быть одним из значений:
* - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры;
* - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры;
* - TSENS_IRQ_EOC_MASK_M: окончание преобразования.
*/
#define __HAL_TSENS_IRQ_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ |= (__INTERRUPT__))
/**
* Запретить прерывание. __INTERRUPT__ может быть одним из значений:
* - TSENS_IRQ_LOW_MASK_M: выход за нижний порог температуры;
* - TSENS_IRQ_HI_MASK_M: выход за верхний порог температуры;
* - TSENS_IRQ_EOC_MASK_M: окончание преобразования.
*/
#define __HAL_TSENS_IRQ_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->TSENS_IRQ &= ~(__INTERRUPT__))
/**
* Очистить флаг прерывания. __FLAG__ может быть одним из значений:
* - TSENS_CLEAR_IRQ_LOW_CLEAR_M: выход за нижний порог температуры;
* - TSENS_CLEAR_IRQ_HI_CLEAR_M: выход за верхний порог температуры;
* - TSENS_CLEAR_IRQ_EOC_CLEAR_M: окончание преобразования.
*/
#define __HAL_TSENS_IRQ_CLEAR(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->TSENS_CLEAR_IRQ = (__FLAG__))
/**
* Получить состояние флага прерывания. __FLAG__ может быть одним из значений:
* - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры;
* - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры;
* - TSENS_IRQ_EOC_IRQ_M: окончание преобразования.
*/
#define __HAL_TSENS_IRQ_GET(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) == (__FLAG__))
/**
* Получить состояние флага прерывания с учетом маски разрешенных прерываний.. __FLAG__ может быть одним из значений:
* - TSENS_IRQ_LOW_IRQ_M: выход за нижний порог температуры;
* - TSENS_IRQ_HI_IRQ_M: выход за верхний порог температуры;
* - TSENS_IRQ_EOC_IRQ_M: окончание преобразования.
*/
#define __HAL_TSENS_IRQ_GET_MASK(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->TSENS_IRQ & (__FLAG__)) & (((__HANDLE__)->Instance->TSENS_IRQ & 0b111) << 3)) == (__FLAG__))
/*
* Define
* Константы-параметры функции установки источника тактирования TSENS
*/
/**
* @brief Перечисление источников тактирования термосенсора.
*/
typedef enum __HAL_TSENS_ClockTypeDef
{
HAL_TSENS_SYS_CLK = 0x0, /**< Системная частота (sys_clk). */
HAL_TSENS_HCLK = 0x1, /**< Частота шины AHB (hclk). */
HAL_TSENS_OSC32M = 0x2, /**< Частота внешнего высокочастотного осциллятора до 32 МГц. */
HAL_TSENS_HSI32M = 0x3, /**< Частота внутреннего высокочастотного осциллятора 32 МГц. */
HAL_TSENS_OSC32K = 0x4, /**< Частота внешнего осциллятора 32 кГц. */
HAL_TSENS_LSI32K = 0x5 /**< Частота внутреннего осциллятора 32 кГц. */
} HAL_TSENS_ClockTypeDef;
/**
* @brief Определение структуры TSENS Handle.
*/
typedef struct __SPI_HandleTypeDef
{
ANALOG_REG_TypeDef *Instance; /**< Адрес регистров блока управления аналоговой подсистемой. */
HAL_TSENS_ClockTypeDef Clock; /**< Источник тактирования TSENS. */
uint32_t Frequency; /**< Частота работы температурного сенсора в Гц. Значение этого параметра может быть не больше 100кГц. */
} TSENS_HandleTypeDef;
/**
* @brief Возвращаемая структура для функции @ref HAL_TSENS_SingleStart.
*/
typedef struct __WDT_ClockTypeDef
{
HAL_StatusTypeDef statusHAL; /**< Статус HAL. */
uint32_t value; /**< Значение температуры в градусах Цельсия. Значение в 100 раз больше. */
} TSENS_ValueTypeDef;
void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens);
HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens);
HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source);
HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div);
HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter);
HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres);
HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres);
HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border);
HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border);
uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens);
void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens);
TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout);
void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens);
void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens);
void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens);
#endif // MIK32V0
#ifdef __cplusplus
}
#endif
#endif // MIK32_TSENS

View File

@ -0,0 +1,120 @@
#ifndef MCU32_HAL_WDT
#define MCU32_HAL_WDT
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_pcc.h"
#include "mcu32_memory_map.h"
#include "wdt.h"
#include "wdt_bus.h"
#include "power_manager.h"
#include "mik32_hal_def.h"
#include "stddef.h"
#define WDT_CLOCK32K_VALUE 32768 /**< Частота осцилляторов OSC32K или LSI32K. */
#define WDT_CLOCK32M_VALUE 32000000 /**< Частота осцилляторов OSC32M или HSI32M. */
#define WDT_MAX_VALUE_CLOCK32K 511875 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32K или LSI32K. */
#define WDT_MAX_VALUE_CLOCK32M 524 /**< Максимально возможный интервал времени в миллисекундах при тактировании от OSC32M или HSI32M. */
#define WDT_TIMEOUT_DEFAULT 10000 /**< Значение задержки по умолчанию. */
/** @brief Проверить установлен ли указанный флаг SPI или нет.
* @param __HANDLE__ Указатель WDT Handle.
* @param __FLAG__ Флаг для проверки.
* Этот параметр должен быть одним из следующих значений:
* - @ref WDT_STA_ENABLED_M: флаг активности таймера
* - @ref WDT_STA_LOADING_M: флаг перезагрузки значения
* - @ref WDT_STA_RST_FLAG_M: флаг генерации сброса сторожевым таймером. Сбрасывается в 0 только при снятии и последующей подаче питания.
*
* @return Состояние флага @p __FLAG__ (TRUE или FALSE).
*/
#define __HAL_WDT_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->STA) & (__FLAG__)) == (__FLAG__))
/**
* @brief Задать источник тактирования сторожевого таймера.
* @param __WDT_CLOCK__ Bсточник тактирования сторожевого таймера.
* Этот параметр должен быть одним из значений перечисления @ref HAL_WDT_Clocks.
*/
#define __HAL_WDT_SET_CLOCK(__WDT_CLOCK__) (PM->WDT_CLK_MUX = (__WDT_CLOCK__) & PM_WDT_CLK_MUX_M)
/**
* @brief Перечисление делителей входной частоты сторожевого таймера.
*
*/
typedef enum __HAL_WDT_Prescale
{
HAL_WDT_PRESCALE_1 = 0, /**< Делитель входной частоты сторожевого таймера 1. */
HAL_WDT_PRESCALE_2 = 1, /**< Делитель входной частоты сторожевого таймера 2. */
HAL_WDT_PRESCALE_4 = 2, /**< Делитель входной частоты сторожевого таймера 4. */
HAL_WDT_PRESCALE_16 = 3, /**< Делитель входной частоты сторожевого таймера 16. */
HAL_WDT_PRESCALE_64 = 4, /**< Делитель входной частоты сторожевого таймера 64. */
HAL_WDT_PRESCALE_256 = 5, /**< Делитель входной частоты сторожевого таймера 256. */
HAL_WDT_PRESCALE_1024 = 6, /**< Делитель входной частоты сторожевого таймера 1024. */
HAL_WDT_PRESCALE_4096 = 7 /**< Делитель входной частоты сторожевого таймера 4096. */
} HAL_WDT_Prescale;
/**
* @brief Перечисление источников тактирования сторожевого таймера.
*/
typedef enum __HAL_WDT_Clocks
{
HAL_WDT_OSC32M, /**< Внешний 32МГц. */
HAL_WDT_HSI32M, /**< Внутренний 32МГц. */
HAL_WDT_OSC32K, /**< Внешний 32кГц. */
HAL_WDT_LSI32K /**< Внутренний 32кГц. */
} HAL_WDT_Clocks;
/**
* @brief Определение структуры конфигурации WDT.
*/
typedef struct __WDT_InitTypeDef
{
HAL_WDT_Clocks Clock; /**< Источник тактирования WDT. */
/**
* @brief Время до перезагрузки контроллера в миллисекундах.
*
* Значение не должно превышать 524 мс при тактировании от источника 32 Мгц и
* 511875 мс при тактировании от источника 32 кГц.
*/
uint32_t ReloadMs;
} WDT_InitTypeDef;
/**
* @brief Определение структуры WDT Handle.
*/
typedef struct __WDT_HandleTypeDef
{
WDT_TypeDef *Instance; /**< Адрес регистров WDT. */
WDT_InitTypeDef Init; /**< Параметры WDT. */
} WDT_HandleTypeDef;
/**
* @brief Возвращаемая структура для функции @ref HAL_WDT_MillisInClock.
*/
typedef struct __WDT_ClockTypeDef
{
uint32_t tick; /**< Начальное значение таймера при запуске или перезапуске для отсчета WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */
int divIndex; /**< Значение делителя частоты таймера для отсчета @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.Init.ReloadMs" миллисекунд. */
} WDT_ClockTypeDef;
void HAL_RTC_MspInit(WDT_HandleTypeDef* hwdt);
HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout);
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout);
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout);
HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout);
void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale);
void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload);
#ifdef __cplusplus
}
#endif
#endif // MCU32_HAL_WDT

View File

@ -0,0 +1,15 @@
#include "mik32_hal.h"
__attribute__((weak)) void HAL_MspInit()
{
__HAL_PCC_PAD_CONFIG_CLK_ENABLE();
__HAL_PCC_EPIC_CLK_ENABLE();
}
HAL_StatusTypeDef HAL_Init()
{
HAL_MspInit();
return HAL_OK;
}

View File

@ -0,0 +1,201 @@
#include "mik32_hal_adc.h"
__attribute__((weak)) void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
if ((hadc->Init.EXTClb == ADC_EXTCLB_ADCREF) && (hadc->Init.EXTRef == ADC_EXTREF_ON))
{
#ifdef MIK32V0
GPIO_InitStruct.Pin = GPIO_PIN_10;
#else // MIK32V2
GPIO_InitStruct.Pin = GPIO_PIN_11;
#endif // MIK32V0
}
GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
switch (hadc->Init.Sel)
{
case ADC_CHANNEL0:
GPIO_InitStruct.Pin = GPIO_PIN_5;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
break;
case ADC_CHANNEL1:
GPIO_InitStruct.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
break;
case ADC_CHANNEL2:
GPIO_InitStruct.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case ADC_CHANNEL3:
GPIO_InitStruct.Pin = GPIO_PIN_4;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case ADC_CHANNEL4:
GPIO_InitStruct.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case ADC_CHANNEL5:
GPIO_InitStruct.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case ADC_CHANNEL6:
GPIO_InitStruct.Pin = GPIO_PIN_11;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case ADC_CHANNEL7:
GPIO_InitStruct.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
}
}
void HAL_ADC_CLBEnable(ADC_HandleTypeDef *hadc)
{
hadc->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S;
}
void HAL_ADC_CLBDisable(ADC_HandleTypeDef *hadc)
{
hadc->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S);
}
void HAL_ADC_VCLBSet(ADC_HandleTypeDef *hadc, uint8_t v_coef)
{
hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S);
hadc->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S);
}
void HAL_ADC_ICLBSet(ADC_HandleTypeDef *hadc, uint8_t i_coef)
{
hadc->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S);
hadc->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S);
}
void HAL_ADC_ResetEnable(ADC_HandleTypeDef *hadc)
{
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_RESETN_S);
#else // MIK32V2
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
(1 << ADC_CONFIG_RESETN_S);
#endif // MIK32V0
}
void HAL_ADC_ResetDisable(ADC_HandleTypeDef *hadc)
{
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_RESETN_S);
#else // MIK32V2
hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_RESETN_M)) & (~ADC_CONFIG_SAH_TIME_M)) |
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M);
#endif // MIK32V0
}
void HAL_ADC_Disable(ADC_HandleTypeDef *hadc)
{
hadc->Instance->ADC_CONFIG &= ~(1 << ADC_CONFIG_EN_S);
HAL_ADC_ResetDisable(hadc);
}
void HAL_ADC_Enable(ADC_HandleTypeDef *hadc)
{
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG |= (1 << ADC_CONFIG_EN_S);
#else // MIK32V2
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
(1 << ADC_CONFIG_EN_S);
#endif // MIK32V0
HAL_ADC_ResetEnable(hadc);
}
void HAL_ADC_ChannelSet(ADC_HandleTypeDef *hadc)
{
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SEL_M)) | (hadc->Init.Sel << ADC_CONFIG_SEL_S); /* Настройка канала АЦП */
#else // MIK32V2
hadc->Instance->ADC_CONFIG = ((hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) & (~ADC_CONFIG_SEL_M)) |
(hadc->Init.Sel << ADC_CONFIG_SEL_S) |
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M);
#endif // MIK32V0
}
void HAL_ADC_Init(ADC_HandleTypeDef *hadc)
{
HAL_ADC_MspInit(hadc);
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG = 0;
#else // MIK32V2
hadc->Instance->ADC_CONFIG = 0x3C00;
#endif // MIK32V0
HAL_ADC_Enable(hadc);
HAL_ADC_ChannelSet(hadc); /* Настройка канала АЦП. Перевод используемого вывода в аналоговый режим */
#ifdef MIK32V0
hadc->Instance->ADC_CONFIG |= (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
(hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
#else // MIK32V2
hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
(hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
(hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
#endif // MIK32V0
}
void HAL_ADC_Single(ADC_HandleTypeDef *hadc)
{
hadc->Instance->ADC_SINGLE = 1;
}
void HAL_ADC_ContinuousDisabled(ADC_HandleTypeDef *hadc)
{
hadc->Instance->ADC_CONTINUOUS = 0;
}
void HAL_ADC_ContinuousEnable(ADC_HandleTypeDef *hadc)
{
hadc->Instance->ADC_CONTINUOUS = 1;
}
void HAL_ADC_WaitValid(ADC_HandleTypeDef *hadc)
{
/* Ожидание актуальных данных - ADC_VALID = 1 */
while (!(hadc->Instance->ADC_VALID))
;
}
uint16_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
{
uint16_t value = hadc->Instance->ADC_VALUE;
return value;
}
uint16_t HAL_ADC_WaitAndGetValue(ADC_HandleTypeDef *hadc)
{
HAL_ADC_WaitValid(hadc);
uint16_t value = HAL_ADC_GetValue(hadc);
return value;
}

View File

@ -0,0 +1,143 @@
#include "mik32_hal_crc32.h"
__attribute__((weak)) void HAL_CRC32_MspInit(CRC_HandleTypeDef* hcrc)
{
__HAL_PCC_CRC32_CLK_ENABLE();
}
void HAL_CRC_SetPoly(CRC_HandleTypeDef *hcrc)
{
/* Задается полином */
hcrc->Instance->POLY = hcrc->Poly;
}
void HAL_CRC_SetInputReverse(CRC_HandleTypeDef *hcrc)
{
/* Найстройка перестановки битов/байтов входных данных */
hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOT_S);
hcrc->Instance->CTRL |= hcrc->InputReverse << CRC_CTRL_TOT_S;
}
void HAL_CRC_SetOutputInversion(CRC_HandleTypeDef *hcrc)
{
hcrc->Instance->CTRL &= ~(1 << CRC_CTRL_FXOR_S);
hcrc->Instance->CTRL |= hcrc->OutputInversion << CRC_CTRL_FXOR_S;
}
void HAL_CRC_SetOutputReverse(CRC_HandleTypeDef *hcrc)
{
/* Найстройка перестановки битов/байтов выходных данных */
hcrc->Instance->CTRL &= ~(0b11 << CRC_CTRL_TOTR_S);
hcrc->Instance->CTRL |= hcrc->OutputReverse << CRC_CTRL_TOTR_S;
}
void HAL_CRC_SetInit(CRC_HandleTypeDef *hcrc)
{
/* Назначение регистра данных: 1 записываем начальное значение */
hcrc->Instance->CTRL |= CRC_CTRL_WAS_M;
/* Pапись в регистр данных 32-разрядное начальное значение */
hcrc->Instance->DATA32 = hcrc->Init;
/* Назначение регистра данных: 0 записываем данные */
hcrc->Instance->CTRL &= ~CRC_CTRL_WAS_M;
}
void HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
{
HAL_CRC32_MspInit(hcrc);
/* Найстройка перестановки битов/байтов входных данных */
HAL_CRC_SetInputReverse(hcrc);
/* Найстройка перестановки битов/байтов выходных данных */
HAL_CRC_SetOutputReverse(hcrc);
/* Инверсия контрольной суммы */
HAL_CRC_SetOutputInversion(hcrc);
/* Задается полином */
HAL_CRC_SetPoly(hcrc);
}
void HAL_CRC_WaitBusy(CRC_HandleTypeDef *hcrc)
{
/* Ожидание 1 такта для установления флага BUSY в 1 после записи в регистр данных слова */
for (uint8_t i = 0; i < 100; i++);
/* Ожидание когда флаг BUSY станет 0 - автомат закончил вычисления */
while (hcrc->Instance->CTRL & CRC_CTRL_BUSY_M);
}
void HAL_CRC_WriteData(CRC_HandleTypeDef *hcrc, uint8_t message[], uint32_t message_length)
{
if(message_length > CRC_MAX_BYTES)
{
#ifdef MIK32_CRC_DEBUG
xprintf("Ошибка: переполнение буфера\n");
#endif
return;
}
/* Запись начального значения Init */
HAL_CRC_SetInit(hcrc);
uint32_t i = 0;
while (i < message_length)
{
if (i + 3 < message_length)
{
hcrc->Instance->DATA32 = (message[i+3] << 0) |
(message[i+2] << 8) |
(message[i+1] << 16) |
(message[i] << 24);
i += 4;
}
else if (i + 1 < message_length)
{
hcrc->Instance->DATA16 = (message[i+1] << 0) |
(message[i] << 8);
i += 2;
}
else
{
hcrc->Instance->DATA8 = message[i];
i += 1;
}
}
}
void HAL_CRC_WriteData32(CRC_HandleTypeDef *hcrc, uint32_t message[], uint32_t message_length)
{
if(message_length > CRC_MAX_WORDS)
{
#ifdef MIK32_CRC_DEBUG
xprintf("Ошибка: переполнение буфера\n");
#endif
return;
}
/* Запись начального значения Init */
HAL_CRC_SetInit(hcrc);
uint32_t data;
for(uint32_t i = 0; i < message_length; i++)
{
data = message[i];
hcrc->Instance->DATA32 = data;
}
}
uint32_t HAL_CRC_ReadCRC(CRC_HandleTypeDef *hcrc)
{
uint32_t CRCValue;
/* Ожидание завершения вычисления CRC */
HAL_CRC_WaitBusy(hcrc);
CRCValue = CRC->DATA32;
return CRCValue;
}

View File

@ -0,0 +1,336 @@
#include "mik32_hal_crypto.h"
/**
* @brief Включение тактирования модуля Crypto.
* @note Эта weak функция может быть переопределена пользователем.
* @param hcrypto Указатель на структуру с настройками Crypto.
*/
__attribute__((weak)) void HAL_CRYPTO_MspInit(Crypto_HandleTypeDef* hcrypto)
{
__HAL_PCC_CRYPTO_CLK_ENABLE();
}
/**
* @brief Сброс счётчиков загружаемых/выгружаемых данных.
* @param hcrypto Указатель на структуру с настройками Crypto.
*/
void HAL_Crypto_CounterReset(Crypto_HandleTypeDef *hcrypto)
{
hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_C_RESET_M;
}
/**
* @brief Ожидать когда модуль станет доступен.
* @param hcrypto Указатель на структуру с настройками Crypto.
*/
void HAL_Crypto_WaitReady(Crypto_HandleTypeDef *hcrypto)
{
while (!(hcrypto->Instance->CONFIG & CRYPTO_CONFIG_READY_M));
}
/**
* @brief Задать алгоритм шифрования.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param Algorithm Алгоритм шифрования.
*/
void HAL_Crypto_SetAlgorithm(Crypto_HandleTypeDef *hcrypto, uint8_t Algorithm)
{
hcrypto->Algorithm = Algorithm;
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
ConfigTemp &= ~CRYPTO_CONFIG_CORE_SEL_M; /* Обнуление DECODE */
ConfigTemp |= Algorithm << CRYPTO_CONFIG_CORE_SEL_S;
hcrypto->Instance->CONFIG = ConfigTemp;
}
/**
* @brief Задать режим шифрования.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param CipherMode Режим шифрования.
*/
void HAL_Crypto_SetCipherMode(Crypto_HandleTypeDef *hcrypto, uint8_t CipherMode)
{
hcrypto->CipherMode = CipherMode;
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
ConfigTemp &= ~CRYPTO_CONFIG_MODE_SEL_M; /* Обнуление MODE_SEL */
ConfigTemp |= CipherMode << CRYPTO_CONFIG_MODE_SEL_S;
hcrypto->Instance->CONFIG = ConfigTemp;
}
/**
* @brief Задать режим перестановки слова.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param SwapMode Режим перестановки слова.
*/
void HAL_Crypto_SetSwapMode(Crypto_HandleTypeDef *hcrypto, uint8_t SwapMode)
{
hcrypto->SwapMode = SwapMode;
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
ConfigTemp &= ~CRYPTO_CONFIG_SWAP_MODE_M; /* Обнуление SWAP_MODE */
ConfigTemp |= SwapMode << CRYPTO_CONFIG_SWAP_MODE_S;
hcrypto->Instance->CONFIG = ConfigTemp;
}
/**
* @brief Задать порядок загрузки/выгрузки данных.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param OrderMode Порядок загрузки/выгрузки данных.
*/
void HAL_Crypto_SetOrderMode(Crypto_HandleTypeDef *hcrypto, uint8_t OrderMode)
{
hcrypto->OrderMode = OrderMode;
uint32_t ConfigTemp = hcrypto->Instance->CONFIG;
ConfigTemp &= ~CRYPTO_CONFIG_ORDER_MODE_M; /* Обнуление ORDER_MODE */
ConfigTemp |= OrderMode << CRYPTO_CONFIG_ORDER_MODE_S;
hcrypto->Instance->CONFIG = ConfigTemp;
}
/**
* @brief Задать вектор инициализации.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param InitVector Вектор инициализации (IV).
* @param IvLength Количество слов в InitVector.
*/
void HAL_Crypto_SetIV(Crypto_HandleTypeDef *hcrypto, uint32_t InitVector[], uint32_t IvLength)
{
for (uint32_t i = 0; i < IvLength; i++)
{
hcrypto->Instance->INIT = InitVector[i];
}
/* В режиме шифрования CTR длина вектора инициализации равна половине блока и такое же количество нулей */
if(hcrypto->CipherMode == CRYPTO_CIPHER_MODE_CTR)
{
for (uint32_t i = 0; i < IvLength; i++)
{
hcrypto->Instance->INIT = 0;
}
}
}
/**
* @brief Задать мастер-ключ.
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param crypto_key Ключ.
*
* @warning Ключ должен быть инициализирован в режиме шифрования (CONFIG.DECODE = 0).
*/
void HAL_Crypto_SetKey(Crypto_HandleTypeDef *hcrypto, uint32_t crypto_key[])
{
uint32_t key_length = 0;
switch (hcrypto->Algorithm)
{
case CRYPTO_ALG_KUZNECHIK:
key_length = CRYPTO_KEY_KUZNECHIK;
break;
case CRYPTO_ALG_MAGMA:
key_length = CRYPTO_KEY_MAGMA;
break;
case CRYPTO_ALG_AES:
key_length = CRYPTO_KEY_AES;
break;
}
/* Ключ должен быть инициализирован в режиме шифрования */
hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M;
for (uint32_t i = 0; i < key_length; i++)
{
hcrypto->Instance->KEY = crypto_key[i];
}
HAL_Crypto_WaitReady(hcrypto);
}
/**
* @brief Инициализировать Crypto в соответствии с настройками @ref Crypto_HandleTypeDef *hcrypto.
* @param hcrypto Указатель на структуру с настройками Crypto.
*/
void HAL_Crypto_Init(Crypto_HandleTypeDef *hcrypto)
{
HAL_CRYPTO_MspInit(hcrypto);
HAL_Crypto_SetAlgorithm(hcrypto, hcrypto->Algorithm); /* Настройка алгоритма шифрования */
HAL_Crypto_SetCipherMode(hcrypto, hcrypto->CipherMode); /* Настройка режима шифрования */
HAL_Crypto_SetSwapMode(hcrypto, hcrypto->SwapMode); /* Настройка перестановки слова */
HAL_Crypto_SetOrderMode(hcrypto, hcrypto->OrderMode); /* Настройка порядка загрузки/выгрузки */
#ifdef MIK32_CRYPTO_DEBUG
switch (hcrypto->Algorithm)
{
case CRYPTO_ALG_KUZNECHIK:
xprintf("KUZNECHIK- ");
break;
case CRYPTO_ALG_MAGMA:
xprintf("MAGMA - ");
break;
case CRYPTO_ALG_AES:
xprintf("AES - ");
break;
}
switch (hcrypto->CipherMode)
{
case CRYPTO_CIPHER_MODE_ECB:
xprintf("ECB\n");
break;
case CRYPTO_CIPHER_MODE_CBC:
xprintf("CBC\n");
break;
case CRYPTO_CIPHER_MODE_CTR:
xprintf("CTR\n");
break;
}
#endif
}
/**
* @brief Зашифровать текст.
*
* Зашифрованный текст передается в массив cipher_text.
*
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param plain_text Массив с данными незашифрованного текста.
* @param cipher_text Массив с данными для зашифрованного текста.
* @param text_length Количество слов в тексте.
*/
void HAL_Crypto_Encode(Crypto_HandleTypeDef *hcrypto, uint32_t plain_text[], uint32_t cipher_text[], uint32_t text_length)
{
uint8_t block_size = 0;
switch (hcrypto->Algorithm)
{
case CRYPTO_ALG_KUZNECHIK:
block_size = CRYPTO_BLOCK_KUZNECHIK;
break;
case CRYPTO_ALG_MAGMA:
block_size = CRYPTO_BLOCK_MAGMA;
break;
case CRYPTO_ALG_AES:
block_size = CRYPTO_BLOCK_AES;
break;
}
if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR) */)
{
#ifdef MIK32_CRYPTO_DEBUG
xprintf("Длина текста не кратна длине блока\n");
#endif
return;
}
/* Режим шифрования */
hcrypto->Instance->CONFIG &= ~CRYPTO_CONFIG_DECODE_M;
for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size)
{
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
{
if (word_index >= text_length)
{
break;
}
hcrypto->Instance->BLOCK = plain_text[word_index];
}
HAL_Crypto_WaitReady(hcrypto);
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
{
if (word_index >= text_length)
{
break;
}
cipher_text[word_index] = hcrypto->Instance->BLOCK;
}
}
}
/**
* @brief Расшифровать текст.
*
* Расшифрованный текст передается в массив plain_text.
*
* @param hcrypto Указатель на структуру с настройками Crypto.
* @param cipher_text Массив с данными зашифрованного текста.
* @param plain_text Массив с данными для незашифрованного текста.
* @param text_length Количество слов в тексте.
*/
void HAL_Crypto_Decode(Crypto_HandleTypeDef *hcrypto, uint32_t cipher_text[], uint32_t plain_text[], uint32_t text_length)
{
uint8_t block_size = 0;
switch (hcrypto->Algorithm)
{
case CRYPTO_ALG_KUZNECHIK:
block_size = CRYPTO_BLOCK_KUZNECHIK;
break;
case CRYPTO_ALG_MAGMA:
block_size = CRYPTO_BLOCK_MAGMA;
break;
case CRYPTO_ALG_AES:
block_size = CRYPTO_BLOCK_AES;
break;
}
if(((text_length % block_size) != 0)/* && (hcrypto->CipherMode != CRYPTO_CIPHER_MODE_CTR)*/)
{
#ifdef MIK32_CRYPTO_DEBUG
xprintf("Длина текста не кратна длине блока\n");
#endif
return;
}
/* Режим расшифровки */
hcrypto->Instance->CONFIG |= CRYPTO_CONFIG_DECODE_M;
for (volatile uint32_t block_index = 0; block_index < text_length; block_index += block_size)
{
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
{
if (word_index >= text_length)
{
break;
}
hcrypto->Instance->BLOCK = cipher_text[word_index];
}
HAL_Crypto_WaitReady(hcrypto);
for (volatile uint32_t word_index = block_index; word_index < (block_index + block_size); word_index++)
{
if (word_index >= text_length)
{
break;
}
plain_text[word_index] = hcrypto->Instance->BLOCK;
}
}
}

View File

@ -0,0 +1,125 @@
#include "mik32_hal_dac.h"
__attribute__((weak)) void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
if ((hdac->Init.EXTClb == DAC_EXTCLB_DACREF) && (hdac->Init.EXTRef == DAC_EXTREF_ON))
{
GPIO_InitStruct.Pin = GPIO_PIN_11;
}
GPIO_InitStruct.Mode = HAL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
if (hdac->Instance_dac == &(ANALOG_REG->DAC0))
{
GPIO_InitStruct.Pin = GPIO_PIN_12;
}
if (hdac->Instance_dac == &(ANALOG_REG->DAC1))
{
GPIO_InitStruct.Pin = GPIO_PIN_13;
}
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
}
void HAL_DAC_CLBEnable(DAC_HandleTypeDef *hdac)
{
hdac->Instance->REFV_CONFIG |= 1 << REF_CLB_EN_S;
}
void HAL_DAC_CLBDisable(DAC_HandleTypeDef *hdac)
{
hdac->Instance->REFV_CONFIG &= ~(1 << REF_CLB_EN_S);
}
void HAL_DAC_VCLBSet(DAC_HandleTypeDef *hdac, uint8_t v_coef)
{
hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_VCOEF_S);
hdac->Instance->REFV_CONFIG |= ((v_coef & 0xF) << REF_CLB_VCOEF_S);
}
void HAL_DAC_ICLBSet(DAC_HandleTypeDef *hdac, uint8_t i_coef)
{
hdac->Instance->REFV_CONFIG &= ~(0xF << REF_CLB_ICOEF_S);
hdac->Instance->REFV_CONFIG |= ((i_coef & 0xF) << REF_CLB_ICOEF_S);
}
void HAL_DAC_SetDiv(DAC_HandleTypeDef *hdac, uint8_t div)
{
//div &= ~(1<<7); // div должно быть 7-битным
hdac->Init.DIV = div;
uint32_t DAC_CFG = hdac->Instance_dac->CFG;
DAC_CFG &= ~DAC_CFG_DIV_M;
DAC_CFG |= DAC_CFG_DIV_M;
hdac->Instance_dac->CFG = DAC_CFG;
}
void HAL_DAC_ResetEnable(DAC_HandleTypeDef *hdac)
{
hdac->Instance_dac->CFG |= DAC_CFG_RESN_M;
}
void HAL_DAC_ResetDisable(DAC_HandleTypeDef *hdac)
{
hdac->Instance_dac->CFG &= ~DAC_CFG_RESN_M;
}
void HAL_DAC_Disable(DAC_HandleTypeDef *hdac)
{
hdac->Instance_dac->CFG &= ~DAC_CFG_EN18_M;
HAL_DAC_ResetDisable(hdac);
}
void HAL_DAC_Enable(DAC_HandleTypeDef *hdac)
{
hdac->Instance_dac->CFG |= DAC_CFG_EN18_M;
HAL_DAC_ResetEnable(hdac);
}
void HAL_DAC_Init(DAC_HandleTypeDef *hdac)
{
HAL_DAC_MspInit(hdac);
/* Очищение регистра настроек ЦАП */
hdac->Instance_dac->CFG = 0;
HAL_DAC_Enable(hdac);
/* Перевод вывода DAC_REF в аналоговый режим */
if((hdac->Init.EXTRef == DAC_EXTREF_ON) || (hdac->Init.EXTClb == DAC_EXTCLB_DACREF))
{
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC_REF_PORT_1_11);
}
/* Перевод вывода ЦАП в аналоговый режим */
if(hdac->Instance_dac == HAL_DAC1)
{
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC1_PORT_1_12);
}
if(hdac->Instance_dac == HAL_DAC2)
{
PAD_CONFIG->PORT_1_CFG |= (DAC_PORT_AS_FUNC3 << 2 * DAC2_PORT_1_13);
}
HAL_DAC_SetDiv(hdac, hdac->Init.DIV); /* Задание делителя */
hdac->Instance_dac->CFG |= (hdac->Init.EXTRef << DAC_CFG_EXTEN_S) | /* Настройка источника опорного напряжения */
(hdac->Init.EXTClb << DAC_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
}
void HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint16_t DAC_Value)
{
DAC_Value &= ~(0xF << 12);
hdac->Instance_dac->VALUE = DAC_Value;
}

View File

@ -0,0 +1,284 @@
#include "mik32_hal_dma.h"
/**
* @brief Данная переменная хранит последнее записанное значение в регистр CHx_CFG.
* @warning Не следует изменять значение данной переменной.
*/
static uint32_t CFGWriteBuffer[4] = {0};
/**
* @brief Данная переменная используется для хранения значения битовых полей CONFIG_STATUS[8:6].
* @warning Не следует изменять значение данной переменной.
*/
static uint32_t ConfigStatusWriteBuffer = 0;
/**
* @brief Включение тактирования модуля OTP.
*
* Эта функция может быть переопределена пользователем.
* @param hdma Указатель на структуру для инициализации DMA.
*/
__attribute__((weak)) void HAL_DMA_MspInit(DMA_InitTypeDef* hdma)
{
__HAL_PCC_DMA_CLK_ENABLE();
}
/**
* @brief Задать номер канала.
* @param hdma_channel Указатель на структуру для инициализации канала DMA.
* @param ChannelIndex Номер канала.
*/
void HAL_DMA_SetChannel(DMA_ChannelHandleTypeDef *hdma_channel, HAL_DMA_ChannelIndexTypeDef ChannelIndex)
{
hdma_channel->ChannelInit.Channel = ChannelIndex;
}
/**
* @brief Очистить все флаги локального прерывания.
* @param hdma Указатель на структуру для инициализации DMA.
*/
void HAL_DMA_ClearLocalIrq(DMA_InitTypeDef *hdma)
{
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_LOCAL_IRQ_M;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
}
/**
* @brief Очистить флаг глобального прерывания.
* @param hdma Указатель на структуру для инициализации DMA.
*/
void HAL_DMA_ClearGlobalIrq(DMA_InitTypeDef *hdma)
{
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_GLOBAL_IRQ_M;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
}
/**
* @brief Очистить флаг прерывания ошибки.
* @param hdma Указатель на структуру для инициализации DMA.
*/
void HAL_DMA_ClearErrorIrq(DMA_InitTypeDef *hdma)
{
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
ConfigStatusWriteBuffer |= DMA_CONFIG_CLEAR_ERROR_IRQ_M;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
ConfigStatusWriteBuffer &= ~(DMA_CONFIG_CLEAR_LOCAL_IRQ_M | DMA_CONFIG_CLEAR_GLOBAL_IRQ_M | DMA_CONFIG_CLEAR_ERROR_IRQ_M);
}
/**
* @brief Очистить все флаги прерываний.
*
* Очищаются флаги локальных прерываний, глобального прерывания, прерывания ошибки.
* @param hdma Указатель на структуру для инициализации DMA.
*/
void HAL_DMA_ClearIrq(DMA_InitTypeDef *hdma)
{
HAL_DMA_ClearLocalIrq(hdma);
HAL_DMA_ClearGlobalIrq(hdma);
HAL_DMA_ClearErrorIrq(hdma);
}
/**
* @brief Задать разрешение чтения текущего статуса канала.
*
* При значении #DMA_CURRENT_VALUE_ENABLE регистры CHx_DST, CHx_SRC, CHx_LEN возвращают текущие значения,
* а в CHx_CFG при считывании меняются битовые поля. При значении #DMA_CURRENT_VALUE_DISABLE регистры возвращают значения при настройке.
* @param hdma Указатель на структуру для инициализации DMA.
* @param CurrentValue Разрешение или запрет чтения текущего статуса канала.
*/
void HAL_DMA_SetCurrentValue(DMA_InitTypeDef *hdma, HAL_DMA_CurrentValueTypeDef CurrentValue)
{
hdma->CurrentValue = CurrentValue;
ConfigStatusWriteBuffer &= ~DMA_CONFIG_CURRENT_VALUE_M;
ConfigStatusWriteBuffer |= CurrentValue << DMA_CONFIG_CURRENT_VALUE_S;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
}
/**
* @brief Разрешить или запретить глобальное прерывание.
* @param hdma Указатель на структуру для инициализации DMA.
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
*/
void HAL_DMA_GlobalIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission)
{
ConfigStatusWriteBuffer &= ~DMA_CONFIG_GLOBAL_IRQ_ENA_M;
ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_GLOBAL_IRQ_ENA_S;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
}
/**
* @brief Разрешить или запретить прерывание ошибки.
* @param hdma Указатель на структуру для инициализации DMA.
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
*/
void HAL_DMA_ErrorIRQEnable(DMA_InitTypeDef *hdma, HAL_DMA_IRQTypeDef Permission)
{
ConfigStatusWriteBuffer &= ~DMA_CONFIG_ERROR_IRQ_ENA_M;
ConfigStatusWriteBuffer |= Permission << DMA_CONFIG_ERROR_IRQ_ENA_S;
hdma->Instance->CONFIG_STATUS = ConfigStatusWriteBuffer;
}
/**
* @brief Разрешить или запретить локальное прерывание.
*
* Прерывание формируется, когда канал завершил задачу.
* @param hdma_channel Структура для инициализации канала DMA.
* @param Permission Разрешение (#DMA_IRQ_ENABLE) или запрет (#DMA_IRQ_DISABLE) прерывания.
*/
void HAL_DMA_LocalIRQEnable(DMA_ChannelHandleTypeDef* hdma_channel, HAL_DMA_IRQTypeDef Permission)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
CFGWriteBuffer[ChannelIndex] &= ~DMA_CH_CFG_IRQ_EN_M;
CFGWriteBuffer[ChannelIndex] |= Permission << DMA_CH_CFG_IRQ_EN_S;
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
}
/**
* @brief Инициализация DMA в соответствии с настройками структуры hdma.
* @param hdma Указатель на структуру для инициализации DMA.
* @return Статус функции после её выполнения (HAL Status).
*/
HAL_StatusTypeDef HAL_DMA_Init(DMA_InitTypeDef *hdma)
{
if (hdma == NULL)
{
return HAL_ERROR;
}
HAL_DMA_MspInit(hdma);
ConfigStatusWriteBuffer = 0;
HAL_DMA_ClearIrq(hdma);
HAL_DMA_SetCurrentValue(hdma, hdma->CurrentValue);
return HAL_OK;
}
/**
* @brief Ожидание готовности канала.
* @param hdma_channel Структура для инициализации канала DMA.
* @param Timeout Количество циклов ожидания. Стандартное значение #DMA_TIMEOUT_DEFAULT.
* @return Статус функции после её выполнения (HAL Status).
*/
HAL_StatusTypeDef HAL_DMA_Wait(DMA_ChannelHandleTypeDef* hdma_channel, uint32_t Timeout)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
uint32_t mask = (1 << ChannelIndex) << DMA_STATUS_READY_S;
while (Timeout-- != 0)
{
if ((hdma_channel->dma->Instance->CONFIG_STATUS & mask) != 0)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
/**
* @brief Получить статус готовности канала.
* @param hdma_channel Структура для инициализации канала DMA.
* @return Статус готовности канала. 0 - канал занят, 1 - канал готов к работе.
*/
int HAL_DMA_GetChannelReadyStatus(DMA_ChannelHandleTypeDef* hdma_channel)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
uint32_t status = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_READY_S));
status = (status >> DMA_STATUS_READY_S ) >> ChannelIndex;
return status;
}
/**
* @brief Получить статус локального прерывания канала.
* @param hdma_channel Структура для инициализации канала DMA.
* @return Статус локального прерывания канала. 0 - прерывания нет, 1 - прерывание есть.
*/
int HAL_DMA_GetChannelIrq(DMA_ChannelHandleTypeDef* hdma_channel)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
uint32_t ChannelIrq = (hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_IRQ_S);
ChannelIrq = ( ChannelIrq >> DMA_STATUS_CHANNEL_IRQ_S ) >> ChannelIndex;
return ChannelIrq;
}
/**
* @brief Получить статус состояния канала при ошибках на шине.
* @param hdma_channel Структура для инициализации канала DMA.
* @return Статус состояния канала при ошибках на шине. 0 - нет ошибки, 1 - есть ошибка.
*/
int HAL_DMA_GetBusError(DMA_ChannelHandleTypeDef* hdma_channel)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
uint32_t BusError = ((hdma_channel->dma->Instance->CONFIG_STATUS) & ((1 << ChannelIndex) << DMA_STATUS_CHANNEL_BUS_ERROR_S));
BusError = ( BusError >> DMA_STATUS_CHANNEL_BUS_ERROR_S ) >> ChannelIndex;
return BusError;
}
/**
* @brief Принудительная остановка работы канала.
* @param hdma_channel Структура для инициализации канала DMA.
*/
void HAL_DMA_ChannelDisable(DMA_ChannelHandleTypeDef *hdma_channel)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
CFGWriteBuffer[ChannelIndex] &= ~(DMA_CH_CFG_ENABLE_M);
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
}
/**
* @brief Инициализация работы канала.
* @param hdma_channel Структура для инициализации канала DMA.
*/
void HAL_DMA_ChannelEnable(DMA_ChannelHandleTypeDef *hdma_channel)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M;
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
}
/**
* @brief Запуск работы канала с настройками из структуры hdma_channel.
* @param hdma_channel Структура для инициализации канала DMA.
* @param SRC Адрес источника.
* @param DST Адрес назначения
* @param Len Количество байт пересылки. Значение следует записывать на 1 меньше числа пересылаемых байт.
* Например, для отправки 8 байт значение Len = 7.
*/
void HAL_DMA_Start(DMA_ChannelHandleTypeDef *hdma_channel, void* SRC, void* DST, uint32_t Len)
{
uint32_t ChannelIndex = hdma_channel->ChannelInit.Channel;
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].SRC = (uint32_t) SRC;
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].DST = (uint32_t) DST;
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].LEN = Len;
CFGWriteBuffer[ChannelIndex] |= DMA_CH_CFG_ENABLE_M
| (hdma_channel->ChannelInit.Priority << DMA_CH_CFG_PRIOR_S)
| (hdma_channel->ChannelInit.ReadMode << DMA_CH_CFG_READ_MODE_S)
| (hdma_channel->ChannelInit.ReadInc << DMA_CH_CFG_READ_INCREMENT_S)
| (hdma_channel->ChannelInit.ReadSize << DMA_CH_CFG_READ_SIZE_S)
| (hdma_channel->ChannelInit.ReadBurstSize << DMA_CH_CFG_READ_BURST_SIZE_S)
| (hdma_channel->ChannelInit.ReadRequest << DMA_CH_CFG_READ_REQUETS_S)
| (hdma_channel->ChannelInit.ReadAck << DMA_CH_CFG_READ_ACK_EN_S)
| (hdma_channel->ChannelInit.WriteMode << DMA_CH_CFG_WRITE_MODE_S)
| (hdma_channel->ChannelInit.WriteInc << DMA_CH_CFG_WRITE_INCREMENT_S)
| (hdma_channel->ChannelInit.WriteSize << DMA_CH_CFG_WRITE_SIZE_S)
| (hdma_channel->ChannelInit.WriteBurstSize << DMA_CH_CFG_WRITE_BURST_SIZE_S)
| (hdma_channel->ChannelInit.WriteRequest << DMA_CH_CFG_WRITE_REQUETS_S)
| (hdma_channel->ChannelInit.WriteAck << DMA_CH_CFG_WRITE_ACK_EN_S);
hdma_channel->dma->Instance->CHANNELS[ChannelIndex].CFG = CFGWriteBuffer[ChannelIndex];
}

View File

@ -0,0 +1,197 @@
#include "mik32_hal_eeprom.h"
const uint8_t N_LD_DEFAULT = 1;
const uint8_t N_R_2_DEFAULT = 1;
HAL_StatusTypeDef HAL_EEPROM_Init(HAL_EEPROM_HandleTypeDef *eeprom)
{
if (eeprom->Instance != EEPROM_REGS)
{
return HAL_ERROR;
}
eeprom->Instance->EECON = 0;
HAL_EEPROM_SetMode(eeprom, eeprom->Mode);
HAL_EEPROM_SetErrorCorrection(eeprom, eeprom->ErrorCorrection);
HAL_EEPROM_SetInterrupt(eeprom, eeprom->EnableInterrupt);
return HAL_OK;
}
HAL_StatusTypeDef HAL_EEPROM_Erase(
HAL_EEPROM_HandleTypeDef *eeprom,
uint16_t address,
uint8_t erasedWordsCount,
HAL_EEPROM_WriteBehaviourTypeDef erasedPages,
uint32_t timeout)
{
eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (erasedPages << EEPROM_EECON_WRBEH_S);
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
{
eeprom->Instance->EEA = address;
for (int i = 0; i < erasedWordsCount; i++)
{
eeprom->Instance->EEDAT = 0;
}
}
else
{
HAL_StatusTypeDef status = HAL_OK;
for (int i = 0; i < erasedWordsCount; i++)
{
eeprom->Instance->EEA = address + i * 4;
eeprom->Instance->EEDAT = 0;
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
return status;
}
}
eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_ER) | EEPROM_EECON_EX_M;
return HAL_EEPROM_WaitBusy(eeprom, timeout);
}
HAL_StatusTypeDef HAL_EEPROM_Write(
HAL_EEPROM_HandleTypeDef *eeprom,
uint16_t address,
uint32_t *data,
uint8_t length,
HAL_EEPROM_WriteBehaviourTypeDef writedPages,
uint32_t timeout)
{
eeprom->Instance->EECON |= EEPROM_EECON_BWE_M | (writedPages << EEPROM_EECON_WRBEH_S);
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
{
eeprom->Instance->EEA = address;
for (int i = 0; i < length; i++)
{
eeprom->Instance->EEDAT = data[i];
}
}
else
{
HAL_StatusTypeDef status = HAL_OK;
for (int i = 0; i < length; i++)
{
eeprom->Instance->EEA = address + i * 4;
eeprom->Instance->EEDAT = data[i];
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
return status;
}
}
eeprom->Instance->EECON |= EEPROM_EECON_OP(EEPROM_EECON_OP_PR) | EEPROM_EECON_EX_M;
return HAL_EEPROM_WaitBusy(eeprom, timeout);
}
HAL_StatusTypeDef HAL_EEPROM_Read(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint32_t *data, uint8_t length, uint32_t timeout)
{
HAL_StatusTypeDef status = HAL_OK;
if (eeprom->Mode == HAL_EEPROM_MODE_TWO_STAGE)
{
eeprom->Instance->EEA = address;
for (uint32_t i = 0; i < length; i++)
{
data[i] = eeprom->Instance->EEDAT;
}
}
else
{
for (uint32_t i = 0; i < length; i++)
{
eeprom->Instance->EEA = address + i * 4;
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
return status;
data[i] = eeprom->Instance->EEDAT;
}
}
return status;
}
void HAL_EEPROM_SetMode(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ModeTypeDef mode)
{
eeprom->Mode = mode;
if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE)
{
eeprom->Instance->EECON |= EEPROM_EECON_APBNWS_M;
}
else
{
eeprom->Instance->EECON &= ~EEPROM_EECON_APBNWS_M;
}
}
void HAL_EEPROM_SetErrorCorrection(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_ErrorCorrectionTypeDef errorCorrection)
{
eeprom->ErrorCorrection = errorCorrection;
if (eeprom->ErrorCorrection == HAL_EEPROM_ECC_DISABLE)
{
eeprom->Instance->EECON |= EEPROM_EECON_DISECC_M;
}
else
{
eeprom->Instance->EECON &= ~EEPROM_EECON_DISECC_M;
}
}
void HAL_EEPROM_SetInterrupt(HAL_EEPROM_HandleTypeDef *eeprom, HAL_EEPROM_EnableInterruptTypeDef enableInterrupt)
{
eeprom->EnableInterrupt = enableInterrupt;
if (eeprom->EnableInterrupt == HAL_EEPROM_SERR_ENABLE)
{
eeprom->Instance->EECON |= EEPROM_EECON_IESERR_M;
}
else
{
eeprom->Instance->EECON &= ~EEPROM_EECON_IESERR_M;
}
}
const int32_t N_EP_1_denominator = 1000 * 1000 * 1000 / (2 * 1000 * 1000);
const int32_t N_EP_2_reduce = 5 * 1000;
const int32_t N_EP_2_numerator = 15 * 1000 / N_EP_2_reduce;
const int32_t N_EP_2_denominator = 1000 * 1000 * 1000 / N_EP_2_reduce;
void HAL_EEPROM_CalculateTimings(HAL_EEPROM_HandleTypeDef *eeprom, int32_t frequency)
{
eeprom->Timings.N_LD = N_LD_DEFAULT;
eeprom->Timings.N_R_2 = N_R_2_DEFAULT;
eeprom->Timings.N_EP_1 = frequency / N_EP_1_denominator;
eeprom->Timings.N_EP_2 = (frequency * N_EP_2_numerator) / N_EP_2_denominator;
int32_t n_r_1_step_1 = (frequency / 1000) * 51;
int32_t n_r_1_step_2 = n_r_1_step_1 / (1000 * 1000);
if ((n_r_1_step_1 % (1000 * 1000)) != 0)
{
n_r_1_step_2 += 1;
}
eeprom->Timings.N_R_1 = n_r_1_step_2;
}
HAL_StatusTypeDef HAL_EEPROM_GetECC(HAL_EEPROM_HandleTypeDef *eeprom, uint16_t address, uint8_t *buf_value_ecc, uint32_t timeout)
{
HAL_StatusTypeDef status = HAL_OK;
eeprom->Instance->EEA = address;
if (eeprom->Mode == HAL_EEPROM_MODE_THREE_STAGE)
{
if ((status = HAL_EEPROM_WaitBusy(eeprom, timeout)) != HAL_OK)
return status;
}
*buf_value_ecc = eeprom->Instance->EERB;
return status;
}

View File

@ -0,0 +1,260 @@
#include "mik32_hal_gpio.h"
/** Для обхода бага МК, чтение из регистра IRQ_LINE_MUX всегда возвращает 0
* \note Используется в функциях HAL_GPIO_InitInterruptLine и HAL_GPIO_DeInitInterruptLine
*/
volatile uint32_t current_irq_line_mux = 0;
/**
* @brief Инициализация модуля GPIO_x в соответствии с указанными параметрами в GPIO_Init.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param GPIO_Init указатель на структуру GPIO_InitTypeDef, которая содержит информацию о конфигурации для указанного модуля GPIO.
* @return статус HAL.
* @warning функция не включает тактирование выбранного модуля GPIO. Включить тактирование можно, например, с помощью макроса @ref __HAL_PCC_GPIO_2_CLK_ENABLE.
*/
HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init)
{
uint32_t *port_cfg = 0;
uint32_t *port_ds = 0;
uint32_t *port_pupd = 0;
uint32_t position = 0;
uint32_t current_pin = 0;
switch ((uint32_t)GPIO_x)
{
case (uint32_t)GPIO_0:
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_0_CFG);
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_0_DS);
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_0_PUPD);
break;
case (uint32_t)GPIO_1:
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_1_CFG);
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_1_DS);
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_1_PUPD);
break;
case (uint32_t)GPIO_2:
port_cfg = (uint32_t *)&(PAD_CONFIG->PORT_2_CFG);
port_ds = (uint32_t *)&(PAD_CONFIG->PORT_2_DS);
port_pupd = (uint32_t *)&(PAD_CONFIG->PORT_2_PUPD);
break;
default:
return HAL_ERROR;
break;
}
// magic_foo(pinMask, port_cfg, port_pupd, port_ds)
while (((GPIO_Init->Pin) >> position) != 0)
{
current_pin = GPIO_Init->Pin & (1 << position);
if (current_pin)
{
*port_cfg = (*port_cfg & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Mode & 0b11);
if ((GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT) || (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_OUTPUT))
{
if (GPIO_Init->Mode == HAL_GPIO_MODE_GPIO_INPUT)
{
GPIO_x->DIRECTION_IN = 1 << position;
}
else
{
GPIO_x->DIRECTION_OUT = 1 << position;
}
}
*port_ds = (*port_ds & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->DS);
*port_pupd = (*port_pupd & (~PAD_CONFIG_PIN_M(position))) | PAD_CONFIG_PIN(position, GPIO_Init->Pull);
}
position++;
}
return HAL_OK;
}
/**
* @brief Инициализация модуля GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
* @param mode режим вывода.
* @param pull режим подтяжки вывода.
* @param driveStrength перечисление режимов нагрузочной способности.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = pin;
GPIO_InitStruct.Mode = mode;
GPIO_InitStruct.Pull = pull;
GPIO_InitStruct.DS = driveStrength;
return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct);
}
/**
* @brief Считать текущее состояние выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, с которых считывание значение.
* @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW.
*/
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
GPIO_PinState bitStatus;
if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW)
{
bitStatus = GPIO_PIN_HIGH;
}
else
{
bitStatus = GPIO_PIN_LOW;
}
return bitStatus;
}
/**
* @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
* @param pinState значение состояние вывода, в которое будут установлены указанные выводы.
* Этот параметр должен быть одним из значений:
* - @ref GPIO_PIN_LOW низкий выходной уровень
* - @ref GPIO_PIN_HIGH высокий выходной уровень
*/
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState)
{
if (pinState == GPIO_PIN_LOW)
{
GPIO_x->CLEAR = pin;
}
else
{
GPIO_x->SET = pin;
}
}
/**
* @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
*/
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
GPIO_x->OUTPUT_ ^= pin;
}
/**
* @brief Функция инициализации линии прерывания.
* \param mux настройка мультиплексора линии прерывания.
* \param mode режим линии прерывания.
* @return Статус HAL.
* \note Номер линии прерывания можно получить после настройки мультиплексора.
* Введите в mux GPIO_MUX_GPIO_X_X, где X - номера порта и вывода,
* и нажмите Ctrl+Пробел: появятся варианты констант для данного вывода,
* далее достаточно выбрать константу для доступной линии.
* В mode введите GPIO_INT_MODE и нажмите Ctrl+Пробел: появятся варианты типов прерываний канала.
*/
HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode)
{
int irq_line_num = mux >> GPIO_IRQ_LINE_S;
mode &= 0b111;
if (irq_line_num > 7)
return HAL_ERROR;
current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num);
current_irq_line_mux |= GPIO_IRQ_LINE_MUX(mux, irq_line_num);
GPIO_IRQ->LINE_MUX = current_irq_line_mux;
if (mode & GPIO_MODE_BIT_LEVEL_M) // GPIO_INT_MODE_HIGH, GPIO_INT_MODE_RISING
{
GPIO_IRQ->LEVEL_SET = (1 << irq_line_num); // нарастающий фронт или логический уровень 1
}
else
{
GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num); // спадающий фронт или логический уровень 0
}
if (mode & GPIO_MODE_BIT_EDGE_M) // GPIO_INT_MODE_FALLING, GPIO_INT_MODE_RISING, GPIO_INT_MODE_CHANGE
{
GPIO_IRQ->EDGE = (1 << irq_line_num); // тип прерывания - событие (фронт/спад)
}
else
{
GPIO_IRQ->LEVEL = (1 << irq_line_num); // тип прерывания - логический уровень
}
if (mode & GPIO_MODE_BIT_ANYEDGE_M) // GPIO_INT_MODE_CHANGE
{
GPIO_IRQ->ANY_EDGE_SET = (1 << irq_line_num); // разрешено прерывание по любому фронту
}
else
{
GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num); // запрещено прерывание по любому фронту
}
GPIO_IRQ->ENABLE_SET = (1 << irq_line_num);
return HAL_OK;
}
/**
* @brief Функция деинициализации линии прерывания, запрещает прерывание и возвращает настройки по умолчанию для указанной лини.
* @param irqLine номер линии прерывания.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
if (irq_line_num > 7)
return HAL_ERROR;
GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num);
current_irq_line_mux &= ~GPIO_IRQ_LINE_MUX_M(irq_line_num);
GPIO_IRQ->LINE_MUX = current_irq_line_mux;
GPIO_IRQ->LEVEL = (1 << irq_line_num);
GPIO_IRQ->LEVEL_CLEAR = (1 << irq_line_num);
GPIO_IRQ->ANY_EDGE_CLEAR = (1 << irq_line_num);
return HAL_OK;
}
/**
* @brief Получить состояние линии прерывания.
* @param irqLine номер линии прерывания.
* @return Возвращает 1 если сработало прерывание данной линии, иначе 0.
*/
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0;
}
/**
* @brief Функция чтения логического уровня вывода, подключенного к линии прерывания.
* @param irqLine номер линии прерывания.
* @return Логический уровень вывода.
*/
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num);
}
/**
* @brief Функция сброса регистра состояния прерываний.
* @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT
* выставляется 1 в разряде, соответствующем линии прерывания.
* После обработки прерывания необходимо сбросить данный регистр
* в обработчике прерывания trap_handler().
* Если после обработки прерывания регистр не был сброшен,
* обработчик будет вызван снова, программа будет бесконечно вызывать обработчик.
*/
void HAL_GPIO_ClearInterrupts()
{
GPIO_IRQ->CLEAR = 0b11111111;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
#include "mik32_hal_irq.h"
// #define MIK32_IRQ_DEBUG
void HAL_IRQ_EnableInterrupts()
{
set_csr(mstatus, MSTATUS_MIE);
set_csr(mie, MIE_MEIE);
}
void HAL_IRQ_DisableInterrupts()
{
clear_csr(mie, MIE_MEIE);
}
void HAL_EPIC_MaskEdgeSet(uint32_t InterruptMask)
{
EPIC->MASK_EDGE_SET |= InterruptMask;
}
void HAL_EPIC_MaskEdgeClear(uint32_t InterruptMask)
{
EPIC->MASK_EDGE_CLEAR |= InterruptMask;
}
void HAL_EPIC_MaskLevelSet(uint32_t InterruptMask)
{
EPIC->MASK_LEVEL_SET |= InterruptMask;
}
void HAL_EPIC_MaskLevelClear(uint32_t InterruptMask)
{
EPIC->MASK_LEVEL_CLEAR |= InterruptMask;
}
uint32_t HAL_EPIC_GetStatus()
{
return EPIC->STATUS;
}
uint32_t HAL_EPIC_GetRawStatus()
{
return EPIC->RAW_STATUS;
}

View File

@ -0,0 +1,388 @@
#include "mik32_hal_otp.h"
#include "mik32_hal.h"
/**
* @brief Включение тактирования модуля OTP.
*
* Эта функция может быть переопределена пользователем.
*
* @param hotp Указатель на структуру с настройками OTP.
*/
__attribute__((weak)) void HAL_OTP_MspInit(OTP_HandleTypeDef* hotp)
{
__HAL_PCC_OTP_CONTROLLER_CLK_ENABLE();
}
/**
* @brief Включить/выключить режим пониженного энергопотребления.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param PowerOff Режим пониженного энергопотребления.
*/
void HAL_OTP_PowerOff(OTP_HandleTypeDef *hotp, uint8_t PowerOff)
{
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
OtpadjConfig &= ~OTP_OTPADJ_POWER_OFF_I_M;
OtpadjConfig |= PowerOff << OTP_OTPADJ_POWER_OFF_I_S;
hotp->Instance->OTPADJ = OtpadjConfig;
/* После выхода из режима пониженного энергопотребления необходимо выдержать паузу */
for (volatile int i = 0; i < 1000; i++);
}
/**
* @brief Задать напряжение на UPP матрице.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param UppReadVoltage Напряжение на UPP матрице.
*/
void HAL_OTP_SetUppRead(OTP_HandleTypeDef *hotp, uint8_t UppReadVoltage)
{
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
OtpadjConfig &= ~OTP_OTPADJ_SEL_UPP_READ_I_M;
OtpadjConfig |= UppReadVoltage << OTP_OTPADJ_SEL_UPP_READ_I_S;
hotp->Instance->OTPADJ = OtpadjConfig;
}
/**
* @brief Задать ток считывания.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param ReadCur Ток считывания.
*/
void HAL_OTP_SetReadCur(OTP_HandleTypeDef *hotp, uint8_t ReadCur)
{
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
OtpadjConfig &= ~OTP_OTPADJ_SEL_READ_CUR_I_M;
OtpadjConfig |= ReadCur << OTP_OTPADJ_SEL_READ_CUR_I_S;
hotp->Instance->OTPADJ = OtpadjConfig;
}
/**
* @brief Инициализация рекомендуемых временных интервалов.
*
* @param hotp Указатель на структуру с настройками OTP.
*/
void HAL_OPT_TimeInit(OTP_HandleTypeDef *hotp)
{
uint8_t APBMDivider = PM->DIV_APB_M;
uint8_t AHBDivider = PM->DIV_AHB;
uint32_t OscillatorSystem = PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M;
uint32_t OtpadjConfig = hotp->Instance->OTPADJ;
uint32_t otpwt1_config = hotp->Instance->OTPWT1;
uint32_t otpwt2_config = hotp->Instance->OTPWT2;
/* Рекомендуемое значение для N_RA, N_RH, N_SU, N_H. ceil(40/Period), где Period в нс */
uint32_t Div = 0;
/* Тактирование от 32МГц */
if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M))
{
Div = 1000;
}
/* Тактирование от 32кГц */
if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M))
{
Div = 1000000;
}
uint32_t recommended_value = 0;
if((40 * 32) % (((APBMDivider + 1) * (AHBDivider + 1)) * Div) == 0)
{
recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div);
}
else
{
recommended_value = (40 * 32) / (((APBMDivider + 1) * (AHBDivider + 1)) * Div) + 1;
}
/* Рекомендуемое значение N_W = 50 000 000 нс / Pclk, где Pclk период тактового сигнала в нс */
uint32_t recommended_N_W = 0;
if((OscillatorSystem == PM_AHB_CLK_MUX_HSI32M_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32M_M))
{
recommended_N_W = (5 * 32 * 10000) / ((APBMDivider + 1) * (AHBDivider + 1));
}
/* Тактирование от 32кГц */
if((OscillatorSystem == PM_AHB_CLK_MUX_LSI32K_M) || (OscillatorSystem == PM_AHB_CLK_MUX_OSC32K_M))
{
recommended_N_W = (5 * 32 * 10) / ((APBMDivider + 1) * (AHBDivider + 1));
}
OtpadjConfig &= ~OTP_OTPADJ_N_RSU_M; /* При частоте менее 200МГц рекомендуемое значение 0 */
OtpadjConfig &= ~OTP_OTPADJ_N_RA_M;
OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RA_S;
OtpadjConfig &= ~OTP_OTPADJ_N_RH_M;
OtpadjConfig |= recommended_value << OTP_OTPADJ_N_RH_S;
otpwt1_config &= ~OTP_OTPWT1_N_SU_M;
otpwt1_config |= recommended_value << OTP_OTPWT1_N_SU_S;
otpwt1_config &= ~OTP_OTPWT1_N_H_M;
otpwt1_config |= recommended_value << OTP_OTPWT1_N_H_S;
otpwt2_config &= ~OTP_OTPWT2_N_W_M;
otpwt2_config |= recommended_N_W << OTP_OTPWT2_N_W_S;
hotp->Instance->OTPADJ = OtpadjConfig;
hotp->Instance->OTPWT1 = otpwt1_config;
hotp->Instance->OTPWT2 = otpwt2_config;
}
/**
* @brief
*
* @param hotp Указатель на структуру с настройками OTP.
* @param ReadMode Режим чтения
*/
void HAL_OPT_SetReadMode(OTP_HandleTypeDef *hotp, uint8_t ReadMode)
{
uint32_t OtpconConfig = hotp->Instance->OTPCON;
OtpconConfig &= ~OTP_OTPCON_APBNWS_M;
OtpconConfig |= ReadMode << OTP_OTPCON_APBNWS_S;
hotp->Instance->OTPCON = OtpconConfig;
hotp->ReadMode = ReadMode;
}
/**
* @brief Инициализировать OTP.
*
* @param hotp Указатель на структуру с настройками OTP.
*/
void HAL_OTP_Init(OTP_HandleTypeDef *hotp)
{
HAL_OTP_MspInit(hotp);
// /* Настройка временных ограничений */
HAL_OPT_TimeInit(hotp);
// /* Выбор напряжения на UPP матрицы */
HAL_OTP_SetUppRead(hotp, OTP_UPP_READ_2_5V);
/* Режим чтения */
HAL_OPT_SetReadMode(hotp, hotp->ReadMode);
}
/**
* @brief Ожидать сброса флага BSY.
*
* Флаг BSY = 1 - Блок занят (выполняется запрошенная операция).
* Используется при операции записи и чтении в 3 этапа.
*
* @param hotp Указатель на структуру с настройками OTP.
*/
void HAL_OTP_WaitBSY(OTP_HandleTypeDef *hotp)
{
/* Опрос флага BSY пока он не станет очищен */
while (hotp->Instance->OTPSTA & OTP_OTPSTA_BSY_M);
}
/**
* @brief Записать массив данных в тестовый столбец.
*
* @warning Если в массиве Data количество бит больше размера столбца, начиная с Address, то запись продолжится с начала столбца.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7.
* @param Data Данные для записи в тестовый столбец.
* @param DataLength Размер массива Data.
*/
void HAL_OTP_WriteTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength)
{
/* OTPA[4:3] = 10b - тестовый столбец OTP */
hotp->Instance->OTPA = 0b10000 + (Address & 0b111);
for (uint32_t i = 0; i < DataLength; i++)
{
hotp->Instance->OTPDAT = Data[i];
HAL_OTP_WaitBSY(hotp);
}
}
/**
* @brief Записать данные в тестовую строку.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param Data Данные для записи в тестовую строку.
*/
void HAL_OTP_WriteTestRow(OTP_HandleTypeDef *hotp, uint32_t Data)
{
/* OTPA[4:3] = 01b - тестовая строка OTP */
hotp->Instance->OTPA = 0b01000;
hotp->Instance->OTPDAT = Data;
HAL_OTP_WaitBSY(hotp);
}
/**
* @brief Записать бит в тестовую ячейку.
*
* @param hotp Указатель на структуру с настройками OTP.
* @param Data Бит для записи в тестовую ячейку.
*/
void HAL_OTP_WriteTestBit(OTP_HandleTypeDef *hotp, uint32_t Data)
{
/* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */
hotp->Instance->OTPA = 0b11000;
hotp->Instance->OTPDAT = Data;
HAL_OTP_WaitBSY(hotp);
}
/**
* @brief Записать данные в основной массив OTP.
* @param hotp Указатель на структуру с настройками OTP.
* @param Address Начальная строка. Значение может быть в пределах от 0 до 7.
* @param Data Данные для записи в основной массив OTP.
* @param DataLength Размер массива Data.
*/
void HAL_OTP_Write(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t Data[], uint32_t DataLength)
{
/* OTPA[4:3] = 00b - основной массив OTP */
hotp->Instance->OTPA = 0b00000 + (Address & 0b111);
for (uint32_t i = 0; i < DataLength; i++)
{
hotp->Instance->OTPDAT = Data[i];
HAL_OTP_WaitBSY(hotp);
}
}
/**
* @brief Прочитать данные из тестового столбца.
* @param hotp Указатель на структуру с настройками OTP.
* @param Address Начальная ячейка столбца. Значение может быть в пределах от 0 до 7.
* @param DataRead Массив для считывания данных тестового столбца.
* @param DataLength Размер массива DataRead.
*/
void HAL_OTP_ReadTestColumn(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength)
{
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
{
/* OTPA[4:3] = 10b - тестовый столбец OTP */
uint8_t address_mask = 0b00111;
uint8_t address_column_mask = (1 << 4);
for (uint32_t i = 0; i < DataLength; i++)
{
hotp->Instance->OTPA = ((Address + i) & address_mask) | address_column_mask;
HAL_OTP_WaitBSY(hotp);
DataRead[i] = hotp->Instance->OTPDAT;
}
}
else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */
{
/* OTPA[4:3] = 10b - тестовый столбец OTP */
uint8_t address_column = 0b10000 + (Address & 0b111);
hotp->Instance->OTPA = address_column;
DataRead[0] = hotp->Instance->OTPDAT;
for (uint32_t i = 0; i < DataLength; i++)
{
DataRead[i] = hotp->Instance->OTPDAT;
}
}
}
/**
* @brief Прочитать данные из тестовой строки.
* @param hotp Указатель на структуру с настройками OTP.
* @return Тестовая строка.
*/
uint32_t HAL_OTP_ReadTestRow(OTP_HandleTypeDef *hotp)
{
uint32_t DataRead = 0;
/* OTPA[4:3] = 01b - тестовая строка OTP */
hotp->Instance->OTPA = 0b01000;
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
{
HAL_OTP_WaitBSY(hotp);
}
else
{
DataRead = hotp->Instance->OTPDAT;
}
DataRead = hotp->Instance->OTPDAT;
return DataRead;
}
/**
* @brief Прочитать бит из тестовой ячейки.
* @param hotp hotp - Указатель на структуру с настройками OTP.
* @return Бит из тестовой ячейки.
*/
uint32_t HAL_OTP_ReadTestBit(OTP_HandleTypeDef *hotp)
{
uint32_t DataRead = 0;
/* OTPA[4:3] = 11b - последняя тестовая ячейка в тестовой строке */
hotp->Instance->OTPA = 0b11000;
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
{
HAL_OTP_WaitBSY(hotp);
}
else
{
DataRead = hotp->Instance->OTPDAT;
}
DataRead = hotp->Instance->OTPDAT;
return DataRead;
}
/**
* @brief Прочитать данные из основного массива OTP.
* @param hotp Указатель на структуру с настройками OTP.
* @param Address Начальная строка основного массива OTP. Значение может быть в пределах от 0 до 7.
* @param DataRead Массив для считывания данных основного массива OTP.
* @param DataLength Размер массива DataRead.
*/
void HAL_OTP_Read(OTP_HandleTypeDef *hotp, uint8_t Address, uint32_t DataRead[], uint32_t DataLength)
{
if (hotp->ReadMode == OPT_READ_3STAGES) /* Чтение в 3 этапа. Без вставки тактов ожидания. С опросом BSY. Без автоинкрементирования адреса OTPA */
{
/* OTPA[4:3] = 00b - основной массив OTP */
uint8_t address_mask = 0b00111;
for (uint32_t i = 0; i < DataLength; i++)
{
hotp->Instance->OTPA = (Address + i) & address_mask;
HAL_OTP_WaitBSY(hotp);
DataRead[i] = hotp->Instance->OTPDAT;
}
}
else /* Чтение в 2 этапа. Со вставкой тактов ожидания. Без опроса BSY. С автоинкрементированием адреса OTPA. */
{
/* OTPA[4:3] = 00b - основной массив OTP */
hotp->Instance->OTPA = 0b00000 + (Address & 0b111);
DataRead[0] = hotp->Instance->OTPDAT;
for (uint32_t i = 0; i < DataLength; i++)
{
DataRead[i] = hotp->Instance->OTPDAT;
}
}
}

View File

@ -0,0 +1,399 @@
#include "mik32_hal_pcc.h"
/**
* @brief Включить источник тактирования.
* @param Oscillator Источник тактирования для включения.
* @warning Аргумент функции не является маской.
*
*/
void HAL_PCC_OscEnable(HAL_PCC_OscillatorTypeTypeDef Oscillator)
{
switch (Oscillator)
{
case PCC_OSCILLATORTYPE_HSI32M:
WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Включить HSI32M
break;
case PCC_OSCILLATORTYPE_OSC32M:
WU->CLOCKS_SYS &= ~(1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M
break;
case PCC_OSCILLATORTYPE_LSI32K:
WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_LSI32K_EN_S); // Включить LSI32K
break;
case PCC_OSCILLATORTYPE_OSC32K:
WU->CLOCKS_BU &= ~(1 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K
break;
default:
break;
}
}
/**
* @brief Выключить источник тактирования.
* @param Oscillator Источник тактирования для выключения.
* @warning Аргумент функции не является маской.
*
*/
void HAL_PCC_OscDisable(uint32_t Oscillator)
{
switch (Oscillator)
{
case PCC_OSCILLATORTYPE_HSI32M:
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M
break;
case PCC_OSCILLATORTYPE_OSC32M:
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M
break;
case PCC_OSCILLATORTYPE_LSI32K:
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K
break;
case PCC_OSCILLATORTYPE_OSC32K:
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K
break;
}
}
/**
* @brief Выбрать опорный источник тактирования монитора частоты.
*
* Функция предназначена для назначения опорного источника тактирования монитора частоты.
*
* @param Force32KClk Опорный источник тактирования монитора частоты.
* @return Состояние об ошибках.
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
* то функция вернет ошибку HAL_TIMEOUT, а выбранный источник не будет назначен.
*
*/
HAL_StatusTypeDef HAL_PCC_FreqMonRefSet(HAL_PCC_FreqMonitorSourceTypeDef Force32KClk)
{
uint32_t clockswitch_timeout = 0;
uint32_t ref_clk_m = 0;
uint32_t ref_clk_flag_m = 0;
switch (Force32KClk)
{
case PCC_FREQ_MONITOR_SOURCE_AUTO:
WU->CLOCKS_SYS &= ~WU_CLOCKS_SYS_FORCE_32K_CLK_M;
return HAL_OK;
case PCC_FREQ_MONITOR_SOURCE_OSC32K:
ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_OSC32K_M;
ref_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
break;
case PCC_FREQ_MONITOR_SOURCE_LSI32K:
ref_clk_m = WU_CLOCKS_SYS_FORCE_32K_CLK_LSI32K_M;
ref_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
break;
default:
return HAL_ERROR;
}
while (!(PM->FREQ_STATUS & ref_clk_flag_m))
{
clockswitch_timeout++;
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
WU->CLOCKS_SYS = (WU->CLOCKS_SYS & ~(WU_CLOCKS_SYS_FORCE_32K_CLK_M)) | ref_clk_m;
for (volatile int i = 0; i < 100; i++)
;
return HAL_OK;
}
/**
* @brief Выбрать приоритетный источник тактирования системы.
*
* Функция предназначена для назначения приоритетного источника тактирования системы. Если ForceOscSys = #PCC_FORCE_OSC_SYS_FIXED,
* то источник тактирования системы не будет автоматически переключаться, при пропадании сигнала.
*
* @param OscillatorSystem Источник тактирования системы.
* @param ForceOscSys Запрет автоматического переключения с выбранного источника тактирования.
* @return Состояние об ошибках.
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник будет назначен приоритетным. Разрешение автоматического
* переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED.
*
*/
HAL_StatusTypeDef HAL_PCC_SetOscSystem(uint32_t OscillatorSystem, HAL_PCC_ForceOscSysTypeDef ForceOscSys)
{
uint32_t clockswitch_timeout = 0;
uint32_t sys_clk_m = 0;
uint32_t osc_clk_flag_m = 0;
/* Настройка источника тактирования системы */
switch (OscillatorSystem)
{
case PCC_OSCILLATORTYPE_HSI32M:
sys_clk_m = PM_AHB_CLK_MUX_HSI32M_M;
osc_clk_flag_m = PM_FREQ_STATUS_HSI32M_M;
break;
case PCC_OSCILLATORTYPE_OSC32M:
sys_clk_m = PM_AHB_CLK_MUX_OSC32M_M;
osc_clk_flag_m = PM_FREQ_STATUS_OSC32M_M;
break;
case PCC_OSCILLATORTYPE_LSI32K:
sys_clk_m = PM_AHB_CLK_MUX_LSI32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
break;
case PCC_OSCILLATORTYPE_OSC32K:
sys_clk_m = PM_AHB_CLK_MUX_OSC32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
break;
default:
return HAL_ERROR;
}
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
{
clockswitch_timeout++;
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
{
PM->AHB_CLK_MUX = sys_clk_m | PM_AHB_FORCE_MUX_UNFIXED;
return HAL_TIMEOUT;
}
}
PM->AHB_CLK_MUX = sys_clk_m | (ForceOscSys << PM_AHB_FORCE_MUX_S);
for (volatile int i = 0; i < 100; i++)
;
return HAL_OK;
}
/**
* @brief Выбрать приоритетный источник тактирования RTC.
*
* Функция предназначена для назначения приоритетного источника RTC.
*
* @param Oscillator Источник тактирования RTC.
* @return Состояние об ошибках.
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет назначен приоритетным.
*
*/
HAL_StatusTypeDef HAL_PCC_RTCClock(HAL_PCC_RTCClockSourceTypeDef Oscillator)
{
uint32_t clockswitch_timeout = 0;
uint32_t rtc_clk_m = 0;
uint32_t osc_clk_flag_m = 0;
switch (Oscillator)
{
case PCC_RTC_CLOCK_SOURCE_AUTO:
WU->CLOCKS_BU &= ~WU_CLOCKS_BU_RTC_CLK_MUX_M;
return HAL_OK;
case PCC_RTC_CLOCK_SOURCE_LSI32K:
rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_LSI32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
break;
case PCC_RTC_CLOCK_SOURCE_OSC32K:
rtc_clk_m = WU_CLOCKS_BU_RTC_CLK_MUX_OSC32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
break;
default:
return HAL_ERROR;
}
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
{
clockswitch_timeout++;
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
/* Выбор источника тактирования RTC */
WU->CLOCKS_BU = (WU->CLOCKS_BU & ~WU_CLOCKS_BU_RTC_CLK_MUX_M) | rtc_clk_m;
WU->RTC_CONRTOL = WU_RTC_CONTROL_RESET_CLEAR_M;
for (volatile int i = 0; i < 100; i++)
;
return HAL_OK;
}
/**
* @brief Выбрать источник тактирования RTC в составе ядра.
*
* Функция предназначена для выбора приоритетного источника RTC в составе ядра.
*
* @param Oscillator Источник тактирования RTC в составе ядра.
* @return Состояние об ошибках.
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет выбран.
*
*/
HAL_StatusTypeDef HAL_PCC_CPURTCClock(HAL_PCC_CPURTCClockSourceTypeDef Oscillator)
{
uint32_t clockswitch_timeout = 0;
uint32_t rtc_clk_m = 0;
uint32_t osc_clk_flag_m = 0;
switch (Oscillator)
{
case PCC_CPU_RTC_CLOCK_SOURCE_LSI32K:
rtc_clk_m = PM_CPU_RTC_CLK_MUX_LSI32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_LSI32K_M;
break;
case PCC_CPU_RTC_CLOCK_SOURCE_OSC32K:
rtc_clk_m = PM_CPU_RTC_CLK_MUX_OSC32K_M;
osc_clk_flag_m = PM_FREQ_STATUS_OSC32K_M;
break;
default:
return HAL_ERROR;
}
while (!(PM->FREQ_STATUS & osc_clk_flag_m))
{
clockswitch_timeout++;
if (clockswitch_timeout >= CLOCKSWITCH_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
PM->CPU_RTC_CLK_MUX = rtc_clk_m;
for (volatile int i = 0; i < 100; i++)
;
return HAL_OK;
}
/**
* @brief Задать делитель шины AHB.
* @param DividerAHB Делитель.
*
* Делитель является 32-х битным числом. Частота шины AHB определяется по формуле: @f$ \frac{F_{sys\_clk}}{DividerAHB + 1} @f$.
*/
void HAL_PCC_DividerAHB(uint32_t DividerAHB)
{
PM->DIV_AHB = DividerAHB;
}
/**
* @brief Задать делитель шины APB_M.
* @param DividerAPB_M Делитель.
*
* Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_M + 1} @f$.
*/
void HAL_PCC_DividerAPB_M(uint32_t DividerAPB_M)
{
PM->DIV_APB_M = DividerAPB_M;
}
/**
* @brief Задать делитель шины APB_P.
* @param DividerAPB_P Делитель.
*
* Делитель является 32-х битным числом. Частота шины APB_M определяется по формуле: @f$ \frac{F_{AHB}}{DividerAPB\_P + 1} @f$.
*/
void HAL_PCC_DividerAPB_P(uint32_t DividerAPB_P)
{
PM->DIV_APB_P = DividerAPB_P;
}
/**
* @brief Настроить тактирование и монитор частоты.
*
* Функция для настройки тактирования и монитора частоты в соответствии с заданными настройками в PCC_Init.
*
* @param PCC_Init Структура с настройками.
* @return Структура с состояниями об ошибках.
* @warning Если выбранный источник не детектируется монитором частоты в течение #CLOCKSWITCH_TIMEOUT_VALUE итераций,
* то функция вернет ошибку HAL_TIMEOUT. При этом выбранный источник не будет применен. Если такая ошибка возникла при
* при выборе системного источника, то выбранный источник будет назначен приоритетным. Разрешение автоматического
* переключения будет установлено как #PCC_FORCE_OSC_SYS_UNFIXED.
*
*/
PCC_ConfigErrorsTypeDef HAL_PCC_Config(PCC_InitTypeDef *PCC_Init)
{
PCC_ConfigErrorsTypeDef errors = {HAL_OK};
/* Включить все источники тактирования */
WU->CLOCKS_SYS &= ~(0b11 << WU_CLOCKS_SYS_OSC32M_EN_S); // Включить OSC32M и HSI32M
WU->CLOCKS_BU &= ~(0b11 << WU_CLOCKS_BU_OSC32K_EN_S); // Включить OSC32K и LSI32K
WU->CLOCKS_SYS = WU_CLOCKS_SYS_ADJ_HSI32M(PCC_Init->HSI32MCalibrationValue); // Поправочный коэффициент HSI32M
WU->CLOCKS_BU = WU_CLOCKS_BU_ADJ_LSI32K(PCC_Init->LSI32KCalibrationValue); // Поправочный коэффициент LSI32K
/* Опорный источник для монитора частоты */
errors.FreqMonRef = HAL_PCC_FreqMonRefSet(PCC_Init->FreqMon.Force32KClk);
/* Настройка источника тактирования системы */
errors.SetOscSystem = HAL_PCC_SetOscSystem(PCC_Init->FreqMon.OscillatorSystem, PCC_Init->FreqMon.ForceOscSys);
/* Делители частоты */
HAL_PCC_DividerAHB(PCC_Init->AHBDivider);
HAL_PCC_DividerAPB_M(PCC_Init->APBMDivider);
HAL_PCC_DividerAPB_P(PCC_Init->APBPDivider);
/* Выбор источника тактирования RTC */
errors.RTCClock = HAL_PCC_RTCClock(PCC_Init->RTCClockSelection);
/* Выбор источника тактирования RTC в составе ядра*/
errors.CPURTCClock = HAL_PCC_CPURTCClock(PCC_Init->RTCClockCPUSelection);
/* Отключение неиспользуемых источников тактирования */
/* Источники 32МГц */
/* Внутренний */
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_HSI32M))
{
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_HSI32M_EN_S); // Выключить HSI32M
}
// /* Внешний */
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32M))
{
WU->CLOCKS_SYS |= (1 << WU_CLOCKS_SYS_OSC32M_EN_S); // Выключить OSC32M
}
/* Источники 32кГц */
/* Внутренний */
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_LSI32K))
{
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_LSI32K_EN_S); // Выключить LSI32K
}
/* Внешний */
if (!(PCC_Init->OscillatorEnable & PCC_OSCILLATORTYPE_OSC32K))
{
WU->CLOCKS_BU |= (1 << WU_CLOCKS_BU_OSC32K_EN_S); // Выключить OSC32K
}
return errors;
}
/**
* @brief Получить частоту приоритетного системного источника тактирования в Гц.
* @return Частота приоритетного системного источника в Гц.
* @warning Система может тактироваться не от приоритетного источника. Например, если источник не был назначен принудительно и сигнал от источника отсутствует.
* В таком случае автоматически выбирается источник в соответствии со следующим приоритетом: OSC32M, HSI32M, OSC32K, LSI32K.
*/
uint32_t HAL_PCC_GetSysClockFreq()
{
uint32_t system_clock = 0;
switch (PM->AHB_CLK_MUX & PM_AHB_CLK_MUX_M)
{
case PM_AHB_CLK_MUX_OSC32M_M:
system_clock = OSC_SYSTEM_VALUE;
break;
case PM_AHB_CLK_MUX_OSC32K_M:
system_clock = OSC_CLOCK_VALUE;
break;
case PM_AHB_CLK_MUX_HSI32M_M:
system_clock = HSI_VALUE;
break;
case PM_AHB_CLK_MUX_LSI32K_M:
system_clock = LSI_VALUE;
break;
}
return system_clock;
}

View File

@ -0,0 +1,271 @@
#include "mik32_hal_rtc.h"
__attribute__((weak)) void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
__HAL_PCC_RTC_CLK_ENABLE();
}
void HAL_RTC_WaitFlag(RTC_HandleTypeDef *hrtc)
{
uint32_t retry_limit = 10000;
for (uint32_t i = 0; i < retry_limit; i++)
{
if ((hrtc->Instance->CTRL & RTC_CTRL_FLAG_M) == 0)
{
return;
}
}
while (hrtc->Instance->CTRL & RTC_CTRL_FLAG_M);
#ifdef MIK32_RTC_DEBUG
xprintf("Ожидание установки CTRL.FLAG в 0 превышено\n");
#endif
}
void HAL_RTC_Disable(RTC_HandleTypeDef *hrtc)
{
// Для записи даты нужно сбросить бит EN в регистре CTRL
RTC->CTRL &= ~RTC_CTRL_EN_M;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_Enable(RTC_HandleTypeDef *hrtc)
{
// Установка бита EN включает модуль RTC
RTC->CTRL |= RTC_CTRL_EN_M;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime)
{
uint8_t DOW, TH, H, TM, M, TS, S;
DOW = sTime->Dow;
TH = sTime->Hours / 10;
H = sTime->Hours % 10;
TM = sTime->Minutes / 10;
M = sTime->Minutes % 10;
TS = sTime->Seconds / 10;
S = sTime->Seconds % 10;
uint32_t RTC_time = (DOW << RTC_TIME_DOW_S) | // День недели
(TH << RTC_TIME_TH_S) | // Десятки часов
(H << RTC_TIME_H_S) | // Единицы часов
(TM << RTC_TIME_TM_S) | // Десятки минут
(M << RTC_TIME_M_S) | // Единицы минут
(TS << RTC_TIME_TS_S) | // Десятки секунд
(S << RTC_TIME_S_S) | // Единицы секунд
(0 << RTC_TIME_TOS_S); // Десятые секунды
#ifdef MIK32_RTC_DEBUG
xprintf("Установка времени RTC\n");
#endif
hrtc->Instance->TIME = RTC_time;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate)
{
uint8_t TC, C, TY, Y, TM, M, TD, D;
TC = sDate->Century / 10;
C = sDate->Century % 10;
TY = sDate->Year / 10;
Y = sDate->Year % 10;
TM = sDate->Month / 10;
M = sDate->Month % 10;
TD = sDate->Day / 10;
D = sDate->Day % 10;
uint32_t RTC_data = (TC << RTC_DATE_TC_S) | // Десятки века
(C << RTC_DATE_C_S) | // Единицы века
(TY << RTC_DATE_TY_S) | // Десятки года
(Y << RTC_DATE_Y_S) | // Единицы года
(TM << RTC_DATE_TM_S) | // Десятки месяца
(M << RTC_DATE_M_S) | // Единицы месяца
(TD << RTC_DATE_TD_S) | // Десятки числа
(D << RTC_DATE_D_S); // Единицы числа
#ifdef MIK32_RTC_DEBUG
xprintf("Установка даты RTC\n");
#endif
hrtc->Instance->DATE = RTC_data;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_Alarm_SetTime(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
{
uint8_t DOW, TH, H, TM, M, TS, S;
DOW = sAlarm->AlarmTime.Dow;
TH = sAlarm->AlarmTime.Hours / 10;
H = sAlarm->AlarmTime.Hours % 10;
TM = sAlarm->AlarmTime.Minutes / 10;
M = sAlarm->AlarmTime.Minutes % 10;
TS = sAlarm->AlarmTime.Seconds / 10;
S = sAlarm->AlarmTime.Seconds % 10;
uint32_t RTC_alarm_time = (DOW << RTC_TIME_DOW_S) | // День недели
(TH << RTC_TIME_TH_S) | // Десятки часов
(H << RTC_TIME_H_S) | // Единицы часов
(TM << RTC_TIME_TM_S) | // Десятки минут
(M << RTC_TIME_M_S) | // Единицы минут
(TS << RTC_TIME_TS_S) | // Десятки секунд
(S << RTC_TIME_S_S) | // Единицы секунд
(0 << RTC_TIME_TOS_S); // Десятые секунды
#ifdef MIK32_RTC_DEBUG
xprintf("Установка времени будильника\n");
#endif
hrtc->Instance->TALRM = RTC_alarm_time | sAlarm->MaskAlarmTime;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_Alarm_SetDate(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
{
uint8_t TC, C, TY, Y, TM, M, TD, D;
TC = sAlarm->AlarmDate.Century / 10;
C = sAlarm->AlarmDate.Century % 10;
TY = sAlarm->AlarmDate.Year / 10;
Y = sAlarm->AlarmDate.Year % 10;
TM = sAlarm->AlarmDate.Month / 10;
M = sAlarm->AlarmDate.Month % 10;
TD = sAlarm->AlarmDate.Day / 10;
D = sAlarm->AlarmDate.Day % 10;
uint32_t RTC_alarm_data = (TC << RTC_DATE_TC_S) | // Десятки века
(C << RTC_DATE_C_S) | // Единицы века
(TY << RTC_DATE_TY_S) | // Десятки года
(Y << RTC_DATE_Y_S) | // Единицы года
(TM << RTC_DATE_TM_S) | // Десятки месяца
(M << RTC_DATE_M_S) | // Единицы месяца
(TD << RTC_DATE_TD_S) | // Десятки числа
(D << RTC_DATE_D_S); // Единицы числа
#ifdef MIK32_RTC_DEBUG
xprintf("Установка даты будильника\n");
#endif
hrtc->Instance->DALRM = RTC_alarm_data | sAlarm->MaskAlarmDate;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm)
{
HAL_RTC_Alarm_SetTime(hrtc, sAlarm);
HAL_RTC_Alarm_SetDate(hrtc, sAlarm);
}
void HAL_RTC_AlarmDisable(RTC_HandleTypeDef *hrtc)
{
hrtc->Instance->TALRM &= ~(RTC_TALRM_CS_M | RTC_TALRM_CM_M | RTC_TALRM_CH_M | RTC_TALRM_CDOW_M);
HAL_RTC_WaitFlag(hrtc);
hrtc->Instance->DALRM &= ~(RTC_DALRM_CD_M | RTC_DALRM_CM_M | RTC_DALRM_CY_M | RTC_DALRM_CC_M);
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_ClearAlrmFlag(RTC_HandleTypeDef *hrtc)
{
/* Сброс флага ALRM в RTC */
hrtc->Instance->CTRL &= ~RTC_CTRL_ALRM_M;
HAL_RTC_WaitFlag(hrtc);
}
int HAL_RTC_GetAlrmFlag(RTC_HandleTypeDef *hrtc)
{
return (hrtc->Instance->CTRL & RTC_CTRL_ALRM_M) >> RTC_CTRL_ALRM_S;
}
RTC_DateTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc)
{
uint8_t TC, C, TY, Y, TM, M, TD, D;
uint32_t rtc_date_read = hrtc->Instance->DATE;
RTC_DateTypeDef sDate = {0};
TC = (rtc_date_read & RTC_DATE_TC_M) >> RTC_DATE_TC_S;
C = (rtc_date_read & RTC_DATE_C_M) >> RTC_DATE_C_S;
TY = (rtc_date_read & RTC_DATE_TY_M) >> RTC_DATE_TY_S;
Y = (rtc_date_read & RTC_DATE_Y_M) >> RTC_DATE_Y_S;
TM = (rtc_date_read & RTC_DATE_TM_M) >> RTC_DATE_TM_S;
M = (rtc_date_read & RTC_DATE_M_M) >> RTC_DATE_M_S;
TD = (rtc_date_read & RTC_DATE_TD_M) >> RTC_DATE_TD_S;
D = (rtc_date_read & RTC_DATE_D_M) >> RTC_DATE_D_S;
sDate.Century = TC * 10 + C;
sDate.Year = TY * 10 + Y;
sDate.Month = TM * 10 + M;
sDate.Day = TD * 10 + D;
#ifdef MIK32_RTC_DEBUG
xprintf("\n%d%d век\n", TC, C);
xprintf("%d%d.%d%d.%d%d\n", TD, D, TM, M, TY, Y);
#endif
return sDate;
}
RTC_TimeTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc)
{
RTC_TimeTypeDef sTime;
sTime.Dow = hrtc->Instance->DOW;
sTime.Hours = hrtc->Instance->TH * 10 + hrtc->Instance->H;
sTime.Minutes = hrtc->Instance->TM * 10 + hrtc->Instance->M;
sTime.Seconds = hrtc->Instance->TS * 10 + hrtc->Instance->S;
#ifdef MIK32_RTC_DEBUG
switch (hrtc->Instance->DOW)
{
case 1:
xprintf("Понедельник\n");
break;
case 2:
xprintf("Вторник\n");
break;
case 3:
xprintf("Среда\n");
break;
case 4:
xprintf("Четверг\n");
break;
case 5:
xprintf("Пятница\n");
break;
case 6:
xprintf("Суббота\n");
break;
case 7:
xprintf("Воскресенье\n");
break;
}
xprintf("%d%d:%d%d:%d%d.%d\n", hrtc->Instance->TH, hrtc->Instance->H, hrtc->Instance->TM,
hrtc->Instance->M, hrtc->Instance->TS, hrtc->Instance->S, hrtc->Instance->TOS);
#endif
return sTime;
}
void HAL_RTC_SetInterruptAlarm(RTC_HandleTypeDef *hrtc, uint32_t InterruptEnable)
{
hrtc->Interrupts.Alarm = InterruptEnable;
uint32_t config = hrtc->Instance->CTRL;
config &= ~RTC_CTRL_INTE_M;
config |= InterruptEnable << RTC_CTRL_INTE_S;
hrtc->Instance->CTRL = config;
HAL_RTC_WaitFlag(hrtc);
}
void HAL_RTC_InterruptInit(RTC_HandleTypeDef *hrtc)
{
HAL_RTC_SetInterruptAlarm(hrtc, hrtc->Interrupts.Alarm);
}
int HAL_RTC_GetINTE(RTC_HandleTypeDef *hrtc)
{
return (hrtc->Instance->CTRL & RTC_CTRL_INTE_M) >> RTC_CTRL_INTE_S;
}

View File

@ -0,0 +1,628 @@
#include "mik32_hal_spi.h"
/**
* @brief Инициализация SPI MSP.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
__attribute__((weak)) void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (hspi->Instance == SPI_0)
{
__HAL_PCC_SPI_0_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
switch (hspi->Init.ChipSelect)
{
case SPI_CS_0:
GPIO_InitStruct.Pin = GPIO_PIN_4;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
break;
case SPI_CS_1:
GPIO_InitStruct.Pin = GPIO_PIN_14;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
break;
case SPI_CS_2:
GPIO_InitStruct.Pin = GPIO_PIN_15;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
break;
case SPI_CS_3:
GPIO_InitStruct.Pin = GPIO_PIN_6;
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
break;
}
/* В режиме ведущего вывод SPIx_N_SS_IN должен быть в режиме SPI с подтяжкой к питанию. */
GPIO_InitStruct.Pin = GPIO_PIN_3;
if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER)
{
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
}
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
}
if (hspi->Instance == SPI_1)
{
__HAL_PCC_SPI_1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
switch (hspi->Init.ChipSelect)
{
case SPI_CS_0:
GPIO_InitStruct.Pin = GPIO_PIN_4;
break;
case SPI_CS_1:
GPIO_InitStruct.Pin = GPIO_PIN_5;
break;
case SPI_CS_2:
GPIO_InitStruct.Pin = GPIO_PIN_6;
break;
case SPI_CS_3:
GPIO_InitStruct.Pin = GPIO_PIN_7;
break;
}
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
if (hspi->Init.SPI_Mode == HAL_SPI_MODE_MASTER)
{
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
}
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
}
}
/**
* @brief Включить модуль SPI.
*
* Перед включением модуля производится сброс флагов ошибок и очистка буферов TX и RX.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_Enable(SPI_HandleTypeDef *hspi)
{
HAL_SPI_ClearError(hspi);
__HAL_SPI_ENABLE(hspi);
}
/**
* @brief Выключить модуль SPI.
*
* После выключения модуля производится сброс флагов ошибок и очистка буферов TX и RX.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_Disable(SPI_HandleTypeDef *hspi)
{
__HAL_SPI_DISABLE(hspi);
HAL_SPI_ClearError(hspi);
}
/**
* @brief Задать задержку BTWN.
*
* Задержка в периодах опорного тактового сигнала между снятием сигнала выбора одного ведомого
* устройства и установкой сигнала выбора другого ведомого устройства.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param btwn задержка BTWN в периодах опорного тактового сигнала.
* Этот параметр может быть значением в пределах от 0 до 255.
*/
void HAL_SPI_SetDelayBTWN(SPI_HandleTypeDef *hspi, uint8_t btwn)
{
hspi->Instance->DELAY &= ~SPI_DELAY_BTWN_M;
hspi->Instance->DELAY |= SPI_DELAY_BTWN(btwn);
}
/**
* @brief Задать задержку AFTER.
*
* Задержка в периодах опорного тактового сигнала между последним битом текущего слова
* и первым битом следующего слова.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param after Задержка AFTER в периодах опорного тактового сигнала.
* Этот параметр может быть числом в пределах от 0 до 255.
*/
void HAL_SPI_SetDelayAFTER(SPI_HandleTypeDef *hspi, uint8_t after)
{
hspi->Instance->DELAY &= ~SPI_DELAY_AFTER_M;
hspi->Instance->DELAY |= SPI_DELAY_AFTER(after);
}
/**
* @brief Задать задержку INIT.
*
* Дополнительная задержка в периодах опорного тактового сигнала между установкой
* сигнала n_ss_out в «0» и передачей первого бита.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param init задержка INIT в периодах опорного тактового сигнала.
* Этот параметр может быть числом в пределах от 0 до 255.
*/
void HAL_SPI_SetDelayINIT(SPI_HandleTypeDef *hspi, uint8_t init)
{
hspi->Instance->DELAY &= ~SPI_DELAY_INIT_M;
hspi->Instance->DELAY |= SPI_DELAY_INIT(init);
}
/**
* @brief Задать задержку перед передачей.
*
* Модуль SPI в режиме ведомого устройства начинает передачу только когда тактовый сигнал
* sclk_in (внешнего ведущего устройства) не изменяется в течение количества периодов опорного
* тактового сигнала SPI заданного в этом поле или когда модуль SPI не активен.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param slave_idle_counter задержку перед передачей в периодах опорного тактового сигнала.
* Этот параметр может быть числом в пределах от 0 до 255.
*/
void HAL_SPI_SetSlaveIdleCounter(SPI_HandleTypeDef *hspi, uint8_t slave_idle_counter)
{
hspi->Instance->SIC = slave_idle_counter;
}
/**
* @brief Задать уровень, при котором TX_FIFO считается незаполненным и формируется
* прерывание TX_FIFO_NOT_full (IXR_TXOW).
*
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param threshold уровень, при котором TX_FIFO считается не заполненным.
*/
void HAL_SPI_SetThresholdTX(SPI_HandleTypeDef *hspi, uint32_t threshold)
{
hspi->Init.ThresholdTX = threshold;
hspi->Instance->TX_THR = threshold;
}
/**
* @brief Получить идентификационный номер модуля. Ожидаемое ID 0x01090100.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @return идентификационный номер модуля.
*/
uint32_t HAL_SPI_ReadModuleID(SPI_HandleTypeDef *hspi)
{
return hspi->Instance->ID;
}
/**
* @brief Инициализировать SPI в соответствии с настройками в @ref SPI_HandleTypeDef.
*
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
HAL_StatusTypeDef error_code = HAL_OK;
if (hspi == NULL)
{
return HAL_ERROR;
}
HAL_SPI_MspInit(hspi);
HAL_SPI_ClearError(hspi);
/* Выключение модуля SPI */
HAL_SPI_Disable(hspi);
uint32_t SPI_config = 0;
/* Настройка режима ведомого */
switch (hspi->Init.SPI_Mode)
{
case HAL_SPI_MODE_MASTER:
SPI_config = SPI_CONFIG_MASTER_M;
break;
case HAL_SPI_MODE_SLAVE:
SPI_config = SPI_CONFIG_SLAVE_M;
hspi->Init.ManualCS = SPI_MANUALCS_OFF;
break;
}
/* Настройки SPI */
SPI_config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S) | /* Настройка делителя частоты */
(hspi->Init.ManualCS << SPI_CONFIG_MANUAL_CS_S) | /* Настройка режима управления сигналом CS */
(hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) | /* Настройка фазы тактового сигнала */
(hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S) | /* Настройка полярности тактового сигнала */
(hspi->Init.Decoder << SPI_CONFIG_PERI_SEL_S); /* Настройка использования внешнего декодера */
//(hspi->Init.DataSize << SPI_CONFIG_DATA_SZ_S); /* Длина передаваемой посылки */
/* Выбор ведомого в соответствии с режимом ManualCS */
if (hspi->Init.ManualCS == SPI_MANUALCS_ON)
{
/* Ведомое устройство не выбрано. Ручное управление сигналом CS */
SPI_config |= SPI_CS_NONE << SPI_CONFIG_CS_S;
}
else
{
/* Выбор ведомого устройства в автоматическом режиме управления CS */
SPI_config |= hspi->Init.ChipSelect << SPI_CONFIG_CS_S;
}
/* Установка выбранных настроек */
hspi->Instance->CONFIG = SPI_config;
HAL_SPI_SetDelayBTWN(hspi, 1);
HAL_SPI_SetDelayAFTER(hspi, 0);
HAL_SPI_SetDelayINIT(hspi, 0);
/* уровень при котором регистр TX считается незаполненным и формируется прерывание */
if (hspi->Init.ThresholdTX > 8)
{
return HAL_ERROR;
}
HAL_SPI_SetThresholdTX(hspi, hspi->Init.ThresholdTX);
hspi->TxCount = 0;
hspi->RxCount = 0;
hspi->State = HAL_SPI_STATE_READY;
return error_code;
}
/**
* @brief Очистить буфер TX_FIFO.
*
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_ClearTXFIFO(SPI_HandleTypeDef *hspi)
{
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M;
}
/**
* @brief Очистить буфер RX_FIFO.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_ClearRXFIFO(SPI_HandleTypeDef *hspi)
{
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_RX_FIFO_M;
}
/**
* @brief Сбросить флаги ошибок, очистить буферы RX и TX.
*
* @warning Функция выключает модуль SPI.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
**/
void HAL_SPI_ClearError(SPI_HandleTypeDef *hspi)
{
/* Сброс ошибок */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
__HAL_SPI_DISABLE(hspi);
HAL_SPI_ClearRXFIFO(hspi);
HAL_SPI_ClearTXFIFO(hspi);
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
(void) unused;
}
/**
* @brief Выбрать ведомое устройство.
*
* В ручном режиме управления сигналом выбора ведомого
* @ref SPI_InitTypeDef::ManualCS "SPI_HandleTypeDef.Init.ManualCS" = @ref SPI_MANUALCS_ON при вызове функции выбранный вывод
* перейдет в активное состояние (низкий уровень).
*
* В автоматическом режиме управления сигналом выбора ведомого функция задает один из сигналов
* CS0 - CS3, который будет использован во время передачи.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param CS_M ведомое устройство.
* Этот параметр должен быть одним из следующих значений:
* - @ref SPI_CS_NONE - ведомое устройство не выбрано
* - @ref SPI_CS_0 - ведомое устройство 1
* - @ref SPI_CS_1 - ведомое устройство 2
* - @ref SPI_CS_2 - ведомое устройство 3
* - @ref SPI_CS_3 - ведомое устройство 4
* Если используется внешний декодер (@ref SPI_InitTypeDef::Decoder "SPI_HandleTypeDef.Init.Decoder" = @ref SPI_DECODER_USE),
* @ref SPI_InitTypeDef::ChipSelect "SPI_HandleTypeDef.Init.ChipSelect" отображается на выводах CS0 - CS3.
*/
void HAL_SPI_CS_Enable(SPI_HandleTypeDef *hspi, uint32_t CS_M)
{
hspi->Init.ChipSelect = CS_M;
CS_M = CS_M << SPI_CONFIG_CS_S;
hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | CS_M;
}
/**
* @brief Перевести активный сигнал выбора ведомого в неактивное состояние (высокий уровень).
*
* Функция устанавливает значение @ref SPI_CS_NONE - ведомые устройства не выбраны.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi)
{
hspi->Init.ChipSelect = SPI_CS_NONE;
hspi->Instance->CONFIG = (hspi->Instance->CONFIG & ~SPI_CONFIG_CS_M) | SPI_CONFIG_CS_NONE_M;
}
/**
* @brief Запустить передачу и прием данных.
*
* Байты поочередно передаются и считываются по одному байту.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param TransmitBytes указатель на буфер передаваемых данных.
* @param ReceiveBytes указатель на буфер считываемых данных.
* @param DataSize число байт для отправки и приема.
* @param Timeout продолжительность тайм-аута.
* @return Статус HAL.
*
* @warning Во время обмена пороговое значение ThresholdTX = 1.
*/
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout)
{
uint32_t txallowed = 1;
HAL_StatusTypeDef error_code = HAL_OK;
uint32_t timeout_counter = 0;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)ReceiveBytes;
hspi->RxCount = DataSize;
hspi->pTxBuffPtr = (uint8_t *)TransmitBytes;
hspi->TxCount = DataSize;
hspi->Instance->TX_THR = 1;
/* Включить SPI если выключено */
if (!(hspi->Instance->ENABLE & SPI_ENABLE_M))
{
__HAL_SPI_ENABLE(hspi);
}
while ((hspi->TxCount > 0) || (hspi->RxCount > 0))
{
/* Проверка флага TX_FIFO_NOT_FULL */
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) && (hspi->TxCount > 0) && (txallowed == 1))
{
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
hspi->pTxBuffPtr++;
hspi->TxCount--;
/* Следующие данные - прием (Rx). Tx не разрешен */
txallowed = 0;
}
/* Ожидание когда установится флаг RX_FIFO_NOT_EMPTY */
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) && (hspi->RxCount > 0))
{
*(hspi->pRxBuffPtr) = hspi->Instance->RXDATA;
hspi->pRxBuffPtr++;
hspi->RxCount--;
/* Следующие данные - передача (Tx). Tx разрешается */
txallowed = 1;
}
if (((timeout_counter++) >= Timeout) || (Timeout == 0U))
{
error_code = HAL_TIMEOUT;
goto error;
}
}
error:
__HAL_SPI_DISABLE(hspi);
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
(void) unused;
return error_code;
}
/**
* @brief Запустить передачу и прием данных с учетом порогового значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX".
*
* Сначала полностью заполняется буфер TX. Затем начинается передача, состоящая из цикличного считывания
* и отправки @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт. Если во
* время ожидания байта в буфере RX опустошился буфер TX ниже порогового значения ThresholdTX,
* то в буфер TX записывается 1 байт. За одну итерацию цикла в буфер TX записывается и считывается из буфера RX не более
* @ref SPI_BUFFER_SIZE - @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX" + 1 байт.
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param TransmitBytes указатель на буфер передаваемых данных.
* @param ReceiveBytes указатель на буфер считываемых данных.
* @param DataSize число байт для отправки и приема.
* @param Timeout продолжительность тайм-аута.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout)
{
uint32_t tx_offset = 0; /* Номер отправляемого байта */
uint32_t rx_offset = 0; /* Номер считываемого байта */
uint32_t tx_counter = 0; /* Количество записанных байт в буфер TX за итерацию */
uint32_t write_read_bytes = SPI_BUFFER_SIZE - hspi->Init.ThresholdTX + 1; /* Число байт для записи и чтения в итерации */
uint32_t status_tx = 0; /* Регистр состояний флагов SPI во время записи в TXDATA */
uint32_t timeout_counter = Timeout;
HAL_StatusTypeDef error_code = HAL_OK;
/* Очистка ошибок */
HAL_SPI_ClearError(hspi);
/* Первая запись буфера до полного заполнения */
while (!(hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_FULL_M))
{
hspi->Instance->TXDATA = TransmitBytes[tx_offset];
tx_offset++;
/* Количество записанных байт не должно быть больше буфера */
if (tx_offset >= SPI_BUFFER_SIZE)
{
return HAL_ERROR;
}
}
/* Включить SPI */
__HAL_SPI_ENABLE(hspi);
while ((tx_offset < DataSize) || (rx_offset < DataSize))
{
/* Чтение (8 - Threshold + 1) байт. */
if (rx_offset < DataSize)
{
for (uint32_t rx_counter = 0; (rx_counter < write_read_bytes) && (rx_offset < DataSize); rx_counter++)
{
timeout_counter = Timeout;
while (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M))
{
if (!(timeout_counter--))
{
error_code = HAL_TIMEOUT;
goto error;
}
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
{
goto error;
}
/* Если буфер RX пуст, а буфер TX опустошился ниже порогового значения, то в буфер TX записывается байт. */
if (((tx_counter != 0) || ((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)) && (tx_offset < DataSize) && (tx_counter < write_read_bytes))
{
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
{
goto error;
}
hspi->Instance->TXDATA = TransmitBytes[tx_offset++];
tx_counter++;
}
}
ReceiveBytes[rx_offset++] = hspi->Instance->RXDATA;
}
}
if (tx_offset < DataSize)
{
timeout_counter = Timeout;
/* Ожидание опустошение буфера ниже */
while ((tx_counter == 0) && (!((status_tx = hspi->Instance->INT_STATUS) & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M)))
{
if (!(timeout_counter--))
{
error_code = HAL_TIMEOUT;
goto error;
}
if (status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M))
{
goto error;
}
}
for (; (tx_counter < write_read_bytes) && (tx_offset < DataSize); tx_counter++)
{
hspi->Instance->TXDATA = TransmitBytes[tx_offset++];
}
tx_counter = 0;
}
}
error:
__HAL_SPI_DISABLE(hspi);
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
if ((status_tx & (SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M)))
{
if (status_tx & SPI_INT_STATUS_RX_OVERFLOW_M)
{
hspi->ErrorCode |= HAL_SPI_ERROR_OVR;
}
else
{
hspi->ErrorCode |= HAL_SPI_ERROR_MODF;
}
error_code = HAL_ERROR;
}
status_tx = hspi->Instance->INT_STATUS;
return error_code;
}
/**
* @brief Запустить передачу и прием данных с прерываниями.
*
* Во время передачи используются следующие прерывания:
* - RX_OVERFLOW: прерывание при переполнении буфера RX_FIFO
* - MODE_FAIL: напряжение на выводе n_ss_in не соответствую режиму работы SPI
* - TX_FIFO_NOT_FULL: регистр TX_FIFO не заполнен (опустошился ниже значения @ref SPI_InitTypeDef::ThresholdTX "SPI_HandleTypeDef.Init.ThresholdTX")
* - RX_FIFO_NOT_EMPTY: буфер RX_FIFO не пустой
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
* @param TransmitBytes указатель на буфер передаваемых данных.
* @param ReceiveBytes указатель на буфер считываемых данных.
* @param Size число байт для отправки и приема.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size)
{
HAL_StatusTypeDef error_code = HAL_OK;
if ((TransmitBytes == NULL) || (ReceiveBytes == NULL) || (Size == 0))
{
error_code = HAL_ERROR;
return error_code;
}
if (hspi->Init.ThresholdTX == 0)
{
error_code = HAL_ERROR;
return error_code;
}
hspi->State = HAL_SPI_STATE_BUSY;
hspi->pTxBuffPtr = TransmitBytes;
hspi->TxCount = Size;
hspi->pRxBuffPtr = ReceiveBytes;
hspi->RxCount = Size;
/* Очистка ошибок */
HAL_SPI_ClearError(hspi);
/* Первая запись буфера до полного заполнения */
for (uint32_t i = 0; i < SPI_BUFFER_SIZE; i++)
{
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
hspi->pTxBuffPtr++;
hspi->TxCount--;
}
/* Включить SPI если выключено */
if (!(hspi->Instance->ENABLE & SPI_ENABLE_M))
{
__HAL_SPI_ENABLE(hspi);
}
HAL_SPI_InterruptEnable(hspi, SPI_INT_STATUS_RX_OVERFLOW_M | SPI_INT_STATUS_MODE_FAIL_M /* Прерывания ошибок */
| SPI_INT_STATUS_TX_FIFO_NOT_FULL_M | SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M); /* Прерывания опустошения буфера TX и наличие байтов в буфере RX */
return error_code;
}

View File

@ -0,0 +1,127 @@
#include <mik32_hal_spifi.h>
__attribute__((weak)) void HAL_SPIFI_MspInit()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_PCC_SPIFI_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
}
void HAL_SPIFI_MemoryMode_Init(SPIFI_MemoryModeConfig_HandleTypeDef *spifi)
{
HAL_SPIFI_MspInit();
spifi->Instance->STAT |= SPIFI_CONFIG_STAT_RESET_M;
spifi->Instance->CLIMIT = spifi->CacheLimit; // Граница кеширования
if (spifi->CacheEnable)
{
spifi->Instance->CTRL |= SPIFI_CONFIG_CTRL_CACHE_EN_M;
}
else
{
spifi->Instance->CTRL &= ~SPIFI_CONFIG_CTRL_CACHE_EN_M;
}
// Настройка команды чтения
spifi->Instance->MCMD = ((spifi->Command.InterimLength << SPIFI_CONFIG_MCMD_INTLEN_S) |
(spifi->Command.FieldForm << SPIFI_CONFIG_MCMD_FIELDFORM_S) |
(spifi->Command.FrameForm << SPIFI_CONFIG_MCMD_FRAMEFORM_S) |
(spifi->Command.OpCode << SPIFI_CONFIG_MCMD_OPCODE_S));
}
HAL_StatusTypeDef HAL_SPIFI_SendCommand(
SPIFI_HandleTypeDef *spifi,
SPIFI_CommandTypeDef *cmd,
uint32_t address,
uint16_t bufferSize,
uint8_t *readBuffer,
uint8_t *writeBuffer,
uint32_t timeout)
{
return HAL_SPIFI_SendCommand_LL(
spifi,
cmd->Direction |
SPIFI_CONFIG_CMD_INTLEN(cmd->InterimLength) |
SPIFI_CONFIG_CMD_FIELDFORM(cmd->FieldForm) |
SPIFI_CONFIG_CMD_FRAMEFORM(cmd->FrameForm) |
SPIFI_CONFIG_CMD_OPCODE(cmd->OpCode),
address,
bufferSize,
readBuffer,
writeBuffer,
cmd->InterimData,
timeout);
}
HAL_StatusTypeDef HAL_SPIFI_SendCommand_LL(
SPIFI_HandleTypeDef *spifi,
uint32_t cmd,
uint32_t address,
uint16_t bufferSize,
uint8_t *readBuffer,
uint8_t *writeBuffer,
uint32_t interimData,
uint32_t timeout)
{
spifi->Instance->STAT |= SPIFI_CONFIG_STAT_INTRQ_M;
spifi->Instance->ADDR = address;
spifi->Instance->IDATA = interimData;
spifi->Instance->CMD = cmd | SPIFI_CONFIG_CMD_DATALEN(bufferSize);
if (cmd & SPIFI_CONFIG_CMD_DOUT_M)
{
if ((bufferSize > 0) && (writeBuffer == 0))
{
return HAL_ERROR;
}
for (int i = 0; i < bufferSize; i++)
{
spifi->Instance->DATA8 = writeBuffer[i];
}
}
else
{
if ((bufferSize > 0) && (readBuffer == 0))
{
return HAL_ERROR;
}
for (int i = 0; i < bufferSize; i++)
{
readBuffer[i] = (uint8_t)spifi->Instance->DATA8;
}
}
HAL_StatusTypeDef waitStatus = HAL_SPIFI_WaitCommandProcessing(spifi, timeout);
if ((waitStatus == HAL_OK) && (cmd & SPIFI_CONFIG_CMD_POLL_M))
{
if (SPIFI_CONFIG->DATA8 == (cmd & SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE_M))
{
return HAL_OK;
}
return HAL_ERROR;
}
return waitStatus;
}
bool HAL_SPIFI_IsMemoryModeEnabled(SPIFI_HandleTypeDef *spifi)
{
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_MCINIT_M) != 0;
}
void HAL_SPIFI_Reset(SPIFI_HandleTypeDef *spifi)
{
spifi->Instance->STAT = SPIFI_CONFIG_STAT_RESET_M;
}
bool HAL_SPIFI_IsReady(SPIFI_HandleTypeDef *spifi)
{
return (spifi->Instance->STAT & SPIFI_CONFIG_STAT_RESET_M) == 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,495 @@
#include "mik32_hal_timer32.h"
__attribute__((weak)) void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (htimer32->Instance == TIMER32_0)
{
__HAL_PCC_TIMER32_0_CLK_ENABLE();
}
if (htimer32->Instance == TIMER32_1)
{
__HAL_PCC_TIMER32_1_CLK_ENABLE();
if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD)
{
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
}
}
if (htimer32->Instance == TIMER32_2)
{
__HAL_PCC_TIMER32_2_CLK_ENABLE();
if (htimer32->Clock.Source == TIMER32_SOURCE_TX_PAD)
{
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
}
}
}
__attribute__((weak)) void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (timerChannel->TimerInstance == TIMER32_1)
{
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
}
if (timerChannel->TimerInstance == TIMER32_2)
{
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_TIMER_SERIAL;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
}
}
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer)
{
if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2))
{
return HAL_ERROR;
}
HAL_TIMER32_MspInit(timer);
HAL_Timer32_Top_Set(timer, timer->Top);
HAL_Timer32_Prescaler_Set(timer, timer->Clock.Prescaler);
HAL_Timer32_CountMode_Set(timer, timer->CountMode);
HAL_Timer32_Source_Set(timer, timer->Clock.Source);
HAL_Timer32_InterruptFlags_Clear(timer);
HAL_Timer32_State_Set(timer, timer->State);
HAL_Timer32_InterruptMask_Set(timer, 0);
return HAL_OK;
}
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state)
{
timer->State = state;
if (state == TIMER32_STATE_DISABLE)
{
timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M;
}
else
{
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M;
}
}
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top)
{
timer->Top = top;
timer->Instance->TOP = top;
}
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler)
{
timer->Clock.Prescaler = prescaler;
timer->Instance->PRESCALER = prescaler;
}
void HAL_Timer32_Source_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_SourceTypeDef source)
{
timer->Clock.Source = source;
uint32_t timer_cfg_mux_tim32_s = 0;
switch ((uint32_t)timer->Instance)
{
case (uint32_t)TIMER32_0:
timer_cfg_mux_tim32_s = MUX_TIM32_0;
break;
case (uint32_t)TIMER32_1:
timer_cfg_mux_tim32_s = MUX_TIM32_1;
break;
case (uint32_t)TIMER32_2:
timer_cfg_mux_tim32_s = MUX_TIM32_2;
break;
default:
break;
}
uint32_t timer_cfg_reg = PM->TIMER_CFG & (~PM_TIMER_CFG_MUX_TIMER_M(timer_cfg_mux_tim32_s));
uint32_t timer_control_reg = timer->Instance->CONTROL & (~TIMER32_CONTROL_CLOCK_M);
/* В начале настройки переключается на hclk */
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M;
switch (source)
{
// case TIMER32_SOURCE_PRESCALER:
// timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_PRESCALER_M;
// break;
case TIMER32_SOURCE_TIM1_SYS_CLK:
timer_cfg_reg |= TIMER32_TIM1_SYS_CLK << timer_cfg_mux_tim32_s;
PM->TIMER_CFG = timer_cfg_reg;
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M;
break;
case TIMER32_SOURCE_TIM1_HCLK:
timer_cfg_reg |= TIMER32_TIM1_HCLK << timer_cfg_mux_tim32_s;
PM->TIMER_CFG = timer_cfg_reg;
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM1_M;
break;
case TIMER32_SOURCE_TIM2_OSC32K:
timer_cfg_reg |= TIMER32_TIM2_OSC32K << timer_cfg_mux_tim32_s;
PM->TIMER_CFG = timer_cfg_reg;
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M;
break;
case TIMER32_SOURCE_TIM2_LSI32K:
timer_cfg_reg |= TIMER32_TIM2_LSI32K << timer_cfg_mux_tim32_s;
PM->TIMER_CFG = timer_cfg_reg;
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TIM2_M;
break;
case TIMER32_SOURCE_TX_PAD:
timer->Instance->CONTROL = timer_control_reg | TIMER32_CONTROL_CLOCK_TX_PIN_M;
break;
default:
break;
}
}
void HAL_Timer32_InterruptMask_Set(TIMER32_HandleTypeDef *timer, uint32_t intMask)
{
timer->InterruptMask |= intMask;
timer->Instance->INT_MASK |= intMask;
}
void HAL_Timer32_InterruptMask_Clear(TIMER32_HandleTypeDef *timer, uint32_t intMask)
{
timer->InterruptMask &= ~intMask;
timer->Instance->INT_MASK &= ~intMask;
}
void HAL_Timer32_CountMode_Set(TIMER32_HandleTypeDef *timer, uint8_t countMode)
{
timer->CountMode = countMode;
uint32_t timer32_control_temp = timer->Instance->CONTROL;
timer32_control_temp &= ~TIMER32_CONTROL_MODE_M;
timer32_control_temp |= countMode << TIMER32_CONTROL_MODE_S;
timer->Instance->CONTROL = timer32_control_temp;
}
void HAL_Timer32_InterruptFlags_ClearMask(TIMER32_HandleTypeDef *timer, uint32_t clearMask)
{
timer->Instance->INT_CLEAR = clearMask;
}
HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
HAL_TIMER32_Channel_MspInit(timerChannel);
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert);
HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge);
HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR);
HAL_Timer32_Channel_ICR_Clear(timerChannel);
HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise);
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
HAL_Timer32_Channel_Disable(timerChannel);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
HAL_Timer32_Channel_ICR_Clear(timerChannel);
HAL_Timer32_Channel_Mode_Set(timerChannel, 0);
HAL_Timer32_Channel_Noise_Set(timerChannel, 0);
HAL_Timer32_Channel_OCR_Set(timerChannel, 0);
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, 0);
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_Enable(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->State = TIMER32_STATE_ENABLE;
timerChannel->Instance->CNTRL |= TIMER32_CH_CNTRL_ENABLE_M;
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_Disable(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->State = TIMER32_STATE_DISABLE;
timerChannel->Instance->CNTRL &= ~TIMER32_CH_CNTRL_ENABLE_M;
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_PWM_Invert_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_PWMInvertTypeDef PWM_Invert)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->PWM_Invert = PWM_Invert;
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_INVERTED_PWM_M);
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (PWM_Invert << TIMER32_CH_CNTRL_INVERTED_PWM_S);
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_Mode_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_ModeTypeDef mode)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->Mode = mode;
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_MODE_M);
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (mode << TIMER32_CH_CNTRL_MODE_S);
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_CaptureEdge_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, HAL_TIMER32_CHANNEL_CaptureEdgeTypeDef captureEdge)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->CaptureEdge = captureEdge;
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_CAPTURE_EDGE_M);
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (captureEdge << TIMER32_CH_CNTRL_CAPTURE_EDGE_S);
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_OCR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t OCR)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->OCR = OCR;
timerChannel->Instance->OCR = OCR;
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint32_t ICR)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->Instance->ICR = ICR;
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_ICR_Clear(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->Instance->ICR = 0;
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Channel_Noise_Set(TIMER32_CHANNEL_HandleTypeDef *timerChannel, uint8_t noise)
{
if (timerChannel->TimerInstance == TIMER32_0)
{
return HAL_ERROR;
}
timerChannel->Noise = noise;
uint32_t timer32_channelcontrol_temp = timerChannel->Instance->CNTRL & (~TIMER32_CH_CNTRL_NOISE_M);
timerChannel->Instance->CNTRL = timer32_channelcontrol_temp | (noise << TIMER32_CH_CNTRL_NOISE_S);
return HAL_OK;
}
void HAL_Timer32_Start(TIMER32_HandleTypeDef *timer)
{
timer->State = TIMER32_STATE_ENABLE;
timer->Instance->ENABLE |= TIMER32_ENABLE_TIM_EN_M;
}
void HAL_Timer32_Stop(TIMER32_HandleTypeDef *timer)
{
timer->State = TIMER32_STATE_DISABLE;
timer->Instance->ENABLE &= ~TIMER32_ENABLE_TIM_EN_M;
}
void HAL_Timer32_Base_Start_IT(TIMER32_HandleTypeDef *timer)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M);
HAL_Timer32_Start(timer);
}
void HAL_Timer32_Base_Stop_IT(TIMER32_HandleTypeDef *timer)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M);
HAL_Timer32_Stop(timer);
}
HAL_StatusTypeDef HAL_Timer32_PWM_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timer->Instance == TIMER32_0)
{
return HAL_ERROR;
}
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_PWM)
{
return HAL_ERROR;
}
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OVERFLOW_M);
/* Включить канал */
HAL_Timer32_Channel_Enable(timerChannel);
/* Запустить счет */
HAL_Timer32_Start(timer);
return HAL_OK;
}
void HAL_Timer32_PWM_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OVERFLOW_M);
/* Включить канал */
HAL_Timer32_Channel_Disable(timerChannel);
/* Запустить счет */
HAL_Timer32_Stop(timer);
}
HAL_StatusTypeDef HAL_Timer32_Compare_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timer->Instance == TIMER32_0)
{
return HAL_ERROR;
}
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_COMPARE)
{
return HAL_ERROR;
}
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex));
/* Включить канал */
HAL_Timer32_Channel_Enable(timerChannel);
/* Запустить счет */
HAL_Timer32_Start(timer);
return HAL_OK;
}
void HAL_Timer32_Compare_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_OC_M(timerChannel->ChannelIndex));
/* Включить канал */
HAL_Timer32_Channel_Disable(timerChannel);
/* Запустить счет */
HAL_Timer32_Stop(timer);
}
HAL_StatusTypeDef HAL_Timer32_Capture_Start_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timer->Instance == TIMER32_0)
{
return HAL_ERROR;
}
if (timerChannel->Mode != TIMER32_CHANNEL_MODE_CAPTURE)
{
return HAL_ERROR;
}
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Set(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex));
/* Включить канал */
HAL_Timer32_Channel_Enable(timerChannel);
/* Запустить счет */
HAL_Timer32_Start(timer);
return HAL_OK;
}
void HAL_Timer32_Capture_Stop_IT(TIMER32_HandleTypeDef *timer, TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Clear(timer, TIMER32_INT_IC_M(timerChannel->ChannelIndex));
/* Включить канал */
HAL_Timer32_Channel_Disable(timerChannel);
/* Запустить счет */
HAL_Timer32_Stop(timer);
}
void HAL_Timer32_Start_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Set(timer, intMask);
/* Запустить счет */
HAL_Timer32_Start(timer);
}
void HAL_Timer32_Stop_IT(TIMER32_HandleTypeDef *timer, uint32_t intMask)
{
/* Включить прерывание по переполнению */
HAL_Timer32_InterruptMask_Clear(timer, intMask);
/* Запустить счет */
HAL_Timer32_Stop(timer);
}

View File

@ -0,0 +1,364 @@
#ifndef MIK32V0
#include "mik32_hal_tsens.h"
/**
* @brief Функция включения тактирования аналогового блока (включающего термосенсор).
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
*/
__attribute__((weak)) void HAL_TSENS_MspInit(TSENS_HandleTypeDef *htsens)
{
__HAL_PCC_ANALOG_REGS_CLK_ENABLE();
}
/**
* @brief Функция начальной инициализации термосенсора.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_TSENS_Init(TSENS_HandleTypeDef *htsens)
{
HAL_StatusTypeDef errorCode = HAL_OK;
HAL_TSENS_MspInit(htsens);
/* Включение, тактирование температурного сенсора, отключение режима сброса. */
ANALOG_REG->TSENS_CFG = (1<<TSENS_CFG_NRST_S)|
(1<<TSENS_CFG_NPD_CLK_S)|
(1<<TSENS_CFG_NPD_S);
// Установка источника тактирования термосенсора.
if ((errorCode = HAL_TSENS_ClockSource(htsens, htsens->Clock)) != HAL_OK)
{
return errorCode;
}
// Подбор делителя для заданной частоты термосенсора.
if ((errorCode = HAL_TSENS_Clock(htsens, htsens->Frequency)) != HAL_OK)
{
return errorCode;
}
return errorCode;
}
/**
* @brief Функция установки источника тактирования термосенсора.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param clk_source источник тактирования термосенсора.
* - @ref HAL_TSENS_SYS_CLK - системная тактовая частота
* - @ref HAL_TSENS_HCLK - частота шины АНВ
* - @ref HAL_TSENS_OSC32M - внешний генератор 32МГц
* - @ref HAL_TSENS_HSI32M - внутренний генератор 32МГц
* - @ref HAL_TSENS_OSC32K - внешний генератор 32кГц
* - @ref HAL_TSENS_LSI32K - внутренний генератор 32кГц
* @return Статус HAL.
* HAL_OK, если источник тактирования установлен успешно
* HAL_ERROR, если входной параметр некорректен.
*/
HAL_StatusTypeDef HAL_TSENS_ClockSource(TSENS_HandleTypeDef *htsens, HAL_TSENS_ClockTypeDef clk_source)
{
switch (clk_source)
{
case HAL_TSENS_SYS_CLK:
case HAL_TSENS_HCLK:
case HAL_TSENS_OSC32M:
case HAL_TSENS_HSI32M:
case HAL_TSENS_OSC32K:
case HAL_TSENS_LSI32K:
break;
default:
return HAL_ERROR;
}
htsens->Clock = clk_source;
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_CLK_MUX_M)) | (clk_source << TSENS_CFG_CLK_MUX_S);
return HAL_OK;
}
/**
* @brief Функция установки делителя частоты для термосенсора.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param clk_div делитель частоты термосенсора.
* Этот параметр может принимать значения от 0 до 1023.
* @return Статус HAL.
* HAL_OK, если делитель частоты установлен успешно;
* HAL_ERROR, если делитель частоты слишком мал или слишком велик для получения частоты термосенсора 0 - 100 кГц.
*/
HAL_StatusTypeDef HAL_TSENS_ClockDivider(TSENS_HandleTypeDef *htsens, uint16_t clk_div)
{
if (clk_div >= 1024) return HAL_ERROR;
clk_div &= 0x3FF;
uint32_t divider;
uint32_t systemFreq = HAL_PCC_GetSysClockFreq();
uint32_t tsensFreq = 0;
switch (htsens->Clock)
{
case HAL_TSENS_SYS_CLK:
divider = (clk_div + 1) << 1;
tsensFreq = systemFreq / divider;
if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR;
break;
case HAL_TSENS_HCLK:
divider = ((uint32_t)PM->DIV_AHB + 1) * ((clk_div + 1) << 1);
tsensFreq = systemFreq / divider;
if ((tsensFreq > 100000UL)||(tsensFreq == 0)) return HAL_ERROR;
break;
case HAL_TSENS_OSC32M:
if (clk_div < (OSC_SYSTEM_VALUE/200000 - 1)) return HAL_ERROR;
tsensFreq = OSC_SYSTEM_VALUE/((1 + clk_div) << 1);
break;
case HAL_TSENS_HSI32M:
if (clk_div < (HSI_VALUE/200000 - 1)) return HAL_ERROR;
tsensFreq = HSI_VALUE/((1 + clk_div) << 1);
break;
case HAL_TSENS_OSC32K:
case HAL_TSENS_LSI32K:
tsensFreq = OSC_CLOCK_VALUE/((1 + clk_div) << 1);
break;
default:
return HAL_ERROR;
}
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (clk_div << TSENS_CFG_DIV_S);
htsens->Frequency = tsensFreq;
return HAL_OK;
}
/**
* @brief Функция установки тактовой частоты для термосенсора.
*
* Функция подбирает делитель для получения наиболее близкой частоты термосенсора к заданной.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param f_enter тактовая частота термосенсора.
* @return Статус HAL.
* HAL_OK, если частота установлена успешно
* HAL_ERROR, если введенная частота не попадает в область допустимых значений частот 0 - 100 кГц или если невозможно подобрать делитель.
*/
HAL_StatusTypeDef HAL_TSENS_Clock(TSENS_HandleTypeDef *htsens, uint32_t f_enter)
{
if ((f_enter > 100000UL)||(f_enter == 0)) return HAL_ERROR;
uint32_t f_real;
uint32_t systemFreq = HAL_PCC_GetSysClockFreq();
switch (htsens->Clock)
{
case HAL_TSENS_SYS_CLK:
f_real = systemFreq; /* Примечание: надо проверить какой источник и входимость в диапазон */
break;
case HAL_TSENS_HCLK:
f_real = systemFreq / (PM->DIV_AHB + 1); /* Примечание: надо проверить какой источник и входимость в диапазон */
break;
case HAL_TSENS_OSC32M:
f_real = OSC_SYSTEM_VALUE;
break;
case HAL_TSENS_HSI32M:
f_real = HSI_VALUE;
break;
case HAL_TSENS_OSC32K:
f_real = OSC_CLOCK_VALUE;
break;
case HAL_TSENS_LSI32K:
f_real = LSI_VALUE;
break;
default:
return HAL_ERROR;
}
uint32_t divider = (f_real / f_enter) >> 1;
if (divider == 0) return HAL_ERROR;
uint32_t pre_result = f_real / (divider << 1);
while ((pre_result > 100000) && (divider <= 0x400))
{
divider += 1;
if (divider > 0x400)
{
return HAL_ERROR;
}
pre_result = f_real / (divider << 1);
}
divider -= 1;
/* Запись данных */
ANALOG_REG->TSENS_CFG = (ANALOG_REG->TSENS_CFG & (~TSENS_CFG_DIV_M)) | (divider<<TSENS_CFG_DIV_S);
htsens->Frequency = f_real / ((1 + divider) << 1);
return HAL_OK;
}
/**
* @brief Функция установки сырого значения нижнего порога температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param low_tres сырое значение нижнего порога температуры.
* Этот параметр может принимать значение от 225 до 603.
* @return Статус HAL.
* HAL_OK, если нижнее пороговое значение установлено успешно;
* HAL_ERROR, если значение low_tres не попадает в диапазон [225, 603].
*/
HAL_StatusTypeDef HAL_TSENS_SetLowThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t low_tres)
{
if (low_tres > 603 || low_tres < 225)
{
return HAL_ERROR;
}
low_tres &= 0x3FF;
htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_LOW_M)) | ((uint32_t)low_tres << TSENS_TRESHOLD_LOW_S);
return HAL_OK;
}
/**
* @brief Функция установки сырого значения верхнего порога температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param hi_tres сырое значение верхнего порога температуры.
* Этот параметр может принимать значение от 225 до 603.
* @return Статус HAL.
* HAL_OK, если верхнее пороговое значение установлено успешно;
* HAL_ERROR, если значение hi_tres не попадает в диапазон [225, 603].
*/
HAL_StatusTypeDef HAL_TSENS_SetHiThresholdRaw(TSENS_HandleTypeDef *htsens, uint16_t hi_tres)
{
if (hi_tres > 603 || hi_tres < 225)
{
return HAL_ERROR;
}
hi_tres &= 0x3FF;
htsens->Instance->TSENS_THRESHOLD = (htsens->Instance->TSENS_THRESHOLD & (~TSENS_TRESHOLD_HI_M)) | ((uint32_t)hi_tres << TSENS_TRESHOLD_HI_S);
return HAL_OK;
}
/**
* @brief Функция установки значения нижнего порога температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param low_temp_border значение нижнего порога температуры в градусах Цельсия.
* Этот параметр может принимать значение от -40 до 125.
* @return Статус HAL.
* HAL_OK, если нижнее пороговое значение установлено успешно;
* HAL_ERROR, если рассчитанное значение нижнего порога не попадает в диапазон [225, 603].
*/
HAL_StatusTypeDef HAL_TSENS_SetLowThreshold(TSENS_HandleTypeDef *htsens, int low_temp_border)
{
return HAL_TSENS_SetLowThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(low_temp_border));
}
/**
* @brief Функция установки значения верхнего порога температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param hi_temp_border значение верхнего порога температуры в градусах Цельсия.
* Этот параметр может принимать значение от -40 до 125.
* @return Статус HAL.
* HAL_OK, если верхнее пороговое значение установлено успешно;
* HAL_ERROR, если рассчитанное значение верхнего порога не попадает в диапазон [225, 603].
*/
HAL_StatusTypeDef HAL_TSENS_SetHiThreshold(TSENS_HandleTypeDef *htsens, int hi_temp_border)
{
return HAL_TSENS_SetHiThresholdRaw(htsens, TSENS_CELSIUS_TO_VALUE(hi_temp_border));
}
/**
* @brief Функция чтения и перевода в градусы Цельсия данных термосенсора.
*
* Функция используется для получения значения температуры в непрерывном режиме измерения (Continuous).
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @return температура в градусах Цельсия, увеличенная в 100 раз.
*/
uint32_t HAL_TSENS_GetTemperature(TSENS_HandleTypeDef *htsens)
{
return TSENS_VALUE_TO_CELSIUS(__HAL_TSENS_READ_MEASUREMENT(htsens));
}
/**
* @brief Запустить непрерывное измерение температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
*/
void HAL_TSENS_ContinuousStart(TSENS_HandleTypeDef *htsens)
{
__HAL_TSENS_RELEASE_RESET(htsens);
__HAL_TSENS_CONTINUOUS_START(htsens);
}
/**
* @brief Запустить одиночное измерение температуры.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
* @param timeout значение таймаута. Если значение 0, то ожидание флага конца преобразования никогда не прервется.
* @return Структура со статусом HAL и измеренным значением температуры.
* @ref TSENS_ValueTypeDef.statusHAL статус HAL
* @ref TSENS_ValueTypeDef.value значение температуры в градусах Цельсия. Значение в 100 раз больше.
*/
TSENS_ValueTypeDef HAL_TSENS_SingleStart(TSENS_HandleTypeDef *htsens, uint32_t timeout)
{
uint32_t timeoutCounter = timeout;
__HAL_TSENS_RELEASE_RESET(htsens);
__HAL_TSENS_SINGLE_START(htsens);
while (!__HAL_TSENS_GET_EOC(htsens))
{
if ((timeoutCounter-- == 0) && (timeout != 0))
{
return (TSENS_ValueTypeDef) {.statusHAL = HAL_TIMEOUT, .value = 0};
}
}
uint32_t rawValue = __HAL_TSENS_READ_MEASUREMENT(htsens);
return (TSENS_ValueTypeDef) {.statusHAL = HAL_OK, .value = TSENS_VALUE_TO_CELSIUS(rawValue)};
}
/**
* @brief Запустить непрерывное измерение температуры с использованием прерываний.
*
* Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения).
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
*/
void HAL_TSENS_ContinuousStart_IT(TSENS_HandleTypeDef *htsens)
{
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
__HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
__HAL_TSENS_RELEASE_RESET(htsens);
__HAL_TSENS_CONTINUOUS_START(htsens);
}
/**
* @brief Запустить одиночное измерение температуры с использованием прерываний.
*
* Включаются все прерывания датчика температуры (окончание преобразование, выход измеренного значения температуры за пороговые значения).
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
*/
void HAL_TSENS_SingleStart_IT(TSENS_HandleTypeDef *htsens)
{
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
__HAL_TSENS_IRQ_ENABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
__HAL_TSENS_RELEASE_RESET(htsens);
__HAL_TSENS_SINGLE_START(htsens);
}
/**
* @brief Прервать измерение температуры и отключить прерывания.
*
* Функция останавливает измерения, выключает все прерывания термосенсора и очищает флаги прерываний.
* @param htsens указатель на структуру TSENS_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля TSENS.
*/
void HAL_TSENS_Stop_IT(TSENS_HandleTypeDef *htsens)
{
__HAL_TSENS_FORCE_RESET(htsens);
__HAL_TSENS_IRQ_DISABLE(htsens, TSENS_IRQ_LOW_MASK_M | TSENS_IRQ_HI_MASK_M | TSENS_IRQ_EOC_MASK_M);
__HAL_TSENS_IRQ_CLEAR(htsens, TSENS_CLEAR_IRQ_LOW_CLEAR_M | TSENS_CLEAR_IRQ_HI_CLEAR_M | TSENS_CLEAR_IRQ_EOC_CLEAR_M);
}
#endif // MIK32V0

View File

@ -0,0 +1,203 @@
#include "mik32_hal_wdt.h"
uint16_t TimeOut = 20;
uint16_t WDT_prescale[] = {1, 2, 4, 16, 64, 256, 1024, 4096};
/**
* @brief Инициализация WDT MSP.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
*
* информацию о конфигурации для модуля WDT.
*/
__attribute__((weak)) void HAL_RTC_MspInit(WDT_HandleTypeDef *hwdt)
{
__HAL_PCC_WDT_CLK_ENABLE();
}
/**
* @brief Расчет начального значения отсчета таймера соответствующее времени до перезагрузки @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs".
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @return Структура с рассчитанным начальным значением @ref WDT_ClockTypeDef.tick и код подобранного делителя частоты @ref WDT_ClockTypeDef.divIndex.
* Значение 0 в @ref WDT_ClockTypeDef.tick означает ошибку при расчете.
*/
WDT_ClockTypeDef HAL_WDT_MillisInClock(WDT_HandleTypeDef *hwdt)
{
uint32_t wdtClock = 0;
if (hwdt->Init.Clock < HAL_WDT_OSC32K)
{
if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32M)
{
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0};
}
wdtClock = WDT_CLOCK32M_VALUE;
}
else
{
if (hwdt->Init.ReloadMs > WDT_MAX_VALUE_CLOCK32K)
{
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0};
}
wdtClock = WDT_CLOCK32K_VALUE;
}
uint32_t tick = 0;
int divIndex = 0;
int countDiv = sizeof(WDT_prescale) / sizeof(*WDT_prescale);
for (divIndex = 0; divIndex < countDiv; divIndex++)
{
tick = ((wdtClock / (WDT_prescale[divIndex])) * hwdt->Init.ReloadMs) / 1000;
if ((tick <= 4095) && (tick != 0))
{
tick = 4095 - tick;
break;
}
else if (divIndex == (countDiv - 1))
{
return (WDT_ClockTypeDef){.tick = 0, .divIndex = 0}; /* Не удалось подобрать делитель для заданного времени отсчета WDT */
}
}
return (WDT_ClockTypeDef){.tick = tick, .divIndex = divIndex};
}
/**
* @brief Инициализировать WDT в соответствии с настройками в @ref WDT_HandleTypeDef.
*
* Функция включает тактирование таймера, задает источник тактирование сторожевого таймера WDT, настраивает делитель частоты
* таймера и начальное значение отсчета в соответствии с временем указанным в @ref WDT_InitTypeDef::ReloadMs "WDT_HandleTypeDef.init.ReloadMs".
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
if (hwdt->Instance != WDT)
{
return HAL_ERROR;
}
HAL_RTC_MspInit(hwdt);
if (HAL_WDT_Stop(hwdt, timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
PM->WDT_CLK_MUX = hwdt->Init.Clock;
WDT_ClockTypeDef wdtClock = HAL_WDT_MillisInClock(hwdt);
if (wdtClock.tick == 0)
{
return HAL_ERROR;
}
uint32_t conValue = (wdtClock.divIndex << WDT_CON_PRESCALE_S) | WDT_CON_PRELOAD(wdtClock.tick);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
return HAL_OK;
}
/**
* @brief Перезагрузка значения сторожевого таймера.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param timeout продолжительность тайм-аута.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_START;
while (timeout--)
{
if (!(hwdt->Instance->STA & WDT_STA_LOADING_M))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
/**
* @brief Запустить таймер WDT.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param timeout продолжительность тайм-аута.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_START;
while (timeout--)
{
if (hwdt->Instance->STA & WDT_STA_ENABLED_M)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
/**
* @brief Остановить таймер.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param timeout продолжительность тайм-аута.
* @return Статус HAL.
*/
HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_STOP;
while (timeout--)
{
if (!(hwdt->Instance->STA & WDT_STA_ENABLED_M))
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
/**
* @brief Задать делитель частоты WDT.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param prescale делитель частоты WDT.
*/
void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale)
{
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRESCALE_M)) | ((prescale << WDT_CON_PRESCALE_S) & WDT_CON_PRESCALE_M);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
}
/**
* @brief Задать начальное значение таймера при запуске или перезапуске.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param preload начальное значение таймера при запуске или перезапуске.
*/
void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload)
{
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRELOAD_M)) | WDT_CON_PRELOAD(preload);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
}

View File

@ -0,0 +1,103 @@
#ifndef MIK32_HAL_SPIFI_W25
#define MIK32_HAL_SPIFI_W25
#ifdef __cplusplus
extern "C" {
#endif
#include "mik32_hal_def.h"
#include "mik32_hal_spifi.h"
typedef enum __HAL_SPIFI_W25_SREGTypeDef
{
W25_SREG1 = 1,
W25_SREG2 = 2,
} HAL_SPIFI_W25_SREGTypeDef;
typedef struct __SPIFI_W25_ManufacturerDeviceIDTypeDef
{
uint8_t Manufacturer;
uint8_t Device;
} W25_ManufacturerDeviceIDTypeDef;
#define SPIFI_W25_SREG1_BUSY_S 0
#define SPIFI_W25_SREG1_BUSY_M (1 << SPIFI_W25_SREG1_BUSY_S)
#define SPIFI_W25_SREG1_WRITE_ENABLE_S 1
#define SPIFI_W25_SREG1_WRITE_ENABLE_M (1 << SPIFI_W25_SREG1_WRITE_ENABLE_S)
#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_S 2
#define SPIFI_W25_SREG1_BLOCK_PROTECT_0_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_0_S)
#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_S 3
#define SPIFI_W25_SREG1_BLOCK_PROTECT_1_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_1_S)
#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_S 4
#define SPIFI_W25_SREG1_BLOCK_PROTECT_2_M (1 << SPIFI_W25_SREG1_BLOCK_PROTECT_2_S)
#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S 5
#define SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_M (1 << SPIFI_W25_SREG1_TOP_BOTTOM_PROTECT_S)
#define SPIFI_W25_SREG1_SECTOR_PROTECT_S 6
#define SPIFI_W25_SREG1_SECTOR_PROTECT_M (1 << SPIFI_W25_SREG1_SECTOR_PROTECT_S)
#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S 7
#define SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_M (1 << SPIFI_W25_SREG1_STATUS_REGISTER_PROTECT_0_S)
#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S 0
#define SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_M (1 << SPIFI_W25_SREG2_STATUS_REGISTER_PROTECT_1_S)
#define SPIFI_W25_SREG2_QUAD_ENABLE_S 1
#define SPIFI_W25_SREG2_QUAD_ENABLE_M (1 << SPIFI_W25_SREG2_QUAD_ENABLE_S)
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S 3
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_1_S)
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S 4
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_2_S)
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S 5
#define SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_M (1 << SPIFI_W25_SREG2_SECURITY_REGISTER_LOCK_BIT_3_S)
#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S 6
#define SPIFI_W25_SREG2_COMPLEMENT_PROTECT_M (1 << SPIFI_W25_SREG2_COMPLEMENT_PROTECT_S)
#define SPIFI_W25_SREG2_SUSPEND_STATUS_S 7
#define SPIFI_W25_SREG2_SUSPEND_STATUS_M (1 << SPIFI_W25_SREG2_SUSPEND_STATUS_S)
void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi);
uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef SREG);
HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2);
void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2);
#include "xprintf.h"
static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
while (timeout-- != 0)
{
if ((HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1) & 1) == 0)
{
return HAL_OK;
}
}
return HAL_TIMEOUT;
}
HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout);
void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address);
void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi);
void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes);
HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi);
HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi);
#ifdef __cplusplus
}
#endif
#endif // MIK32_HAL_W25

View File

@ -0,0 +1,59 @@
#ifndef MIK32_HAL_SSD130
#define MIK32_HAL_SSD130
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SSD1306_128x64
#define SSD1306_128x32
#endif
#define BRIGHTNESS_FULL 0xFF
#define BRIGHTNESS_HAL 0x7F
#define START_PAGE 0
#define END_PAGE 7
#define START_COLUMN 0
#define END_COLUMN 127
/* Десятые часов */
#define START_COLUMN_TH 0
#define END_COLUMN_TH 24
/* Единицы часов */
#define START_COLUMN_H 25
#define END_COLUMN_H 49
/* Разделитель - двоеточие */
#define START_COLUMN_COLON 50
#define END_COLUMN_COLON 74
/* Десятые минут */
#define START_COLUMN_TM 75
#define END_COLUMN_TM 99
/* Единицы минут */
#define START_COLUMN_M 100
#define END_COLUMN_M 124
#define SYMBOL_COLON 58
#define SYMBOL_SMILE 13
#include <stdint.h>
#include "mik32_hal_i2c.h"
/* COM (СЛЕДУЮЩИЙ БАЙТ будет командой), DAT (СЛЕДУЮЩИЙ БАЙТ будет данными) и DATS (ВСЕ СЛЕДУЮЩИЕ БАЙТЫ будут данными) */
#define DATS 0b01000000
#define DAT 0b11000000
#define COM 0b10000000
HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness);
HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page);
HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,257 @@
#include "mik32_hal_spifi_w25.h"
#define SPIFI_W25_WRITE_SREG_BUSY 10000
#define SPIFI_W25_PROGRAM_BUSY 100000
typedef enum __HAL_SPIFI_W25_OPCodesTypeDef
{
// Standard SPI Instructions
WRITE_ENABLE = 0x06,
VOLATILE_SR_WRITE_ENABLE = 0x50,
WRITE_DISABLE = 0x04,
READ_SREG1 = 0x05,
READ_SREG2 = 0x35,
WRITE_SREG = 0x01,
PAGE_PROGRAM = 0x02,
SECTOR_ERASE_4K = 0x20,
BLOCK_ERASE_32K = 0x52,
BLOCK_ERASE_64K = 0xD8,
CHIP_ERASE = 0x60,
ERASE_PROGRAM_SUSPEND = 0x75,
ERASE_PROGRAM_RESUME = 0x7A,
POWER_DOWN = 0xB9,
READ_DATA = 0x03,
FAST_READ = 0x0B,
RELEASE_POWERDOWN_ID = 0xAB,
MANUFACTURER_DEVICE_ID = 0x90,
JEDEC_ID = 0x9F,
READ_UNIQUE_ID = 0x4B,
READ_SFDP_REGISTERS = 0x5A,
ERASE_SECURITY_REGISTERS = 0x44,
PROGRAM_SECURITY_REGISTERS = 0x42,
READ_SECURITY_REGISTERS = 0x48,
ENABLE_QPI = 0x38,
ENABLE_RESET = 0x66,
RESET = 0x99,
// Quad SPI Instructions
QUAD_PAGE_PROGRAM = 0x32,
FAST_READ_QUAD_OUTPUT = 0x6B,
FAST_READ_QUAD_IO = 0xEB,
WORD_READ_QUAD_IO = 0xE7,
OCTAL_WORD_READ_QUAD_IO = 0xE3,
SET_BURST_WITH_WRAP = 0x77,
MANUFACTURER_DEVICE_ID_BY_QUAD_IO = 0x94,
} HAL_SPIFI_W25_OPCodesTypeDef;
#define HAL_SPIFI_W25_SREG2_BUSY 2
const uint32_t cmd_write_enable =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(WRITE_ENABLE);
const uint32_t cmd_volatile_sr_write_enable =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(VOLATILE_SR_WRITE_ENABLE);
const uint32_t cmd_read_sreg1 =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(READ_SREG1);
const uint32_t cmd_read_sreg2 =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(READ_SREG2);
const uint32_t cmd_write_sreg =
SPIFI_DIRECTION_OUTPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(WRITE_SREG);
const uint32_t cmd_page_program =
SPIFI_DIRECTION_OUTPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(PAGE_PROGRAM);
const uint32_t cmd_sector_erase_4k =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(SECTOR_ERASE_4K);
const uint32_t cmd_read_data =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(READ_DATA);
const uint32_t cmd_manufacturer_device_id =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(MANUFACTURER_DEVICE_ID);
const uint32_t cmd_quad_page_program =
SPIFI_DIRECTION_OUTPUT |
SPIFI_CONFIG_CMD_INTLEN(0) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(QUAD_PAGE_PROGRAM);
const uint32_t cmd_fast_read_quad_output =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(1) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_DATA_PARALLEL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_OUTPUT);
const uint32_t cmd_fast_read_quad_io =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_INTLEN(3) |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_OPCODE_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE_3ADDR) |
SPIFI_CONFIG_CMD_OPCODE(FAST_READ_QUAD_IO);
const uint32_t cmd_read_sreg1_polling =
SPIFI_DIRECTION_INPUT |
SPIFI_CONFIG_CMD_POLL_INDEX(0) |
SPIFI_CONFIG_CMD_POLL_REQUIRED_VALUE(0) |
SPIFI_CONFIG_CMD_POLL_M |
SPIFI_CONFIG_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CONFIG_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OPCODE) |
SPIFI_CONFIG_CMD_OPCODE(READ_SREG1);
void HAL_SPIFI_W25_WriteEnable(SPIFI_HandleTypeDef *spifi)
{
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
}
void HAL_SPIFI_W25_VolatileSRWriteEnable(SPIFI_HandleTypeDef *spifi)
{
HAL_SPIFI_SendCommand_LL(spifi, cmd_volatile_sr_write_enable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
}
uint8_t HAL_SPIFI_W25_ReadSREG(SPIFI_HandleTypeDef *spifi, HAL_SPIFI_W25_SREGTypeDef sreg)
{
uint8_t byte = 0;
uint32_t cmd = cmd_read_sreg1;
if (sreg == W25_SREG1)
{
cmd = cmd_read_sreg1;
}
else if (sreg == W25_SREG2)
{
cmd = cmd_read_sreg2;
}
HAL_SPIFI_SendCommand_LL(spifi, cmd, 0, 1, &byte, 0, 0, HAL_SPIFI_TIMEOUT);
return byte;
}
HAL_StatusTypeDef HAL_SPIFI_W25_WriteSREG(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2)
{
uint8_t data[2] = {sreg1, sreg2};
HAL_SPIFI_W25_WriteEnable(spifi);
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT);
return HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_WRITE_SREG_BUSY);
}
void HAL_SPIFI_W25_WriteSREG_Volatile(SPIFI_HandleTypeDef *spifi, uint8_t sreg1, uint8_t sreg2)
{
uint8_t data[2] = {sreg1, sreg2};
HAL_SPIFI_W25_VolatileSRWriteEnable(spifi);
HAL_SPIFI_SendCommand_LL(spifi, cmd_write_sreg, 0, 2, 0, data, 0, HAL_SPIFI_TIMEOUT);
}
HAL_StatusTypeDef HAL_SPIFI_W25_WaitBusy_Polling(SPIFI_HandleTypeDef *spifi, uint32_t timeout)
{
return HAL_SPIFI_SendCommand_LL(spifi, cmd_read_sreg1_polling, 0, 0, 0, 0, 0, timeout);
}
void HAL_SPIFI_W25_PageProgram(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
{
HAL_SPIFI_W25_WriteEnable(spifi);
HAL_SPIFI_SendCommand_LL(spifi, cmd_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT);
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
}
void HAL_SPIFI_W25_SectorErase4K(SPIFI_HandleTypeDef *spifi, uint32_t address)
{
HAL_SPIFI_W25_WriteEnable(spifi);
HAL_SPIFI_SendCommand_LL(spifi, cmd_sector_erase_4k, address, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
}
void HAL_SPIFI_W25_ReadData(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
{
HAL_SPIFI_SendCommand_LL(spifi, cmd_read_data, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
}
W25_ManufacturerDeviceIDTypeDef HAL_SPIFI_W25_ReadManufacturerDeviceID(SPIFI_HandleTypeDef *spifi)
{
uint8_t data[2] = {0};
HAL_SPIFI_SendCommand_LL(spifi, cmd_manufacturer_device_id, 0, 2, data, 0, 0, HAL_SPIFI_TIMEOUT);
return (W25_ManufacturerDeviceIDTypeDef){
.Manufacturer = data[0],
.Device = data[1],
};
}
void HAL_SPIFI_W25_PageProgram_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
{
HAL_SPIFI_W25_WriteEnable(spifi);
HAL_SPIFI_SendCommand_LL(spifi, cmd_quad_page_program, address, dataLength, 0, dataBytes, 0, HAL_SPIFI_TIMEOUT);
HAL_SPIFI_W25_WaitBusy(spifi, SPIFI_W25_PROGRAM_BUSY);
}
void HAL_SPIFI_W25_ReadData_Quad(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
{
HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_output, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
}
void HAL_SPIFI_W25_ReadData_Quad_IO(SPIFI_HandleTypeDef *spifi, uint32_t address, uint16_t dataLength, uint8_t *dataBytes)
{
HAL_SPIFI_SendCommand_LL(spifi, cmd_fast_read_quad_io, address, dataLength, dataBytes, 0, 0, HAL_SPIFI_TIMEOUT);
}
HAL_StatusTypeDef HAL_SPIFI_W25_QuadEnable(SPIFI_HandleTypeDef *spifi)
{
uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1);
uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2);
return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 | HAL_SPIFI_W25_SREG2_BUSY);
}
HAL_StatusTypeDef HAL_SPIFI_W25_QuadDisable(SPIFI_HandleTypeDef *spifi)
{
uint8_t sreg1 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG1);
uint8_t sreg2 = HAL_SPIFI_W25_ReadSREG(spifi, W25_SREG2);
return HAL_SPIFI_W25_WriteSREG(spifi, sreg1, sreg2 & (~HAL_SPIFI_W25_SREG2_BUSY));
}

View File

@ -0,0 +1,241 @@
#include "mik32_hal_ssd1306.h"
// Адрес ведомого
uint16_t slave_address = 0b00111100;
uint8_t data_test[] = {
DATS,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/*Символы для SSD1306 128x32*/
/* Символ ":)" */
uint8_t data_symbol_smile[] = {
DATS,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0,
0x00, 0x01, 0x02, 0x07, 0x0F, 0x1E, 0x3C, 0x38, 0x38, 0x78, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, 0x38, 0x38, 0x3C, 0x1E, 0x0F, 0x07, 0x02, 0x01, 0x00
};
/* Символ ":" */
uint8_t data_symbol_colon[] = {
DATS,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* Символ "0" */
uint8_t data_symbol_null[] = {
DATS,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
};
/* Символ "1" */
uint8_t data_symbol_one[] = {
DATS,
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00
};
/* Символ "2" */
uint8_t data_symbol_two[] = {
DATS,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFC, 0xFC, 0xFC, 0xFC, 0x1F, 0x1F, 0x1F, 0x1F, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00
};
/* Символ "3" */
uint8_t data_symbol_three[] = {
DATS,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
};
/* Символ "4" */
uint8_t data_symbol_four[] = {
DATS,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xE3, 0xE3, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
};
/* Символ "5" */
uint8_t data_symbol_five[] = {
DATS,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x01, 0x00, 0x00
};
/* Символ "6" */
uint8_t data_symbol_six[] = {
DATS,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x38, 0x38, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
};
/* Символ "7" */
uint8_t data_symbol_seven[] = {
DATS,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x8F, 0x8F, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* Символ "8" */
uint8_t data_symbol_eight[] = {
DATS,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x00, 0x00,
0x00, 0x00, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x00, 0x00
};
/* Символ "9" */
uint8_t data_symbol_nine[] = {
DATS,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x03, 0x03, 0x03, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};
HAL_StatusTypeDef HAL_SSD1306_Init(I2C_HandleTypeDef *hi2c, uint8_t brightness)
{
// for (volatile int i = 0; i < 1000; i++);
uint8_t Set_MUX_Ratio, Set_COM_Pins;
#ifdef SSD1306_128x64
Set_MUX_Ratio = 0x3F;
Set_COM_Pins = 0x12;
#endif
#ifdef SSD1306_128x32
Set_MUX_Ratio = 0x1F;
Set_COM_Pins = 0x02;
#endif
/* Массив для стандартной инициализации */
uint8_t data_init[] = {
COM, 0xA8, COM, Set_MUX_Ratio, // Set MUX Ratio // 0x3F - 128x64; 0x1F - 128x32
COM, 0xD3, COM, 0x00, // Set Display Offset
COM, 0x40, // Set Display Start Line
COM, 0xA1, // Set Segment re-map
COM, 0xC8, // Set COM Output Scan Direction
COM, 0xDA, COM, Set_COM_Pins,// Set COM Pins hardware configuration. 0x12 - 128x64; 0x02 - 128x32
COM, 0x81, COM, brightness, // Set Contrast Control
COM, 0xA4, // Disable Entire Display On
COM, 0xA6, // Set Normal Display
COM, 0xD5, COM, 0x80, // Set Osc Frequency
COM, 0x8D,COM, 0x14, // Enable charge pump regulator
COM, 0xAF // Display On
};
/* Oled_init - инициализация экрана в стандартном режиме */
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_init, sizeof(data_init), I2C_TIMEOUT_DEFAULT);
}
HAL_StatusTypeDef HAL_SSD1306_SetBorder(I2C_HandleTypeDef *hi2c, uint8_t start_col, uint8_t end_col, uint8_t start_page, uint8_t end_page)
{
uint8_t data_SetBorder[] = {
COM, 0x21, // установка адреса колонок
COM, start_col, // номер стартовой колонки
COM, end_col, // номер конечной колонки
COM, 0x22, // установка адреса страницы
COM, start_page, // номер стартовой страницы
COM, end_page, // номер конечной страницы
};
/* set_border - установка границ вывода на дисплей */
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_SetBorder, sizeof(data_SetBorder), I2C_TIMEOUT_DEFAULT);
}
HAL_StatusTypeDef HAL_SSD1306_CLR_SCR(I2C_HandleTypeDef *hi2c)
{
uint8_t data_CLR_SCR[517] = {COM, 0x20, COM, 0x00, // Horizontal Addressing Mode
DATS};
int counter = 5;
for (int page = 0; page < 4; page++)
{
for(int col = 0; col < 128; col++)
{
data_CLR_SCR[counter] = (uint8_t)0;
counter++;
}
}
/* CLR_SCR - очищение всего экрана в горизонтальном режиме*/
return HAL_I2C_Master_Transmit(hi2c, slave_address, data_CLR_SCR, sizeof(data_CLR_SCR), I2C_TIMEOUT_DEFAULT);
}
HAL_StatusTypeDef HAL_SSD1306_Write(I2C_HandleTypeDef *hi2c, uint8_t symbol)
{
// for (volatile int i = 0; i < 1000; i++);
HAL_StatusTypeDef error_code = HAL_OK;
switch (symbol)
{
case 0:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_null, sizeof(data_symbol_null), I2C_TIMEOUT_DEFAULT);
break;
case 1:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_one, sizeof(data_symbol_one), I2C_TIMEOUT_DEFAULT);
break;
case 2:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_two, sizeof(data_symbol_two), I2C_TIMEOUT_DEFAULT);
break;
case 3:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_three, sizeof(data_symbol_three), I2C_TIMEOUT_DEFAULT);
break;
case 4:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_four, sizeof(data_symbol_four), I2C_TIMEOUT_DEFAULT);
break;
case 5:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_five, sizeof(data_symbol_five), I2C_TIMEOUT_DEFAULT);
break;
case 6:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_six, sizeof(data_symbol_six), I2C_TIMEOUT_DEFAULT);
break;
case 7:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_seven, sizeof(data_symbol_seven), I2C_TIMEOUT_DEFAULT);
break;
case 8:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_eight, sizeof(data_symbol_eight), I2C_TIMEOUT_DEFAULT);
break;
case 9:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_nine, sizeof(data_symbol_nine), I2C_TIMEOUT_DEFAULT);
break;
case SYMBOL_SMILE:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_smile, sizeof(data_symbol_smile), I2C_TIMEOUT_DEFAULT);
break;
default:
error_code = HAL_I2C_Master_Transmit(hi2c, slave_address, data_symbol_colon, sizeof(data_symbol_colon), I2C_TIMEOUT_DEFAULT);
break;
}
return error_code;
}

52
cores/arduino/mik32/shared/.gitignore vendored Normal file
View File

@ -0,0 +1,52 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

View File

@ -0,0 +1,13 @@
# mik32v2-shared
The repository contains header files, startup files, linking scripts and some basic libraries related to MIK32 V2
* include/ - header files of the controller core
* mcu32_memory_map.h - memory map, bus clocking masks, interrupt lines and DMA
* ldscripts/ - linker scripts
* eeprom.ld - loading from ROM
* ram.ld - loading from RAM
* spifi.ld - loading from SPIFI
* libs/ - periphery libraries
* periphery/ - periphery register header files
* runtime/crt0.S - start file

View File

@ -0,0 +1,119 @@
/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
/// @file <csr.h>
/// Architecture specific CSR's defs and inlines
#ifndef SCR_CSR_H
#define SCR_CSR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#define __xstringify(s) __stringify(s)
#define __stringify(s) #s
#ifdef read_csr
#undef read_csr
#endif
#ifdef write_csr
#undef write_csr
#endif
#ifdef swap_csr
#undef swap_csr
#endif
#ifdef set_csr
#undef set_csr
#endif
#ifdef clear_csr
#undef clear_csr
#endif
#ifdef rdtime
#undef rdtime
#endif
#ifdef rdcycle
#undef rdcycle
#endif
#ifdef rdinstret
#undef rdinstret
#endif
#define read_csr(reg) \
({ \
unsigned long __tmp; \
asm volatile ("csrr %0, " __xstringify(reg) : "=r"(__tmp)); \
__tmp; \
})
#define write_csr(reg, val) \
do { \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " __xstringify(reg) ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " __xstringify(reg) ", %0" :: "r"(val)); \
} while (0)
#define swap_csr(reg, val) \
({ \
unsigned long __tmp; \
if (__builtin_constant_p(val) && (val) == 0) \
asm volatile ("csrrw %0, " __xstringify(reg) ", zero" : "=r"(__tmp) :); \
else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(val)); \
else \
asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(val)); \
__tmp; \
})
#define set_csr(reg, bit) \
({ \
unsigned long __tmp; \
if (__builtin_constant_p(bit) && (bit) < 32) \
asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; \
})
#define clear_csr(reg, bit) \
({ \
unsigned long __tmp; \
if (__builtin_constant_p(bit) && (bit) < 32) \
asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; \
})
#define rdtime() read_csr(time)
#define rdcycle() read_csr(cycle)
#define rdinstret() read_csr(instret)
static inline unsigned long __attribute__((const)) cpuid()
{
unsigned long res;
asm ("csrr %0, mcpuid" : "=r"(res));
return res;
}
static inline unsigned long __attribute__((const)) impid()
{
unsigned long res;
asm ("csrr %0, mimpid" : "=r"(res));
return res;
}
#ifdef __cplusplus
}
#endif
#endif // SCR_CSR_H

View File

@ -0,0 +1,250 @@
#ifndef MCU32_MEMORY_MAP_H_INCLUDED
#define MCU32_MEMORY_MAP_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#define EEPROM_BASE_ADDRESS 0x01000000
#define EEPROM_SIZE (16*1024)
#define RAM_BASE_ADDRESS 0x02000000
#define RAM_SIZE (16*1024)
#define SPIFI_BASE_ADDRESS 0x80000000
#define SPIFI_SIZE (2*1024*1024)
#define BOOT_BASE_ADDRESS 0x00000000
#define BOOT_SIZE (16*1024)
#define APB_PERIPH_STEP 0x00000400
#define DMA_CONFIG_BASE_ADDRESS 0x000040000
#define APB_DOM_0_BASE_ADDRESS 0x000050000
#define PM_BASE_ADDRESS 0x000050000
#define EPIC_BASE_ADDRESS 0x000050400
#define TIMER32_0_BASE_ADDRESS 0x000050800
#define PAD_CONFIG_BASE_ADDRESS 0x000050c00
#define WDT_BUS_BASE_ADDRESS 0x000051000
#define OTP_BASE_ADDRESS 0x000051400
#define PVD_CONTROL_BASE_ADDRESS 0x000051800
#define WU_BASE_ADDRESS 0x00060000
#define RTC_BASE_ADDRESS 0x00060400
#define BOOT_MANAGER_BASE_ADDRESS 0x00060800
#define SPIFI_CONFIG_BASE_ADDRESS 0x00070000
#define EEPROM_REGS_BASE_ADDRESS 0x00070400
#define CRYPTO_BASE_ADDRESS 0x00080000
#define CRC_BASE_ADDRESS 0x00080400
#define APB_DOM_3_BASE_ADDRESS 0x00081000
#define WDT_BASE_ADDRESS 0x00081000
#define UART_0_BASE_ADDRESS 0x00081400
#define UART_1_BASE_ADDRESS 0x00081800
#define TIMER16_0_BASE_ADDRESS 0x00081C00
#define TIMER16_1_BASE_ADDRESS 0x00082000
#define TIMER16_2_BASE_ADDRESS 0x00082400
#define TIMER32_1_BASE_ADDRESS 0x00082800
#define TIMER32_2_BASE_ADDRESS 0x00082C00
#define SPI_0_BASE_ADDRESS 0x00083000
#define SPI_1_BASE_ADDRESS 0x00083400
#define I2C_0_BASE_ADDRESS 0x00083800
#define I2C_1_BASE_ADDRESS 0x00083C00
#define GPIO_0_BASE_ADDRESS 0x00084000
#define GPIO_1_BASE_ADDRESS 0x00084400
#define GPIO_2_BASE_ADDRESS 0x00084800
#define GPIO_IRQ_BASE_ADDRESS 0x00084C00
#define ANALOG_REG_BASE_ADDRESS 0x00085000
#define SCR1_TIMER_BASE_ADDRESS 0x00490000
#define DMA_CONFIG (( DMA_CONFIG_TypeDef *) DMA_CONFIG_BASE_ADDRESS )
#define PM (( PM_TypeDef *) PM_BASE_ADDRESS )
#define EPIC (( EPIC_TypeDef *) EPIC_BASE_ADDRESS )
#define TIMER32_0 (( TIMER32_TypeDef *) TIMER32_0_BASE_ADDRESS )
#define PVD_CONTROL (( PVD_CONTROL_TypeDef *) PVD_CONTROL_BASE_ADDRESS )
#define PAD_CONFIG (( PAD_CONFIG_TypeDef *) PAD_CONFIG_BASE_ADDRESS )
#define WDT_BUS (( WDT_BUS_TypeDef *) WDT_BUS_BASE_ADDRESS )
#define OTP (( OTP_TypeDef *) OTP_BASE_ADDRESS )
#define WU (( WU_TypeDef *) WU_BASE_ADDRESS )
#define RTC (( RTC_TypeDef *) RTC_BASE_ADDRESS )
#define BOOT_MANAGER (( BOOT_MANAGER_TypeDef *) BOOT_MANAGER_BASE_ADDRESS )
#define SPIFI_CONFIG (( SPIFI_CONFIG_TypeDef *) SPIFI_CONFIG_BASE_ADDRESS )
#define EEPROM_REGS (( EEPROM_REGS_TypeDef *) EEPROM_REGS_BASE_ADDRESS )
#define CRYPTO (( CRYPTO_TypeDef *) CRYPTO_BASE_ADDRESS )
#define CRC (( CRC_TypeDef *) CRC_BASE_ADDRESS )
#define WDT (( WDT_TypeDef *) WDT_BASE_ADDRESS )
#define UART_0 (( UART_TypeDef *) UART_0_BASE_ADDRESS )
#define UART_1 (( UART_TypeDef *) UART_1_BASE_ADDRESS )
#define TIMER16_0 (( TIMER16_TypeDef *) TIMER16_0_BASE_ADDRESS )
#define TIMER16_1 (( TIMER16_TypeDef *) TIMER16_1_BASE_ADDRESS )
#define TIMER16_2 (( TIMER16_TypeDef *) TIMER16_2_BASE_ADDRESS )
#define TIMER32_1 (( TIMER32_TypeDef *) TIMER32_1_BASE_ADDRESS )
#define TIMER32_2 (( TIMER32_TypeDef *) TIMER32_2_BASE_ADDRESS )
#define SPI_0 (( SPI_TypeDef *) SPI_0_BASE_ADDRESS )
#define SPI_1 (( SPI_TypeDef *) SPI_1_BASE_ADDRESS )
#define I2C_0 (( I2C_TypeDef *) I2C_0_BASE_ADDRESS )
#define I2C_1 (( I2C_TypeDef *) I2C_1_BASE_ADDRESS )
#define GPIO_0 (( GPIO_TypeDef *) GPIO_0_BASE_ADDRESS )
#define GPIO_1 (( GPIO_TypeDef *) GPIO_1_BASE_ADDRESS )
#define GPIO_2 (( GPIO_TypeDef *) GPIO_2_BASE_ADDRESS )
#define GPIO_IRQ (( GPIO_IRQ_TypeDef *) GPIO_IRQ_BASE_ADDRESS )
#define ANALOG_REG (( ANALOG_REG_TypeDef *) ANALOG_REG_BASE_ADDRESS )
#define SCR1_TIMER (( SCR1_TIMER_TypeDef *) SCR1_TIMER_BASE_ADDRESS )
// Clock gating masks to be used with PM module
//AHB BUS
#define PM_CLOCK_AHB_CPU_S 0
#define PM_CLOCK_AHB_CPU_M (1 << PM_CLOCK_AHB_CPU_S)
#define PM_CLOCK_AHB_EEPROM_S 1
#define PM_CLOCK_AHB_EEPROM_M (1 << PM_CLOCK_AHB_EEPROM_S)
#define PM_CLOCK_AHB_RAM_S 2
#define PM_CLOCK_AHB_RAM_M (1 << PM_CLOCK_AHB_RAM_S)
#define PM_CLOCK_AHB_SPIFI_S 3
#define PM_CLOCK_AHB_SPIFI_M (1 << PM_CLOCK_AHB_SPIFI_S)
#define PM_CLOCK_AHB_TCB_S 4
#define PM_CLOCK_AHB_TCB_M (1 << PM_CLOCK_AHB_TCB_S)
#define PM_CLOCK_AHB_DMA_S 5
#define PM_CLOCK_AHB_DMA_M (1 << PM_CLOCK_AHB_DMA_S)
#define PM_CLOCK_AHB_CRYPTO_S 6
#define PM_CLOCK_AHB_CRYPTO_M (1 << PM_CLOCK_AHB_CRYPTO_S)
#define PM_CLOCK_AHB_CRC32_S 7
#define PM_CLOCK_AHB_CRC32_M (1 << PM_CLOCK_AHB_CRC32_S)
//APB M BUS
#define PM_CLOCK_APB_M_PM_S 0
#define PM_CLOCK_APB_M_PM_M (1 << PM_CLOCK_APB_M_PM_S)
#define PM_CLOCK_APB_M_EPIC_S 1
#define PM_CLOCK_APB_M_EPIC_M (1 << PM_CLOCK_APB_M_EPIC_S)
#define PM_CLOCK_APB_M_TIMER32_0_S 2
#define PM_CLOCK_APB_M_TIMER32_0_M (1 << PM_CLOCK_APB_M_TIMER32_0_S)
#define PM_CLOCK_APB_M_PAD_CONFIG_S 3
#define PM_CLOCK_APB_M_PAD_CONFIG_M (1 << PM_CLOCK_APB_M_PAD_CONFIG_S)
#define PM_CLOCK_APB_M_WDT_BUS_S 4
#define PM_CLOCK_APB_M_WDT_BUS_M (1 << PM_CLOCK_APB_M_WDT_BUS_S)
#define PM_CLOCK_APB_M_OTP_CONTROLLER_S 5
#define PM_CLOCK_APB_M_OTP_CONTROLLER_M (1 << PM_CLOCK_APB_M_OTP_CONTROLLER_S)
#define PM_CLOCK_APB_M_PVD_CONTROL_S 6
#define PM_CLOCK_APB_M_PVD_CONTROL_M (1 << PM_CLOCK_APB_M_PVD_CONTROL_S)
#define PM_CLOCK_APB_M_WU_S 7
#define PM_CLOCK_APB_M_WU_M (1 << PM_CLOCK_APB_M_WU_S)
#define PM_CLOCK_APB_M_RTC_S 8
#define PM_CLOCK_APB_M_RTC_M (1 << PM_CLOCK_APB_M_RTC_S)
//APB P BUS
#define PM_CLOCK_APB_P_WDT_S 0
#define PM_CLOCK_APB_P_WDT_M (1 << PM_CLOCK_APB_P_WDT_S)
#define PM_CLOCK_APB_P_UART_0_S 1
#define PM_CLOCK_APB_P_UART_0_M (1 << PM_CLOCK_APB_P_UART_0_S)
#define PM_CLOCK_APB_P_UART_1_S 2
#define PM_CLOCK_APB_P_UART_1_M (1 << PM_CLOCK_APB_P_UART_1_S)
#define PM_CLOCK_APB_P_TIMER16_0_S 3
#define PM_CLOCK_APB_P_TIMER16_0_M (1 << PM_CLOCK_APB_P_TIMER16_0_S)
#define PM_CLOCK_APB_P_TIMER16_1_S 4
#define PM_CLOCK_APB_P_TIMER16_1_M (1 << PM_CLOCK_APB_P_TIMER16_1_S)
#define PM_CLOCK_APB_P_TIMER16_2_S 5
#define PM_CLOCK_APB_P_TIMER16_2_M (1 << PM_CLOCK_APB_P_TIMER16_2_S)
#define PM_CLOCK_APB_P_TIMER32_1_S 6
#define PM_CLOCK_APB_P_TIMER32_1_M (1 << PM_CLOCK_APB_P_TIMER32_1_S)
#define PM_CLOCK_APB_P_TIMER32_2_S 7
#define PM_CLOCK_APB_P_TIMER32_2_M (1 << PM_CLOCK_APB_P_TIMER32_2_S)
#define PM_CLOCK_APB_P_SPI_0_S 8
#define PM_CLOCK_APB_P_SPI_0_M (1 << PM_CLOCK_APB_P_SPI_0_S)
#define PM_CLOCK_APB_P_SPI_1_S 9
#define PM_CLOCK_APB_P_SPI_1_M (1 << PM_CLOCK_APB_P_SPI_1_S)
#define PM_CLOCK_APB_P_I2C_0_S 10
#define PM_CLOCK_APB_P_I2C_0_M (1 << PM_CLOCK_APB_P_I2C_0_S)
#define PM_CLOCK_APB_P_I2C_1_S 11
#define PM_CLOCK_APB_P_I2C_1_M (1 << PM_CLOCK_APB_P_I2C_1_S)
#define PM_CLOCK_APB_P_GPIO_0_S 12
#define PM_CLOCK_APB_P_GPIO_0_M (1 << PM_CLOCK_APB_P_GPIO_0_S)
#define PM_CLOCK_APB_P_GPIO_1_S 13
#define PM_CLOCK_APB_P_GPIO_1_M (1 << PM_CLOCK_APB_P_GPIO_1_S)
#define PM_CLOCK_APB_P_GPIO_2_S 14
#define PM_CLOCK_APB_P_GPIO_2_M (1 << PM_CLOCK_APB_P_GPIO_2_S)
#define PM_CLOCK_APB_P_ANALOG_REGS_S 15
#define PM_CLOCK_APB_P_ANALOG_REGS_M (1 << PM_CLOCK_APB_P_ANALOG_REGS_S)
#define PM_CLOCK_APB_P_GPIO_IRQ_S 16
#define PM_CLOCK_APB_P_GPIO_IRQ_M (1 << PM_CLOCK_APB_P_GPIO_IRQ_S)
// Timer connection to PM multiplexor controling timer inputs
//
#define PM_TIMER32_0_INDEX 0
#define PM_TIMER32_1_INDEX 1
#define PM_TIMER32_2_INDEX 2
#define PM_TIMER16_0_INDEX 3
#define PM_TIMER16_1_INDEX 4
#define PM_TIMER16_2_INDEX 5
// Interrupt lines to be used with EPIC module
//
#define EPIC_TIMER32_0_INDEX 0
#define EPIC_UART_0_INDEX 1
#define EPIC_UART_1_INDEX 2
#define EPIC_SPI_0_INDEX 3
#define EPIC_SPI_1_INDEX 4
#define EPIC_GPIO_IRQ_INDEX 5
#define EPIC_I2C_0_INDEX 6
#define EPIC_I2C_1_INDEX 7
#define EPIC_WDT_INDEX 8
#define EPIC_TIMER16_0_INDEX 9
#define EPIC_TIMER16_1_INDEX 10
#define EPIC_TIMER16_2_INDEX 11
#define EPIC_TIMER32_1_INDEX 12
#define EPIC_TIMER32_2_INDEX 13
#define EPIC_SPIFI_INDEX 14
#define EPIC_RTC_INDEX 15
#define EPIC_EEPROM_INDEX 16
#define EPIC_WDT_DOM3_INDEX 17
#define EPIC_WDT_SPIFI_INDEX 18
#define EPIC_WDT_EEPROM_INDEX 19
#define EPIC_DMA_INDEX 20
#define EPIC_FREQ_MON_INDEX 21
#define EPIC_PVD_AVCC_UNDER 22
#define EPIC_PVD_AVCC_OVER 23
#define EPIC_PVD_VCC_UNDER 24
#define EPIC_PVD_VCC_OVER 25
#define EPIC_BATTERY_NON_GOOD 26
#define EPIC_BOR_INDEX 27
#define EPIC_TSENS_INDEX 28
#define EPIC_ADC_INDEX 29
#define EPIC_DAC0_INDEX 30
#define EPIC_DAC1_INDEX 31
// DMA request lines
//
#define DMA_UART_0_INDEX 0
#define DMA_UART_1_INDEX 1
#define DMA_CRYPTO_INDEX 2
#define DMA_SPI_0_INDEX 3
#define DMA_SPI_1_INDEX 4
#define DMA_I2C_0_INDEX 5
#define DMA_I2C_1_INDEX 6
#define DMA_SPIFI_INDEX 7
#define DMA_TIMER32_1_INDEX 8
#define DMA_TIMER32_2_INDEX 9
#define DMA_DAC0_INDEX 10
#define DMA_DAC1_INDEX 11
#define DMA_TIMER32_0_INDEX 12
#ifdef __cplusplus
}
#endif
#endif // MCU32_MEMORY_MAP_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
#ifndef SCR1_CSR_ENCODING_H
#define SCR1_CSR_ENCODING_H
#ifdef __cplusplus
extern "C" {
#endif
// Bit mask and register value list is based on
// SCR1 External Architecture Specification
// (3.2.4. Machine Mode Standard CSRs)
#define MVENDORID_VALUE 0x0
#define MARCHID_VALUE 0x8
#define MIMPID_VALUE 0x19083000
// MSTATUS masks
//
#define MSTATUS_MIE (0x1 << 3)
#define MSTATUS_MPIE (0x1 << 7)
#define MSTATUS_MPP (0x3 << 11)
// MISA
//
#define MISA_RVC (0x1 << 2)
#define MISA_RVE (0x1 << 4)
#define MISA_RVI (0x1 << 8)
#define MISA_RVM (0x1 << 12)
#define MISA_RVX (0x1 << 23)
#define MISA_MXL (0x3 << 30)
// MIE
//
#define MIE_MSIE (0x1 << 3)
#define MIE_MTIE (0x1 << 7)
#define MIE_MEIE (0x1 << 11)
// MTVEC
//
#define MTVEC_MODE (0x3 << 0)
#define MTVEC_MODE_DIRECT (0x0 << 0)
#define MTVEC_MODE_VECTORED (0x1 << 0)
#define MTVEC_BASE (0xFFFFFFFF & 0xFFFFFFC0)
// MSCRATCH
// MEPC
// MCAUSE
//
#define MCAUSE_EC (0xF << 0)
#define MCAUSE_INT (0x1 << 31)
#define MCAUSE_INSTRUCTION_ADDRESS_MISALIGNED 0
#define MCAUSE_INSTRUCTION_ACCESS_FAULT 1
#define MCAUSE_ILLEGAL_INSTRUCTION 2
#define MCAUSE_BREAKPOINT 3
#define MCAUSE_LOAD_ADDRESS_MISSALIGNED 4
#define MCAUSE_LOAD_ACCESS_FAULT 5
#define MCAUSE_STORE_ADDRESS_MISALIGNED 6
#define MCAUSE_STORE_ACCESS_FAULT 7
//
#define MCAUSE_ECALL_FROM_M_MODE 11
//
#define MCAUSE_MACHINE_SOFTWARE_INTERRUPT 0x80000003
#define MCAUSE_MACHINE_TIMER_INTERRUPT 0x80000007
#define MCAUSE_MACHINE_EXTERNAL_INTERRUPT 0x8000000B
// MTVAL
// MIP
//
#define MIP_MSIP (0x1 << 3)
#define MIP_MTIP (0x1 << 7)
#define MIP_MEIP (0x1 << 11)
// MCYCLE
// MCYCLEH
// MINSTRET
// MINSTRETH
// MCOUNTEN
#define MCOUNTEN_CY (1 << 0)
#define MCOUNTEN_IR (1 << 2)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef __SCR1__SPECIFIC
#define __SCR1__SPECIFIC
#ifdef __cplusplus
extern "C" {
#endif
#define mcounten 0x7E0
// Memory-mapped registers
#define mtime_base 0x00490000
#define mtime_ctrl_offs 0x00
#define mtime_div_offs 0x04
#define mtime_offs 0x08
#define mtimeh_offs 0x0C
#define mtimecmp_offs 0x10
#define mtimecmph_offs 0x14
#define mtime_ctrl mtime_base+mtime_ctrl_offs
#define mtime_div mtime_base+mtime_div_offs
#define mtime mtime_base+mtime_offs
#define mtimeh mtime_base+mtimeh_offs
#define mtimecmp mtime_base+mtimecmp_offs
#define mtimecmph mtime_base+mtimecmph_offs
#define SCR1_MTIME_CTRL_EN 0
#define SCR1_MTIME_CTRL_CLKSRC 1
#define SCR1_MTIME_CTRL_WR_MASK 0x3
#define SCR1_MTIME_DIV_WR_MASK 0x3FF
#ifdef __cplusplus
}
#endif
#endif // _SCR1__SPECIFIC

View File

@ -0,0 +1,92 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
rom (RX): ORIGIN = 0x01000000, LENGTH = 8K
ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K
}
STACK_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(rom) : {
PROVIDE(__TEXT_START__ = .);
*crt0.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(rom) + 0xC0;
KEEP(*crt0.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} >rom
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section")
/* thread-local data segment */
.tdata : {
PROVIDE(_tls_data = .);
PROVIDE(_tdata_begin = .);
*(.tdata .tdata.*)
PROVIDE(_tdata_end = .);
. = ALIGN(CL_SIZE);
} >ram
.tbss : {
PROVIDE(__BSS_START__ = .);
*(.tbss .tbss.*)
. = ALIGN(CL_SIZE);
PROVIDE(_tbss_end = .);
} >ram
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} >ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,98 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
boot : ORIGIN = 0x00000000, LENGTH = 16K
ram : ORIGIN = 0x02000000, LENGTH = 16K
spifi : ORIGIN = 0x80000000, LENGTH = DEFINED(SPIFI_LENGTH) ? SPIFI_LENGTH : 256M
}
STACK_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.boot :
AT(ORIGIN(spifi)) {
PROVIDE(__BOOT_START__ = .);
*crt0.o(.text .text.*)
*(.boot)
. = ALIGN(CL_SIZE);
PROVIDE(__BOOT_END__ = .);
} > boot
/* Placeholder for boot section */
.text ORIGIN(spifi) + SIZEOF(.boot) : {
PROVIDE(__TEXT_START__ = .);
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} > spifi
.data :
AT( ALIGN(__TEXT_END__, CL_SIZE) ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} > ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(spifi) + LENGTH(spifi), "Data image overflows spifi section")
/* bss segment */
.sbss : {
PROVIDE(__BSS_START__ = .);
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} > ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} > ram
/* Code intended to be copied to RAM before execution */
.ram_text :
AT( ALIGN(__DATA_IMAGE_END__, CL_SIZE) ) {
PROVIDE(__RAM_TEXT_START__ = .);
*(.ram_text)
. = ALIGN(CL_SIZE);
PROVIDE(__RAM_TEXT_END__ = .);
} > ram
__RAM_TEXT_IMAGE_START__ = LOADADDR(.ram_text);
__RAM_TEXT_IMAGE_END__ = LOADADDR(.ram_text) + SIZEOF(.ram_text);
ASSERT(__RAM_TEXT_IMAGE_END__ < ORIGIN(spifi) + LENGTH(spifi), "RAM text image overflows spifi section")
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} > ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,91 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K
}
STACK_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(ram) : {
PROVIDE(__TEXT_START__ = .);
*crt0.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(ram) + 0xC0;
KEEP(*crt0.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} >ram
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(ram) + LENGTH(ram) - STACK_SIZE, "Data image overflows ram section")
/* thread-local data segment */
.tdata : {
PROVIDE(_tls_data = .);
PROVIDE(_tdata_begin = .);
*(.tdata .tdata.*)
PROVIDE(_tdata_end = .);
. = ALIGN(CL_SIZE);
} >ram
.tbss : {
PROVIDE(__BSS_START__ = .);
*(.tbss .tbss.*)
. = ALIGN(CL_SIZE);
PROVIDE(_tbss_end = .);
} >ram
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} >ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,92 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
rom (RX): ORIGIN = 0x02000000, LENGTH = 8K
ram (RWX): ORIGIN = 0x02002000, LENGTH = 8K
}
STACK_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(rom) : {
PROVIDE(__TEXT_START__ = .);
*crt0.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(rom) + 0xC0;
KEEP(*crt0.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} >rom
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section")
/* thread-local data segment */
.tdata : {
PROVIDE(_tls_data = .);
PROVIDE(_tdata_begin = .);
*(.tdata .tdata.*)
PROVIDE(_tdata_end = .);
. = ALIGN(CL_SIZE);
} >ram
.tbss : {
PROVIDE(__BSS_START__ = .);
*(.tbss .tbss.*)
. = ALIGN(CL_SIZE);
PROVIDE(_tbss_end = .);
} >ram
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} >ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,92 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
rom (RX): ORIGIN = 0x80000000, LENGTH = 256M
ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K
}
STACK_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(rom) : {
PROVIDE(__TEXT_START__ = .);
*crt0.S.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = 0xC0;
KEEP(*crt0.S.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} >rom
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section")
/* thread-local data segment */
.tdata : {
PROVIDE(_tls_data = .);
PROVIDE(_tdata_begin = .);
*(.tdata .tdata.*)
PROVIDE(_tdata_end = .);
. = ALIGN(CL_SIZE);
} >ram
.tbss : {
PROVIDE(__BSS_START__ = .);
*(.tbss .tbss.*)
. = ALIGN(CL_SIZE);
PROVIDE(_tbss_end = .);
} >ram
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} >ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,114 @@
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
MEMORY {
rom (RX): ORIGIN = 0x80000000, LENGTH = 256M
ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K
}
STACK_SIZE = 1024;
HEAP_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(rom) : {
PROVIDE(__TEXT_START__ = .);
*crt0.S.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(rom) + 0xC0;
KEEP(*crt0.S.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
} >rom
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
PROVIDE(__TEXT_END__ = .);
} >rom AT>rom
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section")
/* thread-local data segment */
.tdata : {
PROVIDE(_tls_data = .);
PROVIDE(_tdata_begin = .);
*(.tdata .tdata.*)
PROVIDE(_tdata_end = .);
. = ALIGN(CL_SIZE);
} >ram
.tbss : {
PROVIDE(__BSS_START__ = .);
*(.tbss .tbss.*)
. = ALIGN(CL_SIZE);
PROVIDE(_tbss_end = .);
} >ram
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.bss : {
*(.bss .bss.*)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
.heap : {
PROVIDE(__heap_start = .);
. += HEAP_SIZE;
. = ALIGN(CL_SIZE);
PROVIDE(__heap_end = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__STACK_END__ = .);
} >ram
/DISCARD/ : {
*(.eh_frame .eh_frame.*)
}
}

View File

@ -0,0 +1,133 @@
#include "dma_lib.h"
void DMA_StartNewTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index,
uint32_t control_value,
uint32_t source_address, uint32_t destination_address, uint32_t length)
{
dma->CHANNELS[channel_index].SRC = source_address;
dma->CHANNELS[channel_index].DST = destination_address;
dma->CHANNELS[channel_index].LEN = length;
dma->CHANNELS[channel_index].CFG = control_value | DMA_CH_CFG_ENABLE_M;
}
void DMA_Wait (DMA_CONFIG_TypeDef* dma, uint32_t channel_index)
{
// uint32_t channel_bits = 0;
while ((dma->CONFIG_STATUS & ((1 << channel_index) << DMA_STATUS_READY_S)) == 0) ;
}
/*
void DMA_StartNewLlTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index,
uint32_t task_address)
{
dma->ENABLE_CH &= ~(1 << channel_index);
dma->CHANNELS[channel_index].DMA_Cntrl = DMA_CONTROL_linkListEnable_M;
dma->CHANNELS[channel_index].SRC_DESCRIPTOR = task_address;
dma->ENABLE_CH |= (1 << channel_index);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned int DMA_Wait_Timeout (DMA_CONFIG_TypeDef* dma, uint32_t channel_index) {
unsigned int TIMEOUT = 30000;
unsigned int wait = 0;
if ((dma->ENABLE_CH & (1 << channel_index)) == 0) {
return 0;
}
uint32_t channel_bits = 0;
channel_bits |= (1 << channel_index) << DMA_DONE_S;
channel_bits |= (1 << channel_index) << DMA_PERROR_SRC_S;
channel_bits |= (1 << channel_index) << DMA_PERROR_DST_S;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for(wait=0;wait<TIMEOUT;wait++) {
if((dma->DMA_STATUS & channel_bits) != 0) {
break;
}
}
if(wait==TIMEOUT) {
return 0;
}
return 1;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned int DMA_ChnDone (DMA_CONFIG_TypeDef* dma, uint32_t channel_index) {
if ((dma->ENABLE_CH & (1 << channel_index)) == 0) {
return DMA_CHN_DONE_ERROR_ENABLE;
}
uint32_t channel_bits = 0;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
channel_bits = (1 << channel_index) << DMA_DONE_S;
if((dma->DMA_STATUS & channel_bits) != 0) {
return DMA_CHN_DONE_ERROR_NO;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
channel_bits = (1 << channel_index) << DMA_PERROR_SRC_S;
if((dma->DMA_STATUS & channel_bits) != 0) {
return DMA_CHN_DONE_ERROR_SRC;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
channel_bits = (1 << channel_index) << DMA_PERROR_DST_S;
if((dma->DMA_STATUS & channel_bits) != 0) {
return DMA_CHN_DONE_ERROR_DST;
}
return DMA_CHN_DONE_NOT_DONE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned int DMA_AllChnDone (DMA_CONFIG_TypeDef* dma) {
if (dma->ENABLE_CH != DMA_ENABLE_M) {
return DMA_CHN_DONE_ERROR_ENABLE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if((dma->DMA_STATUS & DMA_DONE_M) == DMA_DONE_M) {
return DMA_CHN_DONE_ERROR_NO;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if((dma->DMA_STATUS & DMA_PERROR_SRC_M) != 0) {
return DMA_CHN_DONE_ERROR_SRC;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if((dma->DMA_STATUS & DMA_PERROR_DST_M) != 0) {
return DMA_CHN_DONE_ERROR_DST;
}
return DMA_CHN_DONE_NOT_DONE;
}
*/

View File

@ -0,0 +1,54 @@
#ifndef DMA_LIB_H_INCLUDED
#define DMA_LIB_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
/*
#define DMA_CHN_DONE_ERROR_NO 0
#define DMA_CHN_DONE_ERROR_SRC 1
#define DMA_CHN_DONE_ERROR_DST 2
#define DMA_CHN_DONE_ERROR_ENABLE 3
#define DMA_CHN_DONE_NOT_DONE 4
*/
#include "dma_config.h"
/*
Следует пользоваться структурами задач для DMA так, чтобы они не выходили
из области видимости и память под ними не использовалась для других целей,
пока DMA точно не закончил работать с ними.
Например, это относится к созданию переменных этого типа в стеке.
*/
typedef struct
{
uint32_t SrcAddress;
uint32_t DestAddress;
uint32_t LengthBytes;
uint32_t Control;
} DMA_Task_t;
void DMA_StartNewTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index,
uint32_t control_value,
uint32_t source_address, uint32_t destination_address, uint32_t length);
void DMA_Wait(DMA_CONFIG_TypeDef* dma, uint32_t channel_index);
/*
void DMA_StartNewLlTask(DMA_CONFIG_TypeDef* dma, uint32_t channel_index, uint32_t task_address);
unsigned int DMA_Wait_Timeout (DMA_CONFIG_TypeDef* dma, uint32_t channel_index);
unsigned int DMA_ChnDone (DMA_CONFIG_TypeDef* dma, uint32_t channel_index);
unsigned int DMA_AllChnDone (DMA_CONFIG_TypeDef* dma);
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,132 @@
#include "rtc_lib.h"
void RTC_Enable(RTC_TypeDef* rtc)
{
rtc->CTRL |= RTC_CTRL_EN_M;
}
void RTC_Disable(RTC_TypeDef* rtc)
{
rtc->CTRL &= ~RTC_CTRL_EN_M;
}
void RTC_ClearAlarmFlag(RTC_TypeDef* rtc)
{
rtc->CTRL &= ~RTC_CTRL_ALRM_M;
}
void RTC_WaitDataLoading(RTC_TypeDef* rtc)
{
while(rtc->CTRL & RTC_CTRL_FLAG_M) ;
}
void RTC_WaitAlarm(RTC_TypeDef* rtc)
{
while((rtc->CTRL & RTC_CTRL_ALRM_M) == 0) ;
}
void RTC_WriteTimeToReg(RTC_TypeDef* rtc, volatile uint32_t* reg,
uint8_t hours, uint8_t minutes, uint8_t seconds,
uint16_t miliseconds, uint8_t day_of_week
)
{
*reg =
((day_of_week << RTC_TIME_DOW_S) & RTC_TIME_DOW_M) |
(((hours / 10) << RTC_TIME_TH_S) & RTC_TIME_TH_M) |
(((hours % 10) << RTC_TIME_H_S) & RTC_TIME_H_M) |
(((minutes / 10) << RTC_TIME_TM_S) & RTC_TIME_TM_M) |
(((minutes % 10) << RTC_TIME_M_S) & RTC_TIME_M_M) |
(((seconds / 10) << RTC_TIME_TS_S) & RTC_TIME_TS_M) |
(((seconds % 10) << RTC_TIME_S_S) & RTC_TIME_S_M) |
(((miliseconds / 100) << RTC_TIME_TOS_S) & RTC_TIME_TOS_M);
}
void RTC_LoadTime(RTC_TypeDef* rtc,
uint8_t hours, uint8_t minutes, uint8_t seconds,
uint16_t miliseconds, uint8_t day_of_week
)
{
RTC_WriteTimeToReg(rtc, &(rtc->TIME),
hours, minutes, seconds, miliseconds, day_of_week);
RTC_WaitDataLoading(rtc);
}
void RTC_LoadTimeAlarm(RTC_TypeDef* rtc,
uint8_t hours, uint8_t minutes, uint8_t seconds,
uint16_t miliseconds, uint8_t day_of_week
)
{
RTC_WriteTimeToReg(rtc, &(rtc->TALRM),
hours, minutes, seconds, miliseconds, day_of_week);
RTC_WaitDataLoading(rtc);
}
void RTC_WriteDateToReg(RTC_TypeDef* rtc, volatile uint32_t* reg,
uint8_t date, uint8_t month, uint16_t year
)
{
*reg =
(((date / 10) << RTC_DATE_TD_S) & RTC_DATE_TD_M) |
(((date % 10) << RTC_DATE_D_S) & RTC_DATE_D_M) |
(((month / 10) << RTC_DATE_TM_S) & RTC_DATE_TM_M) |
(((month % 10) << RTC_DATE_M_S) & RTC_DATE_M_M) |
(((year % 10) << RTC_DATE_Y_S) & RTC_DATE_Y_M) |
(((year / 10 % 10) << RTC_DATE_TY_S) & RTC_DATE_TY_M) |
(((year /100 % 10) << RTC_DATE_C_S) & RTC_DATE_C_M) |
(((year / 1000) << RTC_DATE_TC_S) & RTC_DATE_TC_M);
}
void RTC_LoadDate(RTC_TypeDef* rtc,
uint8_t date, uint8_t month, uint16_t year
)
{
RTC_WriteDateToReg(rtc, &(rtc->DATE),
date, month, year);
RTC_WaitDataLoading(rtc);
}
void RTC_LoadDateAlarm(RTC_TypeDef* rtc,
uint8_t date, uint8_t month, uint16_t year
)
{
RTC_WriteDateToReg(rtc, &(rtc->DALRM),
date, month, year);
RTC_WaitDataLoading(rtc);
}
void RTC_SetAlarmMask(RTC_TypeDef* rtc,
bool date, bool month, bool year,
bool hours, bool minutes, bool seconds,
bool miliseconds, bool day_of_week
)
{
uint32_t temp;
temp = rtc->TALRM;
temp &= ~(RTC_TALRM_CDOW_M | RTC_TALRM_CH_M |
RTC_TALRM_CM_M | RTC_TALRM_CS_M | RTC_TALRM_CTOS_M);
temp |= (hours ? RTC_TALRM_CH_M : 0) |
(minutes ? RTC_TALRM_CM_M : 0) |
(seconds ? RTC_TALRM_CS_M : 0) |
(miliseconds ? RTC_TALRM_CTOS_M : 0) |
(day_of_week ? RTC_TALRM_CDOW_M : 0);
rtc->TALRM = temp;
temp = rtc->DALRM;
temp &= ~(RTC_DALRM_CC_M | RTC_DALRM_CY_M |
RTC_DALRM_CM_M | RTC_DALRM_CD_M);
temp |= (date ? RTC_DALRM_CD_M : 0) |
(month ? RTC_DALRM_CM_M : 0) |
(year ? (RTC_DALRM_CC_M | RTC_DALRM_CY_M) : 0);
rtc->DALRM = temp;
}

View File

@ -0,0 +1,170 @@
#ifndef RTC_LIB_H_INCLUDED
#define RTC_LIB_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
/** \file
Библиотека для работы с контроллером часов реального времени RTC.
*/
#include "inttypes.h"
#include "stdbool.h"
#include "rtc.h"
/** Запускает RTC
\note Дата и время должны быть заданы предварительно.
\param rtc Указатель для доступа к RTC
*/
void RTC_Enable(RTC_TypeDef* rtc);
/** Останавливает RTC
\param rtc Указатель для доступа к RTC
*/
void RTC_Disable(RTC_TypeDef* rtc);
/** Сбрасывает флаг будильника
\note Если текущее время все еще подходит
для срабатвания будильника, то флаг выставится вновь.
Чтобы этого избежать, можно, например,
обнулить маску будильника.
\param rtc Указатель для доступа к RTC
*/
void RTC_ClearAlarmFlag(RTC_TypeDef* rtc);
/** Ожидает завершение синхронизации после записи в регистры RTC
Функция опрашивает поле FLAG регистра RRTC_CTRL,
пока он не станет равным 0.
\note Когда флаг равен 1,
то идет синхронизация данных между доменами
и нельзя производить запись в другие регистры RTC.
\param rtc Указатель для доступа к RTC
*/
void RTC_WaitDataLoading(RTC_TypeDef* rtc);
/** Ожидает срабатывания будильника
Функция опрашивает флаг ALRM регистра RRTC_CTRL,
пока он не станет равным 1.
\param rtc Указатель для доступа к RTC
*/
void RTC_WaitAlarm(RTC_TypeDef* rtc);
/** Загружает время и день недели
\warning Загружаемые значения должны быть корректными.
Функция не производит их проверку.
\note RTC работает с сотнями милисекунд.
Значения не кратные 100 будут округляются вниз.
\param rtc Указатель для доступа к RTC
\param hours часы
\param minutes минуты
\param seconds секунды
\param miliseconds милисекунды
\param day_of_week порядковый номер дня недели
*/
void RTC_LoadTime(RTC_TypeDef* rtc,
uint8_t hours, uint8_t minutes, uint8_t seconds,
uint16_t miliseconds, uint8_t day_of_week
);
/** Загружает время и день недели для будильника
\warning Загружаемые значения должны быть корректными.
Функция не производит их проверку.
\note RTC работает с сотнями милисекунд.
Значения не кратные 100 округляются вниз.
\param rtc Указатель для доступа к RTC
\param hours часы
\param minutes минуты
\param seconds секунды
\param miliseconds милисекунды
\param day_of_week порядковый номер дня недели
*/
void RTC_LoadTimeAlarm(RTC_TypeDef* rtc,
uint8_t hours, uint8_t minutes, uint8_t seconds,
uint16_t miliseconds, uint8_t day_of_week
);
/** Загружает дату
\warning Загружаемые значения должны быть корректными.
Функция не производит их проверку.
\param rtc Указатель для доступа к RTC
\param date число
\param month месяц
\param year год
*/
void RTC_LoadDate(RTC_TypeDef* rtc,
uint8_t date, uint8_t month, uint16_t year
);
/** Загружает дату будильника
\warning Загружаемые значения должны быть корректными.
Функция не производит их проверку.
\param rtc Указатель для доступа к RTC
\param date число
\param month месяц
\param year год
*/
void RTC_LoadDateAlarm(RTC_TypeDef* rtc,
uint8_t date, uint8_t month, uint16_t year
);
/** Устанавливает маску будильника
Если значение маски равно true,
то поле участвует в сравнении при
определении срабатывания будильника.
\param rtc Указатель для доступа к RTC
\param date число
\param month месяц
\param year год
\param hours часы
\param minutes минуты
\param seconds секунды
\param miliseconds милисекунды
\param day_of_week порядковый номер дня недели
*/
void RTC_SetAlarmMask(RTC_TypeDef* rtc,
bool date, bool month, bool year,
bool hours, bool minutes, bool seconds,
bool miliseconds, bool day_of_week
);
#ifdef __cplusplus
}
#endif
#endif // RTC_LIB_H_INCLUDED

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