From 9aed5d7e7b3c7bf09da712e9c272ece401a7acc9 Mon Sep 17 00:00:00 2001 From: QuakeGod <QuakeGod@sina.com> Date: 星期一, 25 十一月 2024 14:51:23 +0800 Subject: [PATCH] add UltraSonic and MultiWireLess --- C8T6_TestApp2/Ethernet/wizchip_conf.h | 548 Radio_LLCC68_Multi/Inc/ATModem.h | 32 Radio_LLCC68_Multi/Radio/user.h | 21 C8T6_TestApp2/Ethernet/wizchip_conf.c | 636 + ComLib/Inc/BSP.h | 7 Radio_LLCC68_Multi/Ethernet/wizchip_conf.c | 636 + Radio_LLCC68_Multi/Radio/inc/sx126x.h | 1115 ++ C8T6_TestApp2/C8T6_UltroSonic.uvprojx | 756 + C8T6_TestApp2/Radio/src/sx126x-board.c | 216 ComLib/Src/KMachine.c | 4 Radio_LLCC68_Multi/Ethernet/wizchip_conf.h | 548 MDK-ARM/Radio_LLCC68_C8T6_8路无线模块.uvprojx | 2 Radio_LLCC68_Multi/Radio/inc/radio.h | 379 KBus/MDK-ARM/KBus_C8T6_分布IO模块_8路16路.uvprojx | 2 C8T6_TestApp2/RTE/_C8T6_TestApp2/RTE_Components.h | 20 Radio_LLCC68_Multi/Ethernet/W5500/w5500.c | 367 C8T6_TestApp2/Ethernet/socket.h | 466 KSingleLineBus/KSingleLineBus_单总线.uvopt | 6 KSingleLineBus/KSingleLineBus_单总线.uvproj | 13 C8T6_TestApp2/Inc/BoardType.h | 118 C8T6_TestApp2/Src/BoardType.c | 95 MDK-ARM/KLink_C8T6.uvprojx | 2 MDK-ARM/F030C8T6_KAD_4路模拟量.uvprojx | 2 C8T6_TestApp2/Internet/DHCP/dhcp.h | 152 MDK-ARM/KPLC_C8T6_简易PLC.uvprojx | 6 Radio_LLCC68_Multi/Ethernet/W5500/w5500.h | 2054 +++ Radio_LLCC68_Multi/Radio/src/crc.c | 47 C8T6_TestApp2/Internet/DHCP/dhcp.c | 976 + C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.hex | 643 + Radio_LLCC68_Multi/Radio/KWireLess2.h | 441 Radio_LLCC68_Multi/Radio/KWireLess2.c | 1089 + C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.sct | 15 ComLib/Src/debug.c | 4 CCT6_BootLoader/MDK-ARM/CCT6_BtLdr.uvprojx | 2 KPLC/Src/main.c | 113 Radio_LLCC68_Multi/Ethernet/loopback.c | 225 Radio_LLCC68_Multi/Internet/DHCP/dhcp.h | 152 Radio_LLCC68_Multi/Radio/spi.h | 8 Radio_LLCC68_Multi/Ethernet/loopback.h | 38 Ext_FPx/MDK-ARM/Ext_FPx_C8T6_松下扩展.uvprojx | 2 ComLib/Src/BSP.c | 584 Radio_LLCC68_Multi/Internet/DHCP/dhcp.c | 976 + KPLC/Src/BoardType.c | 2 ComLib/startup_stm32f030x8.s | 252 ComLib/Src/stm32f0xx_it.c | 17 C8T6_TestApp2/Inc/BSP_UltraSonic.h | 41 MDK-ARM/KMini_C8T6.uvprojx | 2 C8T6_TestApp2/EventRecorderStub.scvd | 9 Radio_LLCC68_Multi/Radio/inc/crc.h | 24 Radio_LLCC68_Multi/Radio/src/radio.c | 1236 ++ Radio_LLCC68_Multi/Radio/gpio.h | 70 C8T6_TestApp2/DebugConfig/C8T6_TestApp2_STM32F030C8Tx.dbgconf | 42 Radio_LLCC68_Multi/Radio/gpio.c | 101 C8T6_TestApp2/Radio/inc/sx126x.h | 1115 ++ C8T6_TestApp2/Radio/inc/crc.h | 24 C8T6_TestApp2/Radio/inc/radio.h | 379 Radio_LLCC68_Multi/Radio/KWireLess1.h | 344 Radio_LLCC68_Multi/Src/main.c | 817 + Radio_LLCC68_Multi/Radio/KWireLess1.c | 1127 ++ Radio_LLCC68_Multi/Radio/inc/sx126x-board.h | 129 C8T6_TestApp2/Inc/stm32f0xx_hal_conf.h | 324 ComLib/Inc/KMachine.h | 4 Radio_LLCC68_Multi/Radio/src/sx126x-board.c | 216 Radio_LLCC68_Multi/MDK-ARM/LLCC68_C8T6_Multi_8路无线模块.uvprojx | 766 + C8T6_TestApp1/MDK-ARM/F030C8T6_Ext_FPx_New.uvprojx | 2 C8T6_TestApp2/Src/BSP_UltraSonic.c | 1099 + C8T6_TestApp2/startup_stm32f030x8.s | 252 Radio_LLCC68_Multi/Src/ATModem.c | 29 Radio_LLCC68_Multi/Src/BoardType.c | 98 C8T6_TestApp2/Radio/src/crc.c | 47 CCT6_TestApp1/MDK-ARM/F030CCT6_TestApp1.uvprojx | 2 C8T6_TestApp2/Radio/src/radio.c | 1151 ++ C8T6_TestApp2/Src/ADC.c | 115 Radio_LLCC68_Multi/Radio/spi.c | 69 ComLib/Src/PLCfunctions.c | 10 Radio_LLCC68_Multi/Inc/BoardType.h | 130 C8T6_TestApp2/Radio/src/sx126x.c | 716 + Radio_LLCC68_Multi/Internet/DNS/dns.h | 101 ComLib/Src/KLink.c | 2 Radio_LLCC68_Multi/Internet/DNS/dns.c | 563 + MDK-ARM/F030C8T6_KNet_网口模块.uvprojx | 2 C8T6_TestApp2/Ethernet/W5500/w5500.c | 367 ComLib/Src/functions.c | 205 C8T6_TestApp2/Ethernet/W5500/w5500.h | 2054 +++ Radio_LLCC68_Multi/Radio/delay.h | 16 Radio_LLCC68_Multi/Radio/delay.c | 32 C8T6_BootLoader/MDK-ARM/C8T6_BtLdr.uvprojx | 4 MDK-ARM/F030C8T6_KBox_控制盒子.uvprojx | 2 C8T6_TestApp2/Internet/DNS/dns.c | 563 + Radio_LLCC68_Multi/Inc/main.h | 119 ComLib/Inc/functions.h | 5 C8T6_TestApp2/Internet/DNS/dns.h | 101 C8T6_TestApp2/Ethernet/loopback.c | 225 C8T6_TestApp2/Radio/inc/sx126x-board.h | 129 Radio_LLCC68_Multi/Radio/src/sx126x.c | 716 + Radio_LLCC68_Multi/Ethernet/socket.c | 688 + C8T6_TestApp2/Ethernet/socket.c | 688 + Radio_LLCC68_Multi/Ethernet/socket.h | 466 MDK-ARM/KMini_New_CCT6.uvprojx | 2 Radio_LLCC68_Multi/MDK-ARM/startup_stm32f030x8.s | 252 C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2_sct.Bak | 16 C8T6_TestApp2/Ethernet/loopback.h | 38 C8T6_TestApp2/Src/main.c | 1060 + C8T6_TestApp2/Inc/main.h | 120 Radio_LLCC68_Multi/Inc/stm32f0xx_hal_conf.h | 324 C8T6_TestApp2/Inc/ADC.h | 14 KNet.uvmpw | 11 107 files changed, 32,900 insertions(+), 264 deletions(-) diff --git a/C8T6_BootLoader/MDK-ARM/C8T6_BtLdr.uvprojx b/C8T6_BootLoader/MDK-ARM/C8T6_BtLdr.uvprojx index 6724824..8f143bd 100644 --- a/C8T6_BootLoader/MDK-ARM/C8T6_BtLdr.uvprojx +++ b/C8T6_BootLoader/MDK-ARM/C8T6_BtLdr.uvprojx @@ -10,7 +10,8 @@ <TargetName>F030C8T6_BtLdr</TargetName> <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> - <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/C8T6_TestApp1/MDK-ARM/F030C8T6_Ext_FPx_New.uvprojx b/C8T6_TestApp1/MDK-ARM/F030C8T6_Ext_FPx_New.uvprojx index 4fd2279..5795aa3 100644 --- a/C8T6_TestApp1/MDK-ARM/F030C8T6_Ext_FPx_New.uvprojx +++ b/C8T6_TestApp1/MDK-ARM/F030C8T6_Ext_FPx_New.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.hex b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.hex new file mode 100644 index 0000000..51695e3 --- /dev/null +++ b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.hex @@ -0,0 +1,643 @@ +:020000040800F2 +:1000000040180020C9000008C90F00085507000863 +:1000100000000000000000000000000000000000E0 +:10002000000000000000000000000000FF100008B9 +:1000300000000000000000004D130008B11300088C +:10004000DB00000800000000DB000008DB00000807 +:10005000DB000008DB000008DB000008DB00000814 +:1000600000000000DB000008D9030008F5040008C8 +:10007000DB000008DB000008DB00000800000000D7 +:10008000DB0000081116000800000000DB0000087B +:10009000DB000008E1150008DB000008DB000008B9 +:1000A000DB000008F7100008DB00000875180008E6 +:1000B000351900080348854600F0B8F800480047A5 +:1000C00019200008401800200448804704480047D1 +:1000D000FEE7FEE7FEE7FEE7FEE7FEE76D15000838 +:1000E000B500000830B50B4601460020202201244F +:1000F00009E00D46D5409D4205D31D469540491B5C +:100100002546954040191546521E002DF1DC30BDA4 +:1001100070B500242546002801DA01244042002958 +:1001200001DA01254942FFF7DDFFAC4200D0404231 +:10013000002C00D0494270BDF8B5002425460029A6 +:1001400004DA0E46012400214042B141002B04DABA +:100150001E46002352420125B34100F036F88C467A +:1001600017461E46AC4203D0002540428D41AC46A6 +:10017000002C02D0002657429E4161463A46334643 +:1001800001B0F0BD10B5202A04DB0846203AD0406B +:10019000002110BD0B46D340D0402024A21A91402C +:1001A0000843194610BDD2B201E00270401C491E3E +:1001B000FBD270470022F6E710B513460A46044604 +:1001C0001946FFF7F0FF204610BDF0B51FB40646F4 +:1001D000002082B005464024019100901BE0019967 +:1001E00022460F463046FFF7CDFF049A059B801A42 +:1001F000994110D310461946224600F029F8361AC4 +:100200008F410197224601200021009F00F020F835 +:1002100038184D4100902046641E0028DFDC019B09 +:1002200000982946324607B0F0BD0000064C012573 +:10023000064E05E0E36807CC2B430C3C984710348E +:10024000B442F7D3FFF73AFF681D0008881D000885 +:1002500010B5202A04DB0146203A9140002010BD51 +:10026000914020239C1A0346E3401943904010BD5F +:1002700070B5002100BF4848806804221040800803 +:1002800000287DD100BF444B1B6C9BB21946434BE9 +:1002900018680122C307DB0F002B0ED0404B1984D6 +:1002A000404A1B8C404CA34203DA01233F4C23609D +:1002B0005CE000233D4C236058E03A4B0340394C4E +:1002C000A34206D13A4B1B885B18394C2380394A2C +:1002D0004CE0384B0340374CA34225D1344B5B886C +:1002E0005B18334C6380344B1B685B1C324C2360BF +:1002F00023461B68082B15DB2D4C2388DC17640F65 +:10030000E418E410264D2035EC80294C6388DC1776 +:10031000640FE418E4102C810023254C23806380B3 +:10032000254C2360254A21E0244B0340234CA34263 +:1003300004D11B4B20335981214A17E0214B034044 +:10034000204CA34204D1164B203399811E4A0DE064 +:100350001E4B03401D4CA34208D1114B2033D981C1 +:100360001B4B5C8B0E4B20331C82012200BF5303BE +:100370005B0B094CA36200BF00BF23469B6800E0F3 +:1003800008E0144C23401B1D034CA36000BF034B2B +:100390001A6000BF002070BD00240140180000203A +:1003A0000C0500208000001CDC05000094000020EB +:1003B0006C01002000010020140000200002002435 +:1003C000000001C000000140000002C4000002441F +:1003D000A0F7FF1FE8FFFF7F70B54248C06A401CCE +:1003E0004049C86200BF40480068202108404009D9 +:1003F000002866D03B4800683A49096B40183949E3 +:1004000008600846016B443000F0A4F800BF2020CB +:100410003549486000BF33484430817A8907C90FA5 +:10042000002945D100F0CCF804462F4802214A1E8D +:100430002E4B9A5C825853085B004A1E2B4DAA5CD7 +:10044000835000BF024602232649443108268E5FAE +:100450000D68A81900BF591E244D695C8918C86031 +:1004600000BF1046022122464B1EEB5C1B185B6846 +:100470001B0C1B0413434D1E1C4E755D2D186B6029 +:1004800000BF00BF4A1E33469A5C825801231A43BC +:100490004B1E3546EB5CC25000BF1248046300BFE0 +:1004A00013488068802108431149886000BF08E034 +:1004B00000200C4908630846007B02218843094953 +:1004C000087300BF08480068012149020840400A3B +:1004D000002805D000BF08460349486000BF00BFA0 +:1004E00070BD00008C01002000000240CE1C0008FE +:1004F000003801401548C06A401C1449C86200BF5A +:1005000013480068012149030840400B00280DD022 +:1005100000BF08460E49486000BF00200B49086331 +:100520000846007B022188430849087300BF084839 +:100530000068012149040840400C002805D000BF94 +:1005400008460349486000BF00BF7047DC01002037 +:100550000000024010B502460B46002B01D11846A0 +:1005600010BD0820105EC1180420105E884202DC15 +:100570000420105E091A907A40084000907208B278 +:1005800010810620105E884207D10020D0801081A3 +:10059000907A0224A043801C90721846E0E708B5C8 +:1005A00000210AE00022009203E000BF009A521CE2 +:1005B0000092009A182AF8DB491C8142F2DB08BD40 +:1005C00070B504460825655F0626A65FB54201DAC8 +:1005D000701B70BDB54203DD0420205E401BF8E7B0 +:1005E00000BFA07AC007C00F002803D00420205EFF +:1005F000401BEEE7204600F003F9002801D0002060 +:10060000E7E70020E5E70000084B1968084B9A6906 +:10061000064B1B68994203D0044B1968044B9A6936 +:10062000044B53431B14C81A7047000030000020CD +:1006300000E000E05505000002480068401C014948 +:1006400008607047E800002010B5064800681021D7 +:10065000084304490860002000F006F800F018F88C +:10066000002010BD0020024070B5044600F04AF89A +:1006700006467D21C900FFF735FD054600F04AF822 +:1006800000222146501E00F033F8002070BD00000B +:1006900008B500BF154880690121084313498861E6 +:1006A00008468069C007C00F009000BF00BF00BFB0 +:1006B0000846C069090408430C49C8610846C06976 +:1006C00009040840009000BF00BF00221146501FDF +:1006D00000F00EF800221146901E00F009F80022EA +:1006E0001146501E00F004F808BD00000010024042 +:1006F00070B504460D4616462946204600F066FCB5 +:1007000070BD00000148006870470000E400002050 +:100710007047000070B504462546681E09498842A6 +:1007200001D901200CE0681E074948610321081F18 +:1007300000F04CFC0020044988610720086100207B +:1007400070BD0000FFFFFF0000E000E010B5FFF704 +:10075000DFFF10BD00BFFEE7F8B504460E461746A2 +:100760001D46502200212046FFF71DFD002E05D01A +:100770003A4631462046383001F06FF9002D05D059 +:10078000294620464430069A01F067F90020F8BD5A +:1007900070B5044621461248FFF7BAFC11490860BB +:1007A000FFF7B0FF05460E49FFF79CFC0E490860B5 +:1007B00021460E480068FFF795FC0D4908600B487C +:1007C000002302680B480F21FFF7B6FC0A49088096 +:1007D00004480068643009490860002070BD0000CA +:1007E00040420F002800002020000020E4000020EC +:1007F000240000200000404234000020300000208F +:100800000146887A8007C00F7047000010B5044683 +:100810000249002000F004F8002010BD5400002020 +:1008200030B50246054B186A8300044C2434E1506D +:10083000024B1B6A5B1C243C236230BDAC060020CB +:1008400008B5054949690143034A5161114649699F +:100850000140009100BF08BD0010024008B50549E5 +:1008600089690143034A91611146896901400091F8 +:1008700000BF08BD00100240F0B502460B4600263E +:10088000002162E00124B44018682040014600299C +:100890005AD0586814680D464D436F00ED19AC43AB +:1008A0000D464D4345432C43146000BF5868012852 +:1008B00002D0586802280DD1986894680D464D43BF +:1008C0006F00ED19AC430D464D4345432C439460F6 +:1008D00000BF00BF1869D4680D464D436F00ED1985 +:1008E000AC430D464D4345432C43D46000BF58688C +:1008F000022829D1FF2911D85869146A0D464D43A1 +:100900004D434D432F017D1BAC430D464D434D439D +:100910004D4345432C43146200BF15E05F69080A4C +:1009200040430C0A60430C0A60430401241A506AD5 +:10093000A0430C0A64430D0A6C430D0A6C437C43CC +:100940002043506200BF00BF761C1868F0400028AA +:1009500098D15868012802D05868022809D1DC686B +:10096000186855688543074667433D43556000BF97 +:1009700000BF0120F0BD024610690840884201D145 +:10098000012070470020FCE701460869704781623A +:10099000704781617047000070B504467D25ED0009 +:1009A00029462046FFF79EFB401E0449486100206F +:1009B00088610520086100BF70BD000000E000E014 +:1009C00001468868C007C00F012250405040704760 +:1009D0000146C868C0B2704701490860704700000E +:1009E000E400002010B5034600220C7B224610468E +:1009F00003242402A0438C682043024610460124AD +:100A0000A402A0434C682043024610460124E4029D +:100A1000A0430C6820430246104601242403A0434F +:100A2000CC8920430246104601246403A0430C698C +:100A30002043024610460124A403A0434C692043EE +:100A4000024610460124E403A0434C6920430246B9 +:100A50005A64012010BD026A0A4302627047416C69 +:100A60000122D203914341647047816880229143FF +:100A70008160704701688022114301607047416CBA +:100A80000122D203114341647047016801221143DE +:100A90000160704710B50246002313682148824266 +:100AA00002D02148824205D118467024A0434C68E8 +:100AB000204303461B4882420ED01B4882420BD083 +:100AC0001A48824208D01A48824205D01948824208 +:100AD00002D01948824206D1184603242402A043BA +:100AE000CC682043034613608868D06200BF088842 +:100AF000906200BF0B48824208D00D48824205D068 +:100B00000C48824202D00C48824203D1087C106318 +:100B100000BF00BF00BF506901242043506100BFE7 +:100B2000012010BD002C01400004004000200040C6 +:100B3000004001400044014000480140014608696E +:100B4000C007C00F012250405040704770B50246A8 +:100B5000012901D1002418E0042901D1012414E065 +:100B6000102901D1022410E0402901D103240CE016 +:100B7000FF240134A14201D1042406E00124A4028F +:100B8000A14201D1052400E006242346064CE55C81 +:100B9000144618342819054DEE5C0425B540046848 +:100BA000AC43046070BD0000451D00084C1D0008EA +:100BB00070B50246012901D1002418E0042901D1B1 +:100BC000012414E0102901D1022410E0402901D1B0 +:100BD00003240CE0FF240134A14201D1042406E0E7 +:100BE0000124A402A14201D1052400E006242346E9 +:100BF000064CE55C144618342819054DEE5C0825B2 +:100C0000B54004682C43046070BD0000451D000819 +:100C10004C1D0008F8B506460C4615460027012C69 +:100C20000AD0102C0ED0E01FF938002810D00F2168 +:100C30000902401A18D111E02946304600F002FAA4 +:100C4000074612E02946304600F06AFA07460CE0F3 +:100C50002946304600F0CAFA074606E029463046E3 +:100C600000F026FB074600E000BF00BF3846F8BD95 +:100C7000416370478163704781637047C162704709 +:100C80008268024B1A400A4382607047F8BFFFFF38 +:100C9000426870239A430A43426070470146C8691C +:100CA00010221040000970470146C8690822104010 +:100CB000C00870470146C8692022104040097047AB +:100CC0000146C86940221040800970470146086803 +:100CD000102210400009704700B599B0142114A8E3 +:100CE000FFF768FA20210CA8FFF764FA182106A87C +:100CF000FFF760FA18216846FFF75CFA012000044C +:100D0000FFF7ACFD002110A80182002015903D489E +:100D100016900020179018A8017014A93A48FFF700 +:100D2000B9FE3948FFF7A6FE00213748FFF7A8FFB4 +:100D300060200C9000200D900E906B20C0000F9052 +:100D400000201090022011900020129013900CAA05 +:100D500001212D48FFF75EFF01212B48FFF7F6FE2A +:100D600010212948FFF724FF70200C9000200D90DF +:100D70000E9064200F900CAA10212348FFF74AFF21 +:100D800010212148FFF7E2FE50211F48FFF780FFA6 +:100D90001D48FFF76AFE0020069007900890142176 +:100DA00008A8017100216846C184012040030A900F +:100DB00000200B9006A91448FFF714FE01208004C0 +:100DC000FFF73EFD012080030090022001900020EB +:100DD0000290039004900120059069460B48FFF7AC +:100DE0004BFD0120C00300900220019000200290E2 +:100DF000039004900320059069460448FFF73CFDEA +:100E000019B000BDB10600000040014000040048D8 +:100E100000B599B0142114A8FFF7CCF920210CA833 +:100E2000FFF7C8F9182106A8FFF7C4F9182168468A +:100E3000FFF7C0F90120C002FFF710FD002110A844 +:100E40000182002015905C4816900020179018A889 +:100E5000017014A95948FFF71DFE5848FFF70AFE14 +:100E600000215648FFF70CFF01215448FFF7A0FE70 +:100E700060200C9000200D900E9051480F900220A1 +:100E8000109000201190129013900CAA01214B4851 +:100E9000FFF7C0FE01214948FFF758FE0121090371 +:100EA0004648FFF785FE60200C90002010900D90C2 +:100EB0000E906B20C0000F900CAA012109033F483F +:100EC000FFF7A8FE012109033C48FFF73FFE002081 +:100ED0003A498968702291430143384A916000BFC2 +:100EE000042011468968C908C9000143916000BF08 +:100EF00000BF1046C068402188431146C86000BF4B +:100F000000BF0846C0680121890388431146C860B4 +:100F100000BF00211046FFF7BBFE2848FFF7A5FDE4 +:100F20000020069007900890502108A80171002128 +:100F30006846C184012040030A9000200B9006A956 +:100F40001E48FFF74FFD01208004FFF779FC0120C8 +:100F50004004FFF775FC012040030090022001903F +:100F600000200290039004900220059069461548E5 +:100F7000FFF782FCFF20013000900220019000204A +:100F80000290039004900220059069460920C00653 +:100F9000FFF772FC0120C0020090022001900020A7 +:100FA0000290039004900220059069460920C00633 +:100FB000FFF762FC19B000BDB1060000002C014033 +:100FC00059030000000400487047000010B50028D5 +:100FD00019DA1A4A03071B0F083B9B089B00D258DB +:100FE0008307DC0EFF23A3409A438B071B0E840765 +:100FF000E40EA3401A43114B0407240F083CA40835 +:10100000A4001A5118E00E4A03231B02D2188308C9 +:101010009B00D2588307DC0EFF23A3409A438B0723 +:101020001B0E8407E40EA3401A43054B032424023D +:101030001B198408A4001A5110BD00001CED00E02B +:1010400000E100E070B50246002400230025106A8C +:10105000400840001062136A55689469A408A4000F +:1010600020467026B0430E683043044618460226D8 +:10107000B0430E6930430346580840004E68304381 +:1010800003461848824208D01748824205D01748C4 +:10109000824202D0164882421CD118460826B0432C +:1010A0004E69B6003043034618460426B0438E68A6 +:1010B000B600304303462846FF260136B0438E690A +:1010C00030430546284601267602B043CE697600B5 +:1010D0003043054655609461C868506300BF136291 +:1010E000012070BD002C014000400140004401403F +:1010F00000480140704710B500F03AF910BD704744 +:1011000055AA010320000000120101090010000C83 +:1011100000100008881D000800900008CCCC55AADB +:10112000F8B504460D460027002600200090206AEE +:10113000102188432062266A60680090A769032115 +:101140000902384688430746384607210903884381 +:101150002968090208430746304620218843296947 +:101160000901084306463046102188436968090191 +:10117000084306461948844208D01948844205D0DD +:101180001848844202D0184884421DD1304680213C +:1011900088436969890108430646304640218843EF +:1011A000A9688901084306460121890200988843FD +:1011B000A9698900084300900121C9020098884369 +:1011C000E969C9000843009000986060A761204663 +:1011D000E968FFF751FD26620120F8BD002C0140AF +:1011E00000400140004401400048014070B5024603 +:1011F000002400230025106AFF260136B043106248 +:10120000136A5568D469A408A40020467026B04328 +:101210000E6830430446184601267602B0430E6934 +:101220003602304303461846FF260136B0434E6867 +:101230003602304303461A48824208D01948824297 +:1012400005D01948824202D0184882421FD1184660 +:101250000126F602B0434E69B602304303461846F3 +:101260000126B602B0438E68B602304303462846D4 +:1012700001263603B0438E693601304305462846C1 +:1012800001267603B043CE697601304305465560AA +:10129000D461C868D06300BF1362012070BD000034 +:1012A000002C014000400140004401400048014042 +:1012B00070B50246002300240025106A012636037B +:1012C000B0431062146A5568D36903263602184683 +:1012D000B0430346184607263603B0430E6836026D +:1012E00030430346204601267603B0430E69360399 +:1012F00030430446204601263603B0434E68360389 +:10130000304304460D48824208D00D48824205D041 +:101310000C48824202D00C48824207D1284601265E +:10132000B603B0438E69B601304305465560D361BC +:10133000C868106400BF1462012070BD002C014019 +:1013400000400140004401400048014010B5012028 +:10135000C0060549486005480068401C034908600C +:10136000FFF7C8FE10BD000000ED00E040000020C7 +:1013700010B50548FFF724FB002804D00248FFF70A +:1013800027FB044600BF10BD0030014010B50446E5 +:10139000002C05D0012109030448FFF7F8FA04E006 +:1013A000012109030148FFF7F4FA10BD00040048C9 +:1013B00010B5FFF741F9FFF7C9F910BD10B50120CD +:1013C0005F490968814301435D4A116000BF00BF66 +:1013D00010460068C007C00F002803D11E2159A085 +:1013E00000F02AFB00BF5D480068012109040843A2 +:1013F0005A49086000BF00BF00BF5848006801217B +:1014000049040840400C0028F6D000BF5348406B08 +:10141000012108435149486300BF00BF00BF4F4846 +:10142000406B0221084040080028F7D010204B49AB +:10143000496BF8229143C2001143484A516300BFEF +:1014400000BF1046406A012108431146486200BFB0 +:1014500043480521C90452683D231B049A430304F1 +:1014600003400B431A433D4B5A601A46D26A120995 +:10147000120103071B0F1A43384BDA6200BF00BF8B +:10148000184600680121090608431946086000BF94 +:1014900000BF00BF31480068012149060840400EE6 +:1014A0000028F6D000202D494968F02291430143DD +:1014B0002A4A516000BF00BF114649680722120244 +:1014C00091430143254A516000BF022011464968FB +:1014D000890889000143516000BF00BF00BF1F4859 +:1014E00040680C2108400828F8D11E48FFF754FA3C +:1014F0000420042806D11C490969042211431A4A10 +:10150000116105E01849096904229143164A1161E5 +:1015100000BF1448FFF760FA00BF1048406B042179 +:1015200088430E49486300BF0020096B0022134620 +:1015300003229A4091430143084A116300BF10BD42 +:10154000002002405372635C4253505F556C7472CA +:1015500061536F6E69632E6300000000001002404B +:1015600001000100006CDC0200E000E019480068A6 +:101570000121084317490860084640681649084099 +:101580001449486008460068144908401149086039 +:10159000084600680121890488430E49086008460E +:1015A00040683F21090488430A4948600846C06AE8 +:1015B00000090001C8620846006BFF21143188430E +:1015C000044908630846406B400840004863002017 +:1015D00088607047001002400CB8FF08FFFFF6FE5D +:1015E00010B50948FFF7AAFA002806D000BF01206D +:1015F000C0430549086100BF00BF04480079401C92 +:10160000C1B20248017110BD004401404C060020E7 +:1016100010B50948FFF792FA002806D000BF012054 +:10162000C0430549086100BF00BF04488078401CE2 +:10163000C1B20248817010BD001000404C0600206D +:1016400070B50121C9030920C006FFF7A0F92021C8 +:101650001248FFF79EF900260124002519E0082111 +:101660000E48FFF794F90120FEF799FF08210B4877 +:10167000FFF78FF90120FEF792FF20210748FFF7BF +:101680007AF9002802D03046204306466006040E50 +:101690006D1C082DE3DB304670BD000000040048DF +:1016A00070B505460121C9030920C006FFF771F98D +:1016B00008211148FFF76DF920210F48FFF769F95C +:1016C0000220FEF76CFF0121C9030920C006FFF7C5 +:1016D0005EF9422000F012F8002403E0FFF7B0FFAB +:1016E0002855641C042CF9DB0121C9030920C0061C +:1016F000FFF74FF970BD00000004004870B50646C2 +:101700000121C9030920C006FFF741F90124002582 +:101710001DE008210F48FFF73AF930462040002825 +:1017200004D020210B48FFF734F903E020210948B9 +:10173000FFF72DF90120FEF732FF08210548FFF7DA +:1017400028F96006040E0120FEF729FF6D1C082D04 +:10175000DFDB70BD00040048F8B505460E461746AD +:1017600000F034F8E8B200F00FF8002403E0305D38 +:10177000FFF7C4FF641CBC42F9DB0121C903092047 +:10178000C006FFF706F9F8BD10B504460121C903EC +:101790000920C006FFF7FDF808210B48FFF7F9F80C +:1017A00020210948FFF7F5F80220FEF7F8FE012195 +:1017B000C9030920C006FFF7EAF8C0212143084603 +:1017C000FFF79CFF10BD00000004004810B5012188 +:1017D000C9030920C006FFF7DCF808210C48FFF711 +:1017E000D8F820210A48FFF7D4F80220FEF7D7FEE8 +:1017F0000121C9030920C006FFF7C9F84020FFF7FF +:101800007DFF0121C9030920C006FFF7C2F810BD02 +:101810000004004810B50121C9030920C006FFF7E4 +:10182000B8F808210E48FFF7B4F820210C48FFF75C +:10183000B0F80220FEF7B3FE0121C9030920C0065B +:10184000FFF7A5F88A20FFF759FF0121C9030920F6 +:10185000C006FFF79EF820210148FFF79AF810BD57 +:10186000000400480120000701494860704700005B +:1018700000ED00E010B52948FFF71CFA002820D041 +:101880000121274A1170274A117027494969491CCB +:10189000254A516100BF2149898CC9B208461146C9 +:1018A0004968491C51602149214A128888542049BD +:1018B0000988FF2904DA1E490988491C1C4A11803D +:1018C00000BF1648FFF7F0F9002809D000BF082034 +:1018D0001249086200BF1448006A401C124908629D +:1018E0000E48FFF7F3F900280BD00C48FFF7D6F9A4 +:1018F000002806D000BF10200849086200BF00F091 +:101900004FF80648FFF7DCF9002806D000BF40205A +:101910000249086200BF00F057F810BD00380140CE +:10192000BC000020BD0000208C0100201409002014 +:10193000AC00002010B51848FFF7BCF91648FFF7B7 +:10194000B3F9002809D000BF08201349086200BF7E +:101950001248006A401C114908620F48FFF7B6F9A7 +:1019600000280BD00C48FFF799F9002806D000BFDB +:1019700010200949086200BF00F02EF80648FFF762 +:101980009FF9002806D000BF40200349086200BF2D +:1019900000F044F810BD000000440040DC010020CD +:1019A00000B50748806A401C0549886205480088E0 +:1019B000002803DD01204873FFF754FF00BD00003D +:1019C0008C010020AC0000200248406A401C014904 +:1019D000486270478C01002000B50C4805214A1E62 +:1019E0000B4B9A5C121852684020801A09490880F3 +:1019F0000120094948730846806A401C88620548EE +:101A00000088002801DDFFF72DFF00BD0000024027 +:101A1000801A0008AE000020DC01002000B5054857 +:101A2000406A401C0349486201208873FFF71AFF8F +:101A300000BD0000DC01002000BFFEE702E008C896 +:101A4000121F08C1002AFAD170477047002001E038 +:101A500001C1121F002AFBD1704710B5034619605F +:101A600010B298800020D8801881987A40084000F1 +:101A70009872987A0224A043801C9872002010BDAE +:101A8000081C304458000000000404040000080052 +:101A90000000080000080000000800020406080A10 +:101AA0000C0001020304050600C1814001C0804111 +:101AB00001C0804100C1814001C0804100C181401E +:101AC00000C1814001C0804101C0804100C181400E +:101AD00000C1814001C0804100C1814001C08041FE +:101AE00001C0804100C1814001C0804100C18140EE +:101AF00000C1814001C0804100C1814001C08041DE +:101B000001C0804100C1814000C1814001C08041CD +:101B100001C0804100C1814001C0804100C18140BD +:101B200000C1814001C0804101C0804100C18140AD +:101B300000C1814001C0804100C1814001C080419D +:101B400001C0804100C1814000C1814001C080418D +:101B500001C0804100C1814001C0804100C181407D +:101B600000C1814001C0804100C1814001C080416D +:101B700001C0804100C1814001C0804100C181405D +:101B800000C1814001C0804101C0804100C181404D +:101B900000C1814001C0804100C1814001C080413D +:101BA00001C0804100C1814000C0C101C30302C225 +:101BB000C60607C705C5C404CC0C0DCD0FCFCE0E8D +:101BC0000ACACB0BC90908C8D81819D91BDBDA1AFD +:101BD0001EDEDF1FDD1D1CDC14D4D515D71716D66D +:101BE000D21213D311D1D010F03031F133F3F232DD +:101BF00036F6F737F53534F43CFCFD3DFF3F3EFE4D +:101C0000FA3A3BFB39F9F83828E8E929EB2B2AEABC +:101C1000EE2E2FEF2DEDEC2CE42425E527E7E6262C +:101C200022E2E323E12120E0A06061A163A3A2629C +:101C300066A6A767A56564A46CACAD6DAF6F6EAE0C +:101C4000AA6A6BAB69A9A86878B8B979BB7B7ABA7C +:101C5000BE7E7FBF7DBDBC7CB47475B577B7B676EC +:101C600072B2B373B17170B050909151935352925C +:101C700096565797559594549C5C5D9D5F9F9E5ECC +:101C80005A9A9B5B99595898884849894B8B8A4A3C +:101C90004E8E8F4F8D4D4C8C4484854587474686AC +:101CA0008242438341818040000001CC01D800146E +:101CB00001F0003C002801E401A0006C007801B4B0 +:101CC0000050019C01880044060000000400081C2C +:101CD0003044580000000004040400000800000024 +:101CE000080000080000000800020406080A0C00B2 +:101CF000010203040506081C3044580000000004DB +:101D000004040000080000000800000800000008AB +:101D100000020406080A0C000102030405063F063F +:101D20005B4F666D7D077F6F777C395E7971BF860B +:101D3000DBCFE6EDFD87FFEFF7FCB9DEF9F1004000 +:101D4000081C30445800000000040404000008008F +:101D50000000080000080000000800020406080A4D +:101D60000C000102030405060827000800000020FB +:101D7000EC0000003C1A0008F4270008EC000020EA +:101D8000541700004C1A000800000000000000007A +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:102000000109120102010401040110100000000086 +:102010000000000200000600A6B00120FE4908836F +:10202000FF200530FD4B8022FD490090FD48FEF762 +:1020300093FB4020FC4B0246FC490090FC48FEF715 +:102040008BFBFEF701FB00260020FA49086348637A +:10205000F94888630020C863F848C06A0863F848F4 +:1020600000684863F748406A8863F748FEF797FAC4 +:10207000FFF7A4F97D20C000F44908600846006815 +:10208000FEF786FB0120E4490883FEF7BFFBE12051 +:102090004002EF490860FEF7B7FAE6490863ED48E9 +:1020A000C088DD49088201200882FEF7B1FE0121C7 +:1020B000E948FEF7D0FC0421E748FEF7CCFCE648EF +:1020C000FEF7E3FC01210903E348FEF7C4FC6421A9 +:1020D000E148FEF7CFFDFEF7FFFD0121DF48FEF7E7 +:1020E000BAFC0421DD48FEF7B6FCDC48FEF7CDFC67 +:1020F000D948FEF7C4FCD948FEF7C1FCD648FEF724 +:10210000AEFCD648FEF7ABFC01208004CD494969FE +:102110000143CC4A5161114649690140089100BF11 +:1021200000BF182120A8FEF745F8012000032090E9 +:102130000120219003202290002023900120249050 +:1021400020A9C748FEF798FB01210903C448FEF700 +:102150001EFC0120C003209001202190032022902A +:10216000002023900120249020A90920C006FEF71A +:1021700083FB082020900120219003202290002042 +:1021800023900120249020A9B548FEF775FB20205C +:102190002090012021900320229001202390249060 +:1021A00020A9AF48FEF768FB0121C9030920C0063A +:1021B000FEF7EFFB0821AA48FEF7EBFB2021A84819 +:1021C000FEF7E7FBFFF726FB5621A6480170012426 +:1021D00001201F90A4481E90A4481E99FDF798FF67 +:1021E000401E1D9032201C901C991D9840181B9079 +:1021F0001C991D98401A1A901D9D002019900120CD +:1022000018909B48017810A801739948417810A84C +:1022100041739748817810A881739548C17810A8B8 +:10222000C1739348017910A801729148417910A8AF +:1022300041728F48817910A881728D48C17910A8A8 +:10224000C1728B48017A10A801718948417A10A89F +:1022500041718748817A10A881718548C17A10A898 +:10226000C1710021017055214170FF218170002151 +:10227000C17000BF00200A90099026E2F105C80F46 +:10228000FFF784F8761CFFF7C5FA0FA8FFF708FAE6 +:1022900008A8017F0E91007EC009002807D008A879 +:1022A000007DC009002802D10C98401C0C9008A8A1 +:1022B000007E0007C00F002808D008A8007D000796 +:1022C000C00F002802D10C98401E0C9008A8007E78 +:1022D0004007C00F002806D008A8007D4007C00FA7 +:1022E000002800D17F1E08A8007E4006C00F0028ED +:1022F00006D008A8007D4006C00F002800D17F1C32 +:1023000008A8007E8006C00F00281ED008A8007D07 +:102310008006C00F002818D10A98002801D101209A +:1023200000E000200A900A98002807D000244A48BC +:10233000FEF7A5FB4948FEF7A2FB06E0002446484D +:10234000FEF78DFB4548FEF78AFB08A8007E800754 +:10235000C00F002814D008A8007D8007C00F0028F7 +:102360000ED10998002801D1012000E00020099039 +:102370000998002802D00120199001E0002019904E +:102380000E980D90FEF740F908900A98002811D198 +:102390003748C17B10A801733548C17B10A8417331 +:1023A0003348017810A8817331482030417810A853 +:1023B000C1730FE02E48C17B10A8C1732C488178EF +:1023C00010A881732A48017E10A84173284801781B +:1023D00010A8017310A8017B0176417B8176817B77 +:1023E0000177C17B8177FEF70FF90790089907986D +:1023F000401A069000200590059F1D48817A10A87C +:1024000001720A213846FDF783FE1948415C10A885 +:1024100041720A2138462DE0F00600209007002086 +:10242000100700208C010020D40800209408002010 +:10243000DC010020CC0400209F86010080F7FF1FF4 +:102440004000002000100240102700001C00002067 +:10245000B40000202C020020002C0140004001406C +:10246000000400484C060020606D0000006CDC0297 +:102470001E1D0008FDF74CFE0A210190FDF748FEE5 +:1024800010319248415C10A88172642F0CDB6421EA +:102490003846FDF73DFE0A210190FDF739FE8B48D5 +:1024A000415C10A8C17203E008A8017F10A8C172A6 +:1024B00010A8017A4174417AC174817A4175C17A58 +:1024C000C1750020049004980B900A210B98FDF729 +:1024D0001FFE7E48415C10A801710A210B98FDF790 +:1024E00017FE0A210190FDF713FE7848415C10A801 +:1024F000417164210B98FDF70BFE0A210190FDF755 +:1025000007FE7248415C10A881717D21C9000B98BB +:10251000FDF7FEFD0A210190FDF7FAFD6B48415CD5 +:1025200010A8C171017901744179817481790175B3 +:10253000C17981757006C10E01208840401E03904C +:102540002046E117C90E09184911091DCA06D20E05 +:1025500001219140491E03910398C1B210A8017056 +:1025600003980004010E10A8417003980002010EA8 +:1025700010A881708178C176417841770178C17760 +:10258000102214A90020FFF7E7F86420FEF707F8EF +:102590001998002829D0F007C00F002825D06D1EFB +:1025A0001A98854200DC1B9D29464948FEF766FBC8 +:1025B00029464848FEF762FB681CC20F01901018BC +:1025C0004010411E4348FEF753FB681CC20F12180F +:1025D0005210511E3F4A116400BFC20F01901018E3 +:1025E0004010411E3A48FEF743FB0A9800281BD0D2 +:1025F0001898002818D0B007800F022814D11F980F +:10260000012807D13448844201DA641C08E0002024 +:102610001F9005E0012C01DD641E01E001201F90E8 +:1026200021462B48FEF726FBFDF722FE0920C006B7 +:10263000FEF7AAF90290029881B22848018628483C +:10264000FEF7A2F90290029881B2244841862548FB +:10265000FEF79AF90290029881B2204881862248BA +:10266000FEF792F90290029881B21C48C186FDF7EC +:10267000CBFF1E4908601E480068002802D00021D8 +:102680001C4801801C48007BC006C00E02281BD1DC +:102690001748006800280FD0002016490880174806 +:1026A0000068002810D112480168144801601448DD +:1026B00001681448016007E010480068002803D052 +:1026C0000B4800680D49086000BFD7E51E1D0008D3 +:1026D00000400140002C0140BB0200008C0600209D +:1026E0000004004800080048000C0048CC0000200E +:1026F00094000020AC020020CC04002098000020B0 +:102700002C0000209C0000200000000000000000C1 +:1027100000000000000000000000000000000000B9 +:102720000100000010270000000000000000000071 +:102730000000000000000000000000000000000099 +:102740000000000000000000000000000000000089 +:102750000100000000000000000000000302000073 +:102760000101010000000000000000000000000066 +:102770000000000000000000000000000000000059 +:102780000000000000000000000000000000000049 +:102790000000000000000000000000000000000039 +:1027A0000100000000000000FFFFFFFF000000002C +:1027B00000000000000000000100000000C2010055 +:1027C00040420F0000000000000000000000000078 +:1027D00000000000000000000000000000000000F9 +:1027E000000000000000000000000000001BB70017 +:0427F00000000000E5 +:04000005080000B53A +:00000001FF diff --git a/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.sct b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.sct new file mode 100644 index 0000000..bfd263c --- /dev/null +++ b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00010000 { ; load region size_region + ER_IROM1 0x08000000 0x00010000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00002000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2_sct.Bak b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2_sct.Bak new file mode 100644 index 0000000..6c8e805 --- /dev/null +++ b/C8T6_TestApp2/C8T6_TestApp2/C8T6_TestApp2_sct.Bak @@ -0,0 +1,16 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00010000 { ; load region size_region + ER_IROM1 0x08000000 0x00010000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_IRAM1 0x20000000 0x00002000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/C8T6_TestApp2/C8T6_UltroSonic.uvprojx b/C8T6_TestApp2/C8T6_UltroSonic.uvprojx new file mode 100644 index 0000000..94502c9 --- /dev/null +++ b/C8T6_TestApp2/C8T6_UltroSonic.uvprojx @@ -0,0 +1,756 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd"> + + <SchemaVersion>2.1</SchemaVersion> + + <Header>### uVision Project, (C) Keil Software</Header> + + <Targets> + <Target> + <TargetName>C8T6_TestApp2</TargetName> + <ToolsetNumber>0x4</ToolsetNumber> + <ToolsetName>ARM-ADS</ToolsetName> + <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> + <uAC6>0</uAC6> + <TargetOption> + <TargetCommonOption> + <Device>STM32F030C8Tx</Device> + <Vendor>STMicroelectronics</Vendor> + <PackID>Keil.STM32F0xx_DFP.2.1.1</PackID> + <PackURL>https://www.keil.com/pack/</PackURL> + <Cpu>IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE</Cpu> + <FlashUtilSpec></FlashUtilSpec> + <StartupFile></StartupFile> + <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32F030C8Tx$CMSIS\Flash\STM32F0xx_64.FLM))</FlashDriverDll> + <DeviceId>0</DeviceId> + <RegisterFile>$$Device:STM32F030C8Tx$Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f0xx.h</RegisterFile> + <MemoryEnv></MemoryEnv> + <Cmp></Cmp> + <Asm></Asm> + <Linker></Linker> + <OHString></OHString> + <InfinionOptionDll></InfinionOptionDll> + <SLE66CMisc></SLE66CMisc> + <SLE66AMisc></SLE66AMisc> + <SLE66LinkerMisc></SLE66LinkerMisc> + <SFDFile>$$Device:STM32F030C8Tx$CMSIS\SVD\STM32F0x0.svd</SFDFile> + <bCustSvd>0</bCustSvd> + <UseEnv>0</UseEnv> + <BinPath></BinPath> + <IncludePath></IncludePath> + <LibPath></LibPath> + <RegisterFilePath></RegisterFilePath> + <DBRegisterFilePath></DBRegisterFilePath> + <TargetStatus> + <Error>0</Error> + <ExitCodeStop>0</ExitCodeStop> + <ButtonStop>0</ButtonStop> + <NotGenerated>0</NotGenerated> + <InvalidFlash>1</InvalidFlash> + </TargetStatus> + <OutputDirectory>.\C8T6_TestApp2\</OutputDirectory> + <OutputName>C8T6_TestApp2</OutputName> + <CreateExecutable>1</CreateExecutable> + <CreateLib>0</CreateLib> + <CreateHexFile>1</CreateHexFile> + <DebugInformation>1</DebugInformation> + <BrowseInformation>1</BrowseInformation> + <ListingPath>.\C8T6_TestApp2\</ListingPath> + <HexFormatSelection>1</HexFormatSelection> + <Merge32K>0</Merge32K> + <CreateBatchFile>0</CreateBatchFile> + <BeforeCompile> + <RunUserProg1>0</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name></UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopU1X>0</nStopU1X> + <nStopU2X>0</nStopU2X> + </BeforeCompile> + <BeforeMake> + <RunUserProg1>0</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name></UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopB1X>0</nStopB1X> + <nStopB2X>0</nStopB2X> + </BeforeMake> + <AfterMake> + <RunUserProg1>1</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name>fromelf --bin --output="../@L.bin" "#L"</UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopA1X>0</nStopA1X> + <nStopA2X>0</nStopA2X> + </AfterMake> + <SelectedForBatchBuild>0</SelectedForBatchBuild> + <SVCSIdString></SVCSIdString> + </TargetCommonOption> + <CommonProperty> + <UseCPPCompiler>0</UseCPPCompiler> + <RVCTCodeConst>0</RVCTCodeConst> + <RVCTZI>0</RVCTZI> + <RVCTOtherData>0</RVCTOtherData> + <ModuleSelection>0</ModuleSelection> + <IncludeInBuild>1</IncludeInBuild> + <AlwaysBuild>0</AlwaysBuild> + <GenerateAssemblyFile>0</GenerateAssemblyFile> + <AssembleAssemblyFile>0</AssembleAssemblyFile> + <PublicsOnly>0</PublicsOnly> + <StopOnExitCode>3</StopOnExitCode> + <CustomArgument></CustomArgument> + <IncludeLibraryModules></IncludeLibraryModules> + <ComprImg>0</ComprImg> + </CommonProperty> + <DllOption> + <SimDllName>SARMCM3.DLL</SimDllName> + <SimDllArguments> -REMAP </SimDllArguments> + <SimDlgDll>DARMCM1.DLL</SimDlgDll> + <SimDlgDllArguments>-pCM0</SimDlgDllArguments> + <TargetDllName>SARMCM3.DLL</TargetDllName> + <TargetDllArguments> </TargetDllArguments> + <TargetDlgDll>TARMCM1.DLL</TargetDlgDll> + <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments> + </DllOption> + <DebugOption> + <OPTHX> + <HexSelection>1</HexSelection> + <HexRangeLowAddress>0</HexRangeLowAddress> + <HexRangeHighAddress>0</HexRangeHighAddress> + <HexOffset>0</HexOffset> + <Oh166RecLen>16</Oh166RecLen> + </OPTHX> + </DebugOption> + <Utilities> + <Flash1> + <UseTargetDll>1</UseTargetDll> + <UseExternalTool>0</UseExternalTool> + <RunIndependent>0</RunIndependent> + <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging> + <Capability>1</Capability> + <DriverSelection>4096</DriverSelection> + </Flash1> + <bUseTDR>1</bUseTDR> + <Flash2>BIN\UL2CM3.DLL</Flash2> + <Flash3>"" ()</Flash3> + <Flash4></Flash4> + <pFcarmOut></pFcarmOut> + <pFcarmGrp></pFcarmGrp> + <pFcArmRoot></pFcArmRoot> + <FcArmLst>0</FcArmLst> + </Utilities> + <TargetArmAds> + <ArmAdsMisc> + <GenerateListings>0</GenerateListings> + <asHll>1</asHll> + <asAsm>1</asAsm> + <asMacX>1</asMacX> + <asSyms>1</asSyms> + <asFals>1</asFals> + <asDbgD>1</asDbgD> + <asForm>1</asForm> + <ldLst>0</ldLst> + <ldmm>1</ldmm> + <ldXref>1</ldXref> + <BigEnd>0</BigEnd> + <AdsALst>1</AdsALst> + <AdsACrf>1</AdsACrf> + <AdsANop>0</AdsANop> + <AdsANot>0</AdsANot> + <AdsLLst>1</AdsLLst> + <AdsLmap>1</AdsLmap> + <AdsLcgr>1</AdsLcgr> + <AdsLsym>1</AdsLsym> + <AdsLszi>1</AdsLszi> + <AdsLtoi>1</AdsLtoi> + <AdsLsun>1</AdsLsun> + <AdsLven>1</AdsLven> + <AdsLsxf>1</AdsLsxf> + <RvctClst>0</RvctClst> + <GenPPlst>0</GenPPlst> + <AdsCpuType>"Cortex-M0"</AdsCpuType> + <RvctDeviceName></RvctDeviceName> + <mOS>0</mOS> + <uocRom>0</uocRom> + <uocRam>0</uocRam> + <hadIROM>1</hadIROM> + <hadIRAM>1</hadIRAM> + <hadXRAM>0</hadXRAM> + <uocXRam>0</uocXRam> + <RvdsVP>0</RvdsVP> + <hadIRAM2>0</hadIRAM2> + <hadIROM2>0</hadIROM2> + <StupSel>8</StupSel> + <useUlib>1</useUlib> + <EndSel>0</EndSel> + <uLtcg>0</uLtcg> + <nSecure>0</nSecure> + <RoSelD>3</RoSelD> + <RwSelD>3</RwSelD> + <CodeSel>0</CodeSel> + <OptFeed>0</OptFeed> + <NoZi1>0</NoZi1> + <NoZi2>0</NoZi2> + <NoZi3>0</NoZi3> + <NoZi4>0</NoZi4> + <NoZi5>0</NoZi5> + <Ro1Chk>0</Ro1Chk> + <Ro2Chk>0</Ro2Chk> + <Ro3Chk>0</Ro3Chk> + <Ir1Chk>1</Ir1Chk> + <Ir2Chk>0</Ir2Chk> + <Ra1Chk>0</Ra1Chk> + <Ra2Chk>0</Ra2Chk> + <Ra3Chk>0</Ra3Chk> + <Im1Chk>1</Im1Chk> + <Im2Chk>0</Im2Chk> + <OnChipMemories> + <Ocm1> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm1> + <Ocm2> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm2> + <Ocm3> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm3> + <Ocm4> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm4> + <Ocm5> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm5> + <Ocm6> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm6> + <IRAM> + <Type>0</Type> + <StartAddress>0x20000000</StartAddress> + <Size>0x2000</Size> + </IRAM> + <IROM> + <Type>1</Type> + <StartAddress>0x8000000</StartAddress> + <Size>0x10000</Size> + </IROM> + <XRAM> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </XRAM> + <OCR_RVCT1> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT1> + <OCR_RVCT2> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT2> + <OCR_RVCT3> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT3> + <OCR_RVCT4> + <Type>1</Type> + <StartAddress>0x8000000</StartAddress> + <Size>0x10000</Size> + </OCR_RVCT4> + <OCR_RVCT5> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT5> + <OCR_RVCT6> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT6> + <OCR_RVCT7> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT7> + <OCR_RVCT8> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT8> + <OCR_RVCT9> + <Type>0</Type> + <StartAddress>0x20000000</StartAddress> + <Size>0x2000</Size> + </OCR_RVCT9> + <OCR_RVCT10> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT10> + </OnChipMemories> + <RvctStartVector></RvctStartVector> + </ArmAdsMisc> + <Cads> + <interw>1</interw> + <Optim>1</Optim> + <oTime>0</oTime> + <SplitLS>0</SplitLS> + <OneElfS>1</OneElfS> + <Strict>0</Strict> + <EnumInt>0</EnumInt> + <PlainCh>0</PlainCh> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <wLevel>2</wLevel> + <uThumb>0</uThumb> + <uSurpInc>0</uSurpInc> + <uC99>1</uC99> + <uGnu>0</uGnu> + <useXO>0</useXO> + <v6Lang>3</v6Lang> + <v6LangP>3</v6LangP> + <vShortEn>1</vShortEn> + <vShortWch>1</vShortWch> + <v6Lto>0</v6Lto> + <v6WtE>0</v6WtE> + <v6Rtti>0</v6Rtti> + <VariousControls> + <MiscControls></MiscControls> + <Define>USE_FULL_LL_DRIVER,USE_HAL_DRIVER</Define> + <Undefine></Undefine> + <IncludePath>../C8T6_TestApp2/Inc;../C8T6_TestApp2/Src;../Drivers/STM32F0xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F0xx/Include;../Drivers/CMSIS/Include;../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy;..\ComLib\Inc</IncludePath> + </VariousControls> + </Cads> + <Aads> + <interw>1</interw> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <thumb>0</thumb> + <SplitLS>0</SplitLS> + <SwStkChk>0</SwStkChk> + <NoWarn>0</NoWarn> + <uSurpInc>0</uSurpInc> + <useXO>0</useXO> + <uClangAs>0</uClangAs> + <VariousControls> + <MiscControls></MiscControls> + <Define></Define> + <Undefine></Undefine> + <IncludePath></IncludePath> + </VariousControls> + </Aads> + <LDads> + <umfTarg>1</umfTarg> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <noStLib>0</noStLib> + <RepFail>1</RepFail> + <useFile>0</useFile> + <TextAddressRange>0x08000000</TextAddressRange> + <DataAddressRange>0x20000000</DataAddressRange> + <pXoBase></pXoBase> + <ScatterFile></ScatterFile> + <IncludeLibs></IncludeLibs> + <IncludeLibsPath></IncludeLibsPath> + <Misc></Misc> + <LinkerInputFile></LinkerInputFile> + <DisabledWarnings></DisabledWarnings> + </LDads> + </TargetArmAds> + </TargetOption> + <Groups> + <Group> + <GroupName>Application/MDK-ARM</GroupName> + <Files> + <File> + <FileName>startup_stm32f030x8.s</FileName> + <FileType>2</FileType> + <FilePath>.\startup_stm32f030x8.s</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>ComLib/Inc</GroupName> + <Files> + <File> + <FileName>debug.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\debug.h</FilePath> + </File> + <File> + <FileName>functions.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\functions.h</FilePath> + </File> + <File> + <FileName>GlobalDef.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\GlobalDef.h</FilePath> + </File> + <File> + <FileName>KBus.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\KBus.h</FilePath> + </File> + <File> + <FileName>KLink.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\KLink.h</FilePath> + </File> + <File> + <FileName>KMachine.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\KMachine.h</FilePath> + </File> + <File> + <FileName>ModbusRTU.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\ModbusRTU.h</FilePath> + </File> + <File> + <FileName>MyQueue.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\MyQueue.h</FilePath> + </File> + <File> + <FileName>PLCfunctions.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\PLCfunctions.h</FilePath> + </File> + <File> + <FileName>shell.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\shell.h</FilePath> + </File> + <File> + <FileName>stm32_assert.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\stm32_assert.h</FilePath> + </File> + <File> + <FileName>stm32f0xx_it.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\stm32f0xx_it.h</FilePath> + </File> + <File> + <FileName>SpiFlash.h</FileName> + <FileType>5</FileType> + <FilePath>..\ComLib\Inc\SpiFlash.h</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>ComLib/Src</GroupName> + <Files> + <File> + <FileName>debug.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\debug.c</FilePath> + </File> + <File> + <FileName>functions.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\functions.c</FilePath> + </File> + <File> + <FileName>GlobalDef.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\GlobalDef.c</FilePath> + </File> + <File> + <FileName>KBus.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\KBus.c</FilePath> + </File> + <File> + <FileName>KLink.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\KLink.c</FilePath> + </File> + <File> + <FileName>ModbusRTU.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\ModbusRTU.c</FilePath> + </File> + <File> + <FileName>MyQueue.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\MyQueue.c</FilePath> + </File> + <File> + <FileName>PLCfunctions.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\PLCfunctions.c</FilePath> + </File> + <File> + <FileName>shell.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\shell.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_msp.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\stm32f0xx_hal_msp.c</FilePath> + </File> + <File> + <FileName>KMachine.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\KMachine.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_it.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\stm32f0xx_it.c</FilePath> + </File> + <File> + <FileName>SpiFlash.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\SpiFlash.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Inc</GroupName> + <Files> + <File> + <FileName>main.h</FileName> + <FileType>5</FileType> + <FilePath>..\C8T6_TestApp2\Inc\main.h</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_conf.h</FileName> + <FileType>5</FileType> + <FilePath>..\C8T6_TestApp2\Inc\stm32f0xx_hal_conf.h</FilePath> + </File> + <File> + <FileName>BoardType.h</FileName> + <FileType>5</FileType> + <FilePath>..\C8T6_TestApp2\Inc\BoardType.h</FilePath> + </File> + <File> + <FileName>BSP_UltraSonic.h</FileName> + <FileType>5</FileType> + <FilePath>.\Inc\BSP_UltraSonic.h</FilePath> + </File> + <File> + <FileName>ADC.h</FileName> + <FileType>5</FileType> + <FilePath>.\Inc\ADC.h</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Application/User</GroupName> + <Files> + <File> + <FileName>main.c</FileName> + <FileType>1</FileType> + <FilePath>..\C8T6_TestApp2\Src\main.c</FilePath> + </File> + <File> + <FileName>BoardType.c</FileName> + <FileType>1</FileType> + <FilePath>..\C8T6_TestApp2\Src\BoardType.c</FilePath> + </File> + <File> + <FileName>BSP_UltraSonic.c</FileName> + <FileType>1</FileType> + <FilePath>.\Src\BSP_UltraSonic.c</FilePath> + </File> + <File> + <FileName>ADC.c</FileName> + <FileType>1</FileType> + <FilePath>.\Src\ADC.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Drivers/CMSIS</GroupName> + <Files> + <File> + <FileName>system_stm32f0xx.c</FileName> + <FileType>1</FileType> + <FilePath>..\ComLib\Src\system_stm32f0xx.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Drivers/STM32F0xx_HAL_Driver</GroupName> + <Files> + <File> + <FileName>stm32f0xx_ll_gpio.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_gpio.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_exti.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_exti.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_adc.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_adc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_dma.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_dma.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_spi.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_spi.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_tim.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_tim_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_usart.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usart.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_rcc.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_rcc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_rcc.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_rcc_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_i2c.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_i2c_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_gpio.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_dma.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_cortex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_pwr.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_pwr_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_flash.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_flash_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_utils.c</FileName> + <FileType>1</FileType> + <FilePath>../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_utils.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_tim.c</FileName> + <FileType>1</FileType> + <FilePath>..\Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_ll_tim.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_flash.c</FileName> + <FileType>1</FileType> + <FilePath>..\Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_ll_flash.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_i2c.c</FileName> + <FileType>1</FileType> + <FilePath>..\Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_ll_i2c.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_spi.c</FileName> + <FileType>1</FileType> + <FilePath>..\Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_hal_spi.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_spi_ex.c</FileName> + <FileType>1</FileType> + <FilePath>..\Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_hal_spi_ex.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>::CMSIS</GroupName> + </Group> + </Groups> + </Target> + </Targets> + + <RTE> + <apis/> + <components> + <component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.1.1" condition="ARMv6_7_8-M Device"> + <package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.3.0"/> + <targetInfos> + <targetInfo name="C8T6_TestApp2"/> + </targetInfos> + </component> + </components> + <files/> + </RTE> + +</Project> diff --git a/C8T6_TestApp2/DebugConfig/C8T6_TestApp2_STM32F030C8Tx.dbgconf b/C8T6_TestApp2/DebugConfig/C8T6_TestApp2_STM32F030C8Tx.dbgconf new file mode 100644 index 0000000..1725fed --- /dev/null +++ b/C8T6_TestApp2/DebugConfig/C8T6_TestApp2_STM32F030C8Tx.dbgconf @@ -0,0 +1,42 @@ +// File: STM32F030_070.dbgconf +// Version: 1.0.0 +// Note: refer to STM32F030x4/x6/x8/xC, STM32F070x6/xB Reference manual (RM0360) +// refer to STM32F030x4 STM32F030x6, STM32F030x8 STM32F030xC datasheet +// STM32F070CB STM32F070RB, STM32F070C6 STM32F070F6 datasheet + +// <<< Use Configuration Wizard in Context Menu >>> + +// <h> Debug MCU configuration register (DBGMCU_CR) +// <o.2> DBG_STANDBY <i> Debug standby mode +// <o.1> DBG_STOP <i> Debug stop mode +// </h> +DbgMCU_CR = 0x00000006; + +// <h> Debug MCU APB1 freeze register (DBGMCU_APB1_FZ) +// <i> Reserved bits must be kept at reset value +// <o.21> DBG_I2C1_TIMEOUT <i> I2C1 SMBUS timeout mode stopped when core is halted +// <o.12> DBG_IWDG_STOP <i> Independent watchdog stopped when core is halted +// <o.11> DBG_WWDG_STOP <i> Window watchdog stopped when core is halted +// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted +// <o.8> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted +// <o.5> DBG_TIM7_STOP <i> TIM7 counter stopped when core is halted +// <o.4> DBG_TIM6_STOP <i> TIM6 counter stopped when core is halted +// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted +// </h> +DbgMCU_APB1_Fz = 0x00000000; + +// <h> Debug MCU APB2 freeze register (DBGMCU_APB2_FZ) +// <i> Reserved bits must be kept at reset value +// <o.18> DBG_TIM17_STOP <i> TIM17 counter stopped when core is halted +// <o.17> DBG_TIM16_STOP <i> TIM16 counter stopped when core is halted +// <o.16> DBG_TIM15_STOP <i> TIM15 counter stopped when core is halted +// <o.11> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted +// </h> +DbgMCU_APB2_Fz = 0x00000000; + +// <h> Flash Download Options +// <o.0> Option Byte Loading <i> Launch the Option Byte Loading after a Flash Download by setting the OBL_LAUNCH bit (causes a reset) +// </h> +DoOptionByteLoading = 0x00000000; + +// <<< end of configuration section >>> diff --git a/C8T6_TestApp2/Ethernet/W5500/w5500.c b/C8T6_TestApp2/Ethernet/W5500/w5500.c new file mode 100644 index 0000000..1b80858 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/W5500/w5500.c @@ -0,0 +1,367 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include <stdio.h> +#include "w5500.h" + + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN1_); + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + ret = WIZCHIP.IF.SPI._read_byte(); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5000. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_); + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + uint16_t j = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++,j) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN4_); + for(i = 0; i < len/4; i++, j) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i*4] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+1] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+2] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+3] = WIZCHIP.IF.SPI._read_byte(); + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4); + } + len %= 4; // for the rest data + // M20131220 : remove for loop + i *= 4; + if(len >= 2) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_ + + //for(j = 0; j < len/2 ; j++) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i+1] = WIZCHIP.IF.SPI._read_byte(); + i += 2; + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,2); + } + } + len %= 2; + if(len) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_ + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } + #else + #error "Unsupported _WIZCHIP_IO_MODE_SPI_ in W5500 !!!" + #endif + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + uint16_t j = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++,j) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN4_); + for(i = 0; i < len/4; i++, j) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4] ); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+1]); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+2]); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+3]); + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4); + } + len %= 4; // for the rest data + // M20131220 : Remove for loop + i *= 4; + if(len >= 2) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_ + + //for(j = 0; j < len/2 ; j++) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i] ); + WIZCHIP.IF.SPI._write_byte(pBuf[i+1]); + i += 2; + AddrSel = WIZCHIP_OFFSET_INC(AddrSel, 2); + } + len %= 2; + if(len) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_ + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } + } + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + if(len == 0) return; + ptr = getSn_TX_WR(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel,wizdata, len); + + ptr += len; + setSn_TX_WR(sn,ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_RX_RD(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn,ptr); +} + + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr = 0; + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn,ptr); +} + diff --git a/C8T6_TestApp2/Ethernet/W5500/w5500.h b/C8T6_TestApp2/Ethernet/W5500/w5500.h new file mode 100644 index 0000000..2781a5f --- /dev/null +++ b/C8T6_TestApp2/Ethernet/W5500/w5500.h @@ -0,0 +1,2054 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5500_H_ +#define _W5500_H_ + +#include <stdint.h> +#include "Ethernet/wizchip_conf.h" + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address + + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function + */ + + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - <b> Basic I/O function </b> \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - @ref Common_register_group <b>access functions</b> \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# <b> Network Information </b> \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# <b> ICMP packet </b>\n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group <b>access functions</b> \n + * -# <b> SOCKET control</b> \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# <b> SOCKET information</b> \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# <b> SOCKET communication </b> \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# <b> IP header field </b> \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa RTR, RCR : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + + + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + + + /** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access <b>common registers</b>. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access <b>socket registers</b>. + */ + +//------------------------------- defgroup end -------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>RST</td> <td>Reserved</td> <td>WOL</td> <td>PB</td> <td>PPPoE</td> <td>Reserved</td> <td>FARP</td> <td>Reserved</td> </tr> + * </table> + * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. + * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of @ref IR defined as follows. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>CONFLICT</td> <td>UNREACH</td> <td>PPPoE</td> <td>MP</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr> + * </table> + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. + * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n + * Each bit of @ref IMR defined as the following. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>IM_IR7</td> <td>IM_IR6</td> <td>IM_IR5</td> <td>IM_IR4</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr> + * </table> + * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. + * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. + */ +#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref RCR configures the number of time of retransmission. + * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . + */ +#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates + * the destination IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR + * indicates the destination IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + + +//----------------------------- W5500 Socket Registers IOMAP ----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>MULTI/MFEN</td> <td>BCASTB</td> <td>ND/MC/MMB</td> <td>UCASTB/MIP6B</td> <td>Protocol[3]</td> <td>Protocol[2]</td> <td>Protocol[1]</td> <td>Protocol[0]</td> </tr> + * </table> + * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block <b>in UDP Multicasting</b> + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used <b>in UDP mulitcasting</b> + * - @ref Sn_MR_MMB : Multicast Blocking <b>in @ref Sn_MR_MACRAW mode</b> + * - @ref Sn_MR_UCASTB : Unicast Block <b>in UDP Multicating</b> + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking <b>in @ref Sn_MR_MACRAW mode</b> + * - <b>Protocol</b> + * <table> + * <tr> <td><b>Protocol[3]</b></td> <td><b>Protocol[2]</b></td> <td><b>Protocol[1]</b></td> <td><b>Protocol[0]</b></td> <td>@b Meaning</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>Closed</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>TCP</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>UDP</td> </tr> + * <tr> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>MACRAW</td> </tr> + * </table> + * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(<b>Server mode</b>) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(<b>Client mode</b>) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>SEND_OK</td> <td>TIMEOUT</td> <td>RECV</td> <td>DISCON</td> <td>CON</td> </tr> + * </table> + * - \ref Sn_IR_SENDOK : <b>SEND_OK Interrupt</b> + * - \ref Sn_IR_TIMEOUT : <b>TIMEOUT Interrupt</b> + * - \ref Sn_IR_RECV : <b>RECV Interrupt</b> + * - \ref Sn_IR_DISCON : <b>DISCON Interrupt</b> + * - \ref Sn_IR_CON : <b>CON Interrupt</b> + */ +#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of 锟絋CP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of 锟絋CP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In 锟絋CP clientmode, it configures the listen port number of 锟絋CP serverbefore CONNECT command. + * In 锟絋CP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can锟絫 be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. + * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between + * 锟絊ocket n RX Write Pointer (@ref Sn_RX_WR)and 锟絊ocket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of 锟終EEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + + +//----------------------------- W5500 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. + */ +#define IR_MP 0x10 + + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7<<3) +#define PHYCFGR_OPMDC_PDOWN (6<<3) +#define PHYCFGR_OPMDC_NA (5<<3) +#define PHYCFGR_OPMDC_100FA (4<<3) +#define PHYCFGR_OPMDC_100F (3<<3) +#define PHYCFGR_OPMDC_100H (2<<3) +#define PHYCFGR_OPMDC_10F (1<<3) +#define PHYCFGR_OPMDC_10H (0<<3) +#define PHYCFGR_DPX_FULL (1<<2) +#define PHYCFGR_DPX_HALF (0<<2) +#define PHYCFGR_SPD_100 (1<<1) +#define PHYCFGR_SPD_10 (0<<1) +#define PHYCFGR_LNK_ON (1<<0) +#define PHYCFGR_LNK_OFF (0<<0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m + * In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5500 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * <table> + * <tr> <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td> </tr> + * <tr> <td>Sn_MR_CLOSE (000</td> <td></td> </tr> + * <tr> <td>Sn_MR_TCP (001</td> <td>SOCK_INIT (0x13)</td> </tr> + * <tr> <td>Sn_MR_UDP (010</td> <td>SOCK_UDP (0x22)</td> </tr> + * <tr> <td>S0_MR_MACRAW (100</td> <td>SOCK_MACRAW (0x02)</td> </tr> + * </table> + */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). + * In this mode, Socket n operates as a 锟絋CP serverand waits for connection-request (SYN packet) from any 锟絋CP client + * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. + * When a 锟絋CP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a 锟絋CP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to b>TCP server</b>configured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client</b> + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of b>TCP server</b>or b>TCP client</b> the DISCON command processes the disconnect-process (b>Active close</b>or b>Passive close</b>.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\N + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\N + * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N + * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer (b>TCP client</b>.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVER</b>processed the SYN packet from the b>TCP CLIENT</b>during @ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n + * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) \ + WIZCHIP_WRITE(MR,mr) + + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() \ + WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } + + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref IMR register + * @param (uint8_t)imr Value to set @ref IMR register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(IMR, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IMR register + * @return uint8_t. Value of @ref IMR register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(IMR) + + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) \ + WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() \ + WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) \ + WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() \ + WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RTR register + * @param (uint16_t)rtr Value to set @ref RTR register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RTR register + * @return uint16_t. Value of @ref RTR register. + * @sa setRTR() + */ +#define getRTR() \ + ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(RTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RCR register + * @param (uint8_t)rcr Value to set @ref RCR register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(RCR, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RCR register + * @return uint8_t. Value of @ref RCR register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(RCR) + +//================================================== test done =========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) {\ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +//uint16_t getPSID(void); +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) \ + WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() \ + WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) + +/** + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +//uint16_t getSn_TxMAX(uint8_t sn); +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the <i>wizdata(pointer buffer)</i> of the length of <i>len(variable)</i> bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes. + * This function is being called by recv() also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of <i>len(variable)</i> bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +#endif // _W5500_H_ diff --git a/C8T6_TestApp2/Ethernet/loopback.c b/C8T6_TestApp2/Ethernet/loopback.c new file mode 100644 index 0000000..a921092 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/loopback.c @@ -0,0 +1,225 @@ +#include <stdio.h> +#include "loopback.h" +#include "socket.h" +#include "wizchip_conf.h" + +#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK + +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size = 0, sentsize=0; + +#ifdef _LOOPBACK_DEBUG_ + uint8_t destip[4]; + uint16_t destport; +#endif + + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) + { +#ifdef _LOOPBACK_DEBUG_ + getSn_DIPR(sn, destip); + destport = getSn_DPORT(sn); + + printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn,Sn_IR_CON); + } + if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recv(sn, buf, size); + + if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY. + size = (uint16_t) ret; + sentsize = 0; + + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); + if(ret < 0) + { + close(sn); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret = disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port); +#endif + if( (ret = listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP server loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) +{ + int32_t ret; // return value for SOCK_ERRORs + uint16_t size = 0, sentsize=0; + + // Destination (TCP Server) IP info (will be connected) + // >> loopback_tcpc() function parameter + // >> Ex) + // uint8_t destip[4] = {192, 168, 0, 214}; + // uint16_t destport = 5000; + + // Port number for TCP client (will be increased) + static uint16_t any_port = 50000; + + // Socket Status Transitions + // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status) + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // Data Transaction Parts; Handle the [data receive and send] process + ////////////////////////////////////////////////////////////////////////////////////////////// + if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array) + ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer) + + if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end + size = (uint16_t) ret; + sentsize = 0; + + // Data sentsize control + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer) + if(ret < 0) // Send Error occurred (sent data length < 0) + { + close(sn); // socket close + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + ////////////////////////////////////////////////////////////////////////////////////////////// + break; + + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret=disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination) + break; + + case SOCK_CLOSED: + close(sn); + if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){ + if(any_port == 0xffff) any_port = 50000; + return ret; // TCP socket open with 'any_port' port number + } +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP client loopback start\r\n",sn); + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + + switch(getSn_SR(sn)) + { + case SOCK_UDP : + if((size = getSn_RX_RSR(sn)) > 0) + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); + if(ret <= 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: recvfrom error. %ld\r\n",sn,ret); +#endif + return ret; + } + size = (uint16_t) ret; + sentsize = 0; + while(sentsize != size) + { + ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport); + if(ret < 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: sendto error. %ld\r\n",sn,ret); +#endif + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:UDP loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn) + return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port); +#endif + break; + default : + break; + } + return 1; +} + +#endif diff --git a/C8T6_TestApp2/Ethernet/loopback.h b/C8T6_TestApp2/Ethernet/loopback.h new file mode 100644 index 0000000..45c0283 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/loopback.h @@ -0,0 +1,38 @@ +#ifndef _LOOPBACK_H_ +#define _LOOPBACK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/* Loopback test debug message printout enable */ +// #define _LOOPBACK_DEBUG_ + +/* DATA_BUF_SIZE define for Loopback example */ +#ifndef DATA_BUF_SIZE + #define DATA_BUF_SIZE 256 +#endif + +/************************/ +/* Select LOOPBACK_MODE */ +/************************/ +#define LOOPBACK_MAIN_NOBLOCK 0 +#define LOOPBACK_MODE LOOPBACK_MAIN_NOBLOCK + + +/* TCP server Loopback test example */ +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port); + +/* TCP client Loopback test example */ +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport); + +/* UDP Loopback test example */ +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/C8T6_TestApp2/Ethernet/socket.c b/C8T6_TestApp2/Ethernet/socket.c new file mode 100644 index 0000000..2312617 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/socket.c @@ -0,0 +1,688 @@ +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. +//! Copy 4 byte addr value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#define SOCK_ANY_PORT_NUM 0xC000; + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; +static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; + +#if _WIZCHIP_ == 5200 + static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; +#endif + +#define CHECK_SOCKNUM() \ + do{ \ + if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + }while(0); \ + +#define CHECK_SOCKMODE(mode) \ + do{ \ + if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + }while(0); \ + +#define CHECK_SOCKINIT() \ + do{ \ + if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + }while(0); \ + +#define CHECK_SOCKDATA() \ + do{ \ + if(len == 0) return SOCKERR_DATALEN; \ + }while(0); \ + + + +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) +{ + CHECK_SOCKNUM(); + switch(protocol) + { + case Sn_MR_TCP : + case Sn_MR_UDP : + case Sn_MR_MACRAW : + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW : + case Sn_MR_PPPoE : + break; + #endif + default : + return SOCKERR_SOCKMODE; + } + if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if(flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if(flag != 0) + { + switch(protocol) + { + case Sn_MR_TCP: + if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; + break; + case Sn_MR_UDP: + if(flag & SF_IGMP_VER2) + { + if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; + } + #if _WIZCHIP_ == 5500 + if(flag & SF_UNI_BLOCK) + { + if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } + #endif + break; + default: + break; + } + } + close(sn); + setSn_MR(sn, (protocol | (flag & 0xF0))); + if(!port) + { + port = sock_any_port++; + if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn,port); + setSn_CR(sn,Sn_CR_OPEN); + while(getSn_CR(sn)); + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1<<sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while(getSn_SR(sn) == SOCK_CLOSED); + return (int8_t)sn; +} + +int8_t close(uint8_t sn) +{ + CHECK_SOCKNUM(); + + setSn_CR(sn,Sn_CR_CLOSE); + /* wait to process the command... */ + while( getSn_CR(sn) ); + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + sock_is_sending &= ~(1<<sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while(getSn_SR(sn) != SOCK_CLOSED); + return SOCK_OK; +} + +int8_t listen(uint8_t sn) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn,Sn_CR_LISTEN); + while(getSn_CR(sn)); + while(getSn_SR(sn) != SOCK_LISTEN) + { + if(getSn_CR(sn) == SOCK_CLOSED) + { + close(sn); + return SOCKERR_SOCKCLOSED; + } + } + return SOCK_OK; +} + + +int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[0] & 0x000000FF); + if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if(port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn,addr); + setSn_DPORT(sn,port); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR(0); + #endif + setSn_CR(sn,Sn_CR_CONNECT); + while(getSn_CR(sn)); + if(sock_io_mode & (1<<sn)) return SOCK_BUSY; + while(getSn_SR(sn) != SOCK_ESTABLISHED) + { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + return SOCKERR_TIMEOUT; + } + } + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + + return SOCK_OK; +} + +int8_t disconnect(uint8_t sn) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn,Sn_CR_DISCON); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending &= ~(1<<sn); + if(sock_io_mode & (1<<sn)) return SOCK_BUSY; + while(getSn_SR(sn) != SOCK_CLOSED) + { + if(getSn_IR(sn) & Sn_IR_TIMEOUT) + { + close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp=0; + uint16_t freesize=0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS; + if( sock_is_sending & (1<<sn) ) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + #if _WZICHIP_ == 5200 + if(getSn_TX_RD(sn) != sock_next_rd[sn]) + { + setSn_CR(sn,Sn_CR_SEND); + while(getSn_CR(sn)); + return SOCKERR_BUSY; + } + #endif + sock_is_sending &= ~(1<<sn); + } + else if(tmp & Sn_IR_TIMEOUT) + { + close(sn); + return SOCKERR_TIMEOUT; + } + else return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + } + wiz_send_data(sn, buf, len); + #if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; + #endif + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending |= (1 << sn); + return len; +} + + +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp = 0; + uint16_t recvsize = 0; + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if(recvsize < len) len = recvsize; + while(1) + { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) + { + if(tmp == SOCK_CLOSE_WAIT) + { + if(recvsize != 0) break; + else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + else + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; + if(recvsize != 0) break; + }; + if(recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + return len; +} + +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) +{ + uint8_t tmp = 0; + uint16_t freesize = 0; + CHECK_SOCKNUM(); + switch(getSn_MR(sn) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + break; + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + } + // + if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if(port == 0) return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + + setSn_DIPR(sn,addr); + setSn_DPORT(sn,port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR(0); + #endif + + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + while(1) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + //M:20131104 + //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if(tmp & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + //////////// + } + return len; +} + + + +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) +{ + uint8_t mr; + uint8_t head[8]; + uint16_t pack_len=0; + + CHECK_SOCKNUM(); + //CHECK_SOCKMODE(Sn_MR_UDP); + switch((mr=getSn_MR(sn)) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + case Sn_MR_PPPoE: + break; + #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if(sock_remained_size[sn] == 0) + { + while(1) + { + pack_len = getSn_RX_RSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; + if(pack_len != 0) break; + }; + } + sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) + { + case Sn_MR_UDP : + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 8); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + // read peer's IP address, port number & packet length + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW : + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 2); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; + if(sock_remained_size[sn] > 1514) + { + close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn,buf,pack_len); + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 6); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + #endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn,Sn_CR_RECV); + /* wait to process the command... */ + while(getSn_CR(sn)) ; + sock_remained_size[sn] -= pack_len; + //M20140501 : replace 0x01 with PACK_REMAINED + //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; + // + return pack_len; +} + + +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) +{ + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch(cstype) + { + case CS_SET_IOMODE: + tmp = *((uint8_t*)arg); + if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn); + else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn); + else return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + //M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t*)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t*)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t*)arg) = getSn_IR(sn); + break; + case CS_SET_INTMASK: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTMASK: + *((uint8_t*)arg) = getSn_IMR(sn); + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + // M20131220 : Remove warning + //uint8_t tmp; + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_TTL: + setSn_TTL(sn,*(uint8_t*)arg); + break; + case SO_TOS: + setSn_TOS(sn,*(uint8_t*)arg); + break; + case SO_MSS: + setSn_MSSR(sn,*(uint16_t*)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t*)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); + #if _WIZCHIP_ > 5200 + if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; + #endif + setSn_CR(sn,Sn_CR_SEND_KEEP); + while(getSn_CR(sn) != 0) + { + // M20131220 + //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn,*(uint8_t*)arg); + break; + #endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_FLAG: + *(uint8_t*)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t*) arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t*) arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint8_t*) arg = getSn_MSSR(sn); + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + *(uint16_t*) arg = getSn_DPORT(sn); + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t*) arg = getSn_KPALVTR(sn); + break; + #endif + case SO_SENDBUF: + *(uint16_t*) arg = getSn_TX_FSR(sn); + case SO_RECVBUF: + *(uint16_t*) arg = getSn_RX_RSR(sn); + case SO_STATUS: + *(uint8_t*) arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if(getSn_MR(sn) == Sn_MR_TCP) + *(uint16_t*)arg = getSn_RX_RSR(sn); + else + *(uint16_t*)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint8_t*)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} diff --git a/C8T6_TestApp2/Ethernet/socket.h b/C8T6_TestApp2/Ethernet/socket.h new file mode 100644 index 0000000..53411e2 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/socket.h @@ -0,0 +1,466 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. + * But there is a little bit of difference. + * @details + * <b> Comparison between WIZnet and Berkeley SOCKET APIs </b> + * <table> + * <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td> </tr> + * <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr> + * <tr> <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr> + * <tr> <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>send()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td> </tr> + * </table> + * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, + * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n + * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. + * When the listen SOCKET accepts a connection request from a client, it keeps listening. + * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n + * Following figure shows network flow diagram by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n + * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, + * it is changed in order to communicate with the client. + * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n + * If there're many listen SOCKET with same listen port number and a client requests a connection, + * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ + +#include "Ethernet/wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argrument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 + #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 + #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 + #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 + #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 +#endif + +#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. +#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. +#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n + * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediatly. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned immediatly\n + */ +int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. \n + * In Non-block io mode, it return @ref SOCK_BUSY immediatly. \n + + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n + * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n + * In non-block io mode, It return @ref SOCK_BUSY immediatly when socket buffer is not enough. \n + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n + * In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n + * In non-block io mode, it return @ref SOCK_BUSY immediatly when <I>len</I> is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n + * Even if the connectionless socket has been previously connected to a specific address, + * the address and port number parameters override the destination address for that particular datagram only. + * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>. + * In non-block io mode, It return @ref SOCK_BUSY immediatly when socket buffer is not enough. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n + * This function is used to receive UDP and MAC_RAW mode, and handle the header as well. + * This function can divide to received the packet data. + * On the MACRAW SOCKET, the addr and port parameters are ignored. + * @note In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer + * In non-block io mode, it return @ref SOCK_BUSY immediatly when <I>len</I> is greater than data size in socket buffer. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet sized. + * When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * It is valid only when the first call recvfrom for receiving the packet. + * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the packet. +* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); + + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum +{ + SIK_CONNECTED = (1 << 0), ///< conntected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occured + SIK_SENT = (1 << 4), ///< send ok + SIK_ALL = 0x1F, ///< all interrupt +}sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum +{ + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind +}ctlsock_type; + + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum +{ + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket(). + SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set/Get the destionation Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode + #if _WIZCHIP_ > 5200 + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmittion timer in TCP mode + #endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. +}sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. + * Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. \n + * <table> + * <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr> + * <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr> + * <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr> + * <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc. </td></tr> + * </table> + * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to <I>sotype</I>. \n + * <table> + * <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr> + * <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> + * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr> + * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr> + * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> + * </table> + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n + */ +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to <I>sotype</I>. \n + * <table> + * <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr> + * <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr> + * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> + * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr> + * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> </td></tr> + * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> + * <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr> + * <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr> + * <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr> + * </table> + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n + * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, + * This means the zero byte UDP data(UDP Header only) received. + */ +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +#endif // _SOCKET_H_ diff --git a/C8T6_TestApp2/Ethernet/wizchip_conf.c b/C8T6_TestApp2/Ethernet/wizchip_conf.c new file mode 100644 index 0000000..bfc19e3 --- /dev/null +++ b/C8T6_TestApp2/Ethernet/wizchip_conf.c @@ -0,0 +1,636 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* +//! For remove the warning when pointer type size is not 32bit. +//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +//A20140501 : for use the type - ptrdiff_t +#include <stddef.h> +// + +#include "wizchip_conf.h" +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_enter(void) {}; +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_exit(void) {}; +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_select(void) {}; +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_deselect(void) {}; +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + //M20140501 : Explict pointer type casting +//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); }; +uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }; +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + +//M20140501 : Explict pointer type casting +//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; }; +void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }; + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +uint8_t wizchip_spi_readbyte(void) {return 0;}; +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_spi_writebyte(uint8_t wb) {}; + +/** + * @\ref _WIZCHIP instance + */ +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) +{ + if(!cris_en || !cris_ex) + { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } + else + { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) +{ + if(!cs_sel || !cs_desel) + { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } + else + { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); + + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if(!spi_rb || !spi_wb) + { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } + else + { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) +{ + uint8_t tmp = 0; + uint8_t* ptmp[2] = {0,0}; + switch(cwtype) + { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if(arg != 0) + { + ptmp[0] = (uint8_t*)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind*)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind*)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind*)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind*)arg) = wizchip_getinterruptmask(); + break; + #if _WIZCHIP_ > 5100 + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTLEVEL(); + break; + #endif + case CW_GET_ID: + ((uint8_t*)arg)[0] = WIZCHIP.id[0]; + ((uint8_t*)arg)[1] = WIZCHIP.id[1]; + ((uint8_t*)arg)[2] = WIZCHIP.id[2]; + ((uint8_t*)arg)[3] = WIZCHIP.id[3]; + ((uint8_t*)arg)[4] = WIZCHIP.id[4]; + ((uint8_t*)arg)[5] = 0; + break; + #if _WIZCHIP_ == 5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t*)arg); + #endif + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + default: + return -1; + } + return 0; +} + + +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) +{ + + switch(cntype) + { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo*)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo*)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type*)arg); + case CN_GET_NETMODE: + *(netmode_type*)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout*)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout*)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) +{ + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; + getSHAR(mac); + getGAR(gw); getSUBR(sn); getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) +{ + int8_t i; + int8_t tmp = 0; + wizchip_sw_reset(); + if(txsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += txsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_TXBUF_SIZE(i, txsize[i]); + } + if(rxsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += rxsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_RXBUF_SIZE(i, rxsize[i]); + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) +{ + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + ir |= (1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + ir |= sir; + setIR(ir); +#else + setIR(ir); + setSIR(sir); +#endif +} + +intr_kind wizchip_getinterrupt(void) +{ + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + ir = getIR(); + sir = ir 0x0F; +#else + ir = getIR(); + sir = getSIR(); +#endif + +#if _WIZCHIP_ < 5500 + ir &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) +{ + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + simr &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + imr |= simr; + setIMR(imr); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) +{ + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + imr = getIMR(); + simr = imr 0x0F; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) +{ + int8_t tmp; +#if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > 5100 + +int8_t wizphy_getphypmode(void) +{ + int8_t tmp = 0; + #if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #else + tmp = -1; + #endif + return tmp; +} +#endif + +#if _WIZCHIP_ == 5500 +void wizphy_reset(void) +{ + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + if(phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if(phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else + { + if(phyconf->duplex == PHY_DUPLEX_FULL) + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } + else + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) +{ + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if((tmp & PHYCFGR_OPMD)== 0) return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if( pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if( pmode == PHY_POWER_DOWN) + { + if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; + } + else + { + if(tmp & PHYCFGR_OPMDC_ALLA) return 0; + } + return -1; +} +#endif + + +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) +{ + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) +{ + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0]= _DNS_[0]; + pnetinfo->dns[1]= _DNS_[1]; + pnetinfo->dns[2]= _DNS_[2]; + pnetinfo->dns[3]= _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) +{ + uint8_t tmp = 0; +#if _WIZCHIP_ != 5500 + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; +#else + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) +{ + return (netmode_type) getMR(); +} + +void wizchip_settimeout(wiz_NetTimeout* nettime) +{ + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) +{ + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} diff --git a/C8T6_TestApp2/Ethernet/wizchip_conf.h b/C8T6_TestApp2/Ethernet/wizchip_conf.h new file mode 100644 index 0000000..d39040b --- /dev/null +++ b/C8T6_TestApp2/Ethernet/wizchip_conf.h @@ -0,0 +1,548 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#include <stdint.h> +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n + * ex> <code> #define \_WIZCHIP_ 5500 </code> + */ +#define _WIZCHIP_ 5500 // 5100, 5200, 5500 + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ + + +#if (_WIZCHIP_ == 5100) + #define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ + +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +#elif (_WIZCHIP_ == 5200) + #define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + #include "W5200/w5200.h" +#elif (_WIZCHIP_ == 5500) + #define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code> + * + */ + //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ + #include "W5500/w5500.h" +#else + #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ + #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n + * ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code> + */ +#define _WIZCHIP_IO_BASE_ 0x00000000 // + +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS + #ifndef _WIZCHIP_IO_BASE_ + #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." + #endif +#endif + +#if _WIZCHIP_ > 5100 + #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else + #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + + +/******************************************************** +* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. +*********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP +{ + uint16_t if_mode; ///< host interface mode + uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS + { + void (*_enter) (void); ///< crtical section enter + void (*_exit) (void); ///< critial section exit + }CRIS; + /** + * The set of @ref\_WIZCHIP_ select control callback func. + */ + struct _CS + { + void (*_select) (void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + }CS; + /** + * The set of interface IO callback func. + */ + union _IF + { + /** + * For BUS interface IO + */ + struct + { + uint8_t (*_read_byte) (uint32_t AddrSel); + void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + }BUS; + /** + * For SPI interface IO + */ + struct + { + uint8_t (*_read_byte) (void); + void (*_write_byte) (uint8_t wb); + }SPI; + // To be added + // + }IF; +}_WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum +{ + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + +#if _WIZCHIP_ == 5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000 + CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000 +#endif + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal + CW_GET_PHYLINK ///< Get PHY Link status +}ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum +{ + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +}ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum +{ +#if _WIZCHIP_ > 5200 + IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != 5200 + IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > 5100 + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > 5100 + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt +#endif +}intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + + +#if _WIZCHIP_ == 5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, + * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n + * Valid only in W5500. + */ +typedef struct wiz_PhyConf_t +{ + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF + }wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum +{ + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +}dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t +{ + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +}wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum +{ +#if _WIZCHIP_ == 5500 + NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 +#endif + NM_WAKEONLAN = (1<<5), ///< Wake On Lan + NM_PINGBLOCK = (1<<4), ///< Block ping-request + NM_PPPOE = (1<<3), ///< PPPoE mode +}netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. + */ +typedef struct wiz_NetTimeout_t +{ + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +}wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such as + *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. + *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); + + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte usig SPI + *@param spi_wb : callback function to write byte usig SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), + * controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n + * 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); + + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +#if _WIZCHIP_ > 5100 + int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 + int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == 5500 + void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 +/** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_setphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphystat(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ + int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** +* @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout* nettime); + +#endif // _WIZCHIP_CONF_H_ diff --git a/C8T6_TestApp2/EventRecorderStub.scvd b/C8T6_TestApp2/EventRecorderStub.scvd new file mode 100644 index 0000000..2956b29 --- /dev/null +++ b/C8T6_TestApp2/EventRecorderStub.scvd @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> + +<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd"> + +<component name="EventRecorderStub" version="1.0.0"/> <!--name and version of the component--> + <events> + </events> + +</component_viewer> diff --git a/C8T6_TestApp2/Inc/ADC.h b/C8T6_TestApp2/Inc/ADC.h new file mode 100644 index 0000000..ee253dc --- /dev/null +++ b/C8T6_TestApp2/Inc/ADC.h @@ -0,0 +1,14 @@ +/** + ****************************************************************************** + * @file : ADC.h + * @brief : Header for ADC.c file. + * This file contains the user functions defines of the application. + ****************************************************************************** + */ +#ifndef __ADC_H__ +#define __ADC_H__ +#include <stdint.h> + +int ADCProcess2(void); + +#endif /* __ADC_H__ */ diff --git a/C8T6_TestApp2/Inc/BSP_UltraSonic.h b/C8T6_TestApp2/Inc/BSP_UltraSonic.h new file mode 100644 index 0000000..a09f073 --- /dev/null +++ b/C8T6_TestApp2/Inc/BSP_UltraSonic.h @@ -0,0 +1,41 @@ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BSP_H__ +#define __BSP_H__ + +#include "stm32f0xx_ll_rcc.h" +#include "stm32f0xx_ll_adc.h" +#include "stm32f0xx_ll_crc.h" +#include "stm32f0xx_ll_dma.h" +#include "stm32f0xx_ll_spi.h" +#include "stm32f0xx_ll_usart.h" +#include "stm32f0xx_ll_system.h" +#include "stm32f0xx_ll_gpio.h" +#include "stm32f0xx_ll_exti.h" +#include "stm32f0xx_ll_bus.h" +#include "stm32f0xx_ll_cortex.h" +#include "stm32f0xx_ll_utils.h" +#include "stm32f0xx_ll_pwr.h" +#include "stm32f0xx_ll_tim.h" +#include "stm32f0xx_ll_i2c.h" + +void SystemClock_Config(void); +void SystemClock_Config_New(void); +void MX_IWDG_Init(void); +void MX_GPIO_Init(void); +void MX_DMA_Init(void); +void MX_USART1_UART_Init(void); +void MX_USART2_UART_Init(void); +void MX_TIM1_Init(void); +void MX_TIM6_Init(void); +void MX_TIM14_Init(void); +void MX_TIM15_Init(void); +void MX_TIM16_Init(void); + +void MX_SPI1_Init(void); +void MX_SPI2_Init(void); +//void MX_I2C1_Init(void); +void Soft_I2C1_Init(void); +void MX_ADC_Init(void); + +#endif /* __BSP__ */ + diff --git a/C8T6_TestApp2/Inc/BoardType.h b/C8T6_TestApp2/Inc/BoardType.h new file mode 100644 index 0000000..1e584f3 --- /dev/null +++ b/C8T6_TestApp2/Inc/BoardType.h @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * @file : BoardType.h + * @brief : Define of BoardType. + * This file contains the defines of the BoardType. + ****************************************************************************** + */ +#ifndef __BOARDTYPE_H__ +#define __BOARDTYPE_H__ + +/* + 0 //old board 4 in 4 out + 1 //old board 8 in 8 out + 2 //Master 16 in16 out + 3 //Slave 8 in 8 out + 4 //New Master 16 in16 out V1.2 + 5 //Slave 8 in 8 out V1.2 +*/ + +#define USART2_USE_HARDWARE_DE 1 +#define USART2_DE_ASSERTION_TIME 31 +#define USART2_DE_DEASSERTION_TIME 31 + +enum enBOARD_TYPE +{ + BOARD_UNKNOWN =0, + BOARD_OLD4=1, // 1 //old board 4 in 4 o + BOARD_OLD8, //2 old board 8 in 8 o + BOARD_MASTER, //3 Master 16 in16 o + BOARD_SLAVE, //4 Slave 8 in 8 o + BOARD_NEW_MASTER, //5 New Master 16 in16 o + BOARD_NEW_SLAVE, //6 New Slave 8 in 8 o + BOARD_V4_MASTER, //7 New V4 Master 16 in16 o + BOARD_V4_SLAVE, //8 New V4 Slave 8 in 8 o + BOARD_V42_MASTER, //9 New V4.2 Master 16 in16 o + BOARD_V42_SLAVE, //10 New V4.2 Slave 8 in 8 o + + BOARD_V30_MINI =11, //11 Mini Board + BOARD_V45_NET = 13, + BOARD_EXT_FP0 = 14, + BOARD_V50_RADIO_16 = 15, + BOARD_V50_RADIO_8 = 16, + +}; + +#define BOARD_TYPE 9 +#define BOARD_VER 1 + +#define ENABLE_PLC 1 + +#if (BOARD_TYPE == 11) +#define XLAT_FREQ 12 +#elif (BOARD_TYPE == 14) +#define XLAT_FREQ 12 +#else +#define XLAT_FREQ 8 +#endif + +#define GetBoardType() (BOARD_TYPE) + +#if ( BOARD_TYPE == 1) +#define DINPUT 4 +#define DOUTPUT 4 +#elif (BOARD_TYPE == 2 || BOARD_TYPE == 4 || BOARD_TYPE == 6 || BOARD_TYPE == 8 || BOARD_TYPE == 10 || BOARD_TYPE == 11 || BOARD_TYPE == 16) +#define DINPUT 8 +#define DOUTPUT 8 +#elif BOARD_TYPE == 3 || BOARD_TYPE == 5 || BOARD_TYPE == 7 || BOARD_TYPE == 9 || BOARD_TYPE == 13 || BOARD_TYPE == 15 +#define DINPUT 16 +#define DOUTPUT 16 +#elif BOARD_TYPE == 14 +#define DINPUT 0 +#define DOUTPUT 6 +#else +#define DINPUT 0 +#define DOUTPUT 0 +#endif + + +typedef struct tagInfoBlockHdr { + unsigned short nBlkSign; // 开始标志 + unsigned short nBlkTypeVer; // 类型和版本 + unsigned short nBlkSize; // Block 大小, 包括开始和结束标志 + unsigned short Pad1; +}stInfoBlockHdr; + +typedef struct tagInfoBlockTail { + + unsigned short CRC16; + unsigned short EndSign; +}stInfoBlockTail; + +typedef struct tagBtLdrInfoBlock { + stInfoBlockHdr Hdr; + unsigned short nBtldrVer; + unsigned short nBtldrDevice; + unsigned short nBtldrSize; // 设计大小 + unsigned short nBtldrDataSize; //代码大小 + unsigned int nBtldr_AppAddr; + unsigned int nBtldr_NewAppInfoAddr; + unsigned int nBtldr_NewAppAddr; + stInfoBlockTail tail; +}stBtLdrInfoBlock, *pBtLdrInfoBlock; + +typedef struct tagAppInfoBlock { + stInfoBlockHdr Hdr; + unsigned short nAppVer; + unsigned short nAppDevice; + unsigned short nAppSize; // 代码设计大小 + unsigned short nAppDataSize; //实际代码大小 + unsigned int nAppStartAddr; + unsigned int nAppStartOffset; + unsigned int nApp; + stInfoBlockTail tail; +}stAppInfoBlock, * pAppInfoBlock; + + + +#endif /* __BOARDTYPE_H__ */ diff --git a/C8T6_TestApp2/Inc/main.h b/C8T6_TestApp2/Inc/main.h new file mode 100644 index 0000000..44f8e1e --- /dev/null +++ b/C8T6_TestApp2/Inc/main.h @@ -0,0 +1,120 @@ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "BoardType.h" + +#include "stm32f0xx_ll_adc.h" +#include "stm32f0xx_ll_iwdg.h" +#include "stm32f0xx_ll_crc.h" +#include "stm32f0xx_ll_dma.h" +#include "stm32f0xx_ll_spi.h" +#include "stm32f0xx_ll_usart.h" +#include "stm32f0xx_ll_rcc.h" +#include "stm32f0xx_ll_system.h" +#include "stm32f0xx_ll_gpio.h" +#include "stm32f0xx_ll_exti.h" +#include "stm32f0xx_ll_bus.h" +#include "stm32f0xx_ll_cortex.h" +#include "stm32f0xx_ll_tim.h" +#include "stm32f0xx_ll_utils.h" +#include "stm32f0xx_ll_pwr.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private define ------------------------------------------------------------*/ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* USER CODE BEGIN Private defines */ +#include "KBus.h" + +extern stKBusDef KBus1; + +#define Uart1RxBufSize 256 +#define RX2BUFSIZE 64 +#define TX2BUFSIZE 64 +#define DefaultUart1Baud 115200 +#define DefaultUart2Baud 1000000 +#define AlterUart2Baud 500000 + +extern volatile char Uart1BaudGot; +extern volatile char Uart1BaudFirstGot; + +extern unsigned char Uart1Mode; +extern unsigned int Uart1Baud; +extern unsigned int Uart2Baud; + +extern volatile int PendSvCount; + +extern unsigned char Uart1RxBuf1[Uart1RxBufSize]; +extern unsigned char Uart1TxBuf1[260]; + +extern unsigned char Uart2RxBuf1[RX2BUFSIZE]; +extern unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +extern unsigned short Uart1RxBuf1DataLen; +extern unsigned short Uart2RxBuf1DataLen; + +/* USER CODE END Private defines */ + +#ifdef __cplusplus + extern "C" { +#endif +void _Error_Handler(char *, int); + +#define Error_Handler() _Error_Handler(__FILE__, __LINE__) +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/C8T6_TestApp2/Inc/stm32f0xx_hal_conf.h b/C8T6_TestApp2/Inc/stm32f0xx_hal_conf.h new file mode 100644 index 0000000..2a4d2a3 --- /dev/null +++ b/C8T6_TestApp2/Inc/stm32f0xx_hal_conf.h @@ -0,0 +1,324 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2018 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "main.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_EXTI_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined (HSI14_VALUE) +#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)40000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSI) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 0 +#define DATA_CACHE_ENABLE 0 +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/C8T6_TestApp2/Internet/DHCP/dhcp.c b/C8T6_TestApp2/Internet/DHCP/dhcp.c new file mode 100644 index 0000000..3da4709 --- /dev/null +++ b/C8T6_TestApp2/Internet/DHCP/dhcp.c @@ -0,0 +1,976 @@ +//***************************************************************************** +// +//! \file dhcp.c +//! \brief DHCP APIs implement file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Optimize code +//! 2. Add reg_dhcp_cbfunc() +//! 3. Add DHCP_stop() +//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() +//! 5. Don't care system endian +//! 6. Add comments +//! <2012/12/26> V1.1.1 +//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "Ethernet/socket.h" +#include "Internet/DHCP/dhcp.h" + +/* If you want to display debug & procssing message, Define _DHCP_DEBUG_ in dhcp.h */ + +#ifdef _DHCP_DEBUG_ + #include <stdio.h> +#endif + +/* DHCP state machine. */ +#define STATE_DHCP_INIT 0 ///< Initialize +#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER +#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK +#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased +#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP +#define STATE_DHCP_RELEASE 5 ///< No use +#define STATE_DHCP_STOP 6 ///< Stop procssing DHCP + +#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG +#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG + +/* DHCP message OP code */ +#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG +#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG + +/* DHCP message type */ +#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG +#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG +#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG +#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG +#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG +#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG +#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use +#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use + +#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG +#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG + +#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG +#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG +#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG + +#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time + +#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG +#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG + +/* + * @brief DHCP option and value (cf. RFC1533) + */ +enum +{ + padOption = 0, + subnetMask = 1, + timerOffset = 2, + routersOnSubnet = 3, + timeServer = 4, + nameServer = 5, + dns = 6, + logServer = 7, + cookieServer = 8, + lprServer = 9, + impressServer = 10, + resourceLocationServer = 11, + hostName = 12, + bootFileSize = 13, + meritDumpFile = 14, + domainName = 15, + swapServer = 16, + rootPath = 17, + extentionsPath = 18, + IPforwarding = 19, + nonLocalSourceRouting = 20, + policyFilter = 21, + maxDgramReasmSize = 22, + defaultIPTTL = 23, + pathMTUagingTimeout = 24, + pathMTUplateauTable = 25, + ifMTU = 26, + allSubnetsLocal = 27, + broadcastAddr = 28, + performMaskDiscovery = 29, + maskSupplier = 30, + performRouterDiscovery = 31, + routerSolicitationAddr = 32, + staticRoute = 33, + trailerEncapsulation = 34, + arpCacheTimeout = 35, + ethernetEncapsulation = 36, + tcpDefaultTTL = 37, + tcpKeepaliveInterval = 38, + tcpKeepaliveGarbage = 39, + nisDomainName = 40, + nisServers = 41, + ntpServers = 42, + vendorSpecificInfo = 43, + netBIOSnameServer = 44, + netBIOSdgramDistServer = 45, + netBIOSnodeType = 46, + netBIOSscope = 47, + xFontServer = 48, + xDisplayManager = 49, + dhcpRequestedIPaddr = 50, + dhcpIPaddrLeaseTime = 51, + dhcpOptionOverload = 52, + dhcpMessageType = 53, + dhcpServerIdentifier = 54, + dhcpParamRequest = 55, + dhcpMsg = 56, + dhcpMaxMsgSize = 57, + dhcpT1value = 58, + dhcpT2value = 59, + dhcpClassIdentifier = 60, + dhcpClientIdentifier = 61, + endOption = 255 +}; + +/* + * @brief DHCP message format + */ +typedef struct { + uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY + uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB + uint8_t hlen; ///< @ref DHCP_HLENETHERNET + uint8_t hops; ///< @ref DHCP_HOPS + uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. + uint16_t secs; ///< @ref DHCP_SECS + uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST + uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever + uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server + uint8_t siaddr[4]; ///< No use + uint8_t giaddr[4]; ///< No use + uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero + uint8_t sname[64]; ///< No use + uint8_t file[128]; ///< No use + uint8_t OPT[OPT_SIZE]; ///< Option +} RIP_MSG; + + + +uint8_t DHCP_SOCKET; // Socket number for DHCP + +uint8_t DHCP_SIP[4]; // DHCP Server IP address + +// Network information from DHCP Server +uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address +uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP +uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP +uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP +uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP + + +int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state +int8_t dhcp_retry_count = 0; + +uint32_t dhcp_lease_time = INFINITE_LEASETIME; +volatile uint32_t dhcp_tick_1s = 0; // unit 1 second +uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; + +uint32_t DHCP_XID; // Any number + +RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing + +uint8_t HOST_NAME[] = DCHP_HOST_NAME; + +uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. + +/* The default callback function */ +void default_ip_assign(void); +void default_ip_update(void); +void default_ip_conflict(void); + +/* Callback handler */ +void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ +void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ +void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ + +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + + +/* send DISCOVER message to DHCP server */ +void send_DHCP_DISCOVER(void); + +/* send REQEUST message to DHCP server */ +void send_DHCP_REQUEST(void); + +/* send DECLINE message to DHCP server */ +void send_DHCP_DECLINE(void); + +/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ +int8_t check_DHCP_leasedIP(void); + +/* check the timeout in DHCP process */ +uint8_t check_DHCP_timeout(void); + +/* Intialize to timeout process. */ +void reset_DHCP_timeout(void); + +/* Parse message as OFFER and ACK and NACK from DHCP server.*/ +int8_t parseDHCPCMSG(void); + +/* The default handler of ip assign first */ +void default_ip_assign(void) +{ + setSIPR(DHCP_allocated_ip); + setSUBR(DHCP_allocated_sn); + setGAR (DHCP_allocated_gw); +} + +/* The default handler of ip chaged */ +void default_ip_update(void) +{ + /* WIZchip Software Reset */ + setMR(MR_RST); + getMR(); // for delay + default_ip_assign(); + setSHAR(DHCP_CHADDR); +} + +/* The default handler of ip chaged */ +void default_ip_conflict(void) +{ + // WIZchip Software Reset + setMR(MR_RST); + getMR(); // for delay + setSHAR(DHCP_CHADDR); +} + +/* register the call back func. */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) +{ + dhcp_ip_assign = default_ip_assign; + dhcp_ip_update = default_ip_update; + dhcp_ip_conflict = default_ip_conflict; + if(ip_assign) dhcp_ip_assign = ip_assign; + if(ip_update) dhcp_ip_update = ip_update; + if(ip_conflict) dhcp_ip_conflict = ip_conflict; +} + +/* make the common DHCP message */ +void makeDHCPMSG(void) +{ + uint8_t bk_mac[6]; + uint8_t* ptmp; + uint8_t i; + getSHAR(bk_mac); + pDHCPMSG->op = DHCP_BOOTREQUEST; + pDHCPMSG->htype = DHCP_HTYPE10MB; + pDHCPMSG->hlen = DHCP_HLENETHERNET; + pDHCPMSG->hops = DHCP_HOPS; + ptmp = (uint8_t*)(&pDHCPMSG->xid); + *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); + *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); + *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); + *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); + pDHCPMSG->secs = DHCP_SECS; + ptmp = (uint8_t*)(&pDHCPMSG->flags); + *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); + *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); + + pDHCPMSG->ciaddr[0] = 0; + pDHCPMSG->ciaddr[1] = 0; + pDHCPMSG->ciaddr[2] = 0; + pDHCPMSG->ciaddr[3] = 0; + + pDHCPMSG->yiaddr[0] = 0; + pDHCPMSG->yiaddr[1] = 0; + pDHCPMSG->yiaddr[2] = 0; + pDHCPMSG->yiaddr[3] = 0; + + pDHCPMSG->siaddr[0] = 0; + pDHCPMSG->siaddr[1] = 0; + pDHCPMSG->siaddr[2] = 0; + pDHCPMSG->siaddr[3] = 0; + + pDHCPMSG->giaddr[0] = 0; + pDHCPMSG->giaddr[1] = 0; + pDHCPMSG->giaddr[2] = 0; + pDHCPMSG->giaddr[3] = 0; + + pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; + pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; + pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; + pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; + pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; + pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; + + for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; + for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; + for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; + + // MAGIC_COOKIE + pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); + pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); + pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); + pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; +} + +/* SEND DHCP DISCOVER */ +void send_DHCP_DISCOVER(void) +{ + uint16_t i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DISCOVER; + + // Client identifier + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x06; // length of request + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + // send broadcasting packet + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_DISCOVER\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* SEND DHCP REQUEST */ +void send_DHCP_REQUEST(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) + { + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; + pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; + pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; + pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; + ip[0] = DHCP_SIP[0]; + ip[1] = DHCP_SIP[1]; + ip[2] = DHCP_SIP[2]; + ip[3] = DHCP_SIP[3]; + } + else + { + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + } + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_REQUEST; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + { + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + } + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x08; + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = performRouterDiscovery; + pDHCPMSG->OPT[k++] = staticRoute; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_REQUEST\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + +} + +/* SEND DHCP DHCPDECLINE */ +void send_DHCP_DECLINE(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DECLINE; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + //send broadcasting packet + ip[0] = 0xFF; + ip[1] = 0xFF; + ip[2] = 0xFF; + ip[3] = 0xFF; + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Send DHCP_DECLINE\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* PARSE REPLY pDHCPMSG */ +int8_t parseDHCPMSG(void) +{ + uint8_t svr_addr[6]; + uint16_t svr_port; + uint16_t len; + + uint8_t * p; + uint8_t * e; + uint8_t type; + uint8_t opt_len; + + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) + { + len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); + #ifdef _DHCP_DEBUG_ + printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); + #endif + } + else return 0; + if (svr_port == DHCP_SERVER_PORT) { + // compare mac address + if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || + (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || + (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) + return 0; + type = 0; + p = (uint8_t *)(&pDHCPMSG->op); + p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) + e = p + (len - 240); + + while ( p < e ) { + + switch ( *p ) { + + case endOption : + p = e; // for break while(p < e) + break; + case padOption : + p++; + break; + case dhcpMessageType : + p++; + p++; + type = *p++; + break; + case subnetMask : + p++; + p++; + DHCP_allocated_sn[0] = *p++; + DHCP_allocated_sn[1] = *p++; + DHCP_allocated_sn[2] = *p++; + DHCP_allocated_sn[3] = *p++; + break; + case routersOnSubnet : + p++; + opt_len = *p++; + DHCP_allocated_gw[0] = *p++; + DHCP_allocated_gw[1] = *p++; + DHCP_allocated_gw[2] = *p++; + DHCP_allocated_gw[3] = *p++; + p = p + (opt_len - 4); + break; + case dns : + p++; + opt_len = *p++; + DHCP_allocated_dns[0] = *p++; + DHCP_allocated_dns[1] = *p++; + DHCP_allocated_dns[2] = *p++; + DHCP_allocated_dns[3] = *p++; + p = p + (opt_len - 4); + break; + case dhcpIPaddrLeaseTime : + p++; + opt_len = *p++; + dhcp_lease_time = *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + #ifdef _DHCP_DEBUG_ + dhcp_lease_time = 10; + #endif + break; + case dhcpServerIdentifier : + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + break; + default : + p++; + opt_len = *p++; + p += opt_len; + break; + } // switch + } // while + } // if + return type; +} + +uint8_t DHCP_run(void) +{ + uint8_t type; + uint8_t ret; + + if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; + + if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) + socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + + ret = DHCP_RUNNING; + type = parseDHCPMSG(); + + switch ( dhcp_state ) { + case STATE_DHCP_INIT : + DHCP_allocated_ip[0] = 0; + DHCP_allocated_ip[1] = 0; + DHCP_allocated_ip[2] = 0; + DHCP_allocated_ip[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER : + if (type == DHCP_OFFER){ +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_OFFER\r\n"); +#endif + DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; + DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; + DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; + DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_REQUEST : + if (type == DHCP_ACK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_ACK\r\n"); +#endif + if (check_DHCP_leasedIP()) { + // Network info assignment from DHCP + dhcp_ip_assign(); + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred + reset_DHCP_timeout(); + dhcp_ip_conflict(); + dhcp_state = STATE_DHCP_INIT; + } + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_LEASED : + ret = DHCP_IP_LEASED; + if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { + +#ifdef _DHCP_DEBUG_ + printf("> Maintains the IP address \r\n"); +#endif + + type = 0; + OLD_allocated_ip[0] = DHCP_allocated_ip[0]; + OLD_allocated_ip[1] = DHCP_allocated_ip[1]; + OLD_allocated_ip[2] = DHCP_allocated_ip[2]; + OLD_allocated_ip[3] = DHCP_allocated_ip[3]; + + DHCP_XID++; + + send_DHCP_REQUEST(); + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_REREQUEST; + } + break; + + case STATE_DHCP_REREQUEST : + ret = DHCP_IP_LEASED; + if (type == DHCP_ACK) { + dhcp_retry_count = 0; + if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + OLD_allocated_ip[1] != DHCP_allocated_ip[1] || + OLD_allocated_ip[2] != DHCP_allocated_ip[2] || + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) + { + ret = DHCP_IP_CHANGED; + dhcp_ip_update(); + #ifdef _DHCP_DEBUG_ + printf(">IP changed.\r\n"); + #endif + + } + #ifdef _DHCP_DEBUG_ + else printf(">IP is continued.\r\n"); + #endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + default : + break; + } + + return ret; +} + +void DHCP_stop(void) +{ + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; +} + +uint8_t check_DHCP_timeout(void) +{ + uint8_t ret = DHCP_RUNNING; + + if (dhcp_retry_count < MAX_DHCP_RETRY) { + if (dhcp_tick_next < dhcp_tick_1s) { + + switch ( dhcp_state ) { + case STATE_DHCP_DISCOVER : +// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n"); + send_DHCP_DISCOVER(); + break; + + case STATE_DHCP_REQUEST : +// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + case STATE_DHCP_REREQUEST : +// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + default : + break; + } + + dhcp_tick_1s = 0; + dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; + dhcp_retry_count++; + } + } else { // timeout occurred + + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default : + break; + } + reset_DHCP_timeout(); + } + return ret; +} + +int8_t check_DHCP_leasedIP(void) +{ + uint8_t tmp; + int32_t ret; + + //WIZchip RCR value changed for ARP Timeout count control + tmp = getRCR(); + setRCR(0x03); + + // IP conflict detection : ARP request - ARP reply + // Broadcasting ARP Request for check the IP conflict using UDP sendto() function + ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + + // RCR value restore + setRCR(tmp); + + if(ret == SOCKERR_TIMEOUT) { + // UDP send Timeout occurred : allocated IP address is unique, DHCP Success + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Check leased IP - OK\r\n"); +#endif + + return 1; + } else { + // Received ARP reply or etc : IP address conflict occur, DHCP Failed + send_DHCP_DECLINE(); + + ret = dhcp_tick_1s; + while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; + + return 0; + } +} + +void DHCP_init(uint8_t s, uint8_t * buf) +{ + uint8_t zeroip[4] = {0,0,0,0}; + getSHAR(DHCP_CHADDR); + if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) + { + // assing temporary mac address, you should be set SHAR before call this function. + DHCP_CHADDR[0] = 0x00; + DHCP_CHADDR[1] = 0x08; + DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[3] = 0x00; + DHCP_CHADDR[4] = 0x00; + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); + } + + DHCP_SOCKET = s; // SOCK_DHCP + pDHCPMSG = (RIP_MSG*)buf; + DHCP_XID = 0x12345678; + + // WIZchip Netinfo Clear + setSIPR(zeroip); + setSIPR(zeroip); + setGAR(zeroip); + + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_INIT; +} + + +/* Rset the DHCP timeout count and retry count. */ +void reset_DHCP_timeout(void) +{ + dhcp_tick_1s = 0; + dhcp_tick_next = DHCP_WAIT_TIME; + dhcp_retry_count = 0; +} + +void DHCP_time_handler(void) +{ + dhcp_tick_1s++; +} + +void getIPfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_ip[0]; + ip[1] = DHCP_allocated_ip[1]; + ip[2] = DHCP_allocated_ip[2]; + ip[3] = DHCP_allocated_ip[3]; +} + +void getGWfromDHCP(uint8_t* ip) +{ + ip[0] =DHCP_allocated_gw[0]; + ip[1] =DHCP_allocated_gw[1]; + ip[2] =DHCP_allocated_gw[2]; + ip[3] =DHCP_allocated_gw[3]; +} + +void getSNfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_sn[0]; + ip[1] = DHCP_allocated_sn[1]; + ip[2] = DHCP_allocated_sn[2]; + ip[3] = DHCP_allocated_sn[3]; +} + +void getDNSfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_dns[0]; + ip[1] = DHCP_allocated_dns[1]; + ip[2] = DHCP_allocated_dns[2]; + ip[3] = DHCP_allocated_dns[3]; +} + +uint32_t getDHCPLeasetime(void) +{ + return dhcp_lease_time; +} + + + + diff --git a/C8T6_TestApp2/Internet/DHCP/dhcp.h b/C8T6_TestApp2/Internet/DHCP/dhcp.h new file mode 100644 index 0000000..4f2c688 --- /dev/null +++ b/C8T6_TestApp2/Internet/DHCP/dhcp.h @@ -0,0 +1,152 @@ +//***************************************************************************** +// +//! \file dhcp.h +//! \brief DHCP APIs Header file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Move unreferenced DEFINE to dhcp.c +//! <2012/12/26> V1.1.1 +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#ifndef _DHCP_H_ +#define _DHCP_H_ + +/* + * @brief + * @details If you want to display debug & procssing message, Define _DHCP_DEBUG_ + * @note If defined, it dependens on <stdio.h> + */ +//#define _DHCP_DEBUG_ + + +/* Retry to processing DHCP */ +#define MAX_DHCP_RETRY 2 ///< Maxium retry count +#define DHCP_WAIT_TIME 10 ///< Wait Time 10s + + +/* UDP port numbers for DHCP */ +#define DHCP_SERVER_PORT 67 ///< DHCP server port number +#define DHCP_CLIENT_PORT 68 ///< DHCP client port number + + +#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modifyed it any number + +#define DCHP_HOST_NAME "WIZnet\0" + +/* + * @brief return value of @ref DHCP_run() + */ +enum +{ + DHCP_FAILED = 0, ///< Procssing Fail + DHCP_RUNNING, ///< Procssing DHCP proctocol + DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) + DHCP_IP_CHANGED, ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update) + DHCP_IP_LEASED, ///< Stand by + DHCP_STOPPED ///< Stop procssing DHCP protocol +}; + +/* + * @brief DHCP client initialization (outside of the main loop) + * @param s - socket number + * @param buf - buffer for procssing DHCP message + */ +void DHCP_init(uint8_t s, uint8_t * buf); + +/* + * @brief DHCP 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DHCP_time_handler(void); + +/* + * @brief Register call back function + * @param ip_assign - callback func when IP is assigned from DHCP server first + * @param ip_update - callback func when IP is changed + * @prarm ip_conflict - callback func when the assigned IP is conflict with others. + */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + +/* + * @brief DHCP client in the main loop + * @return The value is as the follow \n + * @ref DHCP_FAILED \n + * @ref DHCP_RUNNING \n + * @ref DHCP_IP_ASSIGN \n + * @ref DHCP_IP_CHANGED \n + * @ref DHCP_IP_LEASED \n + * @ref DHCP_STOPPED \n + * + * @note This function is always called by you main task. + */ +uint8_t DHCP_run(void); + +/* + * @brief Stop DHCP procssing + * @note If you want to restart. call DHCP_init() and DHCP_run() + */ +void DHCP_stop(void); + +/* Get Network information assigned from DHCP server */ +/* + * @brief Get IP address + * @param ip - IP address to be returned + */ +void getIPfromDHCP(uint8_t* ip); +/* + * @brief Get Gateway address + * @param ip - Gateway address to be returned + */ +void getGWfromDHCP(uint8_t* ip); +/* + * @brief Get Subnet mask value + * @param ip - Subnet mask to be returned + */ +void getSNfromDHCP(uint8_t* ip); +/* + * @brief Get DNS address + * @param ip - DNS address to be returned + */ +void getDNSfromDHCP(uint8_t* ip); + +/* + * @brief Get the leased time by DHCP sever + * @retrun unit 1s + */ +uint32_t getDHCPLeasetime(void); + +#endif /* _DHCP_H_ */ diff --git a/C8T6_TestApp2/Internet/DNS/dns.c b/C8T6_TestApp2/Internet/DNS/dns.c new file mode 100644 index 0000000..a88f369 --- /dev/null +++ b/C8T6_TestApp2/Internet/DNS/dns.c @@ -0,0 +1,563 @@ +//***************************************************************************** +// +//! \file dns.c +//! \brief DNS APIs Implement file. +//! \details Send DNS query & Receive DNS reponse. \n +//! It depends on stdlib.h & string.h in ansi-c library +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Remove the unused define +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include <string.h> +#include <stdlib.h> + +#include "Ethernet/socket.h" +#include "Internet/DNS/dns.h" + +#ifdef _DNS_DEBUG_ + #include <stdio.h> +#endif + +#define INITRTT 2000L /* Initial smoothed response time */ +#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */ + +#define TYPE_A 1 /* Host address */ +#define TYPE_NS 2 /* Name server */ +#define TYPE_MD 3 /* Mail destination (obsolete) */ +#define TYPE_MF 4 /* Mail forwarder (obsolete) */ +#define TYPE_CNAME 5 /* Canonical name */ +#define TYPE_SOA 6 /* Start of Authority */ +#define TYPE_MB 7 /* Mailbox name (experimental) */ +#define TYPE_MG 8 /* Mail group member (experimental) */ +#define TYPE_MR 9 /* Mail rename name (experimental) */ +#define TYPE_NULL 10 /* Null (experimental) */ +#define TYPE_WKS 11 /* Well-known sockets */ +#define TYPE_PTR 12 /* Pointer record */ +#define TYPE_HINFO 13 /* Host information */ +#define TYPE_MINFO 14 /* Mailbox information (experimental)*/ +#define TYPE_MX 15 /* Mail exchanger */ +#define TYPE_TXT 16 /* Text strings */ +#define TYPE_ANY 255 /* Matches any type */ + +#define CLASS_IN 1 /* The ARPA Internet */ + +/* Round trip timing parameters */ +#define AGAIN 8 /* Average RTT gain = 1/8 */ +#define LAGAIN 3 /* Log2(AGAIN) */ +#define DGAIN 4 /* Mean deviation gain = 1/4 */ +#define LDGAIN 2 /* log2(DGAIN) */ + +/* Header for all domain messages */ +struct dhdr +{ + uint16_t id; /* Identification */ + uint8_t qr; /* Query/Response */ +#define QUERY 0 +#define RESPONSE 1 + uint8_t opcode; +#define IQUERY 1 + uint8_t aa; /* Authoratative answer */ + uint8_t tc; /* Truncation */ + uint8_t rd; /* Recursion desired */ + uint8_t ra; /* Recursion available */ + uint8_t rcode; /* Response code */ +#define NO_ERROR 0 +#define FORMAT_ERROR 1 +#define SERVER_FAIL 2 +#define NAME_ERROR 3 +#define NOT_IMPL 4 +#define REFUSED 5 + uint16_t qdcount; /* Question count */ + uint16_t ancount; /* Answer count */ + uint16_t nscount; /* Authority (name server) count */ + uint16_t arcount; /* Additional record count */ +}; + + +uint8_t* pDNSMSG; // DNS message buffer +uint8_t DNS_SOCKET; // SOCKET number for DNS +uint16_t DNS_MSGID; // DNS message ID + +uint32_t dns_1s_tick; // for timout of DNS processing + +/* converts uint16_t from network buffer to a host byte order integer. */ +uint16_t get16(uint8_t * s) +{ + uint16_t i; + i = *s++ << 8; + i = i + *s; + return i; +} + +/* copies uint16_t to the network buffer with network byte order. */ +uint8_t * put16(uint8_t * s, uint16_t i) +{ + *s++ = i >> 8; + *s++ = i; + return s; +} + + +/* + * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM + * + * Description : This function converts a compressed domain name to the human-readable form + * Arguments : msg - is a pointer to the reply message + * compressed - is a pointer to the domain name in reply message. + * buf - is a pointer to the buffer for the human-readable form name. + * len - is the MAX. size of buffer. + * Returns : the length of compressed message + */ +int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len) +{ + uint16_t slen; /* Length of current segment */ + uint8_t * cp; + int clen = 0; /* Total length of compressed name */ + int indirect = 0; /* Set if indirection encountered */ + int nseg = 0; /* Total number of segments in name */ + + cp = compressed; + + for (;;) + { + slen = *cp++; /* Length of this segment */ + + if (!indirect) clen++; + + if ((slen & 0xc0) == 0xc0) + { + if (!indirect) + clen++; + indirect = 1; + /* Follow indirection */ + cp = &msg[((slen & 0x3f)<<8) + *cp]; + slen = *cp++; + } + + if (slen == 0) /* zero length == all done */ + break; + + len -= slen + 1; + + if (len < 0) return -1; + + if (!indirect) clen += slen; + + while (slen-- != 0) *buf++ = (char)*cp++; + *buf++ = '.'; + nseg++; + } + + if (nseg == 0) + { + /* Root name; represent as single dot */ + *buf++ = '.'; + len--; + } + + *buf++ = '\0'; + len--; + + return clen; /* Length of compressed message */ +} + +/* + * PARSE QUESTION SECTION + * + * Description : This function parses the qeustion record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the qeustion record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_question(uint8_t * msg, uint8_t * cp) +{ + int len; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + + if (len == -1) return 0; + + cp += len; + cp += 2; /* type */ + cp += 2; /* class */ + + return cp; +} + + +/* + * PARSE ANSER SECTION + * + * Description : This function parses the answer record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the answer record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns) +{ + int len, type; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + if (len == -1) return 0; + + cp += len; + type = get16(cp); + cp += 2; /* type */ + cp += 2; /* class */ + cp += 4; /* ttl */ + cp += 2; /* len */ + + + switch (type) + { + case TYPE_A: + /* Just read the address directly into the structure */ + ip_from_dns[0] = *cp++; + ip_from_dns[1] = *cp++; + ip_from_dns[2] = *cp++; + ip_from_dns[3] = *cp++; + break; + case TYPE_CNAME: + case TYPE_MB: + case TYPE_MG: + case TYPE_MR: + case TYPE_NS: + case TYPE_PTR: + /* These types all consist of a single domain name */ + /* convert it to ascii format */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_HINFO: + len = *cp++; + cp += len; + + len = *cp++; + cp += len; + break; + case TYPE_MX: + cp += 2; + /* Get domain name of exchanger */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_SOA: + /* Get domain name of name server */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + /* Get domain name of responsible person */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + cp += 4; + cp += 4; + cp += 4; + cp += 4; + cp += 4; + break; + case TYPE_TXT: + /* Just stash */ + break; + default: + /* Ignore */ + break; + } + + return cp; +} + +/* + * PARSE THE DNS REPLY + * + * Description : This function parses the reply message from DNS server. + * Arguments : dhdr - is a pointer to the header for DNS message + * buf - is a pointer to the reply message. + * len - is the size of reply message. + * Returns : -1 - Domain name lenght is too big + * 0 - Fail (Timout or parse error) + * 1 - Success, + */ +int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns) +{ + uint16_t tmp; + uint16_t i; + uint8_t * msg; + uint8_t * cp; + + msg = pbuf; + memset(pdhdr, 0, sizeof(pdhdr)); + + pdhdr->id = get16(&msg[0]); + tmp = get16(&msg[2]); + if (tmp & 0x8000) pdhdr->qr = 1; + + pdhdr->opcode = (tmp >> 11) & 0xf; + + if (tmp & 0x0400) pdhdr->aa = 1; + if (tmp & 0x0200) pdhdr->tc = 1; + if (tmp & 0x0100) pdhdr->rd = 1; + if (tmp & 0x0080) pdhdr->ra = 1; + + pdhdr->rcode = tmp & 0xf; + pdhdr->qdcount = get16(&msg[4]); + pdhdr->ancount = get16(&msg[6]); + pdhdr->nscount = get16(&msg[8]); + pdhdr->arcount = get16(&msg[10]); + + + /* Now parse the variable length sections */ + cp = &msg[12]; + + /* Question section */ + for (i = 0; i < pdhdr->qdcount; i++) + { + cp = dns_question(msg, cp); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h" + #endif + if(!cp) return -1; + } + + /* Answer section */ + for (i = 0; i < pdhdr->ancount; i++) + { + cp = dns_answer(msg, cp, ip_from_dns); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h" + #endif + if(!cp) return -1; + } + + /* Name server (authority) section */ + for (i = 0; i < pdhdr->nscount; i++) + { + ; + } + + /* Additional section */ + for (i = 0; i < pdhdr->arcount; i++) + { + ; + } + + if(pdhdr->rcode == 0) return 1; // No error + else return 0; +} + + +/* + * MAKE DNS QUERY MESSAGE + * + * Description : This function makes DNS query message. + * Arguments : op - Recursion desired + * name - is a pointer to the domain name. + * buf - is a pointer to the buffer for DNS message. + * len - is the MAX. size of buffer. + * Returns : the pointer to the DNS message. + */ +int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len) +{ + uint8_t *cp; + char *cp1; + char sname[MAXCNAME]; + char *dname; + uint16_t p; + uint16_t dlen; + + cp = buf; + + DNS_MSGID++; + cp = put16(cp, DNS_MSGID); + p = (op << 11) | 0x0100; /* Recursion desired */ + cp = put16(cp, p); + cp = put16(cp, 1); + cp = put16(cp, 0); + cp = put16(cp, 0); + cp = put16(cp, 0); + + strcpy(sname, name); + dname = sname; + dlen = strlen(dname); + for (;;) + { + /* Look for next dot */ + cp1 = strchr(dname, '.'); + + if (cp1 != NULL) len = cp1 - dname; /* More to come */ + else len = dlen; /* Last component */ + + *cp++ = len; /* Write length of component */ + if (len == 0) break; + + /* Copy component up to (but not including) dot */ + strncpy((char *)cp, dname, len); + cp += len; + if (cp1 == NULL) + { + *cp++ = 0; /* Last one; write null and finish */ + break; + } + dname += len+1; + dlen -= len+1; + } + + cp = put16(cp, 0x0001); /* type */ + cp = put16(cp, 0x0001); /* class */ + + return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf))); +} + +/* + * CHECK DNS TIMEOUT + * + * Description : This function check the DNS timeout + * Arguments : None. + * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur + * Note : timeout : retry count and timer both over. + */ + +int8_t check_DNS_timeout(void) +{ + static uint8_t retry_count; + + if(dns_1s_tick >= DNS_WAIT_TIME) + { + dns_1s_tick = 0; + if(retry_count >= MAX_DNS_RETRY) { + retry_count = 0; + return -1; // timeout occurred + } + retry_count++; + return 0; // timer over, but no timeout + } + + return 1; // no timer over, no timeout occur +} + + + +/* DNS CLIENT INIT */ +void DNS_init(uint8_t s, uint8_t * buf) +{ + DNS_SOCKET = s; // SOCK_DNS + pDNSMSG = buf; // User's shared buffer + DNS_MSGID = DNS_MSG_ID; +} + +/* DNS CLIENT RUN */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns) +{ + int8_t ret; + struct dhdr dhp; + uint8_t ip[4]; + uint16_t len, port; + int8_t ret_check_timeout; + + // Socket open + socket(DNS_SOCKET, Sn_MR_UDP, 0, 0); + +#ifdef _DNS_DEBUG_ + printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + + len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE); + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + + while (1) + { + if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0) + { + if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE; + len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port); + #ifdef _DNS_DEBUG_ + printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len); + #endif + ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns); + break; + } + // Check Timeout + ret_check_timeout = check_DNS_timeout(); + if (ret_check_timeout < 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + return 0; // timeout occurred + } + else if (ret_check_timeout == 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Timeout\r\n"); +#endif + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + } + } + close(DNS_SOCKET); + // Return value + // 0 > : failed / 1 - success + return ret; +} + + +/* DNS TIMER HANDLER */ +void DNS_time_handler(void) +{ + dns_1s_tick++; +} + + + diff --git a/C8T6_TestApp2/Internet/DNS/dns.h b/C8T6_TestApp2/Internet/DNS/dns.h new file mode 100644 index 0000000..023e37d --- /dev/null +++ b/C8T6_TestApp2/Internet/DNS/dns.h @@ -0,0 +1,101 @@ +//***************************************************************************** +// +//! \file dns.h +//! \brief DNS APIs Header file. +//! \details Send DNS query & Receive DNS reponse. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Move the no reference define to dns.c +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _DNS_H_ +#define _DNS_H_ + +#include <stdint.h> +/* + * @brief Define it for Debug & Monitor DNS processing. + * @note If defined, it dependens on <stdio.h> + */ +//#define _DNS_DEBUG_ + +#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */ +/* + * @brief Maxium length of your queried Domain name + * @todo SHOULD BE defined it equal as or greater than your Domain name lenght + null character(1) + * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack. + */ +#define MAX_DOMAIN_NAME 16 // for example "www.google.com" + +#define MAX_DNS_RETRY 2 ///< Requery Count +#define DNS_WAIT_TIME 3 ///< Wait response time. unit 1s. + +#define IPPORT_DOMAIN 53 ///< DNS server port number + +#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modifyed it any number +/* + * @brief DNS process initialize + * @param s : Socket number for DNS + * @param buf : Buffer for DNS message + */ +void DNS_init(uint8_t s, uint8_t * buf); + +/* + * @brief DNS process + * @details Send DNS query and receive DNS response + * @param dns_ip : DNS server ip + * @param name : Domain name to be queryed + * @param ip_from_dns : IP address from DNS server + * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n + * 0 : failed (Timeout or Parse error)\n + * 1 : success + * @note This funtion blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME + */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns); + +/* + * @brief DNS 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DNS_time_handler(void); + +#endif /* _DNS_H_ */ diff --git a/C8T6_TestApp2/RTE/_C8T6_TestApp2/RTE_Components.h b/C8T6_TestApp2/RTE/_C8T6_TestApp2/RTE_Components.h new file mode 100644 index 0000000..4edf18b --- /dev/null +++ b/C8T6_TestApp2/RTE/_C8T6_TestApp2/RTE_Components.h @@ -0,0 +1,20 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'C8T6_UltroSonic' + * Target: 'C8T6_TestApp2' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "stm32f0xx.h" + + +#endif /* RTE_COMPONENTS_H */ diff --git a/C8T6_TestApp2/Radio/inc/crc.h b/C8T6_TestApp2/Radio/inc/crc.h new file mode 100644 index 0000000..49136fe --- /dev/null +++ b/C8T6_TestApp2/Radio/inc/crc.h @@ -0,0 +1,24 @@ +#ifndef _CRC_H_ +#define _CRC_H_ + +#include <stdint.h> + +// CRC types +#define CRC_TYPE_CCITT 0 +#define CRC_TYPE_IBM 1 +// Polynomial = X^16 + X^12 + X^5 + 1 +#define POLYNOMIAL_CCITT 0x1021 +// Polynomial = X^16 + X^15 + X^2 + 1 +#define POLYNOMIAL_IBM 0x8005 +// Seeds +#define CRC_IBM_SEED 0xFFFF +#define CRC_CCITT_SEED 0x1D0F + + +uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ); +uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ); + + + +#endif + diff --git a/C8T6_TestApp2/Radio/inc/radio.h b/C8T6_TestApp2/Radio/inc/radio.h new file mode 100644 index 0000000..eb61f7a --- /dev/null +++ b/C8T6_TestApp2/Radio/inc/radio.h @@ -0,0 +1,379 @@ +/*! + * \file radio.h + * + * \brief Radio driver API definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#ifndef __RADIO_H__ +#define __RADIO_H__ + +#include<stdint.h> +#include<stdbool.h> + +//#define USE_MODEM_LORA + +/*! + * Radio driver supported modems + */ +typedef enum +{ + MODEM_FSK = 0, + MODEM_LORA, +}RadioModems_t; + +/*! + * Radio driver internal state machine states definition + */ +typedef enum +{ + RF_IDLE = 0, //!< The radio is idle + RF_RX_RUNNING, //!< The radio is in reception state + RF_TX_RUNNING, //!< The radio is in transmission state + RF_CAD, //!< The radio is doing channel activity detection +}RadioState_t; + +/*! + * \brief Radio driver callback functions + */ +typedef struct +{ + /*! + * \brief Tx Done callback prototype. + */ + void ( *TxDone )( void ); + /*! + * \brief Tx Timeout callback prototype. + */ + void ( *TxTimeout )( void ); + /*! + * \brief Rx Done callback prototype. + * + * \param [IN] payload Received buffer pointer + * \param [IN] size Received buffer size + * \param [IN] rssi RSSI value computed while receiving the frame [dBm] + * \param [IN] snr Raw SNR value given by the radio hardware + * FSK : N/A ( set to 0 ) + * LoRa: SNR value in dB + */ + void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); + /*! + * \brief Rx Timeout callback prototype. + */ + void ( *RxTimeout )( void ); + /*! + * \brief Rx Error callback prototype. + */ + void ( *RxError )( void ); + /*! + * \brief FHSS Change Channel callback prototype. + * + * \param [IN] currentChannel Index number of the current channel + */ + void ( *FhssChangeChannel )( uint8_t currentChannel ); + + /*! + * \brief CAD Done callback prototype. + * + * \param [IN] channelDetected Channel Activity detected during the CAD + */ + void ( *CadDone ) ( bool channelActivityDetected ); +}RadioEvents_t; + +/*! + * \brief Radio driver definition + */ +struct Radio_s +{ + /*! + * \brief Initializes the radio + * + * \param [IN] events Structure containing the driver callback functions + */ + void ( *Init )( RadioEvents_t *events ); + /*! + * Return current radio status + * + * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + */ + RadioState_t ( *GetStatus )( void ); + /*! + * \brief Configures the radio with the given modem + * + * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] + */ + void ( *SetModem )( RadioModems_t modem ); + /*! + * \brief Sets the channel frequency + * + * \param [IN] freq Channel RF frequency + */ + void ( *SetChannel )( uint32_t freq ); + /*! + * \brief Checks if the channel is free for the given time + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] freq Channel RF frequency + * \param [IN] rssiThresh RSSI threshold + * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured + * + * \retval isFree [true: Channel is free, false: Channel is not free] + */ + bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); + /*! + * \brief Generates a 32 bits random value based on the RSSI readings + * + * \remark This function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * \retval randomValue 32 bits random value + */ + uint32_t ( *Random )( void ); + /*! + * \brief Sets the reception parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] symbTimeout Sets the RxSingle timeout value + * FSK : timeout in number of bytes + * LoRa: timeout in symbols + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] hopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] rxContinuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ + void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool freqHopOn, uint8_t hopPeriod, + bool iqInverted, bool rxContinuous ); + /*! + * \brief Sets the transmission parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] power Sets the output power [dBm] + * \param [IN] fdev Sets the frequency deviation (FSK only) + * FSK : [Hz] + * LoRa: 0 + * \param [IN] bandwidth Sets the bandwidth (LoRa only) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] + * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] hopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] timeout Transmission timeout [ms] + */ + void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool freqHopOn, + uint8_t hopPeriod, bool iqInverted, uint32_t timeout ); + /*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ + bool ( *CheckRfFrequency )( uint32_t frequency ); + /*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (ms) for the given packet payload length + */ + uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen ); + /*! + * \brief Sends the buffer of size. Prepares the packet to be sent and sets + * the radio in transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ + void ( *Send )( uint8_t *buffer, uint8_t size ); + /*! + * \brief Sets the radio in sleep mode + */ + void ( *Sleep )( void ); + /*! + * \brief Sets the radio in standby mode + */ + void ( *Standby )( void ); + /*! + * \brief Sets the radio in reception mode for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ + void ( *Rx )( uint32_t timeout ); + /*! + * \brief Start a Channel Activity Detection + */ + void ( *StartCad )( void ); + /*! + * \brief Sets the radio in continuous wave transmission mode + * + * \param [IN]: freq Channel RF frequency + * \param [IN]: power Sets the output power [dBm] + * \param [IN]: time Transmission mode timeout [s] + */ + void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time ); + /*! + * \brief Reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ + int16_t ( *Rssi )( RadioModems_t modem ); + /*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ + void ( *Write )( uint16_t addr, uint8_t data ); + /*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \retval data Register value + */ + uint8_t ( *Read )( uint16_t addr ); + /*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ + void ( *WriteBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); + /*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ + void ( *ReadBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); + /*! + * \brief Sets the maximum payload length. + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] max Maximum payload length in bytes + */ + void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max ); + /*! + * \brief Sets the network to public or private. Updates the sync byte. + * + * \remark Applies to LoRa modem only + * + * \param [IN] enable if true, it enables a public network + */ + void ( *SetPublicNetwork )( bool enable ); + /*! + * \brief Gets the time required for the board plus radio to get out of sleep.[ms] + * + * \retval time Radio plus board wakeup time in ms. + */ + uint32_t ( *GetWakeupTime )( void ); + /*! + * \brief Process radio irq + */ + void ( *IrqProcess )( void ); + /* + * The next functions are available only on SX126x radios. + */ + /*! + * \brief Sets the radio in reception mode with Max LNA gain for the given time + * + * \remark Available on SX126x radios only. + * + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ + void ( *RxBoosted )( uint32_t timeout ); + /*! + * \brief Sets the Rx duty cycle management parameters + * + * \remark Available on SX126x radios only. + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ + void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime ); +}; + +/*! + * \brief Radio driver + * + * \remark This variable is defined and initialized in the specific radio + * board implementation + */ +extern const struct Radio_s Radio; + +#endif // __RADIO_H__ diff --git a/C8T6_TestApp2/Radio/inc/sx126x-board.h b/C8T6_TestApp2/Radio/inc/sx126x-board.h new file mode 100644 index 0000000..0dbecf1 --- /dev/null +++ b/C8T6_TestApp2/Radio/inc/sx126x-board.h @@ -0,0 +1,129 @@ +/* + ______ _ + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + +Description: SX126x driver specific target board functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#ifndef __SX126x_ARCH_H__ +#define __SX126x_ARCH_H__ + +#include "sx126x.h" +/*! + * \brief Initializes the radio I/Os pins interface + */ +//void SX126xIoInit( void ); + +/*! + * \brief Initializes DIO IRQ handlers + * + * \param [IN] irqHandlers Array containing the IRQ callback functions + */ +//void SX126xIoIrqInit( DioIrqHandler dioIrq ); + +/*! + * \brief De-initializes the radio I/Os pins interface. + * + * \remark Useful when going in MCU low power modes + */ +//void SX126xIoDeInit( void ); + +/*! + * \brief HW Reset of the radio + */ +void SX126xReset( void ); + +/*! + * \brief Blocking loop to wait while the Busy pin in high + */ +void SX126xWaitOnBusy( void ); + +/*! + * \brief Wakes up the radio + */ +void SX126xWakeup( void ); + +/*! + * \brief Send a command that write data to the radio + * + * \param [in] opcode Opcode of the command + * \param [in] buffer Buffer to be send to the radio + * \param [in] size Size of the buffer to send + */ +void SX126xWriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Send a command that read data from the radio + * + * \param [in] opcode Opcode of the command + * \param [out] buffer Buffer holding data from the radio + * \param [in] size Size of the buffer + */ +void SX126xReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Write a single byte of data to the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * \param [in] value The data to be written in radio's memory + */ +void SX126xWriteRegister( uint16_t address, uint8_t value ); + +/*! + * \brief Read a single byte of data from the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * + * \retval value The value of the byte at the given address in radio's memory + */ +uint8_t SX126xReadRegister( uint16_t address ); + +/*! + * \brief Sets the radio output power. + * + * \param [IN] power Sets the RF output power + */ +void SX126xSetRfTxPower( int8_t power ); + +/*! + * \brief Gets the board PA selection configuration + * + * \param [IN] channel Channel frequency in Hz + * \retval PaSelect RegPaConfig PaSelect value + */ +uint8_t SX126xGetPaSelect( uint32_t channel ); + +/*! + * \brief Initializes the RF Switch I/Os pins interface + */ +void SX126xAntSwOn( void ); + +/*! + * \brief De-initializes the RF Switch I/Os pins interface + * + * \remark Needed to decrease the power consumption in MCU low power modes + */ +void SX126xAntSwOff( void ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool SX126xCheckRfFrequency( uint32_t frequency ); + +/*! + * Radio hardware and global parameters + */ +extern SX126x_t SX126x; + +#endif // __SX126x_ARCH_H__ diff --git a/C8T6_TestApp2/Radio/inc/sx126x.h b/C8T6_TestApp2/Radio/inc/sx126x.h new file mode 100644 index 0000000..6defe61 --- /dev/null +++ b/C8T6_TestApp2/Radio/inc/sx126x.h @@ -0,0 +1,1115 @@ +/*! + * \file sx126x.h + * + * \brief SX126x driver implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#ifndef __SX126x_H__ +#define __SX126x_H__ + +#include <stdint.h> +#include <stdbool.h> + + +#define SX1261 1 +#define SX1262 2 + +#ifdef USE_TCXO + /*! + * Radio complete Wake-up Time with TCXO stabilisation time + */ + #define RADIO_TCXO_SETUP_TIME 5 // [ms] +#else + /*! + * Radio complete Wake-up Time with TCXO stabilisation time + */ + #define RADIO_TCXO_SETUP_TIME 0 // No Used +#endif + +/*! + * Radio complete Wake-up Time with margin for temperature compensation + */ +#define RADIO_WAKEUP_TIME 3 // [ms] + +/*! + * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds + */ +#define AUTO_RX_TX_OFFSET 2 + +/*! + * \brief LFSR initial value to compute IBM type CRC + */ +#define CRC_IBM_SEED 0xFFFF + +/*! + * \brief LFSR initial value to compute CCIT type CRC + */ +#define CRC_CCITT_SEED 0x1D0F + +/*! + * \brief Polynomial used to compute IBM CRC + */ +#define CRC_POLYNOMIAL_IBM 0x8005 + +/*! + * \brief Polynomial used to compute CCIT CRC + */ +#define CRC_POLYNOMIAL_CCITT 0x1021 + +/*! + * \brief The address of the register holding the first byte defining the CRC seed + * + */ +#define REG_LR_CRCSEEDBASEADDR 0x06BC + +/*! + * \brief The address of the register holding the first byte defining the CRC polynomial + */ +#define REG_LR_CRCPOLYBASEADDR 0x06BE + +/*! + * \brief The address of the register holding the first byte defining the whitening seed + */ +#define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8 +#define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9 + +/*! + * \brief The address of the register holding the packet configuration + */ +#define REG_LR_PACKETPARAMS 0x0704 + +/*! + * \brief The address of the register holding the payload size + */ +#define REG_LR_PAYLOADLENGTH 0x0702 + +/*! + * \brief The addresses of the registers holding SyncWords values + */ +#define REG_LR_SYNCWORDBASEADDRESS 0x06C0 + +/*! + * \brief The addresses of the register holding LoRa Modem SyncWord value + */ +#define REG_LR_SYNCWORD 0x0740 + +/*! + * Syncword for Private LoRa networks + */ +#define LORA_MAC_PRIVATE_SYNCWORD 0x1424 + +/*! + * Syncword for Public LoRa networks + */ +#define LORA_MAC_PUBLIC_SYNCWORD 0x3444 + +/*! + * The address of the register giving a 4 bytes random number + */ +#define RANDOM_NUMBER_GENERATORBASEADDR 0x0819 + +/*! + * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted) + */ +#define REG_RX_GAIN 0x08AC + +/*! + * Change the value on the device internal trimming capacitor + */ +#define REG_XTA_TRIM 0x0911 + +/*! + * Set the current max value in the over current protection + */ +#define REG_OCP 0x08E7 + +/*! + * \brief Structure describing the radio status + */ +typedef union RadioStatus_u +{ + uint8_t Value; + struct + { //bit order is lsb -> msb + uint8_t Reserved : 1; //!< Reserved + uint8_t CmdStatus : 3; //!< Command status + uint8_t ChipMode : 3; //!< Chip mode + uint8_t CpuBusy : 1; //!< Flag for CPU radio busy + }Fields; +}RadioStatus_t; + +/*! + * \brief Structure describing the error codes for callback functions + */ +typedef enum +{ + IRQ_HEADER_ERROR_CODE = 0x01, + IRQ_SYNCWORD_ERROR_CODE = 0x02, + IRQ_CRC_ERROR_CODE = 0x04, +}IrqErrorCode_t; + +enum IrqPblSyncHeaderCode_t +{ + IRQ_PBL_DETECT_CODE = 0x01, + IRQ_SYNCWORD_VALID_CODE = 0x02, + IRQ_HEADER_VALID_CODE = 0x04, +}; + +/*! + * \brief Represents the operating mode the radio is actually running + */ +typedef enum +{ + MODE_SLEEP = 0x00, //! The radio is in sleep mode + MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator + MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator + MODE_FS, //! The radio is in frequency synthesis mode + MODE_TX, //! The radio is in transmit mode + MODE_RX, //! The radio is in receive mode + MODE_RX_DC, //! The radio is in receive duty cycle mode + MODE_CAD //! The radio is in channel activity detection mode +}RadioOperatingModes_t; + +/*! + * \brief Declares the oscillator in use while in standby mode + * + * Using the STDBY_RC standby mode allow to reduce the energy consumption + * STDBY_XOSC should be used for time critical applications + */ +typedef enum +{ + STDBY_RC = 0x00, + STDBY_XOSC = 0x01, +}RadioStandbyModes_t; + +/*! + * \brief Declares the power regulation used to power the device + * + * This command allows the user to specify if DC-DC or LDO is used for power regulation. + * Using only LDO implies that the Rx or Tx current is doubled + */ +typedef enum +{ + USE_LDO = 0x00, // default + USE_DCDC = 0x01, +}RadioRegulatorMode_t; + +/*! + * \brief Represents the possible packet type (i.e. modem) used + */ +typedef enum +{ + PACKET_TYPE_GFSK = 0x00, + PACKET_TYPE_LORA = 0x01, + PACKET_TYPE_NONE = 0x0F, +}RadioPacketTypes_t; + +/*! + * \brief Represents the ramping time for power amplifier + */ +typedef enum +{ + RADIO_RAMP_10_US = 0x00, + RADIO_RAMP_20_US = 0x01, + RADIO_RAMP_40_US = 0x02, + RADIO_RAMP_80_US = 0x03, + RADIO_RAMP_200_US = 0x04, + RADIO_RAMP_800_US = 0x05, + RADIO_RAMP_1700_US = 0x06, + RADIO_RAMP_3400_US = 0x07, +}RadioRampTimes_t; + +/*! + * \brief Represents the number of symbols to be used for channel activity detection operation + */ +typedef enum +{ + LORA_CAD_01_SYMBOL = 0x00, + LORA_CAD_02_SYMBOL = 0x01, + LORA_CAD_04_SYMBOL = 0x02, + LORA_CAD_08_SYMBOL = 0x03, + LORA_CAD_16_SYMBOL = 0x04, +}RadioLoRaCadSymbols_t; + +/*! + * \brief Represents the Channel Activity Detection actions after the CAD operation is finished + */ +typedef enum +{ + LORA_CAD_ONLY = 0x00, + LORA_CAD_RX = 0x01, + LORA_CAD_LBT = 0x10, +}RadioCadExitModes_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum +{ + MOD_SHAPING_OFF = 0x00, + MOD_SHAPING_G_BT_03 = 0x08, + MOD_SHAPING_G_BT_05 = 0x09, + MOD_SHAPING_G_BT_07 = 0x0A, + MOD_SHAPING_G_BT_1 = 0x0B, +}RadioModShapings_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum +{ + RX_BW_4800 = 0x1F, + RX_BW_5800 = 0x17, + RX_BW_7300 = 0x0F, + RX_BW_9700 = 0x1E, + RX_BW_11700 = 0x16, + RX_BW_14600 = 0x0E, + RX_BW_19500 = 0x1D, + RX_BW_23400 = 0x15, + RX_BW_29300 = 0x0D, + RX_BW_39000 = 0x1C, + RX_BW_46900 = 0x14, + RX_BW_58600 = 0x0C, + RX_BW_78200 = 0x1B, + RX_BW_93800 = 0x13, + RX_BW_117300 = 0x0B, + RX_BW_156200 = 0x1A, + RX_BW_187200 = 0x12, + RX_BW_234300 = 0x0A, + RX_BW_312000 = 0x19, + RX_BW_373600 = 0x11, + RX_BW_467000 = 0x09, +}RadioRxBandwidth_t; + +/*! + * \brief Represents the possible spreading factor values in LoRa packet types + */ +typedef enum +{ + LORA_SF5 = 0x05, + LORA_SF6 = 0x06, + LORA_SF7 = 0x07, + LORA_SF8 = 0x08, + LORA_SF9 = 0x09, + LORA_SF10 = 0x0A, + LORA_SF11 = 0x0B, + LORA_SF12 = 0x0C, +}RadioLoRaSpreadingFactors_t; + +/*! + * \brief Represents the bandwidth values for LoRa packet type + */ +typedef enum +{ + LORA_BW_500 = 6, + LORA_BW_250 = 5, + LORA_BW_125 = 4, + LORA_BW_062 = 3, + LORA_BW_041 = 10, + LORA_BW_031 = 2, + LORA_BW_020 = 9, + LORA_BW_015 = 1, + LORA_BW_010 = 8, + LORA_BW_007 = 0, +}RadioLoRaBandwidths_t; + +/*! + * \brief Represents the coding rate values for LoRa packet type + */ +typedef enum +{ + LORA_CR_4_5 = 0x01, + LORA_CR_4_6 = 0x02, + LORA_CR_4_7 = 0x03, + LORA_CR_4_8 = 0x04, +}RadioLoRaCodingRates_t; + +/*! + * \brief Represents the preamble length used to detect the packet on Rx side + */ +typedef enum +{ + RADIO_PREAMBLE_DETECTOR_OFF = 0x00, //!< Preamble detection length off + RADIO_PREAMBLE_DETECTOR_08_BITS = 0x04, //!< Preamble detection length 8 bits + RADIO_PREAMBLE_DETECTOR_16_BITS = 0x05, //!< Preamble detection length 16 bits + RADIO_PREAMBLE_DETECTOR_24_BITS = 0x06, //!< Preamble detection length 24 bits + RADIO_PREAMBLE_DETECTOR_32_BITS = 0x07, //!< Preamble detection length 32 bit +}RadioPreambleDetection_t; + +/*! + * \brief Represents the possible combinations of SyncWord correlators activated + */ +typedef enum +{ + RADIO_ADDRESSCOMP_FILT_OFF = 0x00, //!< No correlator turned on, i.e. do not search for SyncWord + RADIO_ADDRESSCOMP_FILT_NODE = 0x01, + RADIO_ADDRESSCOMP_FILT_NODE_BROAD = 0x02, +}RadioAddressComp_t; + +/*! + * \brief Radio GFSK packet length mode + */ +typedef enum +{ + RADIO_PACKET_FIXED_LENGTH = 0x00, //!< The packet is known on both sides, no header included in the packet + RADIO_PACKET_VARIABLE_LENGTH = 0x01, //!< The packet is on variable size, header included +}RadioPacketLengthModes_t; + +/*! + * \brief Represents the CRC length + */ +typedef enum +{ + RADIO_CRC_OFF = 0x01, //!< No CRC in use + RADIO_CRC_1_BYTES = 0x00, + RADIO_CRC_2_BYTES = 0x02, + RADIO_CRC_1_BYTES_INV = 0x04, + RADIO_CRC_2_BYTES_INV = 0x06, + RADIO_CRC_2_BYTES_IBM = 0xF1, + RADIO_CRC_2_BYTES_CCIT = 0xF2, +}RadioCrcTypes_t; + +/*! + * \brief Radio whitening mode activated or deactivated + */ +typedef enum +{ + RADIO_DC_FREE_OFF = 0x00, + RADIO_DC_FREEWHITENING = 0x01, +}RadioDcFree_t; + +/*! + * \brief Holds the Radio lengths mode for the LoRa packet type + */ +typedef enum +{ + LORA_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included + LORA_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet + LORA_PACKET_EXPLICIT = LORA_PACKET_VARIABLE_LENGTH, + LORA_PACKET_IMPLICIT = LORA_PACKET_FIXED_LENGTH, +}RadioLoRaPacketLengthsMode_t; + +/*! + * \brief Represents the CRC mode for LoRa packet type + */ +typedef enum +{ + LORA_CRC_ON = 0x01, //!< CRC activated + LORA_CRC_OFF = 0x00, //!< CRC not used +}RadioLoRaCrcModes_t; + +/*! + * \brief Represents the IQ mode for LoRa packet type + */ +typedef enum +{ + LORA_IQ_NORMAL = 0x00, + LORA_IQ_INVERTED = 0x01, +}RadioLoRaIQModes_t; + +/*! + * \brief Represents the voltage used to control the TCXO on/off from DIO3 + */ +typedef enum +{ + TCXO_CTRL_1_6V = 0x00, + TCXO_CTRL_1_7V = 0x01, + TCXO_CTRL_1_8V = 0x02, + TCXO_CTRL_2_2V = 0x03, + TCXO_CTRL_2_4V = 0x04, + TCXO_CTRL_2_7V = 0x05, + TCXO_CTRL_3_0V = 0x06, + TCXO_CTRL_3_3V = 0x07, +}RadioTcxoCtrlVoltage_t; + +/*! + * \brief Represents the interruption masks available for the radio + * + * \remark Note that not all these interruptions are available for all packet types + */ +typedef enum +{ + IRQ_RADIO_NONE = 0x0000, + IRQ_TX_DONE = 0x0001, + IRQ_RX_DONE = 0x0002, + IRQ_PREAMBLE_DETECTED = 0x0004, + IRQ_SYNCWORD_VALID = 0x0008, + IRQ_HEADER_VALID = 0x0010, + IRQ_HEADER_ERROR = 0x0020, + IRQ_CRC_ERROR = 0x0040, + IRQ_CAD_DONE = 0x0080, + IRQ_CAD_ACTIVITY_DETECTED = 0x0100, + IRQ_RX_TX_TIMEOUT = 0x0200, + IRQ_RADIO_ALL = 0xFFFF, +}RadioIrqMasks_t; + +/*! + * \brief Represents all possible opcode understood by the radio + */ +typedef enum RadioCommands_e +{ + RADIO_GET_STATUS = 0xC0, + RADIO_WRITE_REGISTER = 0x0D, + RADIO_READ_REGISTER = 0x1D, + RADIO_WRITE_BUFFER = 0x0E, + RADIO_READ_BUFFER = 0x1E, + RADIO_SET_SLEEP = 0x84, + RADIO_SET_STANDBY = 0x80, + RADIO_SET_FS = 0xC1, + RADIO_SET_TX = 0x83, + RADIO_SET_RX = 0x82, + RADIO_SET_RXDUTYCYCLE = 0x94, + RADIO_SET_CAD = 0xC5, + RADIO_SET_TXCONTINUOUSWAVE = 0xD1, + RADIO_SET_TXCONTINUOUSPREAMBLE = 0xD2, + RADIO_SET_PACKETTYPE = 0x8A, + RADIO_GET_PACKETTYPE = 0x11, + RADIO_SET_RFFREQUENCY = 0x86, + RADIO_SET_TXPARAMS = 0x8E, + RADIO_SET_PACONFIG = 0x95, + RADIO_SET_CADPARAMS = 0x88, + RADIO_SET_BUFFERBASEADDRESS = 0x8F, + RADIO_SET_MODULATIONPARAMS = 0x8B, + RADIO_SET_PACKETPARAMS = 0x8C, + RADIO_GET_RXBUFFERSTATUS = 0x13, + RADIO_GET_PACKETSTATUS = 0x14, + RADIO_GET_RSSIINST = 0x15, + RADIO_GET_STATS = 0x10, + RADIO_RESET_STATS = 0x00, + RADIO_CFG_DIOIRQ = 0x08, + RADIO_GET_IRQSTATUS = 0x12, + RADIO_CLR_IRQSTATUS = 0x02, + RADIO_CALIBRATE = 0x89, + RADIO_CALIBRATEIMAGE = 0x98, + RADIO_SET_REGULATORMODE = 0x96, + RADIO_GET_ERROR = 0x17, + RADIO_CLR_ERROR = 0x07, + RADIO_SET_TCXOMODE = 0x97, + RADIO_SET_TXFALLBACKMODE = 0x93, + RADIO_SET_RFSWITCHMODE = 0x9D, + RADIO_SET_STOPRXTIMERONPREAMBLE = 0x9F, + RADIO_SET_LORASYMBTIMEOUT = 0xA0, +}RadioCommands_t; + +/*! + * \brief The type describing the modulation parameters for every packet types + */ +typedef struct +{ + RadioPacketTypes_t PacketType; //!< Packet to which the modulation parameters are referring to. + struct + { + struct + { + uint32_t BitRate; + uint32_t Fdev; + RadioModShapings_t ModulationShaping; + uint8_t Bandwidth; + }Gfsk; + struct + { + RadioLoRaSpreadingFactors_t SpreadingFactor; //!< Spreading Factor for the LoRa modulation + RadioLoRaBandwidths_t Bandwidth; //!< Bandwidth for the LoRa modulation + RadioLoRaCodingRates_t CodingRate; //!< Coding rate for the LoRa modulation + uint8_t LowDatarateOptimize; //!< Indicates if the modem uses the low datarate optimization + }LoRa; + }Params; //!< Holds the modulation parameters structure +}ModulationParams_t; + +/*! + * \brief The type describing the packet parameters for every packet types + */ +typedef struct +{ + RadioPacketTypes_t PacketType; //!< Packet to which the packet parameters are referring to. + struct + { + /*! + * \brief Holds the GFSK packet parameters + */ + struct + { + uint16_t PreambleLength; //!< The preamble Tx length for GFSK packet type in bit + RadioPreambleDetection_t PreambleMinDetect; //!< The preamble Rx length minimal for GFSK packet type + uint8_t SyncWordLength; //!< The synchronization word length for GFSK packet type + RadioAddressComp_t AddrComp; //!< Activated SyncWord correlators + RadioPacketLengthModes_t HeaderType; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted + uint8_t PayloadLength; //!< Size of the payload in the GFSK packet + RadioCrcTypes_t CrcLength; //!< Size of the CRC block in the GFSK packet + RadioDcFree_t DcFree; + }Gfsk; + /*! + * \brief Holds the LoRa packet parameters + */ + struct + { + uint16_t PreambleLength; //!< The preamble length is the number of LoRa symbols in the preamble + RadioLoRaPacketLengthsMode_t HeaderType; //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted + uint8_t PayloadLength; //!< Size of the payload in the LoRa packet + RadioLoRaCrcModes_t CrcMode; //!< Size of CRC block in LoRa packet + RadioLoRaIQModes_t InvertIQ; //!< Allows to swap IQ for LoRa packet + }LoRa; + }Params; //!< Holds the packet parameters structure +}PacketParams_t; + +/*! + * \brief Represents the packet status for every packet type + */ +typedef struct +{ + RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. + struct + { + struct + { + uint8_t RxStatus; + int8_t RssiAvg; //!< The averaged RSSI + int8_t RssiSync; //!< The RSSI measured on last packet + uint32_t FreqError; + }Gfsk; + struct + { + int8_t RssiPkt; //!< The RSSI of the last packet + int8_t SnrPkt; //!< The SNR of the last packet + int8_t SignalRssiPkt; + uint32_t FreqError; + }LoRa; + }Params; +}PacketStatus_t; + +/*! + * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used + */ +typedef struct +{ + RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. + uint16_t PacketReceived; + uint16_t CrcOk; + uint16_t LengthError; +}RxCounter_t; + +/*! + * \brief Represents a calibration configuration + */ +typedef union +{ + struct + { + uint8_t RC64KEnable : 1; //!< Calibrate RC64K clock + uint8_t RC13MEnable : 1; //!< Calibrate RC13M clock + uint8_t PLLEnable : 1; //!< Calibrate PLL + uint8_t ADCPulseEnable : 1; //!< Calibrate ADC Pulse + uint8_t ADCBulkNEnable : 1; //!< Calibrate ADC bulkN + uint8_t ADCBulkPEnable : 1; //!< Calibrate ADC bulkP + uint8_t ImgEnable : 1; + uint8_t : 1; + }Fields; + uint8_t Value; +}CalibrationParams_t; + +/*! + * \brief Represents a sleep mode configuration + */ +typedef union +{ + struct + { + uint8_t WakeUpRTC : 1; //!< Get out of sleep mode if wakeup signal received from RTC + uint8_t Reset : 1; + uint8_t WarmStart : 1; + uint8_t Reserved : 5; + }Fields; + uint8_t Value; +}SleepParams_t; + +/*! + * \brief Represents the possible radio system error states + */ +typedef union +{ + struct + { + uint8_t Rc64kCalib : 1; //!< RC 64kHz oscillator calibration failed + uint8_t Rc13mCalib : 1; //!< RC 13MHz oscillator calibration failed + uint8_t PllCalib : 1; //!< PLL calibration failed + uint8_t AdcCalib : 1; //!< ADC calibration failed + uint8_t ImgCalib : 1; //!< Image calibration failed + uint8_t XoscStart : 1; //!< XOSC oscillator failed to start + uint8_t PllLock : 1; //!< PLL lock failed + uint8_t BuckStart : 1; //!< Buck converter failed to start + uint8_t PaRamp : 1; //!< PA ramp failed + uint8_t : 7; //!< Reserved + }Fields; + uint16_t Value; +}RadioError_t; + +/*! + * Radio hardware and global parameters + */ +typedef struct SX126x_s +{ +// Gpio_t Reset; +// Gpio_t BUSY; +// Gpio_t DIO1; +// Gpio_t DIO2; +// Gpio_t DIO3; +// Spi_t Spi; + PacketParams_t PacketParams; + PacketStatus_t PacketStatus; + ModulationParams_t ModulationParams; +}SX126x_t; + +/*! + * Hardware IO IRQ callback function definition + */ +typedef void ( DioIrqHandler )( void ); + +/*! + * SX126x definitions + */ + +/*! + * \brief Provides the frequency of the chip running on the radio and the frequency step + * + * \remark These defines are used for computing the frequency divider to set the RF frequency + */ +#define XTAL_FREQ ( double )32000000 +#define FREQ_DIV ( double )pow( 2.0, 25.0 ) +#define FREQ_STEP ( double )( XTAL_FREQ / FREQ_DIV ) + +#define RX_BUFFER_SIZE 256 + +/*! + * \brief The radio callbacks structure + * Holds function pointers to be called on radio interrupts + */ +typedef struct +{ + void ( *txDone )( void ); //!< Pointer to a function run on successful transmission + void ( *rxDone )( void ); //!< Pointer to a function run on successful reception + void ( *rxPreambleDetect )( void ); //!< Pointer to a function run on successful Preamble detection + void ( *rxSyncWordDone )( void ); //!< Pointer to a function run on successful SyncWord reception + void ( *rxHeaderDone )( bool isOk ); //!< Pointer to a function run on successful Header reception + void ( *txTimeout )( void ); //!< Pointer to a function run on transmission timeout + void ( *rxTimeout )( void ); //!< Pointer to a function run on reception timeout + void ( *rxError )( IrqErrorCode_t errCode ); //!< Pointer to a function run on reception error + void ( *cadDone )( bool cadFlag ); //!< Pointer to a function run on channel activity detected +}SX126xCallbacks_t; + +/*! + * ============================================================================ + * Public functions prototypes + * ============================================================================ + */ + +/*! + * \brief Initializes the radio driver + */ +void SX126xInit( DioIrqHandler dioIrq ); + +/*! + * \brief Gets the current Operation Mode of the Radio + * + * \retval RadioOperatingModes_t last operating mode + */ +RadioOperatingModes_t SX126xGetOperatingMode( void ); + +/*! + * \brief Wakeup the radio if it is in Sleep mode and check that Busy is low + */ +void SX126xCheckDeviceReady( void ); + +/*! + * \brief Saves the payload to be send in the radio buffer + * + * \param [in] payload A pointer to the payload + * \param [in] size The size of the payload + */ +void SX126xSetPayload( uint8_t *payload, uint8_t size ); + +/*! + * \brief Reads the payload received. If the received payload is longer + * than maxSize, then the method returns 1 and do not set size and payload. + * + * \param [out] payload A pointer to a buffer into which the payload will be copied + * \param [out] size A pointer to the size of the payload received + * \param [in] maxSize The maximal size allowed to copy into the buffer + */ +uint8_t SX126xGetPayload( uint8_t *payload, uint8_t *size, uint8_t maxSize ); + +/*! + * \brief Sends a payload + * + * \param [in] payload A pointer to the payload to send + * \param [in] size The size of the payload to send + * \param [in] timeout The timeout for Tx operation + */ +void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ); + +/*! + * \brief Sets the Sync Word given by index used in GFSK + * + * \param [in] syncWord SyncWord bytes ( 8 bytes ) + * + * \retval status [0: OK, 1: NOK] + */ +uint8_t SX126xSetSyncWord( uint8_t *syncWord ); + +/*! + * \brief Sets the Initial value for the LFSR used for the CRC calculation + * + * \param [in] seed Initial LFSR value ( 2 bytes ) + * + */ +void SX126xSetCrcSeed( uint16_t seed ); + +/*! + * \brief Sets the seed used for the CRC calculation + * + * \param [in] seed The seed value + * + */ +void SX126xSetCrcPolynomial( uint16_t polynomial ); + +/*! + * \brief Sets the Initial value of the LFSR used for the whitening in GFSK protocols + * + * \param [in] seed Initial LFSR value + */ +void SX126xSetWhiteningSeed( uint16_t seed ); + +/*! + * \brief Gets a 32 bits random value generated by the radio + * + * \remark The radio must be in reception mode before executing this function + * + * \retval randomValue 32 bits random value + */ +uint32_t SX126xGetRandom( void ); + +/*! + * \brief Sets the radio in sleep mode + * + * \param [in] sleepConfig The sleep configuration describing data + * retention and RTC wake-up + */ +void SX126xSetSleep( SleepParams_t sleepConfig ); + +/*! + * \brief Sets the radio in configuration mode + * + * \param [in] mode The standby mode to put the radio into + */ +void SX126xSetStandby( RadioStandbyModes_t mode ); + +/*! + * \brief Sets the radio in FS mode + */ +void SX126xSetFs( void ); + +/*! + * \brief Sets the radio in transmission mode + * + * \param [in] timeout Structure describing the transmission timeout value + */ +void SX126xSetTx( uint32_t timeout ); + +/*! + * \brief Sets the radio in reception mode + * + * \param [in] timeout Structure describing the reception timeout value + */ +void SX126xSetRx( uint32_t timeout ); + +/*! + * \brief Sets the radio in reception mode with Boosted LNA gain + * + * \param [in] timeout Structure describing the reception timeout value + */ +void SX126xSetRxBoosted( uint32_t timeout ); + +/*! + * \brief Sets the Rx duty cycle management parameters + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ +void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); + +/*! + * \brief Sets the radio in CAD mode + */ +void SX126xSetCad( void ); + +/*! + * \brief Sets the radio in continuous wave transmission mode + */ +void SX126xSetTxContinuousWave( void ); + +/*! + * \brief Sets the radio in continuous preamble transmission mode + */ +void SX126xSetTxInfinitePreamble( void ); + +/*! + * \brief Decide which interrupt will stop the internal radio rx timer. + * + * \param [in] enable [0: Timer stop after header/syncword detection + * 1: Timer stop after preamble detection] + */ +void SX126xSetStopRxTimerOnPreambleDetect( bool enable ); + +/*! + * \brief Set the number of symbol the radio will wait to validate a reception + * + * \param [in] SymbNum number of LoRa symbols + */ +void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ); + +/*! + * \brief Sets the power regulators operating mode + * + * \param [in] mode [0: LDO, 1:DC_DC] + */ +void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ); + +/*! + * \brief Calibrates the given radio block + * + * \param [in] calibParam The description of blocks to be calibrated + */ +void SX126xCalibrate( CalibrationParams_t calibParam ); + +/*! + * \brief Calibrates the Image rejection depending of the frequency + * + * \param [in] freq The operating frequency + */ +void SX126xCalibrateImage( uint32_t freq ); + +/*! + * \brief Activate the extention of the timeout when long preamble is used + * + * \param [in] enable The radio will extend the timeout to cope with long preamble + */ +void SX126xSetLongPreamble( uint8_t enable ); + +/*! + * \brief Sets the transmission parameters + * + * \param [in] paDutyCycle Duty Cycle for the PA + * \param [in] hpMax 0 for sx1261, 7 for sx1262 + * \param [in] deviceSel 1 for sx1261, 0 for sx1262 + * \param [in] paLut 0 for 14dBm LUT, 1 for 22dBm LUT + */ +void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ); + +/*! + * \brief Defines into which mode the chip goes after a TX / RX done + * + * \param [in] fallbackMode The mode in which the radio goes + */ +void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ); + +/*! + * \brief Write data to the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * \param [in] buffer The data to be written in radio's memory + * \param [in] size The number of bytes to write in radio's memory + */ +void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Read data from the radio memory + * + * \param [in] address The address of the first byte to read from the radio + * \param [out] buffer The buffer that holds data read from radio + * \param [in] size The number of bytes to read from radio's memory + */ +void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Write data to the buffer holding the payload in the radio + * + * \param [in] offset The offset to start writing the payload + * \param [in] buffer The data to be written (the payload) + * \param [in] size The number of byte to be written + */ +void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Read data from the buffer holding the payload in the radio + * + * \param [in] offset The offset to start reading the payload + * \param [out] buffer A pointer to a buffer holding the data from the radio + * \param [in] size The number of byte to be read + */ +void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the IRQ mask and DIO masks + * + * \param [in] irqMask General IRQ mask + * \param [in] dio1Mask DIO1 mask + * \param [in] dio2Mask DIO2 mask + * \param [in] dio3Mask DIO3 mask + */ +void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ); + +/*! + * \brief Returns the current IRQ status + * + * \retval irqStatus IRQ status + */ +uint16_t SX126xGetIrqStatus( void ); + +/*! + * \brief Indicates if DIO2 is used to control an RF Switch + * + * \param [in] enable true of false + */ +void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ); + +/*! + * \brief Indicates if the Radio main clock is supplied from a tcxo + * + * \param [in] tcxoVoltage voltage used to control the TCXO + * \param [in] timeout time given to the TCXO to go to 32MHz + */ +void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ); + +/*! + * \brief Sets the RF frequency + * + * \param [in] frequency RF frequency [Hz] + */ +void SX126xSetRfFrequency( uint32_t frequency ); + +/*! + * \brief Sets the radio for the given protocol + * + * \param [in] packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] + * + * \remark This method has to be called before SetRfFrequency, + * SetModulationParams and SetPacketParams + */ +void SX126xSetPacketType( RadioPacketTypes_t packetType ); + +/*! + * \brief Gets the current radio protocol + * + * \retval packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] + */ +RadioPacketTypes_t SX126xGetPacketType( void ); + +/*! + * \brief Sets the transmission parameters + * + * \param [in] power RF output power [-18..13] dBm + * \param [in] rampTime Transmission ramp up time + */ +void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ); + +/*! + * \brief Set the modulation parameters + * + * \param [in] modParams A structure describing the modulation parameters + */ +void SX126xSetModulationParams( ModulationParams_t *modParams ); + +/*! + * \brief Sets the packet parameters + * + * \param [in] packetParams A structure describing the packet parameters + */ +void SX126xSetPacketParams( PacketParams_t *packetParams ); + +/*! + * \brief Sets the Channel Activity Detection (CAD) parameters + * + * \param [in] cadSymbolNum The number of symbol to use for CAD operations + * [LORA_CAD_01_SYMBOL, LORA_CAD_02_SYMBOL, + * LORA_CAD_04_SYMBOL, LORA_CAD_08_SYMBOL, + * LORA_CAD_16_SYMBOL] + * \param [in] cadDetPeak Limit for detection of SNR peak used in the CAD + * \param [in] cadDetMin Set the minimum symbol recognition for CAD + * \param [in] cadExitMode Operation to be done at the end of CAD action + * [LORA_CAD_ONLY, LORA_CAD_RX, LORA_CAD_LBT] + * \param [in] cadTimeout Defines the timeout value to abort the CAD activity + */ +void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ); + +/*! + * \brief Sets the data buffer base address for transmission and reception + * + * \param [in] txBaseAddress Transmission base address + * \param [in] rxBaseAddress Reception base address + */ +void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ); + +/*! + * \brief Gets the current radio status + * + * \retval status Radio status + */ +RadioStatus_t SX126xGetStatus( void ); + +/*! + * \brief Returns the instantaneous RSSI value for the last packet received + * + * \retval rssiInst Instantaneous RSSI + */ +int8_t SX126xGetRssiInst( void ); + +/*! + * \brief Gets the last received packet buffer status + * + * \param [out] payloadLength Last received packet payload length + * \param [out] rxStartBuffer Last received packet buffer address pointer + */ +void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBuffer ); + +/*! + * \brief Gets the last received packet payload length + * + * \param [out] pktStatus A structure of packet status + */ +void SX126xGetPacketStatus( PacketStatus_t *pktStatus ); + +/*! + * \brief Returns the possible system errors + * + * \retval sysErrors Value representing the possible sys failures + */ +RadioError_t SX126xGetDeviceErrors( void ); + +/*! + * \brief Clear all the errors in the device + */ +void SX126xClearDeviceErrors( void ); + +/*! + * \brief Clears the IRQs + * + * \param [in] irq IRQ(s) to be cleared + */ +void SX126xClearIrqStatus( uint16_t irq ); + +#endif // __SX126x_H__ diff --git a/C8T6_TestApp2/Radio/src/crc.c b/C8T6_TestApp2/Radio/src/crc.c new file mode 100644 index 0000000..68ed1c9 --- /dev/null +++ b/C8T6_TestApp2/Radio/src/crc.c @@ -0,0 +1,47 @@ +#include "crc.h" + + +uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ) +{ + uint8_t i; + + for( i = 0; i < 8; i++ ) + { + if( ( ( ( crc & 0x8000 ) >> 8 ) ^ ( dataByte & 0x80 ) ) != 0 ) + { + crc <<= 1; // shift left once + crc ^= polynomial; // XOR with polynomial + } + else + { + crc <<= 1; // shift left once + } + dataByte <<= 1; // Next data bit + } + return crc; +} + + +uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ) +{ + uint8_t i = 0; + uint16_t crc = 0; + uint16_t polynomial = 0; + + polynomial = ( crcType == CRC_TYPE_IBM ) ? POLYNOMIAL_IBM : POLYNOMIAL_CCITT; + crc = ( crcType == CRC_TYPE_IBM ) ? CRC_IBM_SEED : CRC_CCITT_SEED; + for( i = 0; i < length; i++ ) + { + crc = ComputeCrc( crc, buffer[i], polynomial ); + } + if( crcType == CRC_TYPE_IBM ) + { + return crc; + } + else + { + return( ( uint16_t ) ( ~crc )); + } +} + + diff --git a/C8T6_TestApp2/Radio/src/radio.c b/C8T6_TestApp2/Radio/src/radio.c new file mode 100644 index 0000000..19756a0 --- /dev/null +++ b/C8T6_TestApp2/Radio/src/radio.c @@ -0,0 +1,1151 @@ +/*! + * \file radio.c + * + * \brief Radio driver API definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#include <math.h> +#include <string.h> +#include <stdbool.h> +#include "stm32f0xx.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" + +/*! + * \brief Initializes the radio + * + * \param [IN] events Structure containing the driver callback functions + */ +void RadioInit( RadioEvents_t *events ); + +/*! + * Return current radio status + * + * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + */ +RadioState_t RadioGetStatus( void ); + +/*! + * \brief Configures the radio with the given modem + * + * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] + */ +void RadioSetModem( RadioModems_t modem ); + +/*! + * \brief Sets the channel frequency + * + * \param [IN] freq Channel RF frequency + */ +void RadioSetChannel( uint32_t freq ); + +/*! + * \brief Checks if the channel is free for the given time + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] freq Channel RF frequency + * \param [IN] rssiThresh RSSI threshold + * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured + * + * \retval isFree [true: Channel is free, false: Channel is not free] + */ +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); + +/*! + * \brief Generates a 32 bits random value based on the RSSI readings + * + * \remark This function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * \retval randomValue 32 bits random value + */ +uint32_t RadioRandom( void ); + +/*! + * \brief Sets the reception parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] symbTimeout Sets the RxSingle timeout value + * FSK : timeout in number of bytes + * LoRa: timeout in symbols + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] rxContinuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool FreqHopOn, uint8_t HopPeriod, + bool iqInverted, bool rxContinuous ); + +/*! + * \brief Sets the transmission parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] power Sets the output power [dBm] + * \param [IN] fdev Sets the frequency deviation (FSK only) + * FSK : [Hz] + * LoRa: 0 + * \param [IN] bandwidth Sets the bandwidth (LoRa only) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] timeout Transmission timeout [ms] + */ +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool FreqHopOn, + uint8_t HopPeriod, bool iqInverted, uint32_t timeout ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool RadioCheckRfFrequency( uint32_t frequency ); + +/*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (ms) for the given packet payload length + */ +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ); + +/*! + * \brief Sends the buffer of size. Prepares the packet to be sent and sets + * the radio in transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void RadioSend( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the radio in sleep mode + */ +void RadioSleep( void ); + +/*! + * \brief Sets the radio in standby mode + */ +void RadioStandby( void ); + +/*! + * \brief Sets the radio in reception mode for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRx( uint32_t timeout ); + +/*! + * \brief Start a Channel Activity Detection + */ +void RadioStartCad( void ); + +/*! + * \brief Sets the radio in continuous wave transmission mode + * + * \param [IN]: freq Channel RF frequency + * \param [IN]: power Sets the output power [dBm] + * \param [IN]: time Transmission mode timeout [s] + */ +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ); + +/*! + * \brief Reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ +int16_t RadioRssi( RadioModems_t modem ); + +/*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ +void RadioWrite( uint16_t addr, uint8_t data ); + +/*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \retval data Register value + */ +uint8_t RadioRead( uint16_t addr ); + +/*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the maximum payload length. + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] max Maximum payload length in bytes + */ +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ); + +/*! + * \brief Sets the network to public or private. Updates the sync byte. + * + * \remark Applies to LoRa modem only + * + * \param [IN] enable if true, it enables a public network + */ +void RadioSetPublicNetwork( bool enable ); + +/*! + * \brief Gets the time required for the board plus radio to get out of sleep.[ms] + * + * \retval time Radio plus board wakeup time in ms. + */ +uint32_t RadioGetWakeupTime( void ); + +/*! + * \brief Process radio irq + */ +void RadioIrqProcess( void ); + +/*! + * \brief Sets the radio in reception mode with Max LNA gain for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRxBoosted( uint32_t timeout ); + +/*! + * \brief Sets the Rx duty cycle management parameters + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); + +/*! + * Radio driver structure initialization + */ +const struct Radio_s Radio = +{ + RadioInit, + RadioGetStatus, + RadioSetModem, + RadioSetChannel, + RadioIsChannelFree, + RadioRandom, + RadioSetRxConfig, + RadioSetTxConfig, + RadioCheckRfFrequency, + RadioTimeOnAir, + RadioSend, + RadioSleep, + RadioStandby, + RadioRx, + RadioStartCad, + RadioSetTxContinuousWave, + RadioRssi, + RadioWrite, + RadioRead, + RadioWriteBuffer, + RadioReadBuffer, + RadioSetMaxPayloadLength, + RadioSetPublicNetwork, + RadioGetWakeupTime, + RadioIrqProcess, + // Available on SX126x only + RadioRxBoosted, + RadioSetRxDutyCycle +}; + +/* + * Local types definition + */ + + + /*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t RegValue; +}FskBandwidth_t; + +/*! + * Precomputed FSK bandwidth registers values + */ +const FskBandwidth_t FskBandwidths[] = +{ + { 4800 , 0x1F }, + { 5800 , 0x17 }, + { 7300 , 0x0F }, + { 9700 , 0x1E }, + { 11700 , 0x16 }, + { 14600 , 0x0E }, + { 19500 , 0x1D }, + { 23400 , 0x15 }, + { 29300 , 0x0D }, + { 39000 , 0x1C }, + { 46900 , 0x14 }, + { 58600 , 0x0C }, + { 78200 , 0x1B }, + { 93800 , 0x13 }, + { 117300, 0x0B }, + { 156200, 0x1A }, + { 187200, 0x12 }, + { 234300, 0x0A }, + { 312000, 0x19 }, + { 373600, 0x11 }, + { 467000, 0x09 }, + { 500000, 0x00 }, // Invalid Bandwidth +}; + +const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 }; + +// SF12 SF11 SF10 SF9 SF8 SF7 +static double RadioLoRaSymbTime[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz + { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz + { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz + +uint8_t MaxPayloadLength = 0xFF; + +uint32_t TxTimeout = 0; +uint32_t RxTimeout = 0; + +bool RxContinuous = false; + + +PacketStatus_t RadioPktStatus; +uint8_t RadioRxPayload[255]; + +bool IrqFired = false; + +/* + * SX126x DIO IRQ callback functions prototype + */ + +/*! + * \brief DIO 0 IRQ callback + */ +void RadioOnDioIrq( void ); + +/*! + * \brief Tx timeout timer callback + */ +void RadioOnTxTimeoutIrq( void ); + +/*! + * \brief Rx timeout timer callback + */ +void RadioOnRxTimeoutIrq( void ); + +/* + * Private global variables + */ + + +/*! + * Holds the current network type for the radio + */ +typedef struct +{ + bool Previous; + bool Current; +}RadioPublicNetwork_t; + +static RadioPublicNetwork_t RadioPublicNetwork = { false }; + +/*! + * Radio callbacks variable + */ +static RadioEvents_t* RadioEvents; + +/* + * Public global variables + */ + +/*! + * Radio hardware and global parameters + */ +SX126x_t SX126x; + +/*! + * Tx and Rx timers + */ +//TimerEvent_t TxTimeoutTimer; +//TimerEvent_t RxTimeoutTimer; + +/*! + * Returns the known FSK bandwidth registers value + * + * \param [IN] bandwidth Bandwidth value in Hz + * \retval regValue Bandwidth register value. + */ +static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ) +{ + uint8_t i; + + if( bandwidth == 0 ) + { + return( 0x1F ); + } + + for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ ) + { + if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) ) + { + return FskBandwidths[i+1].RegValue; + } + } + // ERROR: Value not found + while( 1 ); +} + +void RadioInit( RadioEvents_t *events ) +{ + RadioEvents = events; + + SX126xInit( RadioOnDioIrq ); + SX126xSetStandby( STDBY_RC ); + SX126xSetRegulatorMode( USE_DCDC ); + + SX126xSetBufferBaseAddress( 0x00, 0x00 ); + SX126xSetTxParams( 0, RADIO_RAMP_200_US ); + SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + + //Initialize driver timeout timers + //TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); + //TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); + + IrqFired = false; +} + +RadioState_t RadioGetStatus( void ) +{ + switch( SX126xGetOperatingMode( ) ) + { + case MODE_TX: + return RF_TX_RUNNING; + case MODE_RX: + return RF_RX_RUNNING; + case RF_CAD: + return RF_CAD; + default: + return RF_IDLE; + } +} + +void RadioSetModem( RadioModems_t modem ) +{ + switch( modem ) + { + default: + case MODEM_FSK: + SX126xSetPacketType( PACKET_TYPE_GFSK ); + // When switching to GFSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + RadioPublicNetwork.Current = false; + break; + case MODEM_LORA: + SX126xSetPacketType( PACKET_TYPE_LORA ); + // Public/Private network register is reset when switching modems + if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous ) + { + RadioPublicNetwork.Current = RadioPublicNetwork.Previous; + RadioSetPublicNetwork( RadioPublicNetwork.Current ); + } + break; + } +} + +void RadioSetChannel( uint32_t freq ) +{ + SX126xSetRfFrequency( freq ); +} + +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) +{ + bool status = true; + // int16_t rssi = 0; + // uint32_t carrierSenseTime = 0; + + RadioSetModem( modem ); + + RadioSetChannel( freq ); + + RadioRx( 0 ); + + HAL_Delay_nMS( 1 ); + + //carrierSenseTime = TimerGetCurrentTime( ); + + + //Perform carrier sense for maxCarrierSenseTime +// while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ) +// { +// rssi = RadioRssi( modem ); +// +// if( rssi > rssiThresh ) +// { +// status = false; +// break; +// } +// } + RadioSleep( ); + return status; +} + +uint32_t RadioRandom( void ) +{ + uint8_t i; + uint32_t rnd = 0; + + /* + * Radio setup for random number generation + */ + // Set LoRa modem ON + RadioSetModem( MODEM_LORA ); + + // Set radio in continuous reception + SX126xSetRx( 0 ); + + for( i = 0; i < 32; i++ ) + { + HAL_Delay_nMS( 1 ); + // Unfiltered RSSI value reading. Only takes the LSB value + rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i; + } + + RadioSleep( ); + + return rnd; +} + +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool freqHopOn, uint8_t hopPeriod, + bool iqInverted, bool rxContinuous ) +{ + + RxContinuous = rxContinuous; + + if( fixLen == true ) + { + MaxPayloadLength = payloadLen; + } + else + { + MaxPayloadLength = 0xFF; + } + + switch( modem ) + { + case MODEM_FSK: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength; + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREE_OFF; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + + RxTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 ); + break; + + case MODEM_LORA: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126xSetLoRaSymbNumTimeout( symbTimeout ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 12 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 12; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + + // Timeout Max, Timeout handled directly in SetRx function + RxTimeout = 0xFFFF; + + break; + } +} + +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool freqHopOn, + uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) +{ + + switch( modem ) + { + case MODEM_FSK: + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + SX126x.ModulationParams.Params.Gfsk.Fdev = fdev; + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + break; + + case MODEM_LORA: + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 12 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 12; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + break; + } + SX126xSetRfTxPower( power ); + TxTimeout = timeout; +} + +bool RadioCheckRfFrequency( uint32_t frequency ) +{ + return true; +} + +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ) +{ + uint32_t airTime = 0; + + switch( modem ) + { + case MODEM_FSK: + { + airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength + + ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) + + ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) + + pktLen + + ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) / + SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 ); + } + break; + case MODEM_LORA: + { + double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor]; + // time of preamble + double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts; + // Symbol length of payload and time + double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor + + 28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode - + ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) / + ( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor - + ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) * + ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ); + double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 ); + double tPayload = nPayload * ts; + // Time on air + double tOnAir = tPreamble + tPayload; + // return milli seconds + airTime = floor( tOnAir + 0.999 ); + } + break; + } + return airTime; +} + +void RadioSend( uint8_t *buffer, uint8_t size ) +{ + SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + if( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = size; + } + else + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = size; + } + SX126xSetPacketParams( &SX126x.PacketParams ); + + SX126xSendPayload( buffer, size, 0 ); +// TimerSetValue( &TxTimeoutTimer, TxTimeout ); +// TimerStart( &TxTimeoutTimer ); +} + +void RadioSleep( void ) +{ + SleepParams_t params = { 0 }; + + params.Fields.WarmStart = 1; + SX126xSetSleep( params ); + + HAL_Delay_nMS( 2 ); +} + +void RadioStandby( void ) +{ + // SX126xSetStandby( STDBY_XOSC ); //STDBY_RC + SX126xSetFs(); +} + +void RadioRx( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRx( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRx( timeout << 6 ); + } +} + +void RadioRxBoosted( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRxBoosted( timeout << 6 ); + } +} + +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) +{ + SX126xSetRxDutyCycle( rxTime, sleepTime ); +} + +void RadioStartCad( void ) +{ + SX126xSetCad( ); +} + +void RadioTx( uint32_t timeout ) +{ + SX126xSetTx( timeout << 6 ); +} + +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) +{ + SX126xSetRfFrequency( freq ); + SX126xSetRfTxPower( power ); + SX126xSetTxContinuousWave( ); + +// TimerSetValue( &RxTimeoutTimer, time * 1e3 ); +// TimerStart( &RxTimeoutTimer ); +} + +int16_t RadioRssi( RadioModems_t modem ) +{ + return SX126xGetRssiInst( ); +} + +void RadioWrite( uint16_t addr, uint8_t data ) +{ + SX126xWriteRegister( addr, data ); +} + +uint8_t RadioRead( uint16_t addr ) +{ + return SX126xReadRegister( addr ); +} + +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xWriteRegisters( addr, buffer, size ); +} + +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xReadRegisters( addr, buffer, size ); +} + +void RadioWriteFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xWriteBuffer( 0, buffer, size ); +} + +void RadioReadFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xReadBuffer( 0, buffer, size ); +} + +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ) +{ + if( modem == MODEM_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + else + { + if( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + } +} + +void RadioSetPublicNetwork( bool enable ) +{ + RadioPublicNetwork.Current = RadioPublicNetwork.Previous = enable; + + RadioSetModem( MODEM_LORA ); + if( enable == true ) + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); + } + else + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); + } +} + +uint32_t RadioGetWakeupTime( void ) +{ + return( RADIO_TCXO_SETUP_TIME + RADIO_WAKEUP_TIME ); +} + +void RadioOnTxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } +} + +void RadioOnRxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } +} + +void RadioOnDioIrq( void ) +{ + IrqFired = true; +} + +void RadioIrqProcess( void ) +{ + // if( IrqFired == true ) + if(GetRadioDio1Pin()) + { + IrqFired = false; + + uint16_t irqRegs = SX126xGetIrqStatus( ); + SX126xClearIrqStatus( IRQ_RADIO_ALL ); + + if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) + { + RadioEvents->TxDone( ); + } + } + + if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) + { + uint8_t size; + + SX126xGetPayload( RadioRxPayload, &size , 255 ); + SX126xGetPacketStatus( &RadioPktStatus ); + if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) + { + RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt ); + } + } + + if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RadioEvents->RxError( ); + } + } + + if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + { + RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) ); + } + } + + if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) + { + if( SX126xGetOperatingMode( ) == MODE_TX ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } + } + else if( SX126xGetOperatingMode( ) == MODE_RX ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + } + + if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + } +} diff --git a/C8T6_TestApp2/Radio/src/sx126x-board.c b/C8T6_TestApp2/Radio/src/sx126x-board.c new file mode 100644 index 0000000..55d6954 --- /dev/null +++ b/C8T6_TestApp2/Radio/src/sx126x-board.c @@ -0,0 +1,216 @@ +/* + ______ _ + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + +Description: SX126x driver specific target board functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#include "stm32f0xx.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" + + +void SX126xReset( void ) +{ + HAL_Delay_nMS( 10 ); + SetRadionRSTPin_0(); + HAL_Delay_nMS( 20 ); + SetRadionRSTPin_1(); + HAL_Delay_nMS( 10 ); +} + +void SX126xWaitOnBusy( void ) +{ + while(GetRadioBusyPin()); +} + + +void SX126xWakeup( void ) +{ + SetRadioNSSPin_0(); + + SpiInOut(RADIO_GET_STATUS); + SpiInOut(0); + + SetRadioNSSPin_1(); + + // Wait for chip to be ready. + SX126xWaitOnBusy( ); +} + +void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) +{ + + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(( uint8_t )command ); + + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut(buffer[i] ); + } + + SetRadioNSSPin_1(); + + if( command != RADIO_SET_SLEEP ) + { + SX126xWaitOnBusy( ); + } +} + +void SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(( uint8_t )command ); + SpiInOut(0x00 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut(0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(RADIO_WRITE_REGISTER ); + SpiInOut(( address & 0xFF00 ) >> 8 ); + SpiInOut( address & 0x00FF ); + + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut(buffer[i] ); + } + + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xWriteRegister( uint16_t address, uint8_t value ) +{ + SX126xWriteRegisters( address, &value, 1 ); +} + +void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(RADIO_READ_REGISTER ); + SpiInOut(( address & 0xFF00 ) >> 8 ); + SpiInOut( address & 0x00FF ); + SpiInOut( 0 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut(0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +uint8_t SX126xReadRegister( uint16_t address ) +{ + uint8_t data; + SX126xReadRegisters( address, &data, 1 ); + return data; +} + +void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut( RADIO_WRITE_BUFFER ); + SpiInOut( offset ); + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut( buffer[i] ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut( RADIO_READ_BUFFER ); + SpiInOut( offset ); + SpiInOut( 0 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut( 0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xSetRfTxPower( int8_t power ) +{ + SX126xSetTxParams( power, RADIO_RAMP_40_US ); +} + +uint8_t SX126xGetPaSelect( uint32_t channel ) +{ +// if( GpioRead( &DeviceSel ) == 1 ) +// { +// return SX1261; +// } +// else +// { +// return SX1262; +// } + + return SX1262; +} + +void SX126xAntSwOn( void ) +{ + //GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 ); +} + +void SX126xAntSwOff( void ) +{ + // GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); +} + +bool SX126xCheckRfFrequency( uint32_t frequency ) +{ + // Implement check. Currently all frequencies are supported + return true; +} diff --git a/C8T6_TestApp2/Radio/src/sx126x.c b/C8T6_TestApp2/Radio/src/sx126x.c new file mode 100644 index 0000000..3c375a4 --- /dev/null +++ b/C8T6_TestApp2/Radio/src/sx126x.c @@ -0,0 +1,716 @@ +/*! + * \file sx126x.c + * + * \brief SX126x driver implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#include <math.h> +#include <string.h> +#include "sx126x.h" +#include "sx126x-board.h" +#include "delay.h" + +//#define USE_TCXO +/*! + * \brief Radio registers definition + */ +typedef struct +{ + uint16_t Addr; //!< The address of the register + uint8_t Value; //!< The value of the register +}RadioRegisters_t; + +/*! + * \brief Holds the internal operating mode of the radio + */ +static RadioOperatingModes_t OperatingMode; + +/*! + * \brief Stores the current packet type set in the radio + */ +static RadioPacketTypes_t PacketType; + +/*! + * \brief Stores the last frequency error measured on LoRa received packet + */ +volatile uint32_t FrequencyError = 0; + +/*! + * \brief Hold the status of the Image calibration + */ +static bool ImageCalibrated = false; + +/* + * SX126x DIO IRQ callback functions prototype + */ + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xOnDioIrq( void ); + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xSetPollingMode( void ); + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xSetInterruptMode( void ); + +/* + * \brief Process the IRQ if handled by the driver + */ +void SX126xProcessIrqs( void ); + + +void SX126xInit( DioIrqHandler dioIrq ) +{ + SX126xReset( ); + SX126xWakeup( ); + SX126xSetStandby( STDBY_RC ); + +#ifdef USE_TCXO + CalibrationParams_t calibParam; + + SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, RADIO_TCXO_SETUP_TIME << 6 ); // convert from ms to SX126x time base + calibParam.Value = 0x7F; + SX126xCalibrate( calibParam ); + +#endif + + SX126xSetDio2AsRfSwitchCtrl( true ); + OperatingMode = MODE_STDBY_RC; +} + +RadioOperatingModes_t SX126xGetOperatingMode( void ) +{ + return OperatingMode; +} + +void SX126xCheckDeviceReady( void ) +{ + if( ( SX126xGetOperatingMode( ) == MODE_SLEEP ) || ( SX126xGetOperatingMode( ) == MODE_RX_DC ) ) + { + SX126xWakeup( ); + // Switch is turned off when device is in sleep mode and turned on is all other modes + SX126xAntSwOn( ); + } + SX126xWaitOnBusy( ); +} + +void SX126xSetPayload( uint8_t *payload, uint8_t size ) +{ + SX126xWriteBuffer( 0x00, payload, size ); +} + +uint8_t SX126xGetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize ) +{ + uint8_t offset = 0; + + SX126xGetRxBufferStatus( size, &offset ); + if( *size > maxSize ) + { + return 1; + } + SX126xReadBuffer( offset, buffer, *size ); + return 0; +} + +void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ) +{ + SX126xSetPayload( payload, size ); + SX126xSetTx( timeout ); +} + +uint8_t SX126xSetSyncWord( uint8_t *syncWord ) +{ + SX126xWriteRegisters( REG_LR_SYNCWORDBASEADDRESS, syncWord, 8 ); + return 0; +} + +void SX126xSetCrcSeed( uint16_t seed ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( seed >> 8 ) & 0xFF ); + buf[1] = ( uint8_t )( seed & 0xFF ); + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + SX126xWriteRegisters( REG_LR_CRCSEEDBASEADDR, buf, 2 ); + break; + + default: + break; + } +} + +void SX126xSetCrcPolynomial( uint16_t polynomial ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( polynomial >> 8 ) & 0xFF ); + buf[1] = ( uint8_t )( polynomial & 0xFF ); + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + SX126xWriteRegisters( REG_LR_CRCPOLYBASEADDR, buf, 2 ); + break; + + default: + break; + } +} + +void SX126xSetWhiteningSeed( uint16_t seed ) +{ + uint8_t regValue = 0; + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + regValue = SX126xReadRegister( REG_LR_WHITSEEDBASEADDR_MSB ) & 0xFE; + regValue = ( ( seed >> 8 ) & 0x01 ) | regValue; + SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit. + SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_LSB, ( uint8_t )seed ); + break; + + default: + break; + } +} + +uint32_t SX126xGetRandom( void ) +{ + uint8_t buf[] = { 0, 0, 0, 0 }; + + // Set radio in continuous reception + SX126xSetRx( 0 ); + + HAL_Delay_nMS( 1 ); + + SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, buf, 4 ); + + SX126xSetStandby( STDBY_RC ); + + return ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3]; +} + +void SX126xSetSleep( SleepParams_t sleepConfig ) +{ + SX126xAntSwOff( ); + + SX126xWriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 ); + OperatingMode = MODE_SLEEP; +} + +void SX126xSetStandby( RadioStandbyModes_t standbyConfig ) +{ + SX126xWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 ); + if( standbyConfig == STDBY_RC ) + { + OperatingMode = MODE_STDBY_RC; + } + else + { + OperatingMode = MODE_STDBY_XOSC; + } +} + +void SX126xSetFs( void ) +{ + SX126xWriteCommand( RADIO_SET_FS, 0, 0 ); + OperatingMode = MODE_FS; +} + +void SX126xSetTx( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_TX; + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_TX, buf, 3 ); +} + +void SX126xSetRx( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_RX; + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); +} + +void SX126xSetRxBoosted( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_RX; + + SX126xWriteRegister( REG_RX_GAIN, 0x96 ); // max LNA gain, increase current by ~2mA for around ~3dB in sensivity + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); +} + +void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) +{ + uint8_t buf[6]; + + buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( rxTime & 0xFF ); + buf[3] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF ); + buf[4] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF ); + buf[5] = ( uint8_t )( sleepTime & 0xFF ); + SX126xWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 ); + OperatingMode = MODE_RX_DC; +} + +void SX126xSetCad( void ) +{ + SX126xWriteCommand( RADIO_SET_CAD, 0, 0 ); + OperatingMode = MODE_CAD; +} + +void SX126xSetTxContinuousWave( void ) +{ + SX126xWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 ); +} + +void SX126xSetTxInfinitePreamble( void ) +{ + SX126xWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 ); +} + +void SX126xSetStopRxTimerOnPreambleDetect( bool enable ) +{ + SX126xWriteCommand( RADIO_SET_STOPRXTIMERONPREAMBLE, ( uint8_t* )&enable, 1 ); +} + +void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ) +{ + SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, &SymbNum, 1 ); +} + +void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ) +{ + SX126xWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 ); +} + +void SX126xCalibrate( CalibrationParams_t calibParam ) +{ + SX126xWriteCommand( RADIO_CALIBRATE, ( uint8_t* )&calibParam, 1 ); +} + +void SX126xCalibrateImage( uint32_t freq ) +{ + uint8_t calFreq[2]; + + if( freq > 900000000 ) + { + calFreq[0] = 0xE1; + calFreq[1] = 0xE9; + } + else if( freq > 850000000 ) + { + calFreq[0] = 0xD7; + calFreq[1] = 0xD8; + } + else if( freq > 770000000 ) + { + calFreq[0] = 0xC1; + calFreq[1] = 0xC5; + } + else if( freq > 460000000 ) + { + calFreq[0] = 0x75; + calFreq[1] = 0x81; + } + else if( freq > 425000000 ) + { + calFreq[0] = 0x6B; + calFreq[1] = 0x6F; + } + SX126xWriteCommand( RADIO_CALIBRATEIMAGE, calFreq, 2 ); +} + +void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ) +{ + uint8_t buf[4]; + + buf[0] = paDutyCycle; + buf[1] = hpMax; + buf[2] = deviceSel; + buf[3] = paLut; + SX126xWriteCommand( RADIO_SET_PACONFIG, buf, 4 ); +} + +void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ) +{ + SX126xWriteCommand( RADIO_SET_TXFALLBACKMODE, &fallbackMode, 1 ); +} + +void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ) +{ + uint8_t buf[8]; + + buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF ); + buf[1] = ( uint8_t )( irqMask & 0x00FF ); + buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF ); + buf[3] = ( uint8_t )( dio1Mask & 0x00FF ); + buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF ); + buf[5] = ( uint8_t )( dio2Mask & 0x00FF ); + buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF ); + buf[7] = ( uint8_t )( dio3Mask & 0x00FF ); + SX126xWriteCommand( RADIO_CFG_DIOIRQ, buf, 8 ); +} + +uint16_t SX126xGetIrqStatus( void ) +{ + uint8_t irqStatus[2]; + + SX126xReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 ); + return ( irqStatus[0] << 8 ) | irqStatus[1]; +} + +void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ) +{ + SX126xWriteCommand( RADIO_SET_RFSWITCHMODE, &enable, 1 ); +} + +void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ) +{ + uint8_t buf[4]; + + buf[0] = tcxoVoltage & 0x07; + buf[1] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[2] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[3] = ( uint8_t )( timeout & 0xFF ); + + SX126xWriteCommand( RADIO_SET_TCXOMODE, buf, 4 ); +} + +void SX126xSetRfFrequency( uint32_t frequency ) +{ + uint8_t buf[4]; + uint32_t freq = 0; + + if( ImageCalibrated == false ) + { + SX126xCalibrateImage( frequency ); + ImageCalibrated = true; + } + + freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP ); + buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF ); + buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + buf[3] = ( uint8_t )( freq & 0xFF ); + SX126xWriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 ); +} + +void SX126xSetPacketType( RadioPacketTypes_t packetType ) +{ + // Save packet type internally to avoid questioning the radio + PacketType = packetType; + SX126xWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 ); +} + +RadioPacketTypes_t SX126xGetPacketType( void ) +{ + return PacketType; +} + +void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ) +{ + uint8_t buf[2]; + + if( SX126xGetPaSelect( 0 ) == SX1261 ) + { + if( power == 15 ) + { + SX126xSetPaConfig( 0x06, 0x00, 0x01, 0x01 ); + } + else + { + SX126xSetPaConfig( 0x04, 0x00, 0x01, 0x01 ); + } + if( power >= 14 ) + { + power = 14; + } + else if( power < -3 ) + { + power = -3; + } + SX126xWriteRegister( REG_OCP, 0x18 ); // current max is 80 mA for the whole device + } + else // sx1262 + { + SX126xSetPaConfig( 0x04, 0x07, 0x00, 0x01 ); + if( power > 22 ) + { + power = 22; + } + else if( power < -3 ) + { + power = -3; + } + SX126xWriteRegister( REG_OCP, 0x38 ); // current max 160mA for the whole device + } + buf[0] = power; + buf[1] = ( uint8_t )rampTime; + SX126xWriteCommand( RADIO_SET_TXPARAMS, buf, 2 ); +} + +void SX126xSetModulationParams( ModulationParams_t *modulationParams ) +{ + uint8_t n; + uint32_t tempVal = 0; + uint8_t buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if( PacketType != modulationParams->PacketType ) + { + SX126xSetPacketType( modulationParams->PacketType ); + } + + switch( modulationParams->PacketType ) + { + case PACKET_TYPE_GFSK: + n = 8; + tempVal = ( uint32_t )( 32 * ( ( double )XTAL_FREQ / ( double )modulationParams->Params.Gfsk.BitRate ) ); + buf[0] = ( tempVal >> 16 ) & 0xFF; + buf[1] = ( tempVal >> 8 ) & 0xFF; + buf[2] = tempVal & 0xFF; + buf[3] = modulationParams->Params.Gfsk.ModulationShaping; + buf[4] = modulationParams->Params.Gfsk.Bandwidth; + tempVal = ( uint32_t )( ( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP ); + buf[5] = ( tempVal >> 16 ) & 0xFF; + buf[6] = ( tempVal >> 8 ) & 0xFF; + buf[7] = ( tempVal& 0xFF ); + SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); + break; + case PACKET_TYPE_LORA: + n = 4; + buf[0] = modulationParams->Params.LoRa.SpreadingFactor; + buf[1] = modulationParams->Params.LoRa.Bandwidth; + buf[2] = modulationParams->Params.LoRa.CodingRate; + buf[3] = modulationParams->Params.LoRa.LowDatarateOptimize; + + SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); + + break; + default: + case PACKET_TYPE_NONE: + return; + } +} + +void SX126xSetPacketParams( PacketParams_t *packetParams ) +{ + uint8_t n; + uint8_t crcVal = 0; + uint8_t buf[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if( PacketType != packetParams->PacketType ) + { + SX126xSetPacketType( packetParams->PacketType ); + } + + switch( packetParams->PacketType ) + { + case PACKET_TYPE_GFSK: + if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_IBM ) + { + SX126xSetCrcSeed( CRC_IBM_SEED ); + SX126xSetCrcPolynomial( CRC_POLYNOMIAL_IBM ); + crcVal = RADIO_CRC_2_BYTES; + } + else if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_CCIT ) + { + SX126xSetCrcSeed( CRC_CCITT_SEED ); + SX126xSetCrcPolynomial( CRC_POLYNOMIAL_CCITT ); + crcVal = RADIO_CRC_2_BYTES_INV; + } + else + { + crcVal = packetParams->Params.Gfsk.CrcLength; + } + n = 9; + buf[0] = ( packetParams->Params.Gfsk.PreambleLength >> 8 ) & 0xFF; + buf[1] = packetParams->Params.Gfsk.PreambleLength; + buf[2] = packetParams->Params.Gfsk.PreambleMinDetect; + buf[3] = ( packetParams->Params.Gfsk.SyncWordLength /*<< 3*/ ); // convert from byte to bit + buf[4] = packetParams->Params.Gfsk.AddrComp; + buf[5] = packetParams->Params.Gfsk.HeaderType; + buf[6] = packetParams->Params.Gfsk.PayloadLength; + buf[7] = crcVal; + buf[8] = packetParams->Params.Gfsk.DcFree; + break; + case PACKET_TYPE_LORA: + n = 6; + buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF; + buf[1] = packetParams->Params.LoRa.PreambleLength; + buf[2] = packetParams->Params.LoRa.HeaderType; + buf[3] = packetParams->Params.LoRa.PayloadLength; + buf[4] = packetParams->Params.LoRa.CrcMode; + buf[5] = packetParams->Params.LoRa.InvertIQ; + break; + default: + case PACKET_TYPE_NONE: + return; + } + SX126xWriteCommand( RADIO_SET_PACKETPARAMS, buf, n ); +} + +void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ) +{ + uint8_t buf[7]; + + buf[0] = ( uint8_t )cadSymbolNum; + buf[1] = cadDetPeak; + buf[2] = cadDetMin; + buf[3] = ( uint8_t )cadExitMode; + buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF ); + buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF ); + buf[6] = ( uint8_t )( cadTimeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 5 ); + OperatingMode = MODE_CAD; +} + +void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ) +{ + uint8_t buf[2]; + + buf[0] = txBaseAddress; + buf[1] = rxBaseAddress; + SX126xWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); +} + +RadioStatus_t SX126xGetStatus( void ) +{ + uint8_t stat = 0; + RadioStatus_t status; + + SX126xReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 ); + status.Value = stat; + return status; +} + +int8_t SX126xGetRssiInst( void ) +{ + uint8_t buf[1]; + int8_t rssi = 0; + + SX126xReadCommand( RADIO_GET_RSSIINST, buf, 1 ); + rssi = -buf[0] >> 1; + return rssi; +} + +void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer ) +{ + uint8_t status[2]; + + SX126xReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 ); + + // In case of LORA fixed header, the payloadLength is obtained by reading + // the register REG_LR_PAYLOADLENGTH + if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( SX126xReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) ) + { + *payloadLength = SX126xReadRegister( REG_LR_PAYLOADLENGTH ); + } + else + { + *payloadLength = status[0]; + } + *rxStartBufferPointer = status[1]; +} + +void SX126xGetPacketStatus( PacketStatus_t *pktStatus ) +{ + uint8_t status[3]; + + SX126xReadCommand( RADIO_GET_PACKETSTATUS, status, 3 ); + + pktStatus->packetType = SX126xGetPacketType( ); + switch( pktStatus->packetType ) + { + case PACKET_TYPE_GFSK: + pktStatus->Params.Gfsk.RxStatus = status[0]; + pktStatus->Params.Gfsk.RssiSync = -status[1] >> 1; + pktStatus->Params.Gfsk.RssiAvg = -status[2] >> 1; + pktStatus->Params.Gfsk.FreqError = 0; + break; + + case PACKET_TYPE_LORA: + pktStatus->Params.LoRa.RssiPkt = -status[0] >> 1; + ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] >> 2 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) >> 2 ) ); + pktStatus->Params.LoRa.SignalRssiPkt = -status[2] >> 1; + pktStatus->Params.LoRa.FreqError = FrequencyError; + break; + + default: + case PACKET_TYPE_NONE: + // In that specific case, we set everything in the pktStatus to zeros + // and reset the packet type accordingly + memset( pktStatus, 0, sizeof( PacketStatus_t ) ); + pktStatus->packetType = PACKET_TYPE_NONE; + break; + } +} + +RadioError_t SX126xGetDeviceErrors( void ) +{ + RadioError_t error; + + SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t * )&error, 2 ); + return error; +} + +void SX126xClearDeviceErrors( void ) +{ + uint8_t buf[2] = { 0x00, 0x00 }; + SX126xWriteCommand( RADIO_CLR_ERROR, buf, 2 ); +} + +void SX126xClearIrqStatus( uint16_t irq ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF ); + buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF ); + SX126xWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 ); +} diff --git a/C8T6_TestApp2/Src/ADC.c b/C8T6_TestApp2/Src/ADC.c new file mode 100644 index 0000000..bc1e2ce --- /dev/null +++ b/C8T6_TestApp2/Src/ADC.c @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * @file : ADC.c + * @brief : ADC functions program body + ****************************************************************************** + */ +#include "ADC.h" +#include "globaldef.h" +#include "functions.h" +#include "string.h" +#include "modbusRTU.h" + +#include "stm32f0xx_hal.h" + +#define ADCrefAddr 0x1FFFF7BA + + +#define AVGCount 8 + +int nCount6 = 0; +unsigned short ADC_TEMPs[16] ={0}; + +int ADCProcess2() +{ + // ADC channels + // 0 -- --> 0 + // 1 -- --> 1 + // 2 -- + // 3 -- + // 4 -- IN1 ->4 + // 5 -- TEMP ->5 + // 6 -- AC_CURRENT ->6 + // 7 -- + // 8 -- + // --> 5 + // 16 -- Temp --> 16 + // 17 -- Vref --> 17 + + + +uint16_t ADC_ConvertedValue=0; +static int CurChannel=LL_ADC_CHANNEL_0; +//static int waitcount = 0; + + if (!LL_ADC_REG_IsConversionOngoing(ADC1)) + { + //waitcount++; + //if (waitcount<2) return 0; + //waitcount=0; + ADC_ConvertedValue = LL_ADC_REG_ReadConversionData12(ADC1); + + // ADC_RegularChannelConfig(LL_ADC_CHANNEL_17,); + int channels = CurChannel ;//LL_ADC_REG_GetSequencerChannels(ADC1); + int nextchannel = LL_ADC_CHANNEL_0; + if ((channels & LL_ADC_CHANNEL_0) == LL_ADC_CHANNEL_0) + { + KMem.ADCValues[0] = ADC_ConvertedValue; + nextchannel = LL_ADC_CHANNEL_4; + } + else if ((channels & LL_ADC_CHANNEL_4) == LL_ADC_CHANNEL_4) + { + ADC_TEMPs[0] += ADC_ConvertedValue; + + + nextchannel = LL_ADC_CHANNEL_5; + } + else if ((channels & LL_ADC_CHANNEL_5) == LL_ADC_CHANNEL_5) + { + ADC_TEMPs[1] += ADC_ConvertedValue; + + nCount6++; + + if (nCount6 >= AVGCount) { + + KMem.ADCValues[3] = ADC_TEMPs[0]/AVGCount; + + KMem.ADCValues[4] = ADC_TEMPs[1]/AVGCount; + ADC_TEMPs[0]=0; + ADC_TEMPs[1]=0; + nCount6 = 0 ; + + } + // KMem.ADCValues[3] = 255;//ADC_TEMP[0]/16; + // KMem.ADCValues[4] = 768; //ADC_TEMP[1]/16; + nextchannel = LL_ADC_CHANNEL_6; + + }else if ((channels & LL_ADC_CHANNEL_6) == LL_ADC_CHANNEL_6) + { + KMem.ADCValues[6] = ADC_ConvertedValue; + nextchannel = LL_ADC_CHANNEL_TEMPSENSOR; + + }else if ((channels & LL_ADC_CHANNEL_16) == LL_ADC_CHANNEL_16) + { + KMem.ADCValues[16] = ADC_ConvertedValue; + nextchannel = LL_ADC_CHANNEL_VREFINT; + }else if ((channels & LL_ADC_CHANNEL_17) == LL_ADC_CHANNEL_17) + { + KMem.ADCValues[17] = ADC_ConvertedValue; + KMem.ADCValues[18] = *((unsigned short *)ADCrefAddr); + KMem.ADCValues[19] = *((unsigned short *)ADCrefAddr); + + nextchannel = LL_ADC_CHANNEL_0; + }else + { + //ADCValues[0] = ADC_ConvertedValue; + } + //nextchannel = LL_ADC_CHANNEL_VREFINT; + LL_ADC_REG_SetSequencerChannels(ADC1,nextchannel); + LL_ADC_REG_StartConversion(ADC1); + CurChannel = nextchannel; + } + return 0; +} + + diff --git a/C8T6_TestApp2/Src/BSP_UltraSonic.c b/C8T6_TestApp2/Src/BSP_UltraSonic.c new file mode 100644 index 0000000..c8189b7 --- /dev/null +++ b/C8T6_TestApp2/Src/BSP_UltraSonic.c @@ -0,0 +1,1099 @@ +/** + ****************************************************************************** + * @file : BSP.c + * @brief : Board Speciafic program + ****************************************************************************** + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "BSP_UltraSonic.h" + +#include "Globaldef.h" +#include "Functions.h" +#if (BOARD_TYPE == 14) +#include "fpx.h" +#endif + +/** + * @brief System Clock Configuration + * @retval None + */ + +void SystemClock_Config_New(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); + + if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1) + { + Error_Handler(); + } + LL_RCC_HSE_Enable(); + + /* Wait till HSE is ready */ + while(LL_RCC_HSE_IsReady() != 1) { } + + + LL_RCC_HSI14_Enable(); + + /* Wait till HSI14 is ready */ + while(LL_RCC_HSI14_IsReady() != 1) { } + LL_RCC_HSI14_SetCalibTrimming(16); +// return ; + + + LL_RCC_LSI_Enable(); + /* Wait till LSI is ready */ +// while(LL_RCC_LSI_IsReady() != 1) { } + +#if (XLAT_FREQ == 12) + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_3, LL_RCC_PLL_MUL_12); +#else + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_2, LL_RCC_PLL_MUL_12); + +// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_12); +#endif + LL_RCC_PLL_Enable(); + + /* Wait till PLL is ready */ + while(LL_RCC_PLL_IsReady() != 1) { } + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + + /* Wait till System clock is ready */ + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { } + + LL_Init1msTick(48000000); // LL_InitTick(48000000,10000); + LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK); + LL_SetSystemCoreClock(48000000); + LL_RCC_HSI14_EnableADCControl(); + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1); + + +// LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK); + +// HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); + +// SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; + +// LL_SetSystemCoreClock(48000000); +// LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1); + +} + + +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; +// RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + +#if (XLAT_FREQ == 12) + RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV3; +#else + RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2; +#endif + + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + Error_Handler(); + } + + //RCC_OscInitTypeDef RCC_OscInitStruct; + //RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInit; + + /**Initializes the CPU, AHB and APB busses clocks + */ + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; + PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK; + + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the Systick interrupt time + */ +// HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/10000); + HAL_SYSTICK_Config(48000000/1000); + + /**Configure the Systick + */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); +} + +void MX_IWDG_Init(void) +{ + + /* USER CODE BEGIN IWDG_Init 0 */ + + /* USER CODE END IWDG_Init 0 */ + + /* USER CODE BEGIN IWDG_Init 1 */ + + /* USER CODE END IWDG_Init 1 */ + LL_IWDG_Enable(IWDG); + LL_IWDG_EnableWriteAccess(IWDG); + LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_64); + LL_IWDG_SetReloadCounter(IWDG, 4095); + while (LL_IWDG_IsReady(IWDG) != 1) + { + } + + LL_IWDG_SetWindow(IWDG, 4095); + LL_IWDG_ReloadCounter(IWDG); + /* USER CODE BEGIN IWDG_Init 2 */ + + /* USER CODE END IWDG_Init 2 */ + +} +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1); + + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1713; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM1, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM1); + LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 857; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + + + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH4); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 856; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct); + + + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH4); + LL_TIM_SetTriggerInput(TIM1, LL_TIM_TS_ITR0); + LL_TIM_SetSlaveMode(TIM1, LL_TIM_SLAVEMODE_RESET); + LL_TIM_DisableIT_TRIG(TIM1); + LL_TIM_DisableDMAReq_TRIG(TIM1); + LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM1); + + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 80; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct); + + + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + /**TIM1 GPIO Configuration + PB13 ------> TIM1_CH1N + PA8 ------> TIM1_CH1 + PA11 ------> TIM1_CH4 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + +} +/** + * @brief TIM6 Initialization Function + * @param None + * @retval None + */ +void MX_TIM6_Init(void) +{ + + /* USER CODE BEGIN TIM6_Init 0 */ + + /* USER CODE END TIM6_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM6); + + /* TIM6 interrupt Init */ + NVIC_SetPriority(TIM6_IRQn, 0); + NVIC_EnableIRQ(TIM6_IRQn); + + /* USER CODE BEGIN TIM6_Init 1 */ + + /* USER CODE END TIM6_Init 1 */ + TIM_InitStruct.Prescaler = 47; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 999; + LL_TIM_Init(TIM6, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM6); + /* USER CODE BEGIN TIM6_Init 2 */ + LL_TIM_EnableIT_UPDATE(TIM6); + /* USER CODE END TIM6_Init 2 */ + +} + +/** + * @brief TIM14 Initialization Function + * @param None + * @retval None + */ +void MX_TIM14_Init(void) +{ + + /* USER CODE BEGIN TIM14_Init 0 */ + + /* USER CODE END TIM14_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM14); + + /* USER CODE BEGIN TIM14_Init 1 */ + + /* USER CODE END TIM14_Init 1 */ + TIM_InitStruct.Prescaler = 2; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 2400; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM14, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM14); + /* USER CODE BEGIN TIM14_Init 2 */ + + /* USER CODE END TIM14_Init 2 */ + +} + +/** + * @brief TIM15 Initialization Function + * @param None + * @retval None + */ +void MX_TIM15_Init(void) +{ + + /* USER CODE BEGIN TIM15_Init 0 */ + + /* USER CODE END TIM15_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM15); + + /* USER CODE BEGIN TIM15_Init 1 */ + + /* USER CODE END TIM15_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1713; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM15, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM15); + LL_TIM_SetClockSource(TIM15, LL_TIM_CLOCKSOURCE_INTERNAL); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 856; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_LOW; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM15, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM15, LL_TIM_CHANNEL_CH1); + + LL_TIM_OC_EnablePreload(TIM15, LL_TIM_CHANNEL_CH2); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 100; + LL_TIM_OC_Init(TIM15, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM15, LL_TIM_CHANNEL_CH2); + LL_TIM_SetTriggerOutput(TIM15, LL_TIM_TRGO_OC2REF); + LL_TIM_DisableMasterSlaveMode(TIM15); + + + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 20; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM15, &TIM_BDTRInitStruct); + /* USER CODE BEGIN TIM15_Init 2 */ + + /* USER CODE END TIM15_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**TIM15 GPIO Configuration + PB14 ------> TIM15_CH1 + PB15 ------> TIM15_CH1N + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_3; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +} + +/** + * @brief TIM16 Initialization Function + * @param None + * @retval None + */ +void MX_TIM16_Init(void) +{ + + /* USER CODE BEGIN TIM16_Init 0 */ + + /* USER CODE END TIM16_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM16); + /* TIM6 interrupt Init */ + NVIC_SetPriority(TIM16_IRQn, 0); + NVIC_EnableIRQ(TIM16_IRQn); + + /* USER CODE BEGIN TIM16_Init 1 */ + + /* USER CODE END TIM16_Init 1 */ + TIM_InitStruct.Prescaler = 100; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1417; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM16, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM16); + + LL_TIM_OC_EnablePreload(TIM16, LL_TIM_CHANNEL_CH1); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_TOGGLE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 500; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM16, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM16, LL_TIM_CHANNEL_CH1); + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 6; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM16, &TIM_BDTRInitStruct); + + /* USER CODE BEGIN TIM16_Init 2 */ + + /* USER CODE END TIM16_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**TIM16 GPIO Configuration + PA6 ------> TIM16_CH1 + PB6 ------> TIM16_CH1N + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_5; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_TIM_EnableIT_UPDATE(TIM16); +} + + +/* ADC init function */ +void MX_ADC_Init(void) +{ + + LL_ADC_InitTypeDef ADC_InitStruct; + LL_ADC_REG_InitTypeDef ADC_REG_InitStruct; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1); + + /**Configure Regular Channel + */ + LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_0|LL_ADC_CHANNEL_1); + + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_TEMPSENSOR|LL_ADC_PATH_INTERNAL_VREFINT); + + /**Configure Regular Channel + */ + LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_TEMPSENSOR|LL_ADC_CHANNEL_VREFINT); + + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_TEMPSENSOR|LL_ADC_PATH_INTERNAL_VREFINT); + + /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + ADC_InitStruct.Clock = LL_ADC_CLOCK_ASYNC; + ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; + LL_ADC_Init(ADC1, &ADC_InitStruct); + + ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE; + ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_LIMITED; + ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; + LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); + + LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD); + + LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_28CYCLES_5); + + LL_ADC_EnableIT_EOC(ADC1); + + LL_ADC_DisableIT_EOS(ADC1); + + LL_ADC_StartCalibration(ADC1); + +// LL_ADC_EnableInternalRegulator(ADC1); + +// ADC_TempSensorCmd(ENABLE);//????????? +// ADC_VrefintCmd(ENABLE); //???????? + + + //ADC_TempSensorCmd(ENABLE);// + //ADC_ChannelConfig(); + //ADC_VrefintCmd(ENABLE); // + + while( LL_ADC_IsCalibrationOnGoing(ADC1)); + LL_ADC_Enable(ADC1); +/* + LL_ADC_REG_SetDMATransfer(ADC1,LL_ADC_REG_DMA_TRANSFER_UNLIMITED); + LL_ADC_REG_StartConversion(ADC1); +*/ +} + +/* SPI1 init function */ +void MX_SPI1_Init(void) +{ + + LL_SPI_InitTypeDef SPI_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SPI1); + + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ +// GPIO_InitStruct.Pin = LL_GPIO_PIN_5; +// GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; +// GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; +// GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; +// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; +// LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = LL_GPIO_PIN_6; +// GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; +// GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; +// GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; +// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; +// LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = LL_GPIO_PIN_7; +// GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; +// GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; +// GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; +// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; +// LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**SPI1 GPIO Configuration + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +/* + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_5); +*/ + +/* + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); +*/ + /* SPI1 interrupt Init */ + NVIC_SetPriority(SPI1_IRQn, 0); +// NVIC_EnableIRQ(SPI1_IRQn); + /* USER CODE BEGIN SPI1_Init 1 */ + +#if (BOARD_TYPE == 13 || BOARD_TYPE == 9) + + NVIC_EnableIRQ(SPI1_IRQn); + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH; //LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE ; //LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI1, &SPI_InitStruct); + + LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA); + + LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER); +// LL_SPI_EnableNSSPulseMgt(SPI1); + +#elif (BOARD_TYPE == 14) + + NVIC_EnableIRQ(SPI1_IRQn); + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_SLAVE; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; //LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE ; //LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; + SPI_InitStruct.BitOrder = LL_SPI_LSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI1, &SPI_InitStruct); + + LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA); + LL_SPI_DisableNSSPulseMgt(SPI1); + LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER); +// LL_SPI_EnableNSSPulseMgt(SPI1); + LL_SPI_EnableIT_RXNE(SPI1); + +#elif (BOARD_TYPE == 15 || BOARD_TYPE == 16) + + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI1, &SPI_InitStruct); + + LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA); + + LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER); +// LL_SPI_EnableNSSPulseMgt(SPI1); + +#else + + /* USER CODE END SPI1_Init 1 */ + + /* SPI1 parameter configuration*/ + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI1, &SPI_InitStruct); + + LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA); + + LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER); +// LL_SPI_EnableNSSPulseMgt(SPI1); + + /* USER CODE BEGIN SPI1_Init 2 */ + +#endif + + LL_SPI_Enable(SPI1); + /* USER CODE END SPI1_Init 2 */ +} + +/* SPI2 init function */ +void MX_SPI2_Init(void) +{ + + LL_SPI_InitTypeDef SPI_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**SPI2 GPIO Configuration + PB13 ------> SPI2_SCK + PB14 ------> SPI2_MISO + PB15 ------> SPI2_MOSI + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* SPI2 interrupt Init */ + //NVIC_SetPriority(SPI2_IRQn, 0); + //NVIC_EnableIRQ(SPI2_IRQn); + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ + + /* SPI2 parameter configuration*/ + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; //LL_SPI_POLARITY_HIGH;//LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; //LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI2, &SPI_InitStruct); + LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA); + LL_SPI_EnableNSSPulseMgt(SPI2); + /* USER CODE BEGIN SP21_Init 2 */ + LL_SPI_Enable(SPI2); + /* USER CODE END SPI2_Init 2 */ +} + +void Soft_I2C1_Init(void) +{ + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_6|LL_GPIO_PIN_7); + GPIO_InitStruct.Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_6 | LL_GPIO_PIN_7); + +} + +/* USART1 init function */ +void MX_USART1_UART_Init(void) +{ + + LL_USART_InitTypeDef USART_InitStruct; + + LL_GPIO_InitTypeDef GPIO_InitStruct; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1); + + /**USART1 GPIO Configuration + // PA1 ------> USART1_DE + PA9 ------> USART1_TX + PA10 ------> USART1_RX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USART1 DMA Init */ + + /* USART1_TX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_BYTE); + + /* USART1_RX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE); + + /* USART1 interrupt Init */ + NVIC_SetPriority(USART1_IRQn, 0); + NVIC_EnableIRQ(USART1_IRQn); + + USART_InitStruct.BaudRate = Uart1Baud; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); +// LL_USART_EnableDEMode(USART1); +// LL_USART_SetDESignalPolarity(USART1, LL_USART_DE_POLARITY_LOW); +// LL_USART_SetDEAssertionTime(USART1, 1); +// LL_USART_SetDEDeassertionTime(USART1, 1); +// LL_USART_EnableOneBitSamp(USART1); + +#if (USART1_AUTO_BAUDRATE == 1) + LL_USART_EnableAutoBaudRate(USART1); + LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); +#endif + + LL_USART_DisableOverrunDetect(USART1); + LL_USART_ConfigAsyncMode(USART1); + LL_USART_Enable(USART1); +} + + +/* USART2 init function */ +void MX_USART2_UART_Init(void) +{ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + + /**USART2 GPIO Configuration + PA1 ------> USART2_DE + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + + GPIO_InitStruct.Pin = LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +#if (USART2_USE_HARDWARE_DE == 1) + +#else + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +#endif + + /* USART2 DMA Init */ + + /* USART2_TX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MDATAALIGN_BYTE); + + /* USART2_RX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_5, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PRIORITY_LOW); + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MODE_NORMAL); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PDATAALIGN_BYTE); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MDATAALIGN_BYTE); + + /* USART2 interrupt Init */ + NVIC_SetPriority(USART2_IRQn, 0); + NVIC_EnableIRQ(USART2_IRQn); + + NVIC_SetPriority(PendSV_IRQn, 255); + NVIC_EnableIRQ(PendSV_IRQn); +// NVIC_SetPendingIRQ(PendSV_IRQn); + + USART_InitStruct.BaudRate = Uart2Baud; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_8; + LL_USART_Init(USART2, &USART_InitStruct); + +#if (USART2_USE_HARDWARE_DE == 1) + + LL_USART_EnableDEMode(USART2); + LL_USART_SetDESignalPolarity(USART2, LL_USART_DE_POLARITY_LOW); +// LL_USART_SetDESignalPolarity(USART2, LL_USART_DE_POLARITY_HIGH); + LL_USART_SetDEAssertionTime(USART2, 15); + LL_USART_SetDEDeassertionTime(USART2, 15); +#else + +#endif + +// LL_USART_EnableOneBitSamp(USART2); +// LL_USART_EnableAutoBaudRate(USART2); +// LL_USART_SetAutoBaudRateMode(USART2, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + LL_USART_DisableOverrunDetect(USART2); + LL_USART_ConfigAsyncMode(USART2); + LL_USART_Enable(USART2); +} + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + /* Init with LL driver */ + /* DMA controller clock enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); + + /* DMA interrupt init */ + /* DMA1_Channel2_3_IRQn interrupt configuration */ + NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0); + NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + NVIC_SetPriority(DMA1_Channel4_5_IRQn, 0); + NVIC_EnableIRQ(DMA1_Channel4_5_IRQn); +} + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI +*/ +void MX_GPIO_Init(void) +{ + + LL_GPIO_InitTypeDef GPIO_InitStruct; + + /* GPIO Ports Clock Enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOF); + /**/ + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6 |LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_7 ; + GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + + GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + // RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE ); +// PWR_BackupAccessCmd( ENABLE );/* ????RTC??????*/ +// RCC_LSEConfig( RCC_LSE_OFF ); /* ????????,PC14+PC15??????IO*/ + // BKP_TamperPinCmd(DISABLE); /* ????????,PC13??????IO*/ + + + +} + + diff --git a/C8T6_TestApp2/Src/BoardType.c b/C8T6_TestApp2/Src/BoardType.c new file mode 100644 index 0000000..8a91b2c --- /dev/null +++ b/C8T6_TestApp2/Src/BoardType.c @@ -0,0 +1,95 @@ +#include "BoardType.h" +#include "KMachine.h" +#include "KBus.h" + +extern int __Vectors; + +#define APP_ADDR 0x08001000 //应用程序首地址定义 (int)(unsigned char *)(&__Vectors) +#define APPINFOBLOCK_ADDR (APP_ADDR + 0x100) //程序信息块 地址 +#define INFOBLOCK_ADDR (APP_ADDR + 0x1000) //信息块 地址 + +#define APP_START_ADDR IROM1_START_ADDRESS +extern int Region$$Table$$Limit; + +#define MAKE_VER(x,y) ((x<<8)|y) +#define APP_VER MAKE_VER(1,18) + +const stAppInfoBlock AppInfoBlock __attribute__((at(APPINFOBLOCK_ADDR))) = +{ + 0xAA55, // StartSign + 0x0301, // BlockType + sizeof(stAppInfoBlock), //BlockSize + 0, // Pad, + APP_VER, //AppVer + (BOARD_TYPE<<8) + BOARD_VER, //AppDevice; + 0x1000, //AppSize; + 0x0C00, //AppDataSize; + APP_ADDR, //nAppStartAddr + (int)&Region$$Table$$Limit, //nBtldr_NewAppInfoAddr + 0x08009000, //nBtldr_NewAppAddr + 0xCCCC, //crc16; + 0xAA55 //EndSign; + +}; + + +const stKMInfoBlock KMInfoBlock __attribute__((at(INFOBLOCK_ADDR))) = +{ +// sizeof(stKMInfoBlock), + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceType BOARD_VER, //nDevieVer + APP_VER, //ProgVer + 0x0102, //KLinkVer + KBUS_VER, //KBusVer +// 0x0100, //KNetVer +// 0x0100, //KWLVer + + 4, //nCapacity1 ?K + 1, //nCapacity2 ?k + + DINPUT, //nDInput; + DOUTPUT, //nDOutput + + 0, //nAInput + 0, //nAOutput + 0, //nHInput + 0, //nHOutput + 0, //nExt1; + 0, //nExt2; + 0, //nLogSize; + 2, //nPorts; + 0, //nManSize; + 0, //nAbility; + 6, //nSwitchBits; +}; + + +const stDeviceInfo MyDeviceInfo={ + + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceTypeVer // unsigned short ClientType; // 子机类型 + APP_VER, //ProgVer // unsigned short ClientVer; // 子机版本 + + DINPUT, // unsigned char InBitCount; // 输入开关量数量 + DOUTPUT, // unsigned char OutBitCount; // 输出开关量数量 + 0, // unsigned char InDWCount; // 输入数据字数 + 0, // unsigned char OutDWCount; // 输出数据字数 + 0, // unsigned char AIWCount; // 输入模拟量通道(字)数 // 16位为一个字(通道) + 0, // unsigned char AQWCount; // 输出模拟量通道(字)数 // 16位为一个字(通道) +// 0, // unsigned char AIBits; // 每通道位数 // 16位以下 +// 0, // unsigned char AQbits; // 每通道位数 // 16位以下 +}; + +const stExDeviceInfo MyExDeviceInfo ={ + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceTypeVer // unsigned short ClientType; // 子机类型 + APP_VER, //ProgVer // unsigned short ClientVer; // 子机版本 + + DINPUT, // unsigned char InBitCount; // 输入开关量数量 + DOUTPUT, // unsigned char OutBitCount; // 输出开关量数量 + 0, // unsigned char InDWCount; // 输入数据字数 + 0, // unsigned char OutDWCount; // 输出数据字数 + 0, // unsigned char AIWCount; // 输入模拟量通道(字)数 // 16位为一个字(通道) + 0, // unsigned char AQWCount; // 输出模拟量通道(字)数 // 16位为一个字(通道) +// 0, // unsigned char AIBits; // 每通道位数 // 16位以下 +// 0, // unsigned char AQbits; // 每通道位数 // 16位以下 + +}; + diff --git a/C8T6_TestApp2/Src/main.c b/C8T6_TestApp2/Src/main.c new file mode 100644 index 0000000..aaf9a30 --- /dev/null +++ b/C8T6_TestApp2/Src/main.c @@ -0,0 +1,1060 @@ + +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_hal.h" + +/* USER CODE BEGIN Includes */ +#include "Globaldef.h" +#include "debug.h" +#include "Functions.h" +#include "KMachine.h" +#include "PLCfunctions.h" +//#include "KBus.h" +#include "KLink.h" +#include "string.h" +#include "BSP_UltraSonic.h" +#include "ModbusRTU.h" +#if (BOARD_TYPE == 13) +#include "w5500_port.h" +#include "../src/Ethernet/socket.h" +#include "../src/Ethernet/loopback.h" +#elif (BOARD_TYPE == 14) +#include "FP0.h" +#elif (BOARD_TYPE == 15 || BOARD_TYPE == 16) +#include "KWireless.h" +//#include "user.h" +//#include "../src/radio/inc/sx126x-board.h" +#endif + +/* USER CODE END Includes */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +#define RX2BUFSIZE 64 +#define TX2BUFSIZE 64 + +unsigned char Uart1RxBuf[128]; +unsigned char Uart1TxBuf[260]; + +unsigned char Uart2RxBuf[RX2BUFSIZE]; +unsigned char Uart2TxBuf[TX2BUFSIZE]; + +unsigned char Uart1RxBuf1[Uart1RxBufSize]; +unsigned char Uart1TxBuf1[260]; + +unsigned char Uart2RxBuf1[RX2BUFSIZE]; +unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +unsigned short Uart1RxBuf1DataLen = 0; +unsigned short Uart2RxBuf1DataLen = 0; + +unsigned char Uart1Mode = 1; //Uart1宸ヤ綔妯″紡锛� 0 : 鏅�氾紝 1 : 閫忎紶妯″紡 + +unsigned int Uart1Baud = DefaultUart1Baud; +unsigned int Uart2Baud = DefaultUart2Baud; + +//unsigned char Uart1RecvBuf1[Uart1RecvBufSize]; +//unsigned short Uart1RecvBuf1DataLen=0; + +//unsigned char Uart2RecvBuf1[128]; +//unsigned short Uart2RecvBuf1DataLen=0; + +volatile char Uart1BaudGot=0; +volatile char Uart1BaudFirstGot=0; +volatile char Uart1DmaInts=0; + + +unsigned char SlowFlicker=0; +unsigned char FastFlicker=0; + +unsigned int Uart1IdelTimer = 0; + +uint32_t us1,us2,us3,us4,us5,us6; + + +stKBusDef KBus1; // + +extern stDeviceInfo MyDeviceInfo; +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ + + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +const unsigned char LEDSEGTAB[]={ +0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, //0-F +0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1, //0.-F. +0x00,0x40, // ,-,_,~,o,n,N,<,>,J,r, +}; + +/* USER CODE END PFP */ + +/* USER CODE BEGIN 0 */ +#define SET_SCL LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_6) +#define CLR_SCL LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_6) +#define GET_SCL LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_6) +#define SET_SDA LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_7) +#define CLR_SDA LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_7) +#define GET_SDA LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_7) + + +void soft_i2c_start() +{ + SET_SDA; + SET_SCL; + Delay100nS(1); + CLR_SDA; + Delay100nS(1); + CLR_SCL; + Delay100nS(1); +} +void soft_i2c_stop() +{ + CLR_SDA; + Delay100nS(1); + SET_SCL; + Delay100nS(1); + SET_SDA; + Delay100nS(1); +} +void soft_i2c_send8(int nData) +{ + int mask; + mask = 0x80; + for (int j=0;j<8;j++) + { + if (nData & mask) {SET_SDA;} + else {CLR_SDA;} + Delay100nS(1); + SET_SCL; + mask>>=1; + Delay100nS(1); + CLR_SCL; + } + return; +} + +uint8_t soft_i2c_recv8() +{ + unsigned char nData=0; + for (int j=0;j<8;j++) + { + nData <<=1; + Delay100nS(1); + SET_SCL; + nData |= GET_SDA; + Delay100nS(1); + CLR_SCL; + } + return nData; +} + +void soft_i2c_send_ack() +{ + CLR_SDA; + Delay100nS(2); + SET_SCL; + Delay100nS(2); + CLR_SCL; + SET_SDA; + Delay100nS(2); + +} + +void soft_i2c_send_nack() +{ + SET_SDA; + Delay100nS(1); + SET_SCL; + Delay100nS(1); + CLR_SCL; + Delay100nS(1); + SET_SDA; +} +uint8_t soft_i2c_wait_ack(int nTime) +{ + SET_SDA; // Open Drain; + Delay100nS(1); + SET_SCL; + for (int j=0;j<nTime;j++){ + Delay100nS(1); + if (GET_SDA == 0) break; + if (j==nTime-1) return 0; + } + CLR_SCL; + return 1; +} +uint8_t soft_i2c_check_addr(uint8_t Addr) +{ + uint8_t res=0; + soft_i2c_start(); + // Send Device Addr 7bit; + soft_i2c_send8(Addr); + if (soft_i2c_wait_ack(10)) {res=1;} + //Stop + soft_i2c_stop(); +// */ + return res; + +} +uint8_t soft_i2c_read_len( uint8_t Addr , uint8_t Reg, uint8_t len,uint8_t *buf) +{ + int res=0; + //Start + soft_i2c_start(); + // Send Device Addr 7bit; + soft_i2c_send8(Addr &0xfe); + // wait Ack; + if (!soft_i2c_wait_ack(1000)) {soft_i2c_stop();return 1;} + CLR_SCL; + // Send Reg Addr 8bit; + soft_i2c_send8(Reg); + if (!soft_i2c_wait_ack(1000)) {soft_i2c_stop();return 2;} + //Start + soft_i2c_start(); + // Send Device Addr 7bit; + soft_i2c_send8(Addr | 1); + if (!soft_i2c_wait_ack(1000)) {soft_i2c_stop();return 3;} + +// /* + // Recv Data(s) n * 8bit; + SET_SDA; // Open Drain; + for (int i=0;i<len;i++) + { + // recv 1 data 8bit; + unsigned char nData = 0; + nData = soft_i2c_recv8(); + buf[i]=nData; + // Send ACK / NACK; + if (i != len -1) { //ACK + soft_i2c_send_ack(); + } else { // NACK + soft_i2c_send_nack(); + } + } + + //Stop + soft_i2c_stop(); +// */ + return res; +} + +uint8_t soft_i2c_write_len(uint8_t Addr , uint8_t Reg, uint8_t len, uint8_t *buf) +{ + int res=0; + //Start + soft_i2c_start(); + // Send Device Addr 7bit; + soft_i2c_send8(Addr &0xfe); + // wait Ack; + if (!soft_i2c_wait_ack(1000)) return 1; + CLR_SCL; + // Send Reg Addr 8bit; + soft_i2c_send8(Reg); + if (!soft_i2c_wait_ack(1000)) return 2; + for (int i=0;i<len;i++) + { + // send 1 data 8bit; + unsigned char nData = buf[i]; + soft_i2c_send8(nData); + // wait Ack; + if (!soft_i2c_wait_ack(1000)) {res = 5; break;} + } + //Stop + soft_i2c_stop(); + return res; + +} + + + + +int HexToInt(char ch) +{ + if (ch>='0' && ch <='9') return ch-'0'; + if (ch>='A' && ch <='F') return ch-'A'+10; + if (ch>='a' && ch <='f') return ch-'a'+10; + return 0; +} + +void HAL_SYSTICK_Callback(void) +{ + return; +static int Count=0; + CurTickuS += 100; + nCurTick++; + KBus1.nSlaveTick++; + Count++; + if (Count>=10000) + { + Count=0; + KMem.CurTimeSec++; + KMem.ThisRunTime++; KMem.TotalRunTime++; + if (KMRunStat.bLEDFlick) KMRunStat.bLEDFlick--; + if (KMRunStat.bLEDFlick >120) KMRunStat.bLEDFlick=120; + } + + return; +} + +void PendSvCallBack() +{ +/* + if (Uart2Stat.bPacketRecved) + { + KBusParsePacket(&KBus1, (pKBPacket)Uart2RxBuf1, Uart2RxBuf1DataLen); + Uart2RxBuf1DataLen=0; + Uart2Stat.bPacketRecved=0; + Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); + KMem.WDT[2]++; + } +*/ +} + +/* +KBus閫氳鍥炶皟鍑芥暟锛屽綋閫氳鐘舵�佹敼鍙樻垨鏁版嵁鏇存柊鏃惰璋冪敤銆� +鎴栬�呯郴缁熻姹傛椂銆� +*/ +void * KBusEvCallBackFunc(void* pParam, int nEvent, void *pBuf, int nLen1) +{ + switch (nEvent){ + + case KBusEvNone: + break; + case KBusEvCreate: + break; + case KBusEvConnected: + break; + case KBusEvDisConnected: + break; + case KBusEvClosed: + break; + case KBusEvStateChange: + break; + case KBusEvTimeSync: + break; + case KBusEvDataUpdate: + if (KBus1.bMaster) { + for (int i=0;i<16;i++) + { + KMem.WLX[i]=KBusMem.WLX[i]; //KPLC with KBus Master + KBusMem.WLY[i]=KMem.WLY[i]; + } + } else if (KBus1.bSlave) { + KMem.WLX[0]=KBusMem.WLY[0]; //KPLC with KBus Slave + KBusMem.WLX[0]=KMem.WLY[0]; + KMem.WLX[1]=KBusMem.WLY[1]; //KPLC with KBus Slave + KBusMem.WLX[1]=KMem.WLY[1]; + KMem.WLX[2]=KBusMem.WLY[2]; //KPLC with KBus Slave + KBusMem.WLX[2]=KMem.WLY[2]; + KMem.WLX[3]=KBusMem.WLY[3]; //KPLC with KBus Slave + KBusMem.WLX[3]=KMem.WLY[3]; + } + + break; + case KBusEvCmdResponse: + break; + + default: + break; + } + return 0; +} +#define SET_STB() LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15) +#define CLR_STB() LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_15) +#define SET_SCK() LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_3) +#define CLR_SCK() LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_3) +#define SET_DIO() LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_5) +#define CLR_DIO() LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_5) +#define GET_DIO() LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_5) + +void Set_Run_Led(uchar bOn) +{ + if (bOn){ LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_12); } +else { LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_12);} + +} +void TM1629_Send_Byte(uchar byte) +{ + CLR_STB(); + unsigned char mask = 0x01; + for (int i=0;i<8;i++) + { + CLR_SCK(); + if (byte & mask) { SET_DIO(); } + else {CLR_DIO();} + DelayUs(1); + SET_SCK(); + mask<<=1; + DelayUs(1); + } +} +uchar TM1629_Read_Byte() +{ + CLR_STB(); + SET_DIO(); + uchar byte=0; + unsigned char mask = 0x01; + for (int i=0;i<8;i++) + { + CLR_SCK(); + DelayUs(1); + SET_SCK(); + DelayUs(1); + if (GET_DIO()) { byte|=mask; } + mask<<=1; + } + return byte; + +} +void TM1629_disp_on() +{ + SET_STB(); + SET_SCK(); + SET_DIO(); + DelayUs(2); + CLR_STB(); + TM1629_Send_Byte(0x8a); + SET_STB(); + SET_DIO(); +} + +void TM1629_Set_Mode_a() +{ + SET_STB(); + SET_SCK(); + SET_DIO(); + DelayUs(2); + CLR_STB(); + TM1629_Send_Byte(0x40); + SET_STB(); +} +void TM1629_Set_Address(uchar addr) +{ + SET_STB(); + SET_SCK(); + SET_DIO(); + DelayUs(2); + CLR_STB(); + TM1629_Send_Byte(0xc0 | addr); +} + +void TM1629_Send_Data(int addr, const uchar * pbuf, int len) +{ + TM1629_Set_Mode_a(); + TM1629_Set_Address(addr); + for (int i=0;i<len;i++) + { + TM1629_Send_Byte(pbuf[i]); + } + SET_STB(); + +} + +void TM1629_Read_Keys(uchar * pkeybuf) +{ + SET_STB(); + SET_SCK(); + SET_DIO(); + DelayUs(2); + CLR_STB(); + TM1629_Send_Byte(0x42); + for (int i=0;i<4;i++) + pkeybuf[i]=TM1629_Read_Byte(); + SET_STB(); +} +__asm int bintobcd(int a,int b) +{ + add r0,r1,r0 + + BLX lr +} + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * + * @retval None + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + KMRunStat.bLEDFlick = 1; + + InitUartstat(&Uart1Stat,Uart1RxBuf,sizeof(Uart1RxBuf),Uart1TxBuf,sizeof(Uart1TxBuf)); + InitUartstat(&Uart2Stat,Uart2RxBuf,sizeof(Uart2RxBuf),Uart2TxBuf,sizeof(Uart2TxBuf)); + /* USER CODE END 1 */ + + /* MCU Configuration----------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + + int nRunCount = 0; + + KMem.LastScanTime=0; + KMem.ScanTimeuS=0; + KMem.MinScanTimeuS=99999; + KMem.MaxScanTimeuS=0; + +// KMem.SDD[14]=(unsigned int)&KMStoreSysCfg; +// KMem.SDD[15]=(unsigned int)&KMStoreSysCfg1; + KMem.SDD[12]=((uint32_t *)UID_BASE)[0]; +// KMem.SDD[13]=((uint32_t *)UID_BASE)[1]; +// KMem.SDD[14]=((uint32_t *)UID_BASE)[2]; + KMem.SDD[13]=PendSvCount; + KMem.SDD[14]=RCC->CSR; +// KMem.SDD[15]=*(uint32_t *)FLASHSIZE_BASE; +// KMem.SDD[16]=(unsigned int)&KMSysCfg; + + /* USER CODE END Init */ + DelayUs(10000); + /* Configure the system clock */ + SystemClock_Config_New(); + + + /* USER CODE BEGIN SysInit */ + TickFreq=1000; //Tick棰戠巼 + InituS(TickFreq); + // HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/TickFreq); //閲嶆柊瀹氫箟SysTick鐨勯鐜� + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ +// MX_GPIO_Init(); +// MX_DMA_Init(); + + +// KMachineInit(); +// ReadSysCfgFromFlash(&storedKMSysCfg); + + KMRunStat.bLEDFlick = 1; + + + KLinkInit(1); + + //if (KMem.EffJumperSW == 0x00) + Uart1Baud = DefaultUart1Baud; +// MX_USART1_UART_Init(); +// MX_USART2_UART_Init(); +// MX_SPI1_Init(); +// LL_SPI_EnableIT_RXNE(SPI1); +/* + // MX_I2C1_Init(); + Soft_I2C1_Init(); + + + +// MX_IWDG_Init(); + + MX_TIM6_Init(); + LL_TIM_EnableCounter(TIM6); +*/ + /* USER CODE BEGIN 2 */ +// LL_USART_EnableIT_RXNE(USART1); +// LL_USART_EnableIT_IDLE(USART1); +// LL_USART_EnableIT_TC(USART1); + +// LL_USART_EnableIT_RXNE(USART2); +// Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); +// LL_USART_EnableIT_IDLE(USART2); +// LL_USART_EnableIT_TC(USART2); + +// if (bKBusSlave) + { + // LL_USART_EnableAutoBaudRate(USART1); + // LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + // LL_USART_EnableAutoBaudRate(USART2); + // LL_USART_SetAutoBaudRateMode(USART2, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + } + //LL_USART_EnableIT_TXE(USART1); + +// KMem.WDT[50] = SPI_Flash_ReadID(); + + /* USER CODE END 2 */ + + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + +// HAL_Delay(10); +// SetRunLed(1); //Turn On Run Led +// SetErrLed(0); //Turn Off Err Led + + + +// ShowInitInfo(); + KMem.LastScanTime = GetuS(); + + KMRunStat.WorkMode = storedKMSysCfg.theKMSysCfg.workmode; + + KMRunStat.WorkMode = 1; + //KMRunStat.WorkMode2 = 0; + + + + MX_TIM1_Init(); + + LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1N); + LL_TIM_EnableCounter(TIM1); + LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH4); + +// LL_TIM_OC_SetCompareCH4(TIM1,600); + + LL_TIM_OC_SetCompareCH2(TIM1,100); + + + MX_TIM15_Init(); + LL_TIM_CC_EnableChannel(TIM15,LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM15,LL_TIM_CHANNEL_CH1N); + LL_TIM_EnableCounter(TIM15); + + LL_TIM_EnableAllOutputs(TIM1); + LL_TIM_EnableAllOutputs(TIM15); + + LL_TIM_DisableAllOutputs(TIM1); + LL_TIM_DisableAllOutputs(TIM15); + + +// LL_TIM_DisableCounter(TIM1); +// LL_TIM_DisableCounter(TIM15); + + +/* + MX_TIM16_Init(); + + LL_TIM_CC_EnableChannel(TIM16,LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM16,LL_TIM_CHANNEL_CH1N); + LL_TIM_OC_SetCompareCH1(TIM16,600); + LL_TIM_EnableCounter(TIM16); + + LL_TIM_EnableAllOutputs(TIM16); +*/ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_12); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_3 ; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + + SET_STB(); + SET_SCK(); + SET_DIO(); + + + + TM1629_disp_on(); + + KMem.WDB[128]=0x56; + + int nShift = 1; + int nDir = 1; + int nFreq = 28000; + int nOrgFreqFct = (48000000 / nFreq) - 1; + int nFreqFctDlt = 50 ; + + int nMaxFreqFct = nOrgFreqFct + nFreqFctDlt; + int nMinFreqFrc = nOrgFreqFct - nFreqFctDlt; + + int nCurFreqFct = nOrgFreqFct; + + int bEnableSpan = 0; //1; + int bShift = 1; + + uchar ledbuf1[16]; + uchar line1[4]; + uchar line2[4]; + uchar line3[4]; + uchar line4[4]; + + line1[0]=LEDSEGTAB[0]; + line1[1]=LEDSEGTAB[1]; + line1[2]=LEDSEGTAB[2]; + line1[3]=LEDSEGTAB[3]; + + line2[0]=LEDSEGTAB[4]; + line2[1]=LEDSEGTAB[5]; + line2[2]=LEDSEGTAB[6]; + line2[3]=LEDSEGTAB[7]; + + line3[0]=LEDSEGTAB[8]; + line3[1]=LEDSEGTAB[9]; + line3[2]=LEDSEGTAB[0xa]; + line3[3]=LEDSEGTAB[0xb]; + + line4[0]=0x00; + line4[1]=0x55; + line4[2]=0xff; + line4[3]=0x0; + uchar keybuf[4]; + int nCount1=0; + union{ + uchar value; + struct + { + uchar Finc:1; + uchar sweep:1; + uchar Tdec:1; + uchar Pdec:1; + uchar Fdec:1; + uchar On:1; + uchar Tinc:1; + uchar Pinc:1; + }; + } + keys,oldkeys; + + int value1; + int value2; + int value3; + int value4; + + int bPowerOn =0; + int bSweep = 0; + while (1) + { + Set_Run_Led((nRunCount>>8) & 1);; + nRunCount ++; + //int MyKeyStat1,MyKeyStat2; + //MyKeyStat1=GetInput(); + TM1629_disp_on(); + TM1629_Read_Keys(keybuf); + keys.value=keybuf[0]; + + +// value1 = nRunCount; + if (keys.Pinc && !oldkeys.Pinc) { + value1++; + } + if (keys.Pdec && !oldkeys.Pdec) { + value1--; + } + if (keys.Tdec && !oldkeys.Tdec) { + value2--; + } + if (keys.Tinc && !oldkeys.Tinc) { + value2++; + } + + if (keys.On && !oldkeys.On) { + bPowerOn = !bPowerOn; + if (bPowerOn) { + nShift=0; + LL_TIM_EnableAllOutputs(TIM1); + LL_TIM_EnableAllOutputs(TIM15); + }else { + nShift=0; + LL_TIM_DisableAllOutputs(TIM1); + LL_TIM_DisableAllOutputs(TIM15); + } + } + if (keys.sweep && !oldkeys.sweep) { + bSweep = !bSweep; + if (bSweep) { + bEnableSpan = 1; + }else { + bEnableSpan = 0; + } + } + + oldkeys = keys; + + int time1=GetuS(); +// line1[0]= LEDSEGTAB[value1%10]; +// line1[1]= LEDSEGTAB[value1/10%10]; +// line1[2]= LEDSEGTAB[value1/100%10]; +// line1[3]= LEDSEGTAB[value1/1000%10]; + + if (!bPowerOn) { + line1[0] = LEDSEGTAB[15]; + line1[1] = LEDSEGTAB[15]; + line1[2] = LEDSEGTAB[0]; + line1[3] = LEDSEGTAB[33]; + }else { + line1[3] = LEDSEGTAB[15]; + line1[2] = LEDSEGTAB[2]; + line1[1] = LEDSEGTAB[8+16]; + line1[0] = LEDSEGTAB[0]; + } + + ledbuf1[8]=line1[0]; + ledbuf1[0xa]=line1[1]; + ledbuf1[0xc]=line1[2]; + ledbuf1[0xe]=line1[3]; + + int time2=GetuS(); + int dt = time2-time1; + // value2 = dt; + int nCurrent = 0; + value2 = nCurrent; + + line2[0]= LEDSEGTAB[10]; // 'A' + line2[1]= LEDSEGTAB[value2%10]; // '0' - '9' + line2[2]= LEDSEGTAB[value2/10%10 + 16]; // '0.' - '9.' + if (value2>=100) { line2[3]= LEDSEGTAB[value2/100%10]; } + else {line2[3] = keybuf[0];} + ledbuf1[1]=line2[0]; + ledbuf1[3]=line2[1]; + ledbuf1[5]=line2[2]; + ledbuf1[7]=line2[3]; + + int nTime = 0; + value3 = nTime; + line3[0]= LEDSEGTAB[value3%10]; + line3[1]= LEDSEGTAB[value3/10%10]; + line3[2]= LEDSEGTAB[value3/100%10]; + line3[3]= LEDSEGTAB[value3/1000%10]; + + ledbuf1[0]=line3[0]; + ledbuf1[2]=line3[1]; + ledbuf1[4]=line3[2]; + ledbuf1[6]=line3[3]; + +// ledbuf1[9]=line4[3]; + + int level = (1<<((nRunCount>>2) &0x1f)) - 1; + level = (1<<((nShift/32+4) &0x1f)) - 1; + line4[0]=level&0xff; + line4[1]=(level>>8)&0xff; + line4[2]=(level>>16)&0xff; + ledbuf1[0xb]=line4[2]; + ledbuf1[0xd]=line4[1]; + ledbuf1[0xf]=line4[0]; + + + + TM1629_Send_Data(0,ledbuf1,16); + DelayUs(100); + //*((unsigned int *)&(PLCMem.SDT[10]))=nRunCount; + // KMem.nRunCount=nRunCount; + if (bEnableSpan && (nRunCount&0x1) == 0x1) { + + nCurFreqFct --; + if (nCurFreqFct <= nMinFreqFrc) { + nCurFreqFct = nMaxFreqFct; + } + LL_TIM_SetAutoReload(TIM15,nCurFreqFct); + LL_TIM_SetAutoReload(TIM1,nCurFreqFct); + LL_TIM_OC_SetCompareCH1(TIM1,(nCurFreqFct+1)/2-1); + LL_TIM_OC_SetCompareCH4(TIM1,(nCurFreqFct+1)/2-1); + LL_TIM_OC_SetCompareCH1(TIM15,(nCurFreqFct+1)/2-1); + } + + if (bPowerOn&&bShift && (nRunCount&0x3) == 0x2) { + if (nDir == 1) { + if (nShift < 700 -1) {nShift+=1;} + else {nDir = 0;} + }else { + if (nShift > 1) {nShift-=1;} + else {nDir = 1;} + } + LL_TIM_OC_SetCompareCH2(TIM15,nShift); + } + + + ADCProcess(); + int a; + a = LL_GPIO_ReadInputPort(GPIOA); + KMem.WDT[120]=a; + a = LL_GPIO_ReadInputPort(GPIOB); + KMem.WDT[121]=a; + a = LL_GPIO_ReadInputPort(GPIOC); + KMem.WDT[122]=a; + a = LL_GPIO_ReadInputPort(GPIOD); + KMem.WDT[123]=a; + + us2=GetuS(); + if (PowerDownFlag) { KMem.WX[0]=0;} +///* + if ((KMem.nRunCount &0x1f) == 0x02) + { + + if (PowerDownFlag) + { + KMem.WX[0]=0; + if (!OldPowerDownFlag) + { + OldPowerDownFlag = PowerDownFlag; + OldPowerDownEventTime = nCurTick; +// PowerDownProcess(); + } + }else + { + if (OldPowerDownFlag) + { + OldPowerDownFlag=PowerDownFlag; +// PowerRecoverProcess(); + + } + } + } +//*/ + + + + + + +// int nSize=sizeof(stKBusChnStat); +// memcpy(&KMem.SDT[64],&KBusChnStats[1],nSize); +// memcpy(&KMem.SDT[64+nSize/2],&KBusChnStats[2],nSize); +// for (int i=0;i<128;i++) { SDT[i]=i; } +// SDT[48]=55; +/* + if (Uart1RxBuf1DataLen >0 && Uart1Stat.bPacketRecved) + { + int res1 = -1; + res1 = ModBusSlaveParsePkg(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + if (res1 !=0) + { + KLParsePacket(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + } + Uart1RxBuf1DataLen=0; + Uart1Stat.bPacketRecved=0; + Uart1IdelTimer = 0; + }else { + if (Uart1IdelTimer>600000) { // 瓒呰繃60绉掓病鏈夋暟鎹紶杈擄紝閲嶆柊杩涘叆鑷�傚簲娉㈢壒鐜囩姸鎬� + LL_USART_EnableAutoBaudRate(USART1); + LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + }else { + Uart1IdelTimer++; + } + } +*/ + +// LL_IWDG_ReloadCounter(IWDG); + + } //while (1) ; + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + + /* USER CODE END 3 */ + +} + + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @param file: The file name as string. + * @param line: The line in file as a number. + * @retval None + */ +void _Error_Handler(char *file, int line) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/C8T6_TestApp2/startup_stm32f030x8.s b/C8T6_TestApp2/startup_stm32f030x8.s new file mode 100644 index 0000000..7968ead --- /dev/null +++ b/C8T6_TestApp2/startup_stm32f030x8.s @@ -0,0 +1,252 @@ +;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +;* File Name : startup_stm32f030x8.s +;* Author : MCD Application Team +;* Description : STM32F030x8 devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM0 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +;******************************************************************************* + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Stack_Size EQU 0x600 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; <h> Heap Configuration +; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Heap_Size EQU 0x200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD 0 ; Reserved + DCD RTC_IRQHandler ; RTC through EXTI Line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_1_IRQHandler ; EXTI Line 0 and 1 + DCD EXTI2_3_IRQHandler ; EXTI Line 2 and 3 + DCD EXTI4_15_IRQHandler ; EXTI Line 4 to 15 + DCD 0 ; Reserved + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_3_IRQHandler ; DMA1 Channel 2 and Channel 3 + DCD DMA1_Channel4_5_IRQHandler ; DMA1 Channel 4 and Channel 5 + DCD ADC1_IRQHandler ; ADC1 + DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; TIM1 Break, Update, Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD 0 ; Reserved + DCD TIM3_IRQHandler ; TIM3 + DCD TIM6_IRQHandler ; TIM6 + DCD 0 ; Reserved + DCD TIM14_IRQHandler ; TIM14 + DCD TIM15_IRQHandler ; TIM15 + DCD TIM16_IRQHandler ; TIM16 + DCD TIM17_IRQHandler ; TIM17 + DCD I2C1_IRQHandler ; I2C1 + DCD I2C2_IRQHandler ; I2C2 + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler routine +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_5_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + + +WWDG_IRQHandler +RTC_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_3_IRQHandler +DMA1_Channel4_5_IRQHandler +ADC1_IRQHandler +TIM1_BRK_UP_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM3_IRQHandler +TIM6_IRQHandler +TIM14_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/CCT6_BootLoader/MDK-ARM/CCT6_BtLdr.uvprojx b/CCT6_BootLoader/MDK-ARM/CCT6_BtLdr.uvprojx index f95b17d..132fe8d 100644 --- a/CCT6_BootLoader/MDK-ARM/CCT6_BtLdr.uvprojx +++ b/CCT6_BootLoader/MDK-ARM/CCT6_BtLdr.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030CCTx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/CCT6_TestApp1/MDK-ARM/F030CCT6_TestApp1.uvprojx b/CCT6_TestApp1/MDK-ARM/F030CCT6_TestApp1.uvprojx index dcf5715..3645ebd 100644 --- a/CCT6_TestApp1/MDK-ARM/F030CCT6_TestApp1.uvprojx +++ b/CCT6_TestApp1/MDK-ARM/F030CCT6_TestApp1.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030CCTx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/ComLib/Inc/BSP.h b/ComLib/Inc/BSP.h index 221a7b1..f693323 100644 --- a/ComLib/Inc/BSP.h +++ b/ComLib/Inc/BSP.h @@ -24,10 +24,15 @@ void MX_DMA_Init(void); void MX_USART1_UART_Init(void); void MX_USART2_UART_Init(void); +void MX_TIM1_Init(void); void MX_TIM6_Init(void); +void MX_TIM14_Init(void); +void MX_TIM15_Init(void); +void MX_TIM16_Init(void); + void MX_SPI1_Init(void); void MX_SPI2_Init(void); -void MX_I2C1_Init(void); +//void MX_I2C1_Init(void); void Soft_I2C1_Init(void); void MX_ADC_Init(void); diff --git a/ComLib/Inc/KMachine.h b/ComLib/Inc/KMachine.h index d1f709d..552804e 100644 --- a/ComLib/Inc/KMachine.h +++ b/ComLib/Inc/KMachine.h @@ -638,8 +638,8 @@ extern const stKMInfoBlock KMInfoBlock; extern const stStoredKMSysCfg KMDefaultSysCfg; -extern volatile int PowerDownEvent; -extern volatile int OldPowerDownEvent; +extern volatile int PowerDownFlag; +extern volatile int OldPowerDownFlag; extern volatile int OldPowerDownEventTime; int KMachineInit(void); diff --git a/ComLib/Inc/functions.h b/ComLib/Inc/functions.h index aaf82bc..be64e43 100644 --- a/ComLib/Inc/functions.h +++ b/ComLib/Inc/functions.h @@ -97,5 +97,10 @@ void PutOutputSPI1(unsigned int Y); uint16_t SPI_Flash_ReadID(void); +uint8_t SPI1_Flash_ReadSR(void) ; +void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead); +void SPI_FLASH_Write_Enable(void) ; +void W25QXX_Erase_Sector(uint32_t Dst_Addr) ; +void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); #endif /* __MYFUNCTIONS_H__ */ diff --git a/ComLib/Src/BSP.c b/ComLib/Src/BSP.c index 048467f..f53040c 100644 --- a/ComLib/Src/BSP.c +++ b/ComLib/Src/BSP.c @@ -16,94 +16,6 @@ #include "fpx.h" #endif -/* - if ((nCurTick &0xff) ==0) - { - if (freqdir) { freq+=1+freq/10;if (freq>=1500) {freq=1500;freqdir=0;}} - else {freq-=1+freq/10;if (freq<=10) {freq=10;freqdir=1;} } - } -*/ - -/* - static int outputsum=0; - static int freq=10; - static int freqdir=1; - static int phase=0; - static int somb=0; - static int len=0; - static int curbb=0; - - if ((nCurTick &0x3ff) ==1) - { - curbb++; - if (curbb+1==len) - { -// freq=0; - }else if (curbb>=len) - { - somb=musictab1[cur_musicpos*2]; - len=musictab1[cur_musicpos*2+1]; - freq=freqtab[somb]; - curbb=0;cur_musicpos++; if (cur_musicpos >= Totalmusiccount) {cur_musicpos=0;} - } - } - if ((nCurTick &0x3ff) ==0x1ff) - { - if (curbb+1==len) - { - freq=0; - } - } - phase+=freq; - if (phase>=5000) {phase-=5000;} - - - if (outtype==1) - { - outputsum+=freq; - if (outputsum>=5000) - { - //LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_3); - LL_GPIO_TogglePin(GPIOB,LL_GPIO_PIN_3); - outputsum-=5000; - } - else - { - //LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_3); - } - }else if (outtype==2) - { - const int volume = 2500; - int amp; - if (phase<1250) - { - amp=2500+sintab[(phase -0)*256/1250]*volume/256; - - }else if (phase <2500) - { - amp=2500+sintab[(2500-1-phase)*256/1250]*volume/256; - }else if (phase <3750) - { - amp=2500-sintab[(phase-2500)*256/1250]*volume/256; - }else - { - amp=2500-sintab[(5000-1-phase)*256/1250]*volume/256; - } - outputsum+=amp; - if (outputsum>=5000) - { - LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_3); - //LL_GPIO_TogglePin(GPIOB,LL_GPIO_PIN_3); - outputsum-=5000; - } - else - { - LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_3); - } - } -*/ - - /** * @brief System Clock Configuration * @retval None @@ -257,6 +169,117 @@ } /** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1); + + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1713; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM1, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM1); + LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 857; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + + + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH4); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 856; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct); + + + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH4); + LL_TIM_SetTriggerInput(TIM1, LL_TIM_TS_ITR0); + LL_TIM_SetSlaveMode(TIM1, LL_TIM_SLAVEMODE_RESET); + LL_TIM_DisableIT_TRIG(TIM1); + LL_TIM_DisableDMAReq_TRIG(TIM1); + LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM1); + + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 20; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct); + + + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + /**TIM1 GPIO Configuration + PB13 ------> TIM1_CH1N + PA8 ------> TIM1_CH1 + PA11 ------> TIM1_CH4 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + +} +/** * @brief TIM6 Initialization Function * @param None * @retval None @@ -290,6 +313,212 @@ /* USER CODE END TIM6_Init 2 */ } + +/** + * @brief TIM14 Initialization Function + * @param None + * @retval None + */ +void MX_TIM14_Init(void) +{ + + /* USER CODE BEGIN TIM14_Init 0 */ + + /* USER CODE END TIM14_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM14); + + /* USER CODE BEGIN TIM14_Init 1 */ + + /* USER CODE END TIM14_Init 1 */ + TIM_InitStruct.Prescaler = 2; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 2400; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM14, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM14); + /* USER CODE BEGIN TIM14_Init 2 */ + + /* USER CODE END TIM14_Init 2 */ + +} + +/** + * @brief TIM15 Initialization Function + * @param None + * @retval None + */ +void MX_TIM15_Init(void) +{ + + /* USER CODE BEGIN TIM15_Init 0 */ + + /* USER CODE END TIM15_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM15); + + /* USER CODE BEGIN TIM15_Init 1 */ + + /* USER CODE END TIM15_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1713; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM15, &TIM_InitStruct); + LL_TIM_EnableARRPreload(TIM15); + LL_TIM_SetClockSource(TIM15, LL_TIM_CLOCKSOURCE_INTERNAL); + + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 856; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM15, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM15, LL_TIM_CHANNEL_CH1); + + LL_TIM_OC_EnablePreload(TIM15, LL_TIM_CHANNEL_CH2); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 100; + LL_TIM_OC_Init(TIM15, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM15, LL_TIM_CHANNEL_CH2); + LL_TIM_SetTriggerOutput(TIM15, LL_TIM_TRGO_OC2REF); + LL_TIM_DisableMasterSlaveMode(TIM15); + + + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 5; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM15, &TIM_BDTRInitStruct); + /* USER CODE BEGIN TIM15_Init 2 */ + + /* USER CODE END TIM15_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**TIM15 GPIO Configuration + PB14 ------> TIM15_CH1 + PB15 ------> TIM15_CH1N + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_3; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +} + +/** + * @brief TIM16 Initialization Function + * @param None + * @retval None + */ +void MX_TIM16_Init(void) +{ + + /* USER CODE BEGIN TIM16_Init 0 */ + + /* USER CODE END TIM16_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM16); + /* TIM6 interrupt Init */ + NVIC_SetPriority(TIM16_IRQn, 0); + NVIC_EnableIRQ(TIM16_IRQn); + + /* USER CODE BEGIN TIM16_Init 1 */ + + /* USER CODE END TIM16_Init 1 */ + TIM_InitStruct.Prescaler = 100; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1417; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct.RepetitionCounter = 0; + LL_TIM_Init(TIM16, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM16); + + LL_TIM_OC_EnablePreload(TIM16, LL_TIM_CHANNEL_CH1); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_TOGGLE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 500; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM16, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM16, LL_TIM_CHANNEL_CH1); + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = 6; + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM16, &TIM_BDTRInitStruct); + + /* USER CODE BEGIN TIM16_Init 2 */ + + /* USER CODE END TIM16_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**TIM16 GPIO Configuration + PA6 ------> TIM16_CH1 + PB6 ------> TIM16_CH1N + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_5; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_TIM_EnableIT_UPDATE(TIM16); +} + + /* ADC init function */ void MX_ADC_Init(void) { @@ -400,9 +629,10 @@ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; - GPIO_InitStruct.Alternate = LL_GPIO_AF_0; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - + LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); /**SPI1 GPIO Configuration PB3 ------> SPI1_SCK @@ -416,6 +646,19 @@ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; GPIO_InitStruct.Alternate = LL_GPIO_AF_0; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +/* + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; +// GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_5); +*/ + /* GPIO_InitStruct.Pin = LL_GPIO_PIN_4; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; @@ -438,7 +681,7 @@ // NVIC_EnableIRQ(SPI1_IRQn); /* USER CODE BEGIN SPI1_Init 1 */ -#if (BOARD_TYPE == 13) +#if (BOARD_TYPE == 13 || BOARD_TYPE == 9) NVIC_EnableIRQ(SPI1_IRQn); SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; @@ -477,7 +720,8 @@ LL_SPI_DisableNSSPulseMgt(SPI1); LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER); // LL_SPI_EnableNSSPulseMgt(SPI1); - + LL_SPI_EnableIT_RXNE(SPI1); + #elif (BOARD_TYPE == 15 || BOARD_TYPE == 16) SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; @@ -582,7 +826,7 @@ SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; //LL_SPI_POLARITY_HIGH;//LL_SPI_POLARITY_LOW; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; //LL_SPI_PHASE_1EDGE; SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; - SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct.CRCPoly = 7; @@ -610,70 +854,6 @@ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_6 | LL_GPIO_PIN_7); - -} - -/** - * @brief I2C1 Initialization Function - * @param None - * @retval None - */ -void MX_I2C1_Init(void) -{ - - /* USER CODE BEGIN I2C1_Init 0 */ - - /* USER CODE END I2C1_Init 0 */ - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - - LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); - /**I2C1 GPIO Configuration - PB8 ------> I2C1_SCL - PB9 ------> I2C1_SDA - */ - GPIO_InitStruct.Pin = LL_GPIO_PIN_8; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = LL_GPIO_PIN_9; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; - GPIO_InitStruct.Alternate = LL_GPIO_AF_1; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* Peripheral clock enable */ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); - - /* USER CODE BEGIN I2C1_Init 1 */ - - /* USER CODE END I2C1_Init 1 */ - /** I2C Initialization - */ - LL_I2C_DisableOwnAddress2(I2C1); - LL_I2C_DisableGeneralCall(I2C1); - LL_I2C_EnableClockStretching(I2C1); - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.Timing = 0x20303E5D; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - LL_I2C_Init(I2C1, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(I2C1); - LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK); - /* USER CODE BEGIN I2C1_Init 2 */ - - /* USER CODE END I2C1_Init 2 */ } @@ -894,7 +1074,7 @@ LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - GPIO_InitStruct.Pin = LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_8|LL_GPIO_PIN_11; + GPIO_InitStruct.Pin = LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_8; //|LL_GPIO_PIN_11; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; @@ -1049,3 +1229,91 @@ #endif } + + +/* + if ((nCurTick &0xff) ==0) + { + if (freqdir) { freq+=1+freq/10;if (freq>=1500) {freq=1500;freqdir=0;}} + else {freq-=1+freq/10;if (freq<=10) {freq=10;freqdir=1;} } + } +*/ + +/* + static int outputsum=0; + static int freq=10; + static int freqdir=1; + static int phase=0; + static int somb=0; + static int len=0; + static int curbb=0; + + if ((nCurTick &0x3ff) ==1) + { + curbb++; + if (curbb+1==len) + { +// freq=0; + }else if (curbb>=len) + { + somb=musictab1[cur_musicpos*2]; + len=musictab1[cur_musicpos*2+1]; + freq=freqtab[somb]; + curbb=0;cur_musicpos++; if (cur_musicpos >= Totalmusiccount) {cur_musicpos=0;} + } + } + if ((nCurTick &0x3ff) ==0x1ff) + { + if (curbb+1==len) + { + freq=0; + } + } + phase+=freq; + if (phase>=5000) {phase-=5000;} + + + if (outtype==1) + { + outputsum+=freq; + if (outputsum>=5000) + { + //LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_3); + LL_GPIO_TogglePin(GPIOB,LL_GPIO_PIN_3); + outputsum-=5000; + } + else + { + //LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_3); + } + }else if (outtype==2) + { + const int volume = 2500; + int amp; + if (phase<1250) + { + amp=2500+sintab[(phase -0)*256/1250]*volume/256; + + }else if (phase <2500) + { + amp=2500+sintab[(2500-1-phase)*256/1250]*volume/256; + }else if (phase <3750) + { + amp=2500-sintab[(phase-2500)*256/1250]*volume/256; + }else + { + amp=2500-sintab[(5000-1-phase)*256/1250]*volume/256; + } + outputsum+=amp; + if (outputsum>=5000) + { + LL_GPIO_SetOutputPin(GPIOB,LL_GPIO_PIN_3); + //LL_GPIO_TogglePin(GPIOB,LL_GPIO_PIN_3); + outputsum-=5000; + } + else + { + LL_GPIO_ResetOutputPin(GPIOB,LL_GPIO_PIN_3); + } + } +*/ diff --git a/ComLib/Src/KLink.c b/ComLib/Src/KLink.c index 620e1cd..1958936 100644 --- a/ComLib/Src/KLink.c +++ b/ComLib/Src/KLink.c @@ -12,7 +12,7 @@ #include "main.h" #ifdef KWLESS -#include "KWireless.h" +#include "KWireless2.h" #endif //extern stWLRunStat KwRunStat; diff --git a/ComLib/Src/KMachine.c b/ComLib/Src/KMachine.c index 11b8252..b053452 100644 --- a/ComLib/Src/KMachine.c +++ b/ComLib/Src/KMachine.c @@ -128,8 +128,8 @@ int nMaxCurTime=0; volatile int PowerState = 0; -volatile int PowerDownEvent=0; -volatile int OldPowerDownEvent=0; +volatile int PowerDownFlag=0; +volatile int OldPowerDownFlag=1; volatile int OldPowerDownEventTime=0; int nMaxRunStatIndex=-1; unsigned int nMaxRunStatSeq=0; diff --git a/ComLib/Src/PLCfunctions.c b/ComLib/Src/PLCfunctions.c index bf11c44..d75f0e5 100644 --- a/ComLib/Src/PLCfunctions.c +++ b/ComLib/Src/PLCfunctions.c @@ -183,7 +183,7 @@ for (int i=0;i<16;i++) { KMem.WR[i]=0; } - for (int i=0;i<256;i++) { + for (int i=0;i<100;i++) { KMem.DT[i]=0; } return 0; @@ -196,9 +196,15 @@ for (int i=0;i<16;i++) { KMem.WR[i]=0; } - for (int i=0;i<256;i++) { +/* + for (int i=0;i<KLDataDTCount;i++) { KMem.DT[i]=0; } +*/ + for (int i=0;i<100;i++) { + KMem.DT[i]=0; + } + for (int i=0;i<TOTALTIMERS;i++){ PLCMem.Timers[i].nInited=0; } diff --git a/ComLib/Src/debug.c b/ComLib/Src/debug.c index dfe37f0..941ea2b 100644 --- a/ComLib/Src/debug.c +++ b/ComLib/Src/debug.c @@ -203,10 +203,10 @@ nextchannel = LL_ADC_CHANNEL_7; if (KMem.ADCValues[0] < 1500) { - PowerDownEvent=1; + PowerDownFlag=1; }else { - PowerDownEvent=0; + PowerDownFlag=0; } } else if ((channels & LL_ADC_CHANNEL_7) == LL_ADC_CHANNEL_7) diff --git a/ComLib/Src/functions.c b/ComLib/Src/functions.c index 534de72..436f204 100644 --- a/ComLib/Src/functions.c +++ b/ComLib/Src/functions.c @@ -519,12 +519,12 @@ else {LL_GPIO_ResetOutputPin(GPIOC,LL_GPIO_PIN_15);} } #else -void ToggleOutStat() { LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_11);} +void ToggleOutStat() { } //LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_11);} void SetOutStat(uchar bOn) { - if (bOn) {LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_11);} - else {LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_11);} +// if (bOn) {LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_11);} +// else {LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_11);} } #endif @@ -899,27 +899,15 @@ __disable_irq(); STRCLK2_1(); LL_SPI_TransmitData8(SPI2,Y>>8); - int i=0; - while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) - { - } - KMem.SDD[28]=i; - i=0; - while (LL_SPI_IsActiveFlag_BSY(SPI2) == SET) - { - i++; - } + + while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) { } + + while (LL_SPI_IsActiveFlag_BSY(SPI2) == SET) { } LL_SPI_TransmitData8(SPI2,Y); - while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) - { - } - KMem.SDD[28]=i; - i=0; - while (LL_SPI_IsActiveFlag_BSY(SPI2) == SET) - { - i++; - } - KMem.SDD[30]=i; + while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) { } + + while (LL_SPI_IsActiveFlag_BSY(SPI2) == SET) { } + STRCLK2_0(); STRCLK2_1(); __enable_irq(); @@ -1016,83 +1004,144 @@ //W25Q16 ID 0XEF14 //W25Q32 ID 0XEF15 //W25Q32 ID 0XEF16 -#define W25Q80 0XEF13 -#define W25Q16 0XEF14 -#define W25Q32 0XEF15 -#define W25Q64 0XEF16 + +#define W25Q80 0XEF13 +#define W25Q16 0XEF14 +#define W25Q32 0XEF15 +#define W25Q64 0XEF16 +#define W25Q128 0xEF17 //????? -#define SPI_FLASH_CS PAout[15] //??FLASH,???????PB12? -#define SPI_CS_EN LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_15) -#define SPI_CS_NA LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15) +#define SPI1_FLASH_CS PAout[15] //??FLASH,???????PB12? +#define SPI1_CS_EN LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_15) +#define SPI1_CS_NA LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15) -uint8_t SPI_Tranceive8(uint16_t Y) +uint8_t SPI_Tranceive8(SPI_TypeDef * SPIx, uint8_t Y) { int i=0; - while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET){ DelayUs(1);i++; if (i>320) break; } - LL_SPI_TransmitData8(SPI2,Y>>8); + while (LL_SPI_IsActiveFlag_TXE(SPIx) == RESET){ DelayUs(1);i++; if (i>3200) break; } + LL_SPI_TransmitData8(SPIx,Y); i=0; - while (LL_SPI_IsActiveFlag_BSY(SPI2) == SET) { DelayUs(1);i++; if (i>320) break;} + while (LL_SPI_IsActiveFlag_BSY(SPIx) == SET) { DelayUs(1);i++; if (i>3200) break;} i=0; - while (LL_SPI_IsActiveFlag_RXNE(SPI2) == RESET) { DelayUs(1);i++; if (i>320) break;} - Y = LL_SPI_ReceiveData8(SPI2); + while (LL_SPI_IsActiveFlag_RXNE(SPIx) == RESET) { DelayUs(1);i++; if (i>3200) break;} + Y = LL_SPI_ReceiveData8(SPIx); return Y; } -uint8_t SPI_Transmit(uint8_t * tData, uint8_t nLen, uint8_t timeout) +uint8_t SPI_Transmit(SPI_TypeDef * SPIx, uint8_t * tData, uint8_t nLen, uint8_t timeout) { + int nToSend=nLen; + while(nLen > 0) + { + if (LL_SPI_IsActiveFlag_TXE(SPI1) && nToSend>0) { + LL_SPI_TransmitData8(SPI1,*tData++); nToSend--; + } + if (LL_SPI_IsActiveFlag_RXNE(SPI1)) { + LL_SPI_ReceiveData8(SPI1); + nLen--; + } + } + + return 0; for (int i=0;i<nLen;i++) { - SPI_Tranceive8(tData[i]); + SPI_Tranceive8(SPIx, tData[i]); } return 0; } -uint8_t SPI_TransmitReceive(uint8_t * tData, uint8_t * rData, uint8_t nLen, uint8_t timeout) +uint8_t SPI_TransmitReceive(SPI_TypeDef * SPIx, uint8_t * tData, uint8_t * rData, uint8_t nLen, uint8_t timeout) { for (int i=0;i<nLen;i++) { - rData[i] = SPI_Tranceive8(tData[i]); + // rData[i] = SPI_Tranceive8(SPIx, tData[i]); + __IO uint32_t * pSR = &(SPI1->SR); + int j=0; + while ((* pSR & SPI_SR_TXE) == RESET){ } + LL_SPI_TransmitData8(SPIx,tData[i]); + j=0; + // while (LL_SPI_IsActiveFlag_BSY(SPIx) == SET) { DelayUs(1);j++; if (j>3200) break;} + // i=0; + while (LL_SPI_IsActiveFlag_RXNE(SPIx) == RESET) { } + rData[i] = LL_SPI_ReceiveData8(SPIx); } return 0; } +uint8_t SPI1_Tranceive(uint8_t * tData, uint8_t * rData, uint8_t nLen) +{ + register int nToSend=nLen; +// /* + __IO uint32_t * pSR = &(SPI1->SR); + __IO uint8_t * pDR = (__IO uint8_t *)&(SPI1->DR); + __disable_irq(); + while(nLen >0) + { + if (*pSR & SPI_SR_TXE && nToSend>0) { + LL_SPI_TransmitData8(SPI1,*tData++); nToSend--; + } + if (*pSR & SPI_SR_RXNE) { + *rData++ = * pDR; + nLen--; // if (nLen == 0) break; + } + } + +// */ + /* + while(nLen > 0) + { + if (LL_SPI_IsActiveFlag_TXE(SPI1) && nToSend>0) { + LL_SPI_TransmitData8(SPI1,*tData++); nToSend--; + } + if (LL_SPI_IsActiveFlag_RXNE(SPI1)) { + *rData++ = LL_SPI_ReceiveData8(SPI1); + nLen--; // if (nLen == 0) break; + } + } +// */ + __enable_irq(); + return nLen; +} -uint8_t SPI_Flash_ReadSR(void) + +uint8_t SPI1_Flash_ReadSR(void) { uint8_t Data1[2]= {W25X_ReadStatusReg,0x00}; uint8_t Rxdata[2]; uint8_t byte=0; - SPI_CS_EN; - SPI_TransmitReceive(Data1,Rxdata,2,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI1_Tranceive(Data1,Rxdata,2); + SPI1_CS_NA; byte=Rxdata[1]; return byte; } void SPI_Flash_Wait_Busy(void) { - while((SPI_Flash_ReadSR()&0x01)==0x01); // ??BUSY??? + while((SPI1_Flash_ReadSR()&0x01)==0x01); // ??BUSY??? } void SPI_FLASH_Write_SR(uint8_t sr) { uint8_t Data1[2]= {W25X_ReadStatusReg,0x00}; Data1[1]=sr; - SPI_CS_EN; - SPI_Transmit(Data1,2,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI_Transmit(SPI1, Data1, 2,100); + SPI1_CS_NA; } uint16_t SPI_Flash_ReadID(void) { uint16_t Temp = 0; - uint8_t Data1[4] = {W25X_ManufactDeviceID,0x00,0x00,0x00}; - uint8_t Data2[2]= {0x00,0x00}; - uint8_t Rxdata[2]; - SPI_CS_EN; - SPI_Transmit(Data1,4,100); - SPI_TransmitReceive(Data2,Rxdata,2,100); - SPI_CS_NA; - Temp=(Rxdata[0]<<8)|Rxdata[1]; + uint8_t Data1[6] = {W25X_ManufactDeviceID,0x00,0x00,0x00,0x00,0x00}; + uint8_t Data2[6]= {0x00,0x00}; +// uint8_t Rxdata[2]; + SPI1_CS_EN; + //SPI_Transmit(SPI1, Data1,4,100); + // SPI_TransmitReceive(SPI1,Data1,Data2,6,100); + SPI1_Tranceive(Data1,Data2,6); + SPI1_CS_NA; + + Temp=(Data2[4]<<8)|Data2[5]; return Temp; } uint64_t SPI_Flash_ReadUID(uint8_t * Uid) @@ -1106,10 +1155,10 @@ uint8_t Data1[5] = {W25X_ReadUniqueID,0x00,0x00,0x00,0x00}; uint8_t Data2[8]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - SPI_CS_EN; - SPI_Transmit(Data1,5,100); - SPI_TransmitReceive(Data2,uids.Rxdata,8,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI_Transmit(SPI1, Data1,5,100); + SPI_TransmitReceive(SPI1, Data2,uids.Rxdata,8,100); + SPI1_CS_NA; memcpy(Uid,uids.Rxdata,8); uint32_t t1 = __rev(uids.temp2[0]); uids.temp2[0]= __rev(uids.temp2[1]); @@ -1120,17 +1169,17 @@ void SPI_FLASH_Write_Enable(void) { uint8_t Txdata[2]={W25X_WriteEnable}; - SPI_CS_EN; - SPI_Transmit(Txdata,1,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI1_Tranceive(Txdata,Txdata,1); + SPI1_CS_NA; } void SPI_FLASH_Write_Disable(void) { uint8_t Txdata[2]={W25X_WriteDisable}; - SPI_CS_EN; - SPI_Transmit(Txdata,1,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI_Transmit(SPI1, Txdata,1,100); + SPI1_CS_NA; } void W25QXX_Erase_Sector(uint32_t Dst_Addr) { @@ -1144,26 +1193,26 @@ SPI_FLASH_Write_Enable(); //SET WEL ,??? SPI_Flash_Wait_Busy(); - SPI_CS_EN; - SPI_Transmit(Data1,4,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI1_Tranceive(Data1,Data1,4); + SPI1_CS_NA; SPI_Flash_Wait_Busy(); //?????? } void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead) { uint16_t i; uint8_t Data1[4] = {W25X_ReadData,0x00,0x00,0x00}; - uint8_t Data2[16]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +// uint8_t Data2[16]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; Data1[1]=ReadAddr>>16; Data1[2]=ReadAddr>>8; Data1[3]=ReadAddr; - SPI_CS_EN; - SPI_Transmit(Data1,4,100); + SPI1_CS_EN; + SPI_Transmit(SPI1, Data1,4,100); // HAL_SPI_TransmitReceive(&hspi1,pBuffer,pBuffer,NumByteToRead,10); // HAL_SPI_TransmitReceive_DMA(&hspi1,pBuffer,pBuffer,NumByteToRead); - SPI_TransmitReceive(pBuffer,pBuffer,NumByteToRead,100); + SPI1_Tranceive(pBuffer,pBuffer,NumByteToRead); /* for(i=0;i<NumByteToRead/16;i++) { @@ -1174,7 +1223,7 @@ HAL_SPI_TransmitReceive(&hspi1,Data2,pBuffer+i*16,NumByteToRead%16,100); } */ - SPI_CS_NA; + SPI1_CS_NA; } void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) { @@ -1186,10 +1235,10 @@ SPI_FLASH_Write_Enable(); //SET WEL ,??? SPI_Flash_Wait_Busy(); - SPI_CS_EN; - SPI_Transmit(Data1,4,100); - SPI_Transmit(pBuffer,NumByteToWrite,100); - SPI_CS_NA; + SPI1_CS_EN; + SPI_Transmit(SPI1, Data1,4,100); + SPI_Transmit(SPI1, pBuffer,NumByteToWrite,100); + SPI1_CS_NA; SPI_Flash_Wait_Busy(); //?????? } /* diff --git a/ComLib/Src/stm32f0xx_it.c b/ComLib/Src/stm32f0xx_it.c index 032448e..0ee5932 100644 --- a/ComLib/Src/stm32f0xx_it.c +++ b/ComLib/Src/stm32f0xx_it.c @@ -134,7 +134,7 @@ { /* USER CODE BEGIN TIM6_IRQn 0 */ if (LL_TIM_IsActiveFlag_UPDATE(TIM6)) { LL_TIM_ClearFlag_UPDATE(TIM6);} - + KMem.WDB[130]++; // KMem.SDD[46]+=1000; // KMem.SDT[93] = LL_TIM_GetCounter(TIM6); /* USER CODE END TIM6_IRQn 0 */ @@ -144,6 +144,21 @@ } /** + * @brief This function handles TIM6 global interrupt. + */ +void TIM16_IRQHandler(void) +{ + /* USER CODE BEGIN TIM6_IRQn 0 */ + if (LL_TIM_IsActiveFlag_UPDATE(TIM16)) { LL_TIM_ClearFlag_UPDATE(TIM16);} + KMem.WDB[132]++; +// KMem.SDD[46]+=1000; +// KMem.SDT[93] = LL_TIM_GetCounter(TIM6); + /* USER CODE END TIM6_IRQn 0 */ + /* USER CODE BEGIN TIM6_IRQn 1 */ + + /* USER CODE END TIM6_IRQn 1 */ +} +/** * @brief This function handles DMA1 channel 2 and 3 interrupts. */ void DMA1_Channel2_3_IRQHandler(void) diff --git a/ComLib/startup_stm32f030x8.s b/ComLib/startup_stm32f030x8.s new file mode 100644 index 0000000..7968ead --- /dev/null +++ b/ComLib/startup_stm32f030x8.s @@ -0,0 +1,252 @@ +;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +;* File Name : startup_stm32f030x8.s +;* Author : MCD Application Team +;* Description : STM32F030x8 devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM0 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +;******************************************************************************* + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Stack_Size EQU 0x600 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; <h> Heap Configuration +; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Heap_Size EQU 0x200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD 0 ; Reserved + DCD RTC_IRQHandler ; RTC through EXTI Line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_1_IRQHandler ; EXTI Line 0 and 1 + DCD EXTI2_3_IRQHandler ; EXTI Line 2 and 3 + DCD EXTI4_15_IRQHandler ; EXTI Line 4 to 15 + DCD 0 ; Reserved + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_3_IRQHandler ; DMA1 Channel 2 and Channel 3 + DCD DMA1_Channel4_5_IRQHandler ; DMA1 Channel 4 and Channel 5 + DCD ADC1_IRQHandler ; ADC1 + DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; TIM1 Break, Update, Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD 0 ; Reserved + DCD TIM3_IRQHandler ; TIM3 + DCD TIM6_IRQHandler ; TIM6 + DCD 0 ; Reserved + DCD TIM14_IRQHandler ; TIM14 + DCD TIM15_IRQHandler ; TIM15 + DCD TIM16_IRQHandler ; TIM16 + DCD TIM17_IRQHandler ; TIM17 + DCD I2C1_IRQHandler ; I2C1 + DCD I2C2_IRQHandler ; I2C2 + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler routine +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_5_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + + +WWDG_IRQHandler +RTC_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_3_IRQHandler +DMA1_Channel4_5_IRQHandler +ADC1_IRQHandler +TIM1_BRK_UP_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM3_IRQHandler +TIM6_IRQHandler +TIM14_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git "a/Ext_FPx/MDK-ARM/Ext_FPx_C8T6_\346\235\276\344\270\213\346\211\251\345\261\225.uvprojx" "b/Ext_FPx/MDK-ARM/Ext_FPx_C8T6_\346\235\276\344\270\213\346\211\251\345\261\225.uvprojx" index 9140f49..1c5834b 100644 --- "a/Ext_FPx/MDK-ARM/Ext_FPx_C8T6_\346\235\276\344\270\213\346\211\251\345\261\225.uvprojx" +++ "b/Ext_FPx/MDK-ARM/Ext_FPx_C8T6_\346\235\276\344\270\213\346\211\251\345\261\225.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git "a/KBus/MDK-ARM/KBus_C8T6_\345\210\206\345\270\203IO\346\250\241\345\235\227_8\350\267\25716\350\267\257.uvprojx" "b/KBus/MDK-ARM/KBus_C8T6_\345\210\206\345\270\203IO\346\250\241\345\235\227_8\350\267\25716\350\267\257.uvprojx" index b5186ac..20044a6 100644 --- "a/KBus/MDK-ARM/KBus_C8T6_\345\210\206\345\270\203IO\346\250\241\345\235\227_8\350\267\25716\350\267\257.uvprojx" +++ "b/KBus/MDK-ARM/KBus_C8T6_\345\210\206\345\270\203IO\346\250\241\345\235\227_8\350\267\25716\350\267\257.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git a/KNet.uvmpw b/KNet.uvmpw index b06b4c2..bc4c7a5 100644 --- a/KNet.uvmpw +++ b/KNet.uvmpw @@ -17,8 +17,6 @@ <project> <PathAndName>.\MDK-ARM\KPLC_C8T6_绠�鏄揚LC.uvprojx</PathAndName> - <NodeIsActive>1</NodeIsActive> - <NodeIsExpanded>1</NodeIsExpanded> </project> <project> @@ -69,4 +67,13 @@ <PathAndName>.\CCT6_TestApp1\MDK-ARM\F030CCT6_TestApp1.uvprojx</PathAndName> </project> + <project> + <PathAndName>.\C8T6_TestApp2\C8T6_UltroSonic.uvprojx</PathAndName> + </project> + + <project> + <PathAndName>.\Radio_LLCC68_Multi\MDK-ARM\LLCC68_C8T6_Multi_8璺棤绾挎ā鍧�.uvprojx</PathAndName> + <NodeIsActive>1</NodeIsActive> + </project> + </ProjectWorkspace> diff --git a/KPLC/Src/BoardType.c b/KPLC/Src/BoardType.c index 542cccc..8a91b2c 100644 --- a/KPLC/Src/BoardType.c +++ b/KPLC/Src/BoardType.c @@ -12,7 +12,7 @@ extern int Region$$Table$$Limit; #define MAKE_VER(x,y) ((x<<8)|y) -#define APP_VER MAKE_VER(1,16) +#define APP_VER MAKE_VER(1,18) const stAppInfoBlock AppInfoBlock __attribute__((at(APPINFOBLOCK_ADDR))) = { diff --git a/KPLC/Src/main.c b/KPLC/Src/main.c index 3a16726..ddb11cc 100644 --- a/KPLC/Src/main.c +++ b/KPLC/Src/main.c @@ -51,6 +51,8 @@ #include "string.h" #include "BSP.h" #include "ModbusRTU.h" +#include "spiflash.h" + #if (BOARD_TYPE == 13) #include "w5500_port.h" #include "../src/Ethernet/socket.h" @@ -410,6 +412,65 @@ /* USER CODE END 0 */ +/** + * @brief This function handles EXTI line 0 and 1 interrupts. + */ +void EXTI0_1_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI0_1_IRQn 0 */ + + /* USER CODE END EXTI0_1_IRQn 0 */ + if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_0) != RESET) + { + LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0); + /* USER CODE BEGIN LL_EXTI_LINE_1 */ + + unsigned char PowerVolt = LL_GPIO_IsInputPinSet(GPIOA,LL_GPIO_PIN_0); +// KMem.WDT[79]++;// KMem.WDT[79]++; +/* + if (PowerVolt == 0) + { + PowerDownFlag=1; + }else + { + PowerDownFlag=0; + } +// */ + /* USER CODE END LL_EXTI_LINE_1 */ + } + /* USER CODE BEGIN EXTI0_1_IRQn 1 */ + + /* USER CODE END EXTI0_1_IRQn 1 */ +} + +void EXIT_Init() +{ + LL_EXTI_InitTypeDef EXTI_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + + /**/ + LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE0); + + /**/ + LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_0, LL_GPIO_PULL_NO); + + /**/ + LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_INPUT); + + /**/ + EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_0; + EXTI_InitStruct.LineCommand = ENABLE; + EXTI_InitStruct.Mode = LL_EXTI_MODE_IT; + EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING; + LL_EXTI_Init(&EXTI_InitStruct); + + /* EXTI interrupt init*/ + NVIC_SetPriority(EXTI0_1_IRQn, 0); + NVIC_EnableIRQ(EXTI0_1_IRQn); + +} /** * @brief The application entry point. @@ -463,7 +524,7 @@ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); - +// EXIT_Init(); KMachineInit(); ReadSysCfgFromFlash(&storedKMSysCfg); @@ -519,7 +580,8 @@ MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_SPI1_Init(); - LL_SPI_EnableIT_RXNE(SPI1); + + /* // MX_I2C1_Init(); Soft_I2C1_Init(); @@ -623,7 +685,8 @@ KMRunStat.WorkMode = 1; //KMRunStat.WorkMode2 = 0; - + W25QXX_Read((uchar *)(&KMem.DT[100]),256,28*2); + if (KMRunStat.WorkMode == 1){ InitPLC(); KMRunStat.WorkMode2 = KMem.CurJumperSW&0x20 ; @@ -636,8 +699,22 @@ KWireLessInit(KMem.EffJumperSW&0x20,KMem.EffJumperSW&0x0f); KWireLessStart(); #endif - + LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15); + KMem.WDT[82]=0; + + W25QXX_Read(&KMem.WDB[160],0,64); + KMem.WDT[82]++; + KMem.WDT[81]++; + W25QXX_Erase_Sector(0); + int time1=GetuS(); +// W25QXX_Write_Page(&KMem.WDB[160],0,64); +// SPI_Flash_Wait_Busy(); + int time2=GetuS(); + KMem.WDD[38] =time2-time1; +// W25QXX_Erase_Sector(0); + + KMem.SDT[64] = SPI_Flash_ReadID(); while (1) { //int MyKeyStat1,MyKeyStat2; @@ -645,6 +722,12 @@ //*((unsigned int *)&(PLCMem.SDT[10]))=nRunCount; // KMem.nRunCount=nRunCount; +// LL_GPIO_TogglePin(GPIOB,LL_GPIO_PIN_5); +// KMem.SDT[64] = SPI_Flash_ReadID(); +// SPI_FLASH_Write_Enable(); +// KMem.SDT[65] = SPI1_Flash_ReadSR(); + + SlowFlicker=0; FastFlicker=1; us1=GetuS(); @@ -701,25 +784,33 @@ displayInput(KMem.WX[0]); } us2=GetuS(); - if (PowerDownEvent) { KMem.WX[0]=0;} + if (PowerDownFlag) {KMem.WX[0]=0;} ///* - if ((KMem.nRunCount &0x1f) == 0x02) + if ((KMem.nRunCount &0xf) == 0x02) { ADCProcess(); - if (PowerDownEvent) + if (PowerDownFlag) { KMem.WX[0]=0; - if (!OldPowerDownEvent) + if (!OldPowerDownFlag) { - OldPowerDownEvent = PowerDownEvent; + OldPowerDownFlag = PowerDownFlag; OldPowerDownEventTime = nCurTick; + + KMem.WDT[80]++; + KMem.WDT[81]++; + CLR_SDA; + W25QXX_Erase_Sector(0); + W25QXX_Write_Page((uchar *)(&KMem.DT[100]),256,28*2); + W25QXX_Write_Page(&KMem.WDB[160],0,64); + SET_SDA; PowerDownProcess(); } }else { - if (OldPowerDownEvent) + if (OldPowerDownFlag) { - OldPowerDownEvent=PowerDownEvent; + OldPowerDownFlag=PowerDownFlag; PowerRecoverProcess(); } diff --git "a/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvopt" "b/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvopt" index 03a984e..d3bbdd0 100644 --- "a/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvopt" +++ "b/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvopt" @@ -101,6 +101,8 @@ <sRunDeb>0</sRunDeb> <sLrtime>0</sLrtime> <bEvRecOn>1</bEvRecOn> + <bSchkAxf>0</bSchkAxf> + <bTchkAxf>0</bTchkAxf> <nTsel>-1</nTsel> <sDll></sDll> <sDllPa></sDllPa> @@ -202,6 +204,10 @@ <pszMrule></pszMrule> <pSingCmds></pSingCmds> <pMultCmds></pMultCmds> + <pMisraNamep></pMisraNamep> + <pszMrulep></pszMrulep> + <pSingCmdsp></pSingCmdsp> + <pMultCmdsp></pMultCmdsp> </TargetOption> </Target> diff --git "a/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvproj" "b/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvproj" index 500c05f..e3d9910 100644 --- "a/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvproj" +++ "b/KSingleLineBus/KSingleLineBus_\345\215\225\346\200\273\347\272\277.uvproj" @@ -10,6 +10,7 @@ <TargetName>Button</TargetName> <ToolsetNumber>0x0</ToolsetNumber> <ToolsetName>MCS-51</ToolsetName> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STC15W4K32S4 Series</Device> @@ -217,12 +218,14 @@ <Mx51P>0</Mx51P> <hadXRAM2>0</hadXRAM2> <uocXram2>0</uocXram2> + <hadXRAM3>0</hadXRAM3> <ModC2>0</ModC2> <ModH2>0</ModH2> <Mdu_R515>0</Mdu_R515> <Mdu_F120>0</Mdu_F120> <Psoc>0</Psoc> <hadIROM2>0</hadIROM2> + <hadIROM3>0</hadIROM3> <ModSmx2>0</ModSmx2> <cBanks>0</cBanks> <xBanks>0</xBanks> @@ -292,6 +295,16 @@ <StartAddress>0x0</StartAddress> <Size>0x0</Size> </IROM512> + <XRA513> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </XRA513> + <IROM513> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </IROM513> </OnChipMemories> </Target51Misc> <C51> diff --git "a/MDK-ARM/F030C8T6_KAD_4\350\267\257\346\250\241\346\213\237\351\207\217.uvprojx" "b/MDK-ARM/F030C8T6_KAD_4\350\267\257\346\250\241\346\213\237\351\207\217.uvprojx" index 78a06b2..276a365 100644 --- "a/MDK-ARM/F030C8T6_KAD_4\350\267\257\346\250\241\346\213\237\351\207\217.uvprojx" +++ "b/MDK-ARM/F030C8T6_KAD_4\350\267\257\346\250\241\346\213\237\351\207\217.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git "a/MDK-ARM/F030C8T6_KBox_\346\216\247\345\210\266\347\233\222\345\255\220.uvprojx" "b/MDK-ARM/F030C8T6_KBox_\346\216\247\345\210\266\347\233\222\345\255\220.uvprojx" index 83dc1a5..8f6425b 100644 --- "a/MDK-ARM/F030C8T6_KBox_\346\216\247\345\210\266\347\233\222\345\255\220.uvprojx" +++ "b/MDK-ARM/F030C8T6_KBox_\346\216\247\345\210\266\347\233\222\345\255\220.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git "a/MDK-ARM/F030C8T6_KNet_\347\275\221\345\217\243\346\250\241\345\235\227.uvprojx" "b/MDK-ARM/F030C8T6_KNet_\347\275\221\345\217\243\346\250\241\345\235\227.uvprojx" index 163b443..0fce727 100644 --- "a/MDK-ARM/F030C8T6_KNet_\347\275\221\345\217\243\346\250\241\345\235\227.uvprojx" +++ "b/MDK-ARM/F030C8T6_KNet_\347\275\221\345\217\243\346\250\241\345\235\227.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/MDK-ARM/KLink_C8T6.uvprojx b/MDK-ARM/KLink_C8T6.uvprojx index a26ed76..05d8e4b 100644 --- a/MDK-ARM/KLink_C8T6.uvprojx +++ b/MDK-ARM/KLink_C8T6.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/MDK-ARM/KMini_C8T6.uvprojx b/MDK-ARM/KMini_C8T6.uvprojx index 35a3a1d..5c53144 100644 --- a/MDK-ARM/KMini_C8T6.uvprojx +++ b/MDK-ARM/KMini_C8T6.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git a/MDK-ARM/KMini_New_CCT6.uvprojx b/MDK-ARM/KMini_New_CCT6.uvprojx index b7c99c8..2ebbfad 100644 --- a/MDK-ARM/KMini_New_CCT6.uvprojx +++ b/MDK-ARM/KMini_New_CCT6.uvprojx @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030CCTx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git "a/MDK-ARM/KPLC_C8T6_\347\256\200\346\230\223PLC.uvprojx" "b/MDK-ARM/KPLC_C8T6_\347\256\200\346\230\223PLC.uvprojx" index 2582a00..eb89e68 100644 --- "a/MDK-ARM/KPLC_C8T6_\347\256\200\346\230\223PLC.uvprojx" +++ "b/MDK-ARM/KPLC_C8T6_\347\256\200\346\230\223PLC.uvprojx" @@ -10,7 +10,8 @@ <TargetName>F030C8T6_KPLC</TargetName> <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> - <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -311,7 +312,7 @@ <Cads> <interw>1</interw> <Optim>4</Optim> - <oTime>0</oTime> + <oTime>1</oTime> <SplitLS>0</SplitLS> <OneElfS>1</OneElfS> <Strict>0</Strict> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>1</v6Lang> <v6LangP>1</v6LangP> diff --git "a/MDK-ARM/Radio_LLCC68_C8T6_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" "b/MDK-ARM/Radio_LLCC68_C8T6_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" index b313caa..a321a00 100644 --- "a/MDK-ARM/Radio_LLCC68_C8T6_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" +++ "b/MDK-ARM/Radio_LLCC68_C8T6_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" @@ -11,6 +11,7 @@ <ToolsetNumber>0x4</ToolsetNumber> <ToolsetName>ARM-ADS</ToolsetName> <pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed> + <uAC6>0</uAC6> <TargetOption> <TargetCommonOption> <Device>STM32F030C8Tx</Device> @@ -323,6 +324,7 @@ <uThumb>0</uThumb> <uSurpInc>0</uSurpInc> <uC99>1</uC99> + <uGnu>0</uGnu> <useXO>0</useXO> <v6Lang>3</v6Lang> <v6LangP>3</v6LangP> diff --git a/Radio_LLCC68_Multi/Ethernet/W5500/w5500.c b/Radio_LLCC68_Multi/Ethernet/W5500/w5500.c new file mode 100644 index 0000000..1b80858 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/W5500/w5500.c @@ -0,0 +1,367 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include <stdio.h> +#include "w5500.h" + + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) +{ + uint8_t ret; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN1_); + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + ret = WIZCHIP.IF.SPI._read_byte(); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5000. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) +{ + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN1_); + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + uint16_t j = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++,j) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_FDM_OP_LEN4_); + for(i = 0; i < len/4; i++, j) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i*4] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+1] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+2] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i*4+3] = WIZCHIP.IF.SPI._read_byte(); + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4); + } + len %= 4; // for the rest data + // M20131220 : remove for loop + i *= 4; + if(len >= 2) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_ + + //for(j = 0; j < len/2 ; j++) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + pBuf[i+1] = WIZCHIP.IF.SPI._read_byte(); + i += 2; + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,2); + } + } + len %= 2; + if(len) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_ + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } + #else + #error "Unsupported _WIZCHIP_IO_MODE_SPI_ in W5500 !!!" + #endif + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) +{ + uint16_t i = 0; + uint16_t j = 0; + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + +#if( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)) + + #if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for(i = 0; i < len; i++,j) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + #elif( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_ ) + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_FDM_OP_LEN4_); + for(i = 0; i < len/4; i++, j) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4] ); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+1]); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+2]); + WIZCHIP.IF.SPI._write_byte(pBuf[i*4+3]); + AddrSel = WIZCHIP_OFFSET_INC(AddrSel,4); + } + len %= 4; // for the rest data + // M20131220 : Remove for loop + i *= 4; + if(len >= 2) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN4_ to _W5500_SPI_FDM_OP_LEN2_ + + //for(j = 0; j < len/2 ; j++) + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i] ); + WIZCHIP.IF.SPI._write_byte(pBuf[i+1]); + i += 2; + AddrSel = WIZCHIP_OFFSET_INC(AddrSel, 2); + } + len %= 2; + if(len) + { + AddrSel -= 1; // change _W5500_SPI_FDM_OP_LEN2_ to _W5500_SPI_FDM_OP_LEN1_ + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } + } + #else + #error "Unsupported _WIZCHIP_IO_SPI_ in W5500 !!!" + #endif + +#elif ( (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_) ) + + #if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_) + + #elif(_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) + + #else + #error "Unsupported _WIZCHIP_IO_MODE_BUS_ in W5500 !!!" + #endif +#else + #error "Unknown _WIZCHIP_IO_MODE_ in W5500. !!!!" +#endif + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + + +uint16_t getSn_TX_FSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); + } + }while (val != val1); + return val; +} + + +uint16_t getSn_RX_RSR(uint8_t sn) +{ + uint16_t val=0,val1=0; + do + { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + if (val1 != 0) + { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); + } + }while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + if(len == 0) return; + ptr = getSn_TX_WR(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel,wizdata, len); + + ptr += len; + setSn_TX_WR(sn,ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) +{ + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if(len == 0) return; + ptr = getSn_RX_RD(sn); + //M20140501 : implict type casting -> explict type casting + //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn,ptr); +} + + +void wiz_recv_ignore(uint8_t sn, uint16_t len) +{ + uint16_t ptr = 0; + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn,ptr); +} + diff --git a/Radio_LLCC68_Multi/Ethernet/W5500/w5500.h b/Radio_LLCC68_Multi/Ethernet/W5500/w5500.h new file mode 100644 index 0000000..2781a5f --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/W5500/w5500.h @@ -0,0 +1,2054 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _W5500_H_ +#define _W5500_H_ + +#include <stdint.h> +#include "Ethernet/wizchip_conf.h" + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1+4*N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2+4*N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3+4*N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address + + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR,VAL) WIZCHIP_WRITE(ADDR,VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR,BUF,LEN) WIZCHIP_READ_BUF(ADDR,BUF,LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN) WIZCHIP_WRITE(ADDR,BUF,LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref Common_register_access_function and @ref Socket_register_access_function + */ + + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - <b> Basic I/O function </b> \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() \n\n + * + * - @ref Common_register_group <b>access functions</b> \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# <b> Network Information </b> \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# <b> ICMP packet </b>\n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group <b>access functions</b> \n + * -# <b> SOCKET control</b> \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), setSn_IMR(), getSn_IR(), setSn_IR() + * -# <b> SOCKET information</b> \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() + * getSn_MSSR(), setSn_MSSR() + * -# <b> SOCKET communication </b> \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), setSn_TXBUF_SIZE() \n + * getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# <b> IP header field </b> \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + + + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa RTR, RCR : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + + + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication + */ + + + + /** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access <b>common registers</b>. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access <b>socket registers</b>. + */ + +//------------------------------- defgroup end -------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP ----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>RST</td> <td>Reserved</td> <td>WOL</td> <td>PB</td> <td>PPPoE</td> <td>Reserved</td> <td>FARP</td> <td>Reserved</td> </tr> + * </table> + * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be still until the bit will be written to by the host. + * If @ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n + * Each bit of @ref IR defined as follows. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>CONFLICT</td> <td>UNREACH</td> <td>PPPoE</td> <td>MP</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr> + * </table> + * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref IMR is used to mask interrupts. Each bit of @ref IMR corresponds to each bit of @ref IR. + * When a bit of @ref IMR is and the corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref IMR is an interrupt will not be issued even if the corresponding bit of @ref IR is \n\n + * Each bit of @ref IMR defined as the following. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>IM_IR7</td> <td>IM_IR6</td> <td>IM_IR5</td> <td>IM_IR4</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> </tr> + * </table> + * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued. + * In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref RTR configures the retransmission timeout period. The unit of timeout period is 100us and the default of @ref RTR is x07D0or 000 + * And so the default timeout period is 200ms(100us X 2000). During the time configured by @ref RTR, W5500 waits for the peer response + * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command). + * If the peer does not respond within the @ref RTR time, W5500 retransmits the packet or issues timeout. + */ +#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref RCR configures the number of time of retransmission. + * When retransmission occurs as many as ref RCR+1 Timeout interrupt is issued (@ref Sn_IR[TIMEOUT] = . + */ +#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates + * the destination IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when data is sent to a port number + * which socket is not open and @ref UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR + * indicates the destination IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + + +//----------------------------- W5500 Socket Registers IOMAP ----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>MULTI/MFEN</td> <td>BCASTB</td> <td>ND/MC/MMB</td> <td>UCASTB/MIP6B</td> <td>Protocol[3]</td> <td>Protocol[2]</td> <td>Protocol[1]</td> <td>Protocol[0]</td> </tr> + * </table> + * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block <b>in UDP Multicasting</b> + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used <b>in UDP mulitcasting</b> + * - @ref Sn_MR_MMB : Multicast Blocking <b>in @ref Sn_MR_MACRAW mode</b> + * - @ref Sn_MR_UCASTB : Unicast Block <b>in UDP Multicating</b> + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking <b>in @ref Sn_MR_MACRAW mode</b> + * - <b>Protocol</b> + * <table> + * <tr> <td><b>Protocol[3]</b></td> <td><b>Protocol[2]</b></td> <td><b>Protocol[1]</b></td> <td><b>Protocol[0]</b></td> <td>@b Meaning</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>Closed</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>TCP</td> </tr> + * <tr> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>UDP</td> </tr> + * <tr> <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>MACRAW</td> </tr> + * </table> + * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n + * After W5500 accepts the command, the @ref Sn_CR register is automatically cleared to 0x00. + * Even though @ref Sn_CR is cleared to 0x00, the command is still being processed.\n + * To check whether the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(<b>Server mode</b>) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(<b>Client mode</b>) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n + * When an interrupt occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of @ref Sn_IR becomes \n + * In order to clear the @ref Sn_IR bit, the host should write the bit to \n + * <table> + * <tr> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> + * <tr> <td>Reserved</td> <td>Reserved</td> <td>Reserved</td> <td>SEND_OK</td> <td>TIMEOUT</td> <td>RECV</td> <td>DISCON</td> <td>CON</td> </tr> + * </table> + * - \ref Sn_IR_SENDOK : <b>SEND_OK Interrupt</b> + * - \ref Sn_IR_TIMEOUT : <b>TIMEOUT Interrupt</b> + * - \ref Sn_IR_RECV : <b>RECV Interrupt</b> + * - \ref Sn_IR_DISCON : <b>DISCON Interrupt</b> + * - \ref Sn_IR_CON : <b>CON Interrupt</b> + */ +#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UPD mode. It should be set before OPEN command is ordered. + */ +#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or + * it indicates that it is acquired in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In TCP client mode, it configures an IP address of 锟絋CP serverbefore CONNECT command. + * In TCP server mode, it indicates an IP address of 锟絋CP clientafter successfully establishing connection. + * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode. + * In 锟絋CP clientmode, it configures the listen port number of 锟絋CP serverbefore CONNECT command. + * In 锟絋CP Servermode, it indicates the port number of TCP client after successfully establishing connection. + * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n. + */ +#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n. + * It is set before OPEN command. + */ +#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from a peer. + * Although Socket n RX Buffer Block size is initially configured to 2Kbytes, + * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can锟絫 be normally transmitted to a peer. + * Although Socket n TX Buffer Block size is initially configured to 2Kbytes, + * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. + * When exceeded, the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by @ref Sn_TXBUF_SIZE. + * Data bigger than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent. + * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size, + * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size, + * transmit the data after dividing into the checked size and saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP. + * After its initialization, it is auto-increased by SEND command. + * SEND command transmits the saved data from the current @ref Sn_TX_RD to the @ref Sn_TX_WR in the Socket n TX Buffer. + * After transmitting the saved data, the SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. + * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with TCP.\n + * It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased value as many as transmitting data size. + * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between + * 锟絊ocket n RX Write Pointer (@ref Sn_RX_WR)and 锟絊ocket n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased value as many as the reading size. + * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception. + * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), + * then the carry bit is ignored and will automatically update with the lower 16bits value. + */ +#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is occurred and the corresponding bit of @ref Sn_IMR is + * the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is + * Host is interrupted by asserted INTn PIN to low. + */ +#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of 锟終EEP ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, + * and ignored in other modes. The time unit is 5s. + * KA packet is transmittable after @ref Sn_SR is changed to SOCK_ESTABLISHED and after the data is transmitted or received to/from a peer at least once. + * In case of '@ref Sn_KPALVTR > 0', W5500 automatically transmits KA packet after time-period for checking the TCP connection (Auto-keepalive-process). + * In case of '@ref Sn_KPALVTR = 0', Auto-keep-alive-process will not operate, + * and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + + +//----------------------------- W5500 Register values ----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been normally processed, the Interrupt PIN (INTn) asserts to low. + * When using WOL mode, the UDP Socket should be opened with any source port number. (Refer to Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and + * 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as + * When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set. + */ +#define IR_MP 0x10 + + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7<<3) +#define PHYCFGR_OPMDC_PDOWN (6<<3) +#define PHYCFGR_OPMDC_NA (5<<3) +#define PHYCFGR_OPMDC_100FA (4<<3) +#define PHYCFGR_OPMDC_100F (3<<3) +#define PHYCFGR_OPMDC_100H (2<<3) +#define PHYCFGR_OPMDC_10F (1<<3) +#define PHYCFGR_OPMDC_10H (0<<3) +#define PHYCFGR_DPX_FULL (1<<2) +#define PHYCFGR_DPX_HALF (0<<2) +#define PHYCFGR_SPD_100 (1<<1) +#define PHYCFGR_SPD_10 (0<<1) +#define PHYCFGR_LNK_ON (1<<0) +#define PHYCFGR_LNK_OFF (0<<0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number + * before Socket n is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m + * In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n + * When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref RTR. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to itself. + * When this bit is W5500 can receive all packets on Ethernet. + * If user wants to implement Hybrid TCP/IP stack, + * it is recommended that this bit is set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0). + * The table below shows the value of @ref Sn_SR corresponding to @ref Sn_MR.\n + * <table> + * <tr> <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td> </tr> + * <tr> <td>Sn_MR_CLOSE (000</td> <td></td> </tr> + * <tr> <td>Sn_MR_TCP (001</td> <td>SOCK_INIT (0x13)</td> </tr> + * <tr> <td>Sn_MR_UDP (010</td> <td>SOCK_UDP (0x22)</td> </tr> + * <tr> <td>S0_MR_MACRAW (100</td> <td>SOCK_MACRAW (0x02)</td> </tr> + * </table> + */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (Sn_MR(P3:P0) = Sn_MR_TCP). + * In this mode, Socket n operates as a 锟絋CP serverand waits for connection-request (SYN packet) from any 锟絋CP client + * The @ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN. + * When a 锟絋CP clientconnection request is successfully established, + * the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes + * But when a 锟絋CP clientconnection request is failed, Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to b>TCP server</b>configured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n + * The connect-request fails in the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as b>TCP client</b> + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of b>TCP server</b>or b>TCP client</b> the DISCON command processes the disconnect-process (b>Active close</b>or b>Passive close</b>.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (Sn_IR(3)=)= and then @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n, + * TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n + * But SEND_MAC transmits data without the automatic ARP-process.\n + * In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive packet.\n + * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n + * For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR), + * and Socket n RX Read Pointer Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\N + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\N + * It is changed to @ref SOCK_INIT when Sn_MR(P[3:0]) = 001and OPEN command is ordered.\N + * After @ref SOCK_INIT, user can use LISTEN /CONNECT command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer (b>TCP client</b>.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n + * Otherwise it will change to @ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = . + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n + * It is temporarily shown when @ref Sn_SR is changed from @ref SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n + * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n + * Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n + * If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n + * If not, it changes to @ref SOCK_CLOSED after timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the b>TCP SERVER</b>processed the SYN packet from the b>TCP CLIENT</b>during @ref SOCK_LISTEN, or + * when the CONNECT command is successful.\n + * During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and passive-close.\n + * When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n + * This is half-closing status, and data can be transferred.\n + * For full-closing, DISCON command is used. But For just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n + * It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs (@ref Sn_IR[TIMEOUT] = . + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010.\n + * It changes to SOCK_UPD when Sn_MR(P[3:0]) = 010 and OPEN command is ordered.\n + * Unlike TCP mode, data can be transfered without the connection-process. + */ +#define SOCK_UDP 0x22 + +//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = 100and is valid only in Socket 0.\n + * It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n + * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt.\n + * In OS environment, You can replace it to critical section api supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole interrupt. \n + * In OS environment, You can replace it to critical section api supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + + + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ (uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) \ + WIZCHIP_WRITE(MR,mr) + + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() \ + WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) \ + WIZCHIP_WRITE_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) \ + WIZCHIP_READ_BUF(GAR,gar,4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) \ + WIZCHIP_WRITE_BUF(SUBR, subr,4) + + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) \ + WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) \ + WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) \ + WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) \ + WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) \ + WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) {\ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \ + } + + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) \ + WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() \ + (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref IMR register + * @param (uint8_t)imr Value to set @ref IMR register. + * @sa getIMR() + */ +#define setIMR(imr) \ + WIZCHIP_WRITE(IMR, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IMR register + * @return uint8_t. Value of @ref IMR register. + * @sa setIMR() + */ +#define getIMR() \ + WIZCHIP_READ(IMR) + + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) \ + WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() \ + WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) \ + WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() \ + WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RTR register + * @param (uint16_t)rtr Value to set @ref RTR register. + * @sa getRTR() + */ +#define setRTR(rtr) {\ + WIZCHIP_WRITE(RTR, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR,1), (uint8_t) rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RTR register + * @return uint16_t. Value of @ref RTR register. + * @sa setRTR() + */ +#define getRTR() \ + ((WIZCHIP_READ(RTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(RTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref RCR register + * @param (uint8_t)rcr Value to set @ref RCR register. + * @sa getRCR() + */ +#define setRCR(rcr) \ + WIZCHIP_WRITE(RCR, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref RCR register + * @return uint8_t. Value of @ref RCR register. + * @sa setRCR() + */ +#define getRCR() \ + WIZCHIP_READ(RCR) + +//================================================== test done =========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) \ + WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() \ + WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) \ + WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() \ + WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) \ + WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) \ + WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) {\ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +//uint16_t getPSID(void); +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes. + */ +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) \ + WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() \ + WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() \ + WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) \ + WIZCHIP_WRITE(Sn_MR(sn),mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) \ + WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) \ + WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) \ + WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) \ + WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) \ + (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) \ + WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) \ + (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) \ + WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) \ + WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) \ + WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) \ + WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes. + * @sa SetSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) \ + WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) \ + WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) \ + WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) \ + WIZCHIP_WRITE(Sn_TTL(sn), ttl) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) \ + WIZCHIP_READ(Sn_TTL(sn)) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) \ + WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @regurn uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) + + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) \ + WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) \ + WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) + +/** + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +//uint16_t getSn_TxMAX(uint8_t sn); +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the <i>wizdata(pointer buffer)</i> of the length of <i>len(variable)</i> bytes to internal TX memory + * and updates the Tx write pointer register. + * This function is being called by send() and sendto() function also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes. + * This function is being called by recv() also. + * + * @note User should read upper byte first and lower byte later to get proper value. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of <i>len(variable)</i> bytes in internal RX memory. + * @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +#endif // _W5500_H_ diff --git a/Radio_LLCC68_Multi/Ethernet/loopback.c b/Radio_LLCC68_Multi/Ethernet/loopback.c new file mode 100644 index 0000000..a921092 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/loopback.c @@ -0,0 +1,225 @@ +#include <stdio.h> +#include "loopback.h" +#include "socket.h" +#include "wizchip_conf.h" + +#if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK + +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size = 0, sentsize=0; + +#ifdef _LOOPBACK_DEBUG_ + uint8_t destip[4]; + uint16_t destport; +#endif + + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) + { +#ifdef _LOOPBACK_DEBUG_ + getSn_DIPR(sn, destip); + destport = getSn_DPORT(sn); + + printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn,Sn_IR_CON); + } + if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recv(sn, buf, size); + + if(ret <= 0) return ret; // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY. + size = (uint16_t) ret; + sentsize = 0; + + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); + if(ret < 0) + { + close(sn); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret = disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port); +#endif + if( (ret = listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP server loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) +{ + int32_t ret; // return value for SOCK_ERRORs + uint16_t size = 0, sentsize=0; + + // Destination (TCP Server) IP info (will be connected) + // >> loopback_tcpc() function parameter + // >> Ex) + // uint8_t destip[4] = {192, 168, 0, 214}; + // uint16_t destport = 5000; + + // Port number for TCP client (will be increased) + static uint16_t any_port = 50000; + + // Socket Status Transitions + // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status) + switch(getSn_SR(sn)) + { + case SOCK_ESTABLISHED : + if(getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + setSn_IR(sn, Sn_IR_CON); // this interrupt should be write the bit cleared to '1' + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // Data Transaction Parts; Handle the [data receive and send] process + ////////////////////////////////////////////////////////////////////////////////////////////// + if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array) + ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer) + + if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end + size = (uint16_t) ret; + sentsize = 0; + + // Data sentsize control + while(size != sentsize) + { + ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer) + if(ret < 0) // Send Error occurred (sent data length < 0) + { + close(sn); // socket close + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + ////////////////////////////////////////////////////////////////////////////////////////////// + break; + + case SOCK_CLOSE_WAIT : +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:CloseWait\r\n",sn); +#endif + if((ret=disconnect(sn)) != SOCK_OK) return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Socket Closed\r\n", sn); +#endif + break; + + case SOCK_INIT : +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport); +#endif + if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret; // Try to TCP connect to the TCP server (destination) + break; + + case SOCK_CLOSED: + close(sn); + if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){ + if(any_port == 0xffff) any_port = 50000; + return ret; // TCP socket open with 'any_port' port number + } +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:TCP client loopback start\r\n",sn); + //printf("%d:Socket opened\r\n",sn); +#endif + break; + default: + break; + } + return 1; +} + + +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) +{ + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + + switch(getSn_SR(sn)) + { + case SOCK_UDP : + if((size = getSn_RX_RSR(sn)) > 0) + { + if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; + ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); + if(ret <= 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: recvfrom error. %ld\r\n",sn,ret); +#endif + return ret; + } + size = (uint16_t) ret; + sentsize = 0; + while(sentsize != size) + { + ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport); + if(ret < 0) + { +#ifdef _LOOPBACK_DEBUG_ + printf("%d: sendto error. %ld\r\n",sn,ret); +#endif + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: +#ifdef _LOOPBACK_DEBUG_ + //printf("%d:UDP loopback start\r\n",sn); +#endif + if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn) + return ret; +#ifdef _LOOPBACK_DEBUG_ + printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port); +#endif + break; + default : + break; + } + return 1; +} + +#endif diff --git a/Radio_LLCC68_Multi/Ethernet/loopback.h b/Radio_LLCC68_Multi/Ethernet/loopback.h new file mode 100644 index 0000000..45c0283 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/loopback.h @@ -0,0 +1,38 @@ +#ifndef _LOOPBACK_H_ +#define _LOOPBACK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +/* Loopback test debug message printout enable */ +// #define _LOOPBACK_DEBUG_ + +/* DATA_BUF_SIZE define for Loopback example */ +#ifndef DATA_BUF_SIZE + #define DATA_BUF_SIZE 256 +#endif + +/************************/ +/* Select LOOPBACK_MODE */ +/************************/ +#define LOOPBACK_MAIN_NOBLOCK 0 +#define LOOPBACK_MODE LOOPBACK_MAIN_NOBLOCK + + +/* TCP server Loopback test example */ +int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port); + +/* TCP client Loopback test example */ +int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport); + +/* UDP Loopback test example */ +int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Radio_LLCC68_Multi/Ethernet/socket.c b/Radio_LLCC68_Multi/Ethernet/socket.c new file mode 100644 index 0000000..2312617 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/socket.c @@ -0,0 +1,688 @@ +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address. +//! Copy 4 byte addr value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#define SOCK_ANY_PORT_NUM 0xC000; + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; +static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; + +#if _WIZCHIP_ == 5200 + static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; +#endif + +#define CHECK_SOCKNUM() \ + do{ \ + if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + }while(0); \ + +#define CHECK_SOCKMODE(mode) \ + do{ \ + if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + }while(0); \ + +#define CHECK_SOCKINIT() \ + do{ \ + if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + }while(0); \ + +#define CHECK_SOCKDATA() \ + do{ \ + if(len == 0) return SOCKERR_DATALEN; \ + }while(0); \ + + + +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) +{ + CHECK_SOCKNUM(); + switch(protocol) + { + case Sn_MR_TCP : + case Sn_MR_UDP : + case Sn_MR_MACRAW : + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW : + case Sn_MR_PPPoE : + break; + #endif + default : + return SOCKERR_SOCKMODE; + } + if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if(flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if(flag != 0) + { + switch(protocol) + { + case Sn_MR_TCP: + if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; + break; + case Sn_MR_UDP: + if(flag & SF_IGMP_VER2) + { + if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; + } + #if _WIZCHIP_ == 5500 + if(flag & SF_UNI_BLOCK) + { + if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } + #endif + break; + default: + break; + } + } + close(sn); + setSn_MR(sn, (protocol | (flag & 0xF0))); + if(!port) + { + port = sock_any_port++; + if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn,port); + setSn_CR(sn,Sn_CR_OPEN); + while(getSn_CR(sn)); + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1<<sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while(getSn_SR(sn) == SOCK_CLOSED); + return (int8_t)sn; +} + +int8_t close(uint8_t sn) +{ + CHECK_SOCKNUM(); + + setSn_CR(sn,Sn_CR_CLOSE); + /* wait to process the command... */ + while( getSn_CR(sn) ); + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + sock_is_sending &= ~(1<<sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while(getSn_SR(sn) != SOCK_CLOSED); + return SOCK_OK; +} + +int8_t listen(uint8_t sn) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn,Sn_CR_LISTEN); + while(getSn_CR(sn)); + while(getSn_SR(sn) != SOCK_LISTEN) + { + if(getSn_CR(sn) == SOCK_CLOSED) + { + close(sn); + return SOCKERR_SOCKCLOSED; + } + } + return SOCK_OK; +} + + +int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[0] & 0x000000FF); + if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if(port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn,addr); + setSn_DPORT(sn,port); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR(0); + #endif + setSn_CR(sn,Sn_CR_CONNECT); + while(getSn_CR(sn)); + if(sock_io_mode & (1<<sn)) return SOCK_BUSY; + while(getSn_SR(sn) != SOCK_ESTABLISHED) + { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + return SOCKERR_TIMEOUT; + } + } + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + + return SOCK_OK; +} + +int8_t disconnect(uint8_t sn) +{ + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn,Sn_CR_DISCON); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending &= ~(1<<sn); + if(sock_io_mode & (1<<sn)) return SOCK_BUSY; + while(getSn_SR(sn) != SOCK_CLOSED) + { + if(getSn_IR(sn) & Sn_IR_TIMEOUT) + { + close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp=0; + uint16_t freesize=0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS; + if( sock_is_sending & (1<<sn) ) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + #if _WZICHIP_ == 5200 + if(getSn_TX_RD(sn) != sock_next_rd[sn]) + { + setSn_CR(sn,Sn_CR_SEND); + while(getSn_CR(sn)); + return SOCKERR_BUSY; + } + #endif + sock_is_sending &= ~(1<<sn); + } + else if(tmp & Sn_IR_TIMEOUT) + { + close(sn); + return SOCKERR_TIMEOUT; + } + else return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + } + wiz_send_data(sn, buf, len); + #if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; + #endif + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + sock_is_sending |= (1 << sn); + return len; +} + + +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) +{ + uint8_t tmp = 0; + uint16_t recvsize = 0; + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if(recvsize < len) len = recvsize; + while(1) + { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) + { + if(tmp == SOCK_CLOSE_WAIT) + { + if(recvsize != 0) break; + else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + else + { + close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; + if(recvsize != 0) break; + }; + if(recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + return len; +} + +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) +{ + uint8_t tmp = 0; + uint16_t freesize = 0; + CHECK_SOCKNUM(); + switch(getSn_MR(sn) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + break; + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + //M20140501 : For avoiding fatal error on memory align mismatched + //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + } + // + if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if(port == 0) return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + + setSn_DIPR(sn,addr); + setSn_DPORT(sn,port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while(1) + { + freesize = getSn_TX_FSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; + if(len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR(0); + #endif + + setSn_CR(sn,Sn_CR_SEND); + /* wait to process the command... */ + while(getSn_CR(sn)); + #if _WIZCHIP_ == 5200 // for W5200 ARP errata + setSUBR((uint8_t*)"\x00\x00\x00\x00"); + #endif + while(1) + { + tmp = getSn_IR(sn); + if(tmp & Sn_IR_SENDOK) + { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + //M:20131104 + //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if(tmp & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + //////////// + } + return len; +} + + + +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) +{ + uint8_t mr; + uint8_t head[8]; + uint16_t pack_len=0; + + CHECK_SOCKNUM(); + //CHECK_SOCKMODE(Sn_MR_UDP); + switch((mr=getSn_MR(sn)) & 0x0F) + { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + case Sn_MR_PPPoE: + break; + #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if(sock_remained_size[sn] == 0) + { + while(1) + { + pack_len = getSn_RX_RSR(sn); + if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; + if(pack_len != 0) break; + }; + } + sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) + { + case Sn_MR_UDP : + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 8); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + // read peer's IP address, port number & packet length + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW : + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 2); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; + if(sock_remained_size[sn] > 1514) + { + close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn,buf,pack_len); + break; + #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if(sock_remained_size[sn] == 0) + { + wiz_recv_data(sn, head, 6); + setSn_CR(sn,Sn_CR_RECV); + while(getSn_CR(sn)); + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if(len < sock_remained_size[sn]) pack_len = len; + else pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + #endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn,Sn_CR_RECV); + /* wait to process the command... */ + while(getSn_CR(sn)) ; + sock_remained_size[sn] -= pack_len; + //M20140501 : replace 0x01 with PACK_REMAINED + //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; + // + return pack_len; +} + + +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) +{ + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch(cstype) + { + case CS_SET_IOMODE: + tmp = *((uint8_t*)arg); + if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn); + else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn); + else return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + //M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t*)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t*)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t*)arg) = getSn_IR(sn); + break; + case CS_SET_INTMASK: + if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn,*(uint8_t*)arg); + break; + case CS_GET_INTMASK: + *((uint8_t*)arg) = getSn_IMR(sn); + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + // M20131220 : Remove warning + //uint8_t tmp; + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_TTL: + setSn_TTL(sn,*(uint8_t*)arg); + break; + case SO_TOS: + setSn_TOS(sn,*(uint8_t*)arg); + break; + case SO_MSS: + setSn_MSSR(sn,*(uint16_t*)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t*)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); + #if _WIZCHIP_ > 5200 + if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; + #endif + setSn_CR(sn,Sn_CR_SEND_KEEP); + while(getSn_CR(sn) != 0) + { + // M20131220 + //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) + { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn,*(uint8_t*)arg); + break; + #endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg) +{ + CHECK_SOCKNUM(); + switch(sotype) + { + case SO_FLAG: + *(uint8_t*)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t*) arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t*) arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint8_t*) arg = getSn_MSSR(sn); + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t*)arg); + break; + case SO_DESTPORT: + *(uint16_t*) arg = getSn_DPORT(sn); + break; + #if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t*) arg = getSn_KPALVTR(sn); + break; + #endif + case SO_SENDBUF: + *(uint16_t*) arg = getSn_TX_FSR(sn); + case SO_RECVBUF: + *(uint16_t*) arg = getSn_RX_RSR(sn); + case SO_STATUS: + *(uint8_t*) arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if(getSn_MR(sn) == Sn_MR_TCP) + *(uint16_t*)arg = getSn_RX_RSR(sn); + else + *(uint16_t*)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint8_t*)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} diff --git a/Radio_LLCC68_Multi/Ethernet/socket.h b/Radio_LLCC68_Multi/Ethernet/socket.h new file mode 100644 index 0000000..53411e2 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/socket.h @@ -0,0 +1,466 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has much similar name and interface. + * But there is a little bit of difference. + * @details + * <b> Comparison between WIZnet and Berkeley SOCKET APIs </b> + * <table> + * <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td> </tr> + * <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr> + * <tr> <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr> + * <tr> <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>send()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr> + * <tr> <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td> </tr> + * </table> + * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, + * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n + * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. + * When the listen SOCKET accepts a connection request from a client, it keeps listening. + * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n + * Following figure shows network flow diagram by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n + * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, + * it is changed in order to communicate with the client. + * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n + * If there're many listen SOCKET with same listen port number and a client requests a connection, + * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ + +#include "Ethernet/wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY 0 ///< Socket is busy on processing the operation. Valid only Non-block IO Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT (SOCK_ERROR - 3) ///< Socket is not initialized +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argrument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN (Sn_MR_MFEN) ///< In \ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet +#define SF_IGMP_VER2 (Sn_MR_MC) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In \ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE (Sn_MR_MULTI) ///< In \ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 + #define SF_BROAD_BLOCK (Sn_MR_BCASTB) ///< In \ref Sn_MR_UDP or \ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500 + #define SF_MULTI_BLOCK (Sn_MR_MMB) ///< In \ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500 + #define SF_IPv6_BLOCK (Sn_MR_MIP6B) ///< In \ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500 + #define SF_UNI_BLOCK (Sn_MR_UCASTB) ///< In \ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500 +#endif + +#define SF_IO_NONBLOCK 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. +#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. +#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n + * Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediatly. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned immediatly\n + */ +int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. \n + * In Non-block io mode, it return @ref SOCK_BUSY immediatly. \n + + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n + * In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n + * In non-block io mode, It return @ref SOCK_BUSY immediatly when socket buffer is not enough. \n + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t send(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n + * In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n + * In non-block io mode, it return @ref SOCK_BUSY immediatly when <I>len</I> is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n + * Even if the connectionless socket has been previously connected to a specific address, + * the address and port number parameters override the destination address for that particular datagram only. + * @note In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>. + * In non-block io mode, It return @ref SOCK_BUSY immediatly when socket buffer is not enough. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n + * This function is used to receive UDP and MAC_RAW mode, and handle the header as well. + * This function can divide to received the packet data. + * On the MACRAW SOCKET, the addr and port parameters are ignored. + * @note In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer + * In non-block io mode, it return @ref SOCK_BUSY immediatly when <I>len</I> is greater than data size in socket buffer. + * + * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet sized. + * When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. + * It is valid only when the first call recvfrom for receiving the packet. + * When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the packet. +* When it is valid, @ref packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); + + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum +{ + SIK_CONNECTED = (1 << 0), ///< conntected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occured + SIK_SENT = (1 << 4), ///< send ok + SIK_ALL = 0x1F, ///< all interrupt +}sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum +{ + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref sockint_kind +}ctlsock_type; + + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum +{ + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket(). + SO_TTL, ///< Set/Get TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set/Get TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set/Get MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set/Get the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set/Get the destionation Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode + #if _WIZCHIP_ > 5200 + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmittion timer in TCP mode + #endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode. +}sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. + * Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. \n + * <table> + * <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr> + * <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr> + * <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr> + * <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc. </td></tr> + * </table> + * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to <I>sotype</I>. \n + * <table> + * <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr> + * <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> + * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr> + * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr> + * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> + * </table> + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet \n + */ +int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to <I>sotype</I>. \n + * <table> + * <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr> + * <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr> + * <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> + * <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> + * <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr> + * <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> </td></tr> + * <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> + * <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> + * <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr> + * <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr> + * <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr> + * </table> + * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n + * When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, + * This means the zero byte UDP data(UDP Header only) received. + */ +int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg); + +#endif // _SOCKET_H_ diff --git a/Radio_LLCC68_Multi/Ethernet/wizchip_conf.c b/Radio_LLCC68_Multi/Ethernet/wizchip_conf.c new file mode 100644 index 0000000..bfc19e3 --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/wizchip_conf.c @@ -0,0 +1,636 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readbyte() & wizchip_bus_writebyte() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t* +//! For remove the warning when pointer type size is not 32bit. +//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +//A20140501 : for use the type - ptrdiff_t +#include <stddef.h> +// + +#include "wizchip_conf.h" +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_enter(void) {}; +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cris_exit(void) {}; +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_select(void) {}; +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_cs_deselect(void) {}; +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + //M20140501 : Explict pointer type casting +//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *) AddrSel); }; +uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }; +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ + +//M20140501 : Explict pointer type casting +//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*) AddrSel) = wb; }; +void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }; + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +uint8_t wizchip_spi_readbyte(void) {return 0;}; +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe this function or register any functions, + * null function is called. + */ +void wizchip_spi_writebyte(uint8_t wb) {}; + +/** + * @\ref _WIZCHIP instance + */ +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) +{ + if(!cris_en || !cris_ex) + { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } + else + { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) +{ + if(!cs_sel || !cs_desel) + { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } + else + { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); + + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) +{ + while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); + + if(!spi_rb || !spi_wb) + { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } + else + { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) +{ + uint8_t tmp = 0; + uint8_t* ptmp[2] = {0,0}; + switch(cwtype) + { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if(arg != 0) + { + ptmp[0] = (uint8_t*)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind*)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind*)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind*)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind*)arg) = wizchip_getinterruptmask(); + break; + #if _WIZCHIP_ > 5100 + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t*)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t*)arg = getINTLEVEL(); + break; + #endif + case CW_GET_ID: + ((uint8_t*)arg)[0] = WIZCHIP.id[0]; + ((uint8_t*)arg)[1] = WIZCHIP.id[1]; + ((uint8_t*)arg)[2] = WIZCHIP.id[2]; + ((uint8_t*)arg)[3] = WIZCHIP.id[3]; + ((uint8_t*)arg)[4] = WIZCHIP.id[4]; + ((uint8_t*)arg)[5] = 0; + break; + #if _WIZCHIP_ == 5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf*)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t*)arg); + #endif + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if((int8_t)tmp == -1) return -1; + *(uint8_t*)arg = tmp; + break; + default: + return -1; + } + return 0; +} + + +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) +{ + + switch(cntype) + { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo*)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo*)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type*)arg); + case CN_GET_NETMODE: + *(netmode_type*)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout*)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout*)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) +{ + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; + getSHAR(mac); + getGAR(gw); getSUBR(sn); getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) +{ + int8_t i; + int8_t tmp = 0; + wizchip_sw_reset(); + if(txsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += txsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_TXBUF_SIZE(i, txsize[i]); + } + if(rxsize) + { + tmp = 0; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + tmp += rxsize[i]; + if(tmp > 16) return -1; + for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) + setSn_RXBUF_SIZE(i, rxsize[i]); + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) +{ + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + ir |= (1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + ir |= sir; + setIR(ir); +#else + setIR(ir); + setSIR(sir); +#endif +} + +intr_kind wizchip_getinterrupt(void) +{ + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + ir = getIR(); + sir = ir 0x0F; +#else + ir = getIR(); + sir = getSIR(); +#endif + +#if _WIZCHIP_ < 5500 + ir &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) +{ + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < 5200 + simr &= 0x0F; +#endif + +#if _WIZCHIP_ == 5100 + imr |= simr; + setIMR(imr); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) +{ + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ == 5100 + imr = getIMR(); + simr = imr 0x0F; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < 5500 + imr &= ~(1<<4); // IK_WOL +#endif +#if _WIZCHIP_ == 5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) +{ + int8_t tmp; +#if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + else + tmp = PHY_LINK_OFF; +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > 5100 + +int8_t wizphy_getphypmode(void) +{ + int8_t tmp = 0; + #if _WIZCHIP_ == 5200 + if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #elif _WIZCHIP_ == 5500 + if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; + #else + tmp = -1; + #endif + return tmp; +} +#endif + +#if _WIZCHIP_ == 5500 +void wizphy_reset(void) +{ + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + if(phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if(phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else + { + if(phyconf->duplex == PHY_DUPLEX_FULL) + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } + else + { + if(phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf* phyconf) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch(tmp & PHYCFGR_OPMDC_ALLA) + { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf* phyconf) +{ + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) +{ + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if((tmp & PHYCFGR_OPMD)== 0) return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if( pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if( pmode == PHY_POWER_DOWN) + { + if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; + } + else + { + if(tmp & PHYCFGR_OPMDC_ALLA) return 0; + } + return -1; +} +#endif + + +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) +{ + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) +{ + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0]= _DNS_[0]; + pnetinfo->dns[1]= _DNS_[1]; + pnetinfo->dns[2]= _DNS_[2]; + pnetinfo->dns[3]= _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) +{ + uint8_t tmp = 0; +#if _WIZCHIP_ != 5500 + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; +#else + if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) +{ + return (netmode_type) getMR(); +} + +void wizchip_settimeout(wiz_NetTimeout* nettime) +{ + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout* nettime) +{ + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} diff --git a/Radio_LLCC68_Multi/Ethernet/wizchip_conf.h b/Radio_LLCC68_Multi/Ethernet/wizchip_conf.h new file mode 100644 index 0000000..d39040b --- /dev/null +++ b/Radio_LLCC68_Multi/Ethernet/wizchip_conf.h @@ -0,0 +1,548 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#include <stdint.h> +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b 5100, \b 5200 ,\b 5500 or etc. \n\n + * ex> <code> #define \_WIZCHIP_ 5500 </code> + */ +#define _WIZCHIP_ 5500 // 5100, 5200, 5500 + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ + + +#if (_WIZCHIP_ == 5100) + #define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ + +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +#elif (_WIZCHIP_ == 5200) + #define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + #include "W5200/w5200.h" +#elif (_WIZCHIP_ == 5500) + #define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == 5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code> + * + */ + //#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ + #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ + #include "W5500/w5500.h" +#else + #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ + #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n + * ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code> + */ +#define _WIZCHIP_IO_BASE_ 0x00000000 // + +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS + #ifndef _WIZCHIP_IO_BASE_ + #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." + #endif +#endif + +#if _WIZCHIP_ > 5100 + #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else + #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + + +/******************************************************** +* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. +*********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP +{ + uint16_t if_mode; ///< host interface mode + uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS + { + void (*_enter) (void); ///< crtical section enter + void (*_exit) (void); ///< critial section exit + }CRIS; + /** + * The set of @ref\_WIZCHIP_ select control callback func. + */ + struct _CS + { + void (*_select) (void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + }CS; + /** + * The set of interface IO callback func. + */ + union _IF + { + /** + * For BUS interface IO + */ + struct + { + uint8_t (*_read_byte) (uint32_t AddrSel); + void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + }BUS; + /** + * For SPI interface IO + */ + struct + { + uint8_t (*_read_byte) (void); + void (*_write_byte) (uint8_t wb); + }SPI; + // To be added + // + }IF; +}_WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum +{ + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Inializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + +#if _WIZCHIP_ == 5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5000 + CW_SET_PHYCONF, ///< When PHY configured by interal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in interal register. Valid Only W5000 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5000 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as noraml and down when PHYSTATUS.OPMD == 1. Valid Only W5000 +#endif + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal + CW_GET_PHYLINK ///< Get PHY Link status +}ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum +{ + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +}ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum +{ +#if _WIZCHIP_ > 5200 + IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != 5200 + IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > 5100 + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > 5100 + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrpt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrpt +#endif +}intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + + +#if _WIZCHIP_ == 5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500, + * and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n + * Valid only in W5500. + */ +typedef struct wiz_PhyConf_t +{ + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF + }wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum +{ + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +}dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t +{ + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +}wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum +{ +#if _WIZCHIP_ == 5500 + NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500 +#endif + NM_WAKEONLAN = (1<<5), ///< Wake On Lan + NM_PINGBLOCK = (1<<4), ///< Block ping-request + NM_PPPOE = (1<<3), ///< PPPoE mode +}netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. + */ +typedef struct wiz_NetTimeout_t +{ + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +}wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such as + *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. + *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); + + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte usig SPI + *@param spi_wb : callback function to write byte usig SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function + *or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), + * controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n + * 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); + + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +#if _WIZCHIP_ > 5100 + int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100 + int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == 5500 + void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 +/** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_setphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphyconf(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ + void wizphy_getphystat(wiz_PhyConf* phyconf); + /** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ + int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** +* @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout* nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref RTR) and retry count(@ref RCR). + * @details @ref RTR configures the retransmission timeout period and @ref RCR configures the number of time of retransmission. + * @param nettime @ref RTR value and @ref RCR value. Refer to @ref wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout* nettime); + +#endif // _WIZCHIP_CONF_H_ diff --git a/Radio_LLCC68_Multi/Inc/ATModem.h b/Radio_LLCC68_Multi/Inc/ATModem.h new file mode 100644 index 0000000..7f4bada --- /dev/null +++ b/Radio_LLCC68_Multi/Inc/ATModem.h @@ -0,0 +1,32 @@ +#ifndef __ATMODEM_H_V10__ +#define __ATMODEM_H_V10__ + +typedef unsigned char uchar; + +enum ATCmds +{ + ST_M = 0x49, + ST_S = 0x69, + EDsign = 0x0d, +}; + +typedef void (*ATSendPktDef)(char * pBuf, int Len1); + + +typedef struct tagATModemDef +{ + ATSendPktDef ATSendPktFunc; + uchar inputBuf[5]; + uchar outputBuf[5]; + uchar SendBuf[8]; + +}stATModemDef; + +void ATInit(stATModemDef * pATModem, ATSendPktDef pFunc1); +void ATSetCallBack(stATModemDef * pATModem, ATSendPktDef pFunc1); + +int ATParsePacket(stATModemDef * pATModem, char * pBuf, uchar len1); +void ATProcess(stATModemDef * pATModem); + + +#endif /* __ATMODEM_H_V10__ */ diff --git a/Radio_LLCC68_Multi/Inc/BoardType.h b/Radio_LLCC68_Multi/Inc/BoardType.h new file mode 100644 index 0000000..3fc96ac --- /dev/null +++ b/Radio_LLCC68_Multi/Inc/BoardType.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file : BoardType.h + * @brief : Define of BoardType. + * This file contains the defines of the BoardType. + ****************************************************************************** + */ +#ifndef __BOARDTYPE_H__ +#define __BOARDTYPE_H__ + +#define KWLESS 1 + +/* + 0 //old board 4 in 4 out + 1 //old board 8 in 8 out + 2 //Master 16 in16 out + 3 //Slave 8 in 8 out + 4 //New Master 16 in16 out V1.2 + 5 //Slave 8 in 8 out V1.2 +*/ +#define USART1_AUTO_BAUDRATE 0 + +#define USART2_USE_HARDWARE_DE 1 +#define USART2_DE_ASSERTION_TIME 31 +#define USART2_DE_DEASSERTION_TIME 31 + +enum enBOARD_TYPE +{ + BOARD_UNKNOWN =0, + BOARD_OLD4=1, // 1 //old board 4 in 4 o + BOARD_OLD8, //2 old board 8 in 8 o + BOARD_MASTER, //3 Master 16 in16 o + BOARD_SLAVE, //4 Slave 8 in 8 o + BOARD_NEW_MASTER, //5 New Master 16 in16 o + BOARD_NEW_SLAVE, //6 New Slave 8 in 8 o + BOARD_V4_MASTER, //7 New V4 Master 16 in16 o + BOARD_V4_SLAVE, //8 New V4 Slave 8 in 8 o + BOARD_V42_MASTER, //9 New V4.2 Master 16 in16 o + BOARD_V42_SLAVE, //10 New V4.2 Slave 8 in 8 o + + BOARD_V30_MINI =11, //11 Mini Board + BOARD_V45_NET = 13, + BOARD_EXT_FP0 = 14, + BOARD_V50_RADIO_16 = 15, + BOARD_V50_RADIO_8 = 16, + +}; + +#define BOARD_TYPE 16 +#define BOARD_VER 1 + +#if (BOARD_TYPE == 11) +#define XLAT_FREQ 12 +#elif (BOARD_TYPE == 14) +#define XLAT_FREQ 12 +#else +#define XLAT_FREQ 8 +#endif + +#define GetBoardType() (BOARD_TYPE) + +#define PLCFUNC 1 + +#if ( BOARD_TYPE == 1) +#define DINPUT 4 +#define DOUTPUT 4 +#elif (BOARD_TYPE == 2 || BOARD_TYPE == 4 || BOARD_TYPE == 6 || BOARD_TYPE == 8 || BOARD_TYPE == 10 || BOARD_TYPE == 11 ) +#define DINPUT 8 +#define DOUTPUT 8 +#elif BOARD_TYPE == 3 || BOARD_TYPE == 5 || BOARD_TYPE == 7 || BOARD_TYPE == 9 || BOARD_TYPE == 13 +#define DINPUT 16 +#define DOUTPUT 16 +#elif BOARD_TYPE == 14 +#define DINPUT 0 +#define DOUTPUT 6 +#elif (BOARD_TYPE == 15) +#define DINPUT 16 +#define DOUTPUT 16 +#define EXDINPUT 8 +#define EXDOUPUT 8 +#elif (BOARD_TYPE == 16) +#define DINPUT 16 +#define DOUTPUT 16 +#define EXDINPUT 8 +#define EXDOUPUT 8 +#else +#define DINPUT 0 +#define DOUTPUT 0 +#endif + +typedef struct tagInfoBlockHdr { + unsigned short nBlkSign; // 开始标志 + unsigned short nBlkTypeVer; // 类型和版本 + unsigned short nBlkSize; // Block 大小, 包括开始和结束标志 + unsigned short Pad1; +}stInfoBlockHdr; + +typedef struct tagInfoBlockTail { + + unsigned short CRC16; + unsigned short EndSign; +}stInfoBlockTail; + +typedef struct tagBtLdrInfoBlock { + stInfoBlockHdr Hdr; + unsigned short nBtldrVer; + unsigned short nBtldrDevice; + unsigned short nBtldrSize; // 设计大小 + unsigned short nBtldrDataSize; //代码大小 + unsigned int nBtldr_AppAddr; + unsigned int nBtldr_NewAppInfoAddr; + unsigned int nBtldr_NewAppAddr; + stInfoBlockTail tail; +}stBtLdrInfoBlock, *pBtLdrInfoBlock; + +typedef struct tagAppInfoBlock { + stInfoBlockHdr Hdr; + unsigned short nAppVer; + unsigned short nAppDevice; + unsigned short nAppSize; // 代码设计大小 + unsigned short nAppDataSize; //实际代码大小 + unsigned int nAppStartAddr; + unsigned int nAppStartOffset; + unsigned int nApp; + stInfoBlockTail tail; +}stAppInfoBlock, * pAppInfoBlock; + + + +#endif /* __BOARDTYPE_H__ */ diff --git a/Radio_LLCC68_Multi/Inc/main.h b/Radio_LLCC68_Multi/Inc/main.h new file mode 100644 index 0000000..55d4307 --- /dev/null +++ b/Radio_LLCC68_Multi/Inc/main.h @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "BoardType.h" + +#include "stm32f0xx_ll_adc.h" +#include "stm32f0xx_ll_iwdg.h" +#include "stm32f0xx_ll_crc.h" +#include "stm32f0xx_ll_dma.h" +#include "stm32f0xx_ll_spi.h" +#include "stm32f0xx_ll_usart.h" +#include "stm32f0xx_ll_rcc.h" +#include "stm32f0xx_ll_system.h" +#include "stm32f0xx_ll_gpio.h" +#include "stm32f0xx_ll_exti.h" +#include "stm32f0xx_ll_bus.h" +#include "stm32f0xx_ll_cortex.h" +#include "stm32f0xx_ll_tim.h" +#include "stm32f0xx_ll_utils.h" +#include "stm32f0xx_ll_pwr.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private define ------------------------------------------------------------*/ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* USER CODE BEGIN Private defines */ +#include "KBus.h" + +extern stKBusDef KBus1; +#define Uart1RxBufSize 256 +#define RX2BUFSIZE 64 +#define TX2BUFSIZE 64 +#define DefaultUart1Baud 115200 +#define DefaultUart2Baud 1000000 +#define AlterUart2Baud 500000 + +extern volatile char Uart1BaudGot; +extern volatile char Uart1BaudFirstGot; + +extern unsigned char Uart1Mode; +extern unsigned int Uart1Baud; +extern unsigned int Uart2Baud; + +extern volatile int PendSvCount; + +extern unsigned char Uart1RxBuf1[Uart1RxBufSize]; +extern unsigned char Uart1TxBuf1[260]; + +extern unsigned char Uart2RxBuf1[RX2BUFSIZE]; +extern unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +extern unsigned short Uart1RxBuf1DataLen; +extern unsigned short Uart2RxBuf1DataLen; + +/* USER CODE END Private defines */ + +#ifdef __cplusplus + extern "C" { +#endif +void _Error_Handler(char *, int); + +#define Error_Handler() _Error_Handler(__FILE__, __LINE__) +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Radio_LLCC68_Multi/Inc/stm32f0xx_hal_conf.h b/Radio_LLCC68_Multi/Inc/stm32f0xx_hal_conf.h new file mode 100644 index 0000000..2a4d2a3 --- /dev/null +++ b/Radio_LLCC68_Multi/Inc/stm32f0xx_hal_conf.h @@ -0,0 +1,324 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2018 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "main.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_EXTI_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined (HSI14_VALUE) +#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)40000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSI) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 0 +#define DATA_CACHE_ENABLE 0 +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Radio_LLCC68_Multi/Internet/DHCP/dhcp.c b/Radio_LLCC68_Multi/Internet/DHCP/dhcp.c new file mode 100644 index 0000000..3da4709 --- /dev/null +++ b/Radio_LLCC68_Multi/Internet/DHCP/dhcp.c @@ -0,0 +1,976 @@ +//***************************************************************************** +// +//! \file dhcp.c +//! \brief DHCP APIs implement file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Optimize code +//! 2. Add reg_dhcp_cbfunc() +//! 3. Add DHCP_stop() +//! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() +//! 5. Don't care system endian +//! 6. Add comments +//! <2012/12/26> V1.1.1 +//! 1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include "Ethernet/socket.h" +#include "Internet/DHCP/dhcp.h" + +/* If you want to display debug & procssing message, Define _DHCP_DEBUG_ in dhcp.h */ + +#ifdef _DHCP_DEBUG_ + #include <stdio.h> +#endif + +/* DHCP state machine. */ +#define STATE_DHCP_INIT 0 ///< Initialize +#define STATE_DHCP_DISCOVER 1 ///< send DISCOVER and wait OFFER +#define STATE_DHCP_REQUEST 2 ///< send REQEUST and wait ACK or NACK +#define STATE_DHCP_LEASED 3 ///< ReceiveD ACK and IP leased +#define STATE_DHCP_REREQUEST 4 ///< send REQUEST for maintaining leased IP +#define STATE_DHCP_RELEASE 5 ///< No use +#define STATE_DHCP_STOP 6 ///< Stop procssing DHCP + +#define DHCP_FLAGSBROADCAST 0x8000 ///< The broadcast value of flags in @ref RIP_MSG +#define DHCP_FLAGSUNICAST 0x0000 ///< The unicast value of flags in @ref RIP_MSG + +/* DHCP message OP code */ +#define DHCP_BOOTREQUEST 1 ///< Request Message used in op of @ref RIP_MSG +#define DHCP_BOOTREPLY 2 ///< Reply Message used i op of @ref RIP_MSG + +/* DHCP message type */ +#define DHCP_DISCOVER 1 ///< DISCOVER message in OPT of @ref RIP_MSG +#define DHCP_OFFER 2 ///< OFFER message in OPT of @ref RIP_MSG +#define DHCP_REQUEST 3 ///< REQUEST message in OPT of @ref RIP_MSG +#define DHCP_DECLINE 4 ///< DECLINE message in OPT of @ref RIP_MSG +#define DHCP_ACK 5 ///< ACK message in OPT of @ref RIP_MSG +#define DHCP_NAK 6 ///< NACK message in OPT of @ref RIP_MSG +#define DHCP_RELEASE 7 ///< RELEASE message in OPT of @ref RIP_MSG. No use +#define DHCP_INFORM 8 ///< INFORM message in OPT of @ref RIP_MSG. No use + +#define DHCP_HTYPE10MB 1 ///< Used in type of @ref RIP_MSG +#define DHCP_HTYPE100MB 2 ///< Used in type of @ref RIP_MSG + +#define DHCP_HLENETHERNET 6 ///< Used in hlen of @ref RIP_MSG +#define DHCP_HOPS 0 ///< Used in hops of @ref RIP_MSG +#define DHCP_SECS 0 ///< Used in secs of @ref RIP_MSG + +#define INFINITE_LEASETIME 0xffffffff ///< Infinite lease time + +#define OPT_SIZE 312 /// Max OPT size of @ref RIP_MSG +#define RIP_MSG_SIZE (236+OPT_SIZE) /// Max size of @ref RIP_MSG + +/* + * @brief DHCP option and value (cf. RFC1533) + */ +enum +{ + padOption = 0, + subnetMask = 1, + timerOffset = 2, + routersOnSubnet = 3, + timeServer = 4, + nameServer = 5, + dns = 6, + logServer = 7, + cookieServer = 8, + lprServer = 9, + impressServer = 10, + resourceLocationServer = 11, + hostName = 12, + bootFileSize = 13, + meritDumpFile = 14, + domainName = 15, + swapServer = 16, + rootPath = 17, + extentionsPath = 18, + IPforwarding = 19, + nonLocalSourceRouting = 20, + policyFilter = 21, + maxDgramReasmSize = 22, + defaultIPTTL = 23, + pathMTUagingTimeout = 24, + pathMTUplateauTable = 25, + ifMTU = 26, + allSubnetsLocal = 27, + broadcastAddr = 28, + performMaskDiscovery = 29, + maskSupplier = 30, + performRouterDiscovery = 31, + routerSolicitationAddr = 32, + staticRoute = 33, + trailerEncapsulation = 34, + arpCacheTimeout = 35, + ethernetEncapsulation = 36, + tcpDefaultTTL = 37, + tcpKeepaliveInterval = 38, + tcpKeepaliveGarbage = 39, + nisDomainName = 40, + nisServers = 41, + ntpServers = 42, + vendorSpecificInfo = 43, + netBIOSnameServer = 44, + netBIOSdgramDistServer = 45, + netBIOSnodeType = 46, + netBIOSscope = 47, + xFontServer = 48, + xDisplayManager = 49, + dhcpRequestedIPaddr = 50, + dhcpIPaddrLeaseTime = 51, + dhcpOptionOverload = 52, + dhcpMessageType = 53, + dhcpServerIdentifier = 54, + dhcpParamRequest = 55, + dhcpMsg = 56, + dhcpMaxMsgSize = 57, + dhcpT1value = 58, + dhcpT2value = 59, + dhcpClassIdentifier = 60, + dhcpClientIdentifier = 61, + endOption = 255 +}; + +/* + * @brief DHCP message format + */ +typedef struct { + uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY + uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB + uint8_t hlen; ///< @ref DHCP_HLENETHERNET + uint8_t hops; ///< @ref DHCP_HOPS + uint32_t xid; ///< @ref DHCP_XID This increase one every DHCP transaction. + uint16_t secs; ///< @ref DHCP_SECS + uint16_t flags; ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST + uint8_t ciaddr[4]; ///< @ref Request IP to DHCP sever + uint8_t yiaddr[4]; ///< @ref Offered IP from DHCP server + uint8_t siaddr[4]; ///< No use + uint8_t giaddr[4]; ///< No use + uint8_t chaddr[16]; ///< DHCP client 6bytes MAC address. Others is filled to zero + uint8_t sname[64]; ///< No use + uint8_t file[128]; ///< No use + uint8_t OPT[OPT_SIZE]; ///< Option +} RIP_MSG; + + + +uint8_t DHCP_SOCKET; // Socket number for DHCP + +uint8_t DHCP_SIP[4]; // DHCP Server IP address + +// Network information from DHCP Server +uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address +uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP +uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP +uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP +uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP + + +int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state +int8_t dhcp_retry_count = 0; + +uint32_t dhcp_lease_time = INFINITE_LEASETIME; +volatile uint32_t dhcp_tick_1s = 0; // unit 1 second +uint32_t dhcp_tick_next = DHCP_WAIT_TIME ; + +uint32_t DHCP_XID; // Any number + +RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing + +uint8_t HOST_NAME[] = DCHP_HOST_NAME; + +uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. + +/* The default callback function */ +void default_ip_assign(void); +void default_ip_update(void); +void default_ip_conflict(void); + +/* Callback handler */ +void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */ +void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */ +void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */ + +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + + +/* send DISCOVER message to DHCP server */ +void send_DHCP_DISCOVER(void); + +/* send REQEUST message to DHCP server */ +void send_DHCP_REQUEST(void); + +/* send DECLINE message to DHCP server */ +void send_DHCP_DECLINE(void); + +/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */ +int8_t check_DHCP_leasedIP(void); + +/* check the timeout in DHCP process */ +uint8_t check_DHCP_timeout(void); + +/* Intialize to timeout process. */ +void reset_DHCP_timeout(void); + +/* Parse message as OFFER and ACK and NACK from DHCP server.*/ +int8_t parseDHCPCMSG(void); + +/* The default handler of ip assign first */ +void default_ip_assign(void) +{ + setSIPR(DHCP_allocated_ip); + setSUBR(DHCP_allocated_sn); + setGAR (DHCP_allocated_gw); +} + +/* The default handler of ip chaged */ +void default_ip_update(void) +{ + /* WIZchip Software Reset */ + setMR(MR_RST); + getMR(); // for delay + default_ip_assign(); + setSHAR(DHCP_CHADDR); +} + +/* The default handler of ip chaged */ +void default_ip_conflict(void) +{ + // WIZchip Software Reset + setMR(MR_RST); + getMR(); // for delay + setSHAR(DHCP_CHADDR); +} + +/* register the call back func. */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)) +{ + dhcp_ip_assign = default_ip_assign; + dhcp_ip_update = default_ip_update; + dhcp_ip_conflict = default_ip_conflict; + if(ip_assign) dhcp_ip_assign = ip_assign; + if(ip_update) dhcp_ip_update = ip_update; + if(ip_conflict) dhcp_ip_conflict = ip_conflict; +} + +/* make the common DHCP message */ +void makeDHCPMSG(void) +{ + uint8_t bk_mac[6]; + uint8_t* ptmp; + uint8_t i; + getSHAR(bk_mac); + pDHCPMSG->op = DHCP_BOOTREQUEST; + pDHCPMSG->htype = DHCP_HTYPE10MB; + pDHCPMSG->hlen = DHCP_HLENETHERNET; + pDHCPMSG->hops = DHCP_HOPS; + ptmp = (uint8_t*)(&pDHCPMSG->xid); + *(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24); + *(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16); + *(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8); + *(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0); + pDHCPMSG->secs = DHCP_SECS; + ptmp = (uint8_t*)(&pDHCPMSG->flags); + *(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8); + *(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0); + + pDHCPMSG->ciaddr[0] = 0; + pDHCPMSG->ciaddr[1] = 0; + pDHCPMSG->ciaddr[2] = 0; + pDHCPMSG->ciaddr[3] = 0; + + pDHCPMSG->yiaddr[0] = 0; + pDHCPMSG->yiaddr[1] = 0; + pDHCPMSG->yiaddr[2] = 0; + pDHCPMSG->yiaddr[3] = 0; + + pDHCPMSG->siaddr[0] = 0; + pDHCPMSG->siaddr[1] = 0; + pDHCPMSG->siaddr[2] = 0; + pDHCPMSG->siaddr[3] = 0; + + pDHCPMSG->giaddr[0] = 0; + pDHCPMSG->giaddr[1] = 0; + pDHCPMSG->giaddr[2] = 0; + pDHCPMSG->giaddr[3] = 0; + + pDHCPMSG->chaddr[0] = DHCP_CHADDR[0]; + pDHCPMSG->chaddr[1] = DHCP_CHADDR[1]; + pDHCPMSG->chaddr[2] = DHCP_CHADDR[2]; + pDHCPMSG->chaddr[3] = DHCP_CHADDR[3]; + pDHCPMSG->chaddr[4] = DHCP_CHADDR[4]; + pDHCPMSG->chaddr[5] = DHCP_CHADDR[5]; + + for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0; + for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0; + for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0; + + // MAGIC_COOKIE + pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24); + pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16); + pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8); + pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0; +} + +/* SEND DHCP DISCOVER */ +void send_DHCP_DISCOVER(void) +{ + uint16_t i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DISCOVER; + + // Client identifier + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x06; // length of request + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + // send broadcasting packet + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_DISCOVER\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* SEND DHCP REQUEST */ +void send_DHCP_REQUEST(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) + { + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; + pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; + pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; + pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; + ip[0] = DHCP_SIP[0]; + ip[1] = DHCP_SIP[1]; + ip[2] = DHCP_SIP[2]; + ip[3] = DHCP_SIP[3]; + } + else + { + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + } + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_REQUEST; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + { + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + } + + // host name + pDHCPMSG->OPT[k++] = hostName; + pDHCPMSG->OPT[k++] = 0; // length of hostname + for(i = 0 ; HOST_NAME[i] != 0; i++) + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + pDHCPMSG->OPT[k - (i+3+1)] = i+3; // length of hostname + + pDHCPMSG->OPT[k++] = dhcpParamRequest; + pDHCPMSG->OPT[k++] = 0x08; + pDHCPMSG->OPT[k++] = subnetMask; + pDHCPMSG->OPT[k++] = routersOnSubnet; + pDHCPMSG->OPT[k++] = dns; + pDHCPMSG->OPT[k++] = domainName; + pDHCPMSG->OPT[k++] = dhcpT1value; + pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = performRouterDiscovery; + pDHCPMSG->OPT[k++] = staticRoute; + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + +#ifdef _DHCP_DEBUG_ + printf("> Send DHCP_REQUEST\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); + +} + +/* SEND DHCP DHCPDECLINE */ +void send_DHCP_DECLINE(void) +{ + int i; + uint8_t ip[4]; + uint16_t k = 0; + + makeDHCPMSG(); + + k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG() + + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + + // Option Request Param. + pDHCPMSG->OPT[k++] = dhcpMessageType; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_DECLINE; + + pDHCPMSG->OPT[k++] = dhcpClientIdentifier; + pDHCPMSG->OPT[k++] = 0x07; + pDHCPMSG->OPT[k++] = 0x01; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[0]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[1]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[2]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; + pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; + + pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; + pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; + + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; + pDHCPMSG->OPT[k++] = 0x04; + pDHCPMSG->OPT[k++] = DHCP_SIP[0]; + pDHCPMSG->OPT[k++] = DHCP_SIP[1]; + pDHCPMSG->OPT[k++] = DHCP_SIP[2]; + pDHCPMSG->OPT[k++] = DHCP_SIP[3]; + + pDHCPMSG->OPT[k++] = endOption; + + for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; + + //send broadcasting packet + ip[0] = 0xFF; + ip[1] = 0xFF; + ip[2] = 0xFF; + ip[3] = 0xFF; + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Send DHCP_DECLINE\r\n"); +#endif + + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); +} + +/* PARSE REPLY pDHCPMSG */ +int8_t parseDHCPMSG(void) +{ + uint8_t svr_addr[6]; + uint16_t svr_port; + uint16_t len; + + uint8_t * p; + uint8_t * e; + uint8_t type; + uint8_t opt_len; + + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) + { + len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); + #ifdef _DHCP_DEBUG_ + printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); + #endif + } + else return 0; + if (svr_port == DHCP_SERVER_PORT) { + // compare mac address + if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || + (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || + (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) + return 0; + type = 0; + p = (uint8_t *)(&pDHCPMSG->op); + p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) + e = p + (len - 240); + + while ( p < e ) { + + switch ( *p ) { + + case endOption : + p = e; // for break while(p < e) + break; + case padOption : + p++; + break; + case dhcpMessageType : + p++; + p++; + type = *p++; + break; + case subnetMask : + p++; + p++; + DHCP_allocated_sn[0] = *p++; + DHCP_allocated_sn[1] = *p++; + DHCP_allocated_sn[2] = *p++; + DHCP_allocated_sn[3] = *p++; + break; + case routersOnSubnet : + p++; + opt_len = *p++; + DHCP_allocated_gw[0] = *p++; + DHCP_allocated_gw[1] = *p++; + DHCP_allocated_gw[2] = *p++; + DHCP_allocated_gw[3] = *p++; + p = p + (opt_len - 4); + break; + case dns : + p++; + opt_len = *p++; + DHCP_allocated_dns[0] = *p++; + DHCP_allocated_dns[1] = *p++; + DHCP_allocated_dns[2] = *p++; + DHCP_allocated_dns[3] = *p++; + p = p + (opt_len - 4); + break; + case dhcpIPaddrLeaseTime : + p++; + opt_len = *p++; + dhcp_lease_time = *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + #ifdef _DHCP_DEBUG_ + dhcp_lease_time = 10; + #endif + break; + case dhcpServerIdentifier : + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + break; + default : + p++; + opt_len = *p++; + p += opt_len; + break; + } // switch + } // while + } // if + return type; +} + +uint8_t DHCP_run(void) +{ + uint8_t type; + uint8_t ret; + + if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; + + if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) + socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + + ret = DHCP_RUNNING; + type = parseDHCPMSG(); + + switch ( dhcp_state ) { + case STATE_DHCP_INIT : + DHCP_allocated_ip[0] = 0; + DHCP_allocated_ip[1] = 0; + DHCP_allocated_ip[2] = 0; + DHCP_allocated_ip[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER : + if (type == DHCP_OFFER){ +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_OFFER\r\n"); +#endif + DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; + DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; + DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; + DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_REQUEST : + if (type == DHCP_ACK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_ACK\r\n"); +#endif + if (check_DHCP_leasedIP()) { + // Network info assignment from DHCP + dhcp_ip_assign(); + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred + reset_DHCP_timeout(); + dhcp_ip_conflict(); + dhcp_state = STATE_DHCP_INIT; + } + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + + case STATE_DHCP_LEASED : + ret = DHCP_IP_LEASED; + if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { + +#ifdef _DHCP_DEBUG_ + printf("> Maintains the IP address \r\n"); +#endif + + type = 0; + OLD_allocated_ip[0] = DHCP_allocated_ip[0]; + OLD_allocated_ip[1] = DHCP_allocated_ip[1]; + OLD_allocated_ip[2] = DHCP_allocated_ip[2]; + OLD_allocated_ip[3] = DHCP_allocated_ip[3]; + + DHCP_XID++; + + send_DHCP_REQUEST(); + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_REREQUEST; + } + break; + + case STATE_DHCP_REREQUEST : + ret = DHCP_IP_LEASED; + if (type == DHCP_ACK) { + dhcp_retry_count = 0; + if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + OLD_allocated_ip[1] != DHCP_allocated_ip[1] || + OLD_allocated_ip[2] != DHCP_allocated_ip[2] || + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) + { + ret = DHCP_IP_CHANGED; + dhcp_ip_update(); + #ifdef _DHCP_DEBUG_ + printf(">IP changed.\r\n"); + #endif + + } + #ifdef _DHCP_DEBUG_ + else printf(">IP is continued.\r\n"); + #endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if (type == DHCP_NAK) { + +#ifdef _DHCP_DEBUG_ + printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); +#endif + + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + default : + break; + } + + return ret; +} + +void DHCP_stop(void) +{ + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; +} + +uint8_t check_DHCP_timeout(void) +{ + uint8_t ret = DHCP_RUNNING; + + if (dhcp_retry_count < MAX_DHCP_RETRY) { + if (dhcp_tick_next < dhcp_tick_1s) { + + switch ( dhcp_state ) { + case STATE_DHCP_DISCOVER : +// printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n"); + send_DHCP_DISCOVER(); + break; + + case STATE_DHCP_REQUEST : +// printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + case STATE_DHCP_REREQUEST : +// printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n"); + + send_DHCP_REQUEST(); + break; + + default : + break; + } + + dhcp_tick_1s = 0; + dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME; + dhcp_retry_count++; + } + } else { // timeout occurred + + switch(dhcp_state) { + case STATE_DHCP_DISCOVER: + dhcp_state = STATE_DHCP_INIT; + ret = DHCP_FAILED; + break; + case STATE_DHCP_REQUEST: + case STATE_DHCP_REREQUEST: + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + default : + break; + } + reset_DHCP_timeout(); + } + return ret; +} + +int8_t check_DHCP_leasedIP(void) +{ + uint8_t tmp; + int32_t ret; + + //WIZchip RCR value changed for ARP Timeout count control + tmp = getRCR(); + setRCR(0x03); + + // IP conflict detection : ARP request - ARP reply + // Broadcasting ARP Request for check the IP conflict using UDP sendto() function + ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000); + + // RCR value restore + setRCR(tmp); + + if(ret == SOCKERR_TIMEOUT) { + // UDP send Timeout occurred : allocated IP address is unique, DHCP Success + +#ifdef _DHCP_DEBUG_ + printf("\r\n> Check leased IP - OK\r\n"); +#endif + + return 1; + } else { + // Received ARP reply or etc : IP address conflict occur, DHCP Failed + send_DHCP_DECLINE(); + + ret = dhcp_tick_1s; + while((dhcp_tick_1s - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message; + + return 0; + } +} + +void DHCP_init(uint8_t s, uint8_t * buf) +{ + uint8_t zeroip[4] = {0,0,0,0}; + getSHAR(DHCP_CHADDR); + if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) + { + // assing temporary mac address, you should be set SHAR before call this function. + DHCP_CHADDR[0] = 0x00; + DHCP_CHADDR[1] = 0x08; + DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[3] = 0x00; + DHCP_CHADDR[4] = 0x00; + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); + } + + DHCP_SOCKET = s; // SOCK_DHCP + pDHCPMSG = (RIP_MSG*)buf; + DHCP_XID = 0x12345678; + + // WIZchip Netinfo Clear + setSIPR(zeroip); + setSIPR(zeroip); + setGAR(zeroip); + + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_INIT; +} + + +/* Rset the DHCP timeout count and retry count. */ +void reset_DHCP_timeout(void) +{ + dhcp_tick_1s = 0; + dhcp_tick_next = DHCP_WAIT_TIME; + dhcp_retry_count = 0; +} + +void DHCP_time_handler(void) +{ + dhcp_tick_1s++; +} + +void getIPfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_ip[0]; + ip[1] = DHCP_allocated_ip[1]; + ip[2] = DHCP_allocated_ip[2]; + ip[3] = DHCP_allocated_ip[3]; +} + +void getGWfromDHCP(uint8_t* ip) +{ + ip[0] =DHCP_allocated_gw[0]; + ip[1] =DHCP_allocated_gw[1]; + ip[2] =DHCP_allocated_gw[2]; + ip[3] =DHCP_allocated_gw[3]; +} + +void getSNfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_sn[0]; + ip[1] = DHCP_allocated_sn[1]; + ip[2] = DHCP_allocated_sn[2]; + ip[3] = DHCP_allocated_sn[3]; +} + +void getDNSfromDHCP(uint8_t* ip) +{ + ip[0] = DHCP_allocated_dns[0]; + ip[1] = DHCP_allocated_dns[1]; + ip[2] = DHCP_allocated_dns[2]; + ip[3] = DHCP_allocated_dns[3]; +} + +uint32_t getDHCPLeasetime(void) +{ + return dhcp_lease_time; +} + + + + diff --git a/Radio_LLCC68_Multi/Internet/DHCP/dhcp.h b/Radio_LLCC68_Multi/Internet/DHCP/dhcp.h new file mode 100644 index 0000000..4f2c688 --- /dev/null +++ b/Radio_LLCC68_Multi/Internet/DHCP/dhcp.h @@ -0,0 +1,152 @@ +//***************************************************************************** +// +//! \file dhcp.h +//! \brief DHCP APIs Header file. +//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/11/18> 1st Release +//! <2012/12/20> V1.1.0 +//! 1. Move unreferenced DEFINE to dhcp.c +//! <2012/12/26> V1.1.1 +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#ifndef _DHCP_H_ +#define _DHCP_H_ + +/* + * @brief + * @details If you want to display debug & procssing message, Define _DHCP_DEBUG_ + * @note If defined, it dependens on <stdio.h> + */ +//#define _DHCP_DEBUG_ + + +/* Retry to processing DHCP */ +#define MAX_DHCP_RETRY 2 ///< Maxium retry count +#define DHCP_WAIT_TIME 10 ///< Wait Time 10s + + +/* UDP port numbers for DHCP */ +#define DHCP_SERVER_PORT 67 ///< DHCP server port number +#define DHCP_CLIENT_PORT 68 ///< DHCP client port number + + +#define MAGIC_COOKIE 0x63825363 ///< Any number. You can be modifyed it any number + +#define DCHP_HOST_NAME "WIZnet\0" + +/* + * @brief return value of @ref DHCP_run() + */ +enum +{ + DHCP_FAILED = 0, ///< Procssing Fail + DHCP_RUNNING, ///< Procssing DHCP proctocol + DHCP_IP_ASSIGN, ///< First Occupy IP from DHPC server (if cbfunc == null, act as default default_ip_assign) + DHCP_IP_CHANGED, ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update) + DHCP_IP_LEASED, ///< Stand by + DHCP_STOPPED ///< Stop procssing DHCP protocol +}; + +/* + * @brief DHCP client initialization (outside of the main loop) + * @param s - socket number + * @param buf - buffer for procssing DHCP message + */ +void DHCP_init(uint8_t s, uint8_t * buf); + +/* + * @brief DHCP 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DHCP_time_handler(void); + +/* + * @brief Register call back function + * @param ip_assign - callback func when IP is assigned from DHCP server first + * @param ip_update - callback func when IP is changed + * @prarm ip_conflict - callback func when the assigned IP is conflict with others. + */ +void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void)); + +/* + * @brief DHCP client in the main loop + * @return The value is as the follow \n + * @ref DHCP_FAILED \n + * @ref DHCP_RUNNING \n + * @ref DHCP_IP_ASSIGN \n + * @ref DHCP_IP_CHANGED \n + * @ref DHCP_IP_LEASED \n + * @ref DHCP_STOPPED \n + * + * @note This function is always called by you main task. + */ +uint8_t DHCP_run(void); + +/* + * @brief Stop DHCP procssing + * @note If you want to restart. call DHCP_init() and DHCP_run() + */ +void DHCP_stop(void); + +/* Get Network information assigned from DHCP server */ +/* + * @brief Get IP address + * @param ip - IP address to be returned + */ +void getIPfromDHCP(uint8_t* ip); +/* + * @brief Get Gateway address + * @param ip - Gateway address to be returned + */ +void getGWfromDHCP(uint8_t* ip); +/* + * @brief Get Subnet mask value + * @param ip - Subnet mask to be returned + */ +void getSNfromDHCP(uint8_t* ip); +/* + * @brief Get DNS address + * @param ip - DNS address to be returned + */ +void getDNSfromDHCP(uint8_t* ip); + +/* + * @brief Get the leased time by DHCP sever + * @retrun unit 1s + */ +uint32_t getDHCPLeasetime(void); + +#endif /* _DHCP_H_ */ diff --git a/Radio_LLCC68_Multi/Internet/DNS/dns.c b/Radio_LLCC68_Multi/Internet/DNS/dns.c new file mode 100644 index 0000000..a88f369 --- /dev/null +++ b/Radio_LLCC68_Multi/Internet/DNS/dns.c @@ -0,0 +1,563 @@ +//***************************************************************************** +// +//! \file dns.c +//! \brief DNS APIs Implement file. +//! \details Send DNS query & Receive DNS reponse. \n +//! It depends on stdlib.h & string.h in ansi-c library +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Remove the unused define +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#include <string.h> +#include <stdlib.h> + +#include "Ethernet/socket.h" +#include "Internet/DNS/dns.h" + +#ifdef _DNS_DEBUG_ + #include <stdio.h> +#endif + +#define INITRTT 2000L /* Initial smoothed response time */ +#define MAXCNAME (MAX_DOMAIN_NAME + (MAX_DOMAIN_NAME>>1)) /* Maximum amount of cname recursion */ + +#define TYPE_A 1 /* Host address */ +#define TYPE_NS 2 /* Name server */ +#define TYPE_MD 3 /* Mail destination (obsolete) */ +#define TYPE_MF 4 /* Mail forwarder (obsolete) */ +#define TYPE_CNAME 5 /* Canonical name */ +#define TYPE_SOA 6 /* Start of Authority */ +#define TYPE_MB 7 /* Mailbox name (experimental) */ +#define TYPE_MG 8 /* Mail group member (experimental) */ +#define TYPE_MR 9 /* Mail rename name (experimental) */ +#define TYPE_NULL 10 /* Null (experimental) */ +#define TYPE_WKS 11 /* Well-known sockets */ +#define TYPE_PTR 12 /* Pointer record */ +#define TYPE_HINFO 13 /* Host information */ +#define TYPE_MINFO 14 /* Mailbox information (experimental)*/ +#define TYPE_MX 15 /* Mail exchanger */ +#define TYPE_TXT 16 /* Text strings */ +#define TYPE_ANY 255 /* Matches any type */ + +#define CLASS_IN 1 /* The ARPA Internet */ + +/* Round trip timing parameters */ +#define AGAIN 8 /* Average RTT gain = 1/8 */ +#define LAGAIN 3 /* Log2(AGAIN) */ +#define DGAIN 4 /* Mean deviation gain = 1/4 */ +#define LDGAIN 2 /* log2(DGAIN) */ + +/* Header for all domain messages */ +struct dhdr +{ + uint16_t id; /* Identification */ + uint8_t qr; /* Query/Response */ +#define QUERY 0 +#define RESPONSE 1 + uint8_t opcode; +#define IQUERY 1 + uint8_t aa; /* Authoratative answer */ + uint8_t tc; /* Truncation */ + uint8_t rd; /* Recursion desired */ + uint8_t ra; /* Recursion available */ + uint8_t rcode; /* Response code */ +#define NO_ERROR 0 +#define FORMAT_ERROR 1 +#define SERVER_FAIL 2 +#define NAME_ERROR 3 +#define NOT_IMPL 4 +#define REFUSED 5 + uint16_t qdcount; /* Question count */ + uint16_t ancount; /* Answer count */ + uint16_t nscount; /* Authority (name server) count */ + uint16_t arcount; /* Additional record count */ +}; + + +uint8_t* pDNSMSG; // DNS message buffer +uint8_t DNS_SOCKET; // SOCKET number for DNS +uint16_t DNS_MSGID; // DNS message ID + +uint32_t dns_1s_tick; // for timout of DNS processing + +/* converts uint16_t from network buffer to a host byte order integer. */ +uint16_t get16(uint8_t * s) +{ + uint16_t i; + i = *s++ << 8; + i = i + *s; + return i; +} + +/* copies uint16_t to the network buffer with network byte order. */ +uint8_t * put16(uint8_t * s, uint16_t i) +{ + *s++ = i >> 8; + *s++ = i; + return s; +} + + +/* + * CONVERT A DOMAIN NAME TO THE HUMAN-READABLE FORM + * + * Description : This function converts a compressed domain name to the human-readable form + * Arguments : msg - is a pointer to the reply message + * compressed - is a pointer to the domain name in reply message. + * buf - is a pointer to the buffer for the human-readable form name. + * len - is the MAX. size of buffer. + * Returns : the length of compressed message + */ +int parse_name(uint8_t * msg, uint8_t * compressed, char * buf, int16_t len) +{ + uint16_t slen; /* Length of current segment */ + uint8_t * cp; + int clen = 0; /* Total length of compressed name */ + int indirect = 0; /* Set if indirection encountered */ + int nseg = 0; /* Total number of segments in name */ + + cp = compressed; + + for (;;) + { + slen = *cp++; /* Length of this segment */ + + if (!indirect) clen++; + + if ((slen & 0xc0) == 0xc0) + { + if (!indirect) + clen++; + indirect = 1; + /* Follow indirection */ + cp = &msg[((slen & 0x3f)<<8) + *cp]; + slen = *cp++; + } + + if (slen == 0) /* zero length == all done */ + break; + + len -= slen + 1; + + if (len < 0) return -1; + + if (!indirect) clen += slen; + + while (slen-- != 0) *buf++ = (char)*cp++; + *buf++ = '.'; + nseg++; + } + + if (nseg == 0) + { + /* Root name; represent as single dot */ + *buf++ = '.'; + len--; + } + + *buf++ = '\0'; + len--; + + return clen; /* Length of compressed message */ +} + +/* + * PARSE QUESTION SECTION + * + * Description : This function parses the qeustion record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the qeustion record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_question(uint8_t * msg, uint8_t * cp) +{ + int len; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + + if (len == -1) return 0; + + cp += len; + cp += 2; /* type */ + cp += 2; /* class */ + + return cp; +} + + +/* + * PARSE ANSER SECTION + * + * Description : This function parses the answer record of the reply message. + * Arguments : msg - is a pointer to the reply message + * cp - is a pointer to the answer record. + * Returns : a pointer the to next record. + */ +uint8_t * dns_answer(uint8_t * msg, uint8_t * cp, uint8_t * ip_from_dns) +{ + int len, type; + char name[MAXCNAME]; + + len = parse_name(msg, cp, name, MAXCNAME); + + if (len == -1) return 0; + + cp += len; + type = get16(cp); + cp += 2; /* type */ + cp += 2; /* class */ + cp += 4; /* ttl */ + cp += 2; /* len */ + + + switch (type) + { + case TYPE_A: + /* Just read the address directly into the structure */ + ip_from_dns[0] = *cp++; + ip_from_dns[1] = *cp++; + ip_from_dns[2] = *cp++; + ip_from_dns[3] = *cp++; + break; + case TYPE_CNAME: + case TYPE_MB: + case TYPE_MG: + case TYPE_MR: + case TYPE_NS: + case TYPE_PTR: + /* These types all consist of a single domain name */ + /* convert it to ascii format */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_HINFO: + len = *cp++; + cp += len; + + len = *cp++; + cp += len; + break; + case TYPE_MX: + cp += 2; + /* Get domain name of exchanger */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + break; + case TYPE_SOA: + /* Get domain name of name server */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + /* Get domain name of responsible person */ + len = parse_name(msg, cp, name, MAXCNAME); + if (len == -1) return 0; + + cp += len; + + cp += 4; + cp += 4; + cp += 4; + cp += 4; + cp += 4; + break; + case TYPE_TXT: + /* Just stash */ + break; + default: + /* Ignore */ + break; + } + + return cp; +} + +/* + * PARSE THE DNS REPLY + * + * Description : This function parses the reply message from DNS server. + * Arguments : dhdr - is a pointer to the header for DNS message + * buf - is a pointer to the reply message. + * len - is the size of reply message. + * Returns : -1 - Domain name lenght is too big + * 0 - Fail (Timout or parse error) + * 1 - Success, + */ +int8_t parseDNSMSG(struct dhdr * pdhdr, uint8_t * pbuf, uint8_t * ip_from_dns) +{ + uint16_t tmp; + uint16_t i; + uint8_t * msg; + uint8_t * cp; + + msg = pbuf; + memset(pdhdr, 0, sizeof(pdhdr)); + + pdhdr->id = get16(&msg[0]); + tmp = get16(&msg[2]); + if (tmp & 0x8000) pdhdr->qr = 1; + + pdhdr->opcode = (tmp >> 11) & 0xf; + + if (tmp & 0x0400) pdhdr->aa = 1; + if (tmp & 0x0200) pdhdr->tc = 1; + if (tmp & 0x0100) pdhdr->rd = 1; + if (tmp & 0x0080) pdhdr->ra = 1; + + pdhdr->rcode = tmp & 0xf; + pdhdr->qdcount = get16(&msg[4]); + pdhdr->ancount = get16(&msg[6]); + pdhdr->nscount = get16(&msg[8]); + pdhdr->arcount = get16(&msg[10]); + + + /* Now parse the variable length sections */ + cp = &msg[12]; + + /* Question section */ + for (i = 0; i < pdhdr->qdcount; i++) + { + cp = dns_question(msg, cp); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h" + #endif + if(!cp) return -1; + } + + /* Answer section */ + for (i = 0; i < pdhdr->ancount; i++) + { + cp = dns_answer(msg, cp, ip_from_dns); + #ifdef _DNS_DEUBG_ + printf("MAX_DOMAIN_NAME is too small, it should be redfine in dns.h" + #endif + if(!cp) return -1; + } + + /* Name server (authority) section */ + for (i = 0; i < pdhdr->nscount; i++) + { + ; + } + + /* Additional section */ + for (i = 0; i < pdhdr->arcount; i++) + { + ; + } + + if(pdhdr->rcode == 0) return 1; // No error + else return 0; +} + + +/* + * MAKE DNS QUERY MESSAGE + * + * Description : This function makes DNS query message. + * Arguments : op - Recursion desired + * name - is a pointer to the domain name. + * buf - is a pointer to the buffer for DNS message. + * len - is the MAX. size of buffer. + * Returns : the pointer to the DNS message. + */ +int16_t dns_makequery(uint16_t op, char * name, uint8_t * buf, uint16_t len) +{ + uint8_t *cp; + char *cp1; + char sname[MAXCNAME]; + char *dname; + uint16_t p; + uint16_t dlen; + + cp = buf; + + DNS_MSGID++; + cp = put16(cp, DNS_MSGID); + p = (op << 11) | 0x0100; /* Recursion desired */ + cp = put16(cp, p); + cp = put16(cp, 1); + cp = put16(cp, 0); + cp = put16(cp, 0); + cp = put16(cp, 0); + + strcpy(sname, name); + dname = sname; + dlen = strlen(dname); + for (;;) + { + /* Look for next dot */ + cp1 = strchr(dname, '.'); + + if (cp1 != NULL) len = cp1 - dname; /* More to come */ + else len = dlen; /* Last component */ + + *cp++ = len; /* Write length of component */ + if (len == 0) break; + + /* Copy component up to (but not including) dot */ + strncpy((char *)cp, dname, len); + cp += len; + if (cp1 == NULL) + { + *cp++ = 0; /* Last one; write null and finish */ + break; + } + dname += len+1; + dlen -= len+1; + } + + cp = put16(cp, 0x0001); /* type */ + cp = put16(cp, 0x0001); /* class */ + + return ((int16_t)((uint32_t)(cp) - (uint32_t)(buf))); +} + +/* + * CHECK DNS TIMEOUT + * + * Description : This function check the DNS timeout + * Arguments : None. + * Returns : -1 - timeout occurred, 0 - timer over, but no timeout, 1 - no timer over, no timeout occur + * Note : timeout : retry count and timer both over. + */ + +int8_t check_DNS_timeout(void) +{ + static uint8_t retry_count; + + if(dns_1s_tick >= DNS_WAIT_TIME) + { + dns_1s_tick = 0; + if(retry_count >= MAX_DNS_RETRY) { + retry_count = 0; + return -1; // timeout occurred + } + retry_count++; + return 0; // timer over, but no timeout + } + + return 1; // no timer over, no timeout occur +} + + + +/* DNS CLIENT INIT */ +void DNS_init(uint8_t s, uint8_t * buf) +{ + DNS_SOCKET = s; // SOCK_DNS + pDNSMSG = buf; // User's shared buffer + DNS_MSGID = DNS_MSG_ID; +} + +/* DNS CLIENT RUN */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns) +{ + int8_t ret; + struct dhdr dhp; + uint8_t ip[4]; + uint16_t len, port; + int8_t ret_check_timeout; + + // Socket open + socket(DNS_SOCKET, Sn_MR_UDP, 0, 0); + +#ifdef _DNS_DEBUG_ + printf("> DNS Query to DNS Server : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + + len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE); + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + + while (1) + { + if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0) + { + if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE; + len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port); + #ifdef _DNS_DEBUG_ + printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len); + #endif + ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns); + break; + } + // Check Timeout + ret_check_timeout = check_DNS_timeout(); + if (ret_check_timeout < 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]); +#endif + return 0; // timeout occurred + } + else if (ret_check_timeout == 0) { + +#ifdef _DNS_DEBUG_ + printf("> DNS Timeout\r\n"); +#endif + sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN); + } + } + close(DNS_SOCKET); + // Return value + // 0 > : failed / 1 - success + return ret; +} + + +/* DNS TIMER HANDLER */ +void DNS_time_handler(void) +{ + dns_1s_tick++; +} + + + diff --git a/Radio_LLCC68_Multi/Internet/DNS/dns.h b/Radio_LLCC68_Multi/Internet/DNS/dns.h new file mode 100644 index 0000000..023e37d --- /dev/null +++ b/Radio_LLCC68_Multi/Internet/DNS/dns.h @@ -0,0 +1,101 @@ +//***************************************************************************** +// +//! \file dns.h +//! \brief DNS APIs Header file. +//! \details Send DNS query & Receive DNS reponse. +//! \version 1.1.0 +//! \date 2013/11/18 +//! \par Revision history +//! <2013/10/21> 1st Release +//! <2013/12/20> V1.1.0 +//! 1. Remove secondary DNS server in DNS_run +//! If 1st DNS_run failed, call DNS_run with 2nd DNS again +//! 2. DNS_timerHandler -> DNS_time_handler +//! 3. Move the no reference define to dns.c +//! 4. Integrated dns.h dns.c & dns_parse.h dns_parse.c into dns.h & dns.c +//! <2013/12/20> V1.1.0 +//! +//! \author Eric Jung & MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the <ORGANIZATION> nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +#ifndef _DNS_H_ +#define _DNS_H_ + +#include <stdint.h> +/* + * @brief Define it for Debug & Monitor DNS processing. + * @note If defined, it dependens on <stdio.h> + */ +//#define _DNS_DEBUG_ + +#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */ +/* + * @brief Maxium length of your queried Domain name + * @todo SHOULD BE defined it equal as or greater than your Domain name lenght + null character(1) + * @note SHOULD BE careful to stack overflow because it is allocated 1.5 times as MAX_DOMAIN_NAME in stack. + */ +#define MAX_DOMAIN_NAME 16 // for example "www.google.com" + +#define MAX_DNS_RETRY 2 ///< Requery Count +#define DNS_WAIT_TIME 3 ///< Wait response time. unit 1s. + +#define IPPORT_DOMAIN 53 ///< DNS server port number + +#define DNS_MSG_ID 0x1122 ///< ID for DNS message. You can be modifyed it any number +/* + * @brief DNS process initialize + * @param s : Socket number for DNS + * @param buf : Buffer for DNS message + */ +void DNS_init(uint8_t s, uint8_t * buf); + +/* + * @brief DNS process + * @details Send DNS query and receive DNS response + * @param dns_ip : DNS server ip + * @param name : Domain name to be queryed + * @param ip_from_dns : IP address from DNS server + * @return -1 : failed. @ref MAX_DOMIN_NAME is too small \n + * 0 : failed (Timeout or Parse error)\n + * 1 : success + * @note This funtion blocks until success or fail. max time = @ref MAX_DNS_RETRY * @ref DNS_WAIT_TIME + */ +int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns); + +/* + * @brief DNS 1s Tick Timer handler + * @note SHOULD BE register to your system 1s Tick timer handler + */ +void DNS_time_handler(void); + +#endif /* _DNS_H_ */ diff --git "a/Radio_LLCC68_Multi/MDK-ARM/LLCC68_C8T6_Multi_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" "b/Radio_LLCC68_Multi/MDK-ARM/LLCC68_C8T6_Multi_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" new file mode 100644 index 0000000..e6a51b8 --- /dev/null +++ "b/Radio_LLCC68_Multi/MDK-ARM/LLCC68_C8T6_Multi_8\350\267\257\346\227\240\347\272\277\346\250\241\345\235\227.uvprojx" @@ -0,0 +1,766 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd"> + + <SchemaVersion>2.1</SchemaVersion> + + <Header>### uVision Project, (C) Keil Software</Header> + + <Targets> + <Target> + <TargetName>F030C8T6_Radio_LLCC68</TargetName> + <ToolsetNumber>0x4</ToolsetNumber> + <ToolsetName>ARM-ADS</ToolsetName> + <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> + <uAC6>0</uAC6> + <TargetOption> + <TargetCommonOption> + <Device>STM32F030C8Tx</Device> + <Vendor>STMicroelectronics</Vendor> + <PackID>Keil.STM32F0xx_DFP.2.1.1</PackID> + <PackURL>https://www.keil.com/pack/</PackURL> + <Cpu>IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE</Cpu> + <FlashUtilSpec></FlashUtilSpec> + <StartupFile></StartupFile> + <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32F030C8Tx$CMSIS\Flash\STM32F0xx_64.FLM))</FlashDriverDll> + <DeviceId>0</DeviceId> + <RegisterFile>$$Device:STM32F030C8Tx$Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f0xx.h</RegisterFile> + <MemoryEnv></MemoryEnv> + <Cmp></Cmp> + <Asm></Asm> + <Linker></Linker> + <OHString></OHString> + <InfinionOptionDll></InfinionOptionDll> + <SLE66CMisc></SLE66CMisc> + <SLE66AMisc></SLE66AMisc> + <SLE66LinkerMisc></SLE66LinkerMisc> + <SFDFile>$$Device:STM32F030C8Tx$CMSIS\SVD\STM32F0x0.svd</SFDFile> + <bCustSvd>0</bCustSvd> + <UseEnv>0</UseEnv> + <BinPath></BinPath> + <IncludePath></IncludePath> + <LibPath></LibPath> + <RegisterFilePath></RegisterFilePath> + <DBRegisterFilePath></DBRegisterFilePath> + <TargetStatus> + <Error>0</Error> + <ExitCodeStop>0</ExitCodeStop> + <ButtonStop>0</ButtonStop> + <NotGenerated>0</NotGenerated> + <InvalidFlash>1</InvalidFlash> + </TargetStatus> + <OutputDirectory>.\F030C8T6_Radio\</OutputDirectory> + <OutputName>Radio_LLCC68_Multi</OutputName> + <CreateExecutable>1</CreateExecutable> + <CreateLib>0</CreateLib> + <CreateHexFile>1</CreateHexFile> + <DebugInformation>1</DebugInformation> + <BrowseInformation>1</BrowseInformation> + <ListingPath>.\F030C8T6_Radio\</ListingPath> + <HexFormatSelection>1</HexFormatSelection> + <Merge32K>0</Merge32K> + <CreateBatchFile>0</CreateBatchFile> + <BeforeCompile> + <RunUserProg1>0</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name></UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopU1X>0</nStopU1X> + <nStopU2X>0</nStopU2X> + </BeforeCompile> + <BeforeMake> + <RunUserProg1>0</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name></UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopB1X>0</nStopB1X> + <nStopB2X>0</nStopB2X> + </BeforeMake> + <AfterMake> + <RunUserProg1>1</RunUserProg1> + <RunUserProg2>0</RunUserProg2> + <UserProg1Name>fromelf --bin --output="../@L.bin" "#L"</UserProg1Name> + <UserProg2Name></UserProg2Name> + <UserProg1Dos16Mode>0</UserProg1Dos16Mode> + <UserProg2Dos16Mode>0</UserProg2Dos16Mode> + <nStopA1X>0</nStopA1X> + <nStopA2X>0</nStopA2X> + </AfterMake> + <SelectedForBatchBuild>0</SelectedForBatchBuild> + <SVCSIdString></SVCSIdString> + </TargetCommonOption> + <CommonProperty> + <UseCPPCompiler>0</UseCPPCompiler> + <RVCTCodeConst>0</RVCTCodeConst> + <RVCTZI>0</RVCTZI> + <RVCTOtherData>0</RVCTOtherData> + <ModuleSelection>0</ModuleSelection> + <IncludeInBuild>1</IncludeInBuild> + <AlwaysBuild>0</AlwaysBuild> + <GenerateAssemblyFile>0</GenerateAssemblyFile> + <AssembleAssemblyFile>0</AssembleAssemblyFile> + <PublicsOnly>0</PublicsOnly> + <StopOnExitCode>3</StopOnExitCode> + <CustomArgument></CustomArgument> + <IncludeLibraryModules></IncludeLibraryModules> + <ComprImg>0</ComprImg> + </CommonProperty> + <DllOption> + <SimDllName>SARMCM3.DLL</SimDllName> + <SimDllArguments> -REMAP </SimDllArguments> + <SimDlgDll>DARMCM1.DLL</SimDlgDll> + <SimDlgDllArguments>-pCM0</SimDlgDllArguments> + <TargetDllName>SARMCM3.DLL</TargetDllName> + <TargetDllArguments> </TargetDllArguments> + <TargetDlgDll>TARMCM1.DLL</TargetDlgDll> + <TargetDlgDllArguments>-pCM0</TargetDlgDllArguments> + </DllOption> + <DebugOption> + <OPTHX> + <HexSelection>1</HexSelection> + <HexRangeLowAddress>0</HexRangeLowAddress> + <HexRangeHighAddress>0</HexRangeHighAddress> + <HexOffset>0</HexOffset> + <Oh166RecLen>16</Oh166RecLen> + </OPTHX> + </DebugOption> + <Utilities> + <Flash1> + <UseTargetDll>1</UseTargetDll> + <UseExternalTool>0</UseExternalTool> + <RunIndependent>0</RunIndependent> + <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging> + <Capability>1</Capability> + <DriverSelection>4096</DriverSelection> + </Flash1> + <bUseTDR>1</bUseTDR> + <Flash2>BIN\UL2CM3.DLL</Flash2> + <Flash3>"" ()</Flash3> + <Flash4></Flash4> + <pFcarmOut></pFcarmOut> + <pFcarmGrp></pFcarmGrp> + <pFcArmRoot></pFcArmRoot> + <FcArmLst>0</FcArmLst> + </Utilities> + <TargetArmAds> + <ArmAdsMisc> + <GenerateListings>0</GenerateListings> + <asHll>1</asHll> + <asAsm>1</asAsm> + <asMacX>1</asMacX> + <asSyms>1</asSyms> + <asFals>1</asFals> + <asDbgD>1</asDbgD> + <asForm>1</asForm> + <ldLst>0</ldLst> + <ldmm>1</ldmm> + <ldXref>1</ldXref> + <BigEnd>0</BigEnd> + <AdsALst>1</AdsALst> + <AdsACrf>1</AdsACrf> + <AdsANop>0</AdsANop> + <AdsANot>0</AdsANot> + <AdsLLst>1</AdsLLst> + <AdsLmap>1</AdsLmap> + <AdsLcgr>1</AdsLcgr> + <AdsLsym>1</AdsLsym> + <AdsLszi>1</AdsLszi> + <AdsLtoi>1</AdsLtoi> + <AdsLsun>1</AdsLsun> + <AdsLven>1</AdsLven> + <AdsLsxf>1</AdsLsxf> + <RvctClst>0</RvctClst> + <GenPPlst>0</GenPPlst> + <AdsCpuType>"Cortex-M0"</AdsCpuType> + <RvctDeviceName></RvctDeviceName> + <mOS>0</mOS> + <uocRom>0</uocRom> + <uocRam>0</uocRam> + <hadIROM>1</hadIROM> + <hadIRAM>1</hadIRAM> + <hadXRAM>0</hadXRAM> + <uocXRam>0</uocXRam> + <RvdsVP>0</RvdsVP> + <hadIRAM2>0</hadIRAM2> + <hadIROM2>0</hadIROM2> + <StupSel>8</StupSel> + <useUlib>1</useUlib> + <EndSel>0</EndSel> + <uLtcg>0</uLtcg> + <nSecure>0</nSecure> + <RoSelD>3</RoSelD> + <RwSelD>3</RwSelD> + <CodeSel>0</CodeSel> + <OptFeed>0</OptFeed> + <NoZi1>0</NoZi1> + <NoZi2>0</NoZi2> + <NoZi3>0</NoZi3> + <NoZi4>0</NoZi4> + <NoZi5>0</NoZi5> + <Ro1Chk>0</Ro1Chk> + <Ro2Chk>0</Ro2Chk> + <Ro3Chk>0</Ro3Chk> + <Ir1Chk>1</Ir1Chk> + <Ir2Chk>0</Ir2Chk> + <Ra1Chk>0</Ra1Chk> + <Ra2Chk>0</Ra2Chk> + <Ra3Chk>0</Ra3Chk> + <Im1Chk>1</Im1Chk> + <Im2Chk>0</Im2Chk> + <OnChipMemories> + <Ocm1> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm1> + <Ocm2> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm2> + <Ocm3> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm3> + <Ocm4> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm4> + <Ocm5> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm5> + <Ocm6> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </Ocm6> + <IRAM> + <Type>0</Type> + <StartAddress>0x20000000</StartAddress> + <Size>0x2000</Size> + </IRAM> + <IROM> + <Type>1</Type> + <StartAddress>0x8000000</StartAddress> + <Size>0x10000</Size> + </IROM> + <XRAM> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </XRAM> + <OCR_RVCT1> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT1> + <OCR_RVCT2> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT2> + <OCR_RVCT3> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT3> + <OCR_RVCT4> + <Type>1</Type> + <StartAddress>0x8001000</StartAddress> + <Size>0xf000</Size> + </OCR_RVCT4> + <OCR_RVCT5> + <Type>1</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT5> + <OCR_RVCT6> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT6> + <OCR_RVCT7> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT7> + <OCR_RVCT8> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT8> + <OCR_RVCT9> + <Type>0</Type> + <StartAddress>0x200000c0</StartAddress> + <Size>0x1f40</Size> + </OCR_RVCT9> + <OCR_RVCT10> + <Type>0</Type> + <StartAddress>0x0</StartAddress> + <Size>0x0</Size> + </OCR_RVCT10> + </OnChipMemories> + <RvctStartVector></RvctStartVector> + </ArmAdsMisc> + <Cads> + <interw>1</interw> + <Optim>7</Optim> + <oTime>0</oTime> + <SplitLS>0</SplitLS> + <OneElfS>1</OneElfS> + <Strict>0</Strict> + <EnumInt>0</EnumInt> + <PlainCh>0</PlainCh> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <wLevel>2</wLevel> + <uThumb>0</uThumb> + <uSurpInc>0</uSurpInc> + <uC99>1</uC99> + <uGnu>0</uGnu> + <useXO>0</useXO> + <v6Lang>3</v6Lang> + <v6LangP>3</v6LangP> + <vShortEn>1</vShortEn> + <vShortWch>1</vShortWch> + <v6Lto>0</v6Lto> + <v6WtE>0</v6WtE> + <v6Rtti>0</v6Rtti> + <VariousControls> + <MiscControls></MiscControls> + <Define>USE_FULL_LL_DRIVER,USE_HAL_DRIVER</Define> + <Undefine></Undefine> + <IncludePath>../../Radio_LLCC68_Multi/Inc;../../Radio_LLCC68_Multi/Src;../../ComLib/Inc;../../Drivers/STM32F0xx_HAL_Driver/Inc;../../Drivers/CMSIS/Device/ST/STM32F0xx/Include;../../Drivers/CMSIS/Include;../../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy;../../Radio_LLCC68_Multi/Radio/Inc;../../Radio_LLCC68_Multi;..\../Radio_LLCC68_Multi\Radio</IncludePath> + </VariousControls> + </Cads> + <Aads> + <interw>1</interw> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <thumb>0</thumb> + <SplitLS>0</SplitLS> + <SwStkChk>0</SwStkChk> + <NoWarn>0</NoWarn> + <uSurpInc>0</uSurpInc> + <useXO>0</useXO> + <uClangAs>0</uClangAs> + <VariousControls> + <MiscControls></MiscControls> + <Define></Define> + <Undefine></Undefine> + <IncludePath></IncludePath> + </VariousControls> + </Aads> + <LDads> + <umfTarg>1</umfTarg> + <Ropi>0</Ropi> + <Rwpi>0</Rwpi> + <noStLib>0</noStLib> + <RepFail>1</RepFail> + <useFile>0</useFile> + <TextAddressRange>0x08000000</TextAddressRange> + <DataAddressRange>0x20000000</DataAddressRange> + <pXoBase></pXoBase> + <ScatterFile></ScatterFile> + <IncludeLibs></IncludeLibs> + <IncludeLibsPath></IncludeLibsPath> + <Misc></Misc> + <LinkerInputFile></LinkerInputFile> + <DisabledWarnings></DisabledWarnings> + </LDads> + </TargetArmAds> + </TargetOption> + <Groups> + <Group> + <GroupName>Application/MDK-ARM</GroupName> + <Files> + <File> + <FileName>startup_stm32f030x8.s</FileName> + <FileType>2</FileType> + <FilePath>.\startup_stm32f030x8.s</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>ComLib/Inc</GroupName> + <Files> + <File> + <FileName>BSP.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\BSP.h</FilePath> + </File> + <File> + <FileName>debug.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\debug.h</FilePath> + </File> + <File> + <FileName>functions.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\functions.h</FilePath> + </File> + <File> + <FileName>GlobalDef.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\GlobalDef.h</FilePath> + </File> + <File> + <FileName>KBus.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\KBus.h</FilePath> + </File> + <File> + <FileName>KLink.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\KLink.h</FilePath> + </File> + <File> + <FileName>KMachine.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\KMachine.h</FilePath> + </File> + <File> + <FileName>ModbusRTU.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\ModbusRTU.h</FilePath> + </File> + <File> + <FileName>MyQueue.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\MyQueue.h</FilePath> + </File> + <File> + <FileName>PLCfunctions.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\PLCfunctions.h</FilePath> + </File> + <File> + <FileName>shell.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\shell.h</FilePath> + </File> + <File> + <FileName>stm32_assert.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\stm32_assert.h</FilePath> + </File> + <File> + <FileName>stm32f0xx_it.h</FileName> + <FileType>5</FileType> + <FilePath>..\..\Comlib\Inc\stm32f0xx_it.h</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>ComLib/Src</GroupName> + <Files> + <File> + <FileName>debug.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\debug.c</FilePath> + </File> + <File> + <FileName>functions.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\functions.c</FilePath> + </File> + <File> + <FileName>GlobalDef.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\GlobalDef.c</FilePath> + </File> + <File> + <FileName>KBus.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\KBus.c</FilePath> + </File> + <File> + <FileName>KLink.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\KLink.c</FilePath> + </File> + <File> + <FileName>ModbusRTU.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\ModbusRTU.c</FilePath> + </File> + <File> + <FileName>MyQueue.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\MyQueue.c</FilePath> + </File> + <File> + <FileName>PLCfunctions.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\PLCfunctions.c</FilePath> + </File> + <File> + <FileName>shell.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\shell.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_msp.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\stm32f0xx_hal_msp.c</FilePath> + </File> + <File> + <FileName>KMachine.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\KMachine.c</FilePath> + </File> + <File> + <FileName>BSP.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\BSP.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_it.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\stm32f0xx_it.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Inc</GroupName> + <Files> + <File> + <FileName>BoardType.h</FileName> + <FileType>5</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Inc\BoardType.h</FilePath> + </File> + <File> + <FileName>main.h</FileName> + <FileType>5</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Inc\main.h</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_conf.h</FileName> + <FileType>5</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Inc\stm32f0xx_hal_conf.h</FilePath> + </File> + <File> + <FileName>ATModem.h</FileName> + <FileType>5</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Inc\ATModem.h</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Application/User</GroupName> + <Files> + <File> + <FileName>main.c</FileName> + <FileType>1</FileType> + <FilePath>../../Radio_LLCC68_Multi/Src/main.c</FilePath> + </File> + <File> + <FileName>BoardType.c</FileName> + <FileType>1</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Src\BoardType.c</FilePath> + </File> + <File> + <FileName>ATModem.c</FileName> + <FileType>1</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Src\ATModem.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Radio</GroupName> + <Files> + <File> + <FileName>delay.c</FileName> + <FileType>1</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Radio\delay.c</FilePath> + </File> + <File> + <FileName>gpio.c</FileName> + <FileType>1</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Radio\gpio.c</FilePath> + </File> + <File> + <FileName>spi.c</FileName> + <FileType>1</FileType> + <FilePath>..\../Radio_LLCC68_Multi\Radio\spi.c</FilePath> + </File> + <File> + <FileName>crc.c</FileName> + <FileType>1</FileType> + <FilePath>../../Radio_LLCC68_Multi\Radio\src\crc.c</FilePath> + </File> + <File> + <FileName>radio.c</FileName> + <FileType>1</FileType> + <FilePath>../../Radio_LLCC68_Multi\Radio\src\radio.c</FilePath> + </File> + <File> + <FileName>sx126x.c</FileName> + <FileType>1</FileType> + <FilePath>../../Radio_LLCC68_Multi\Radio\src\sx126x.c</FilePath> + </File> + <File> + <FileName>sx126x-board.c</FileName> + <FileType>1</FileType> + <FilePath>../../Radio_LLCC68_Multi\Radio\src\sx126x-board.c</FilePath> + </File> + <File> + <FileName>KWireLess2.c</FileName> + <FileType>1</FileType> + <FilePath>..\Radio\KWireLess2.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Drivers/CMSIS</GroupName> + <Files> + <File> + <FileName>system_stm32f0xx.c</FileName> + <FileType>1</FileType> + <FilePath>..\..\Comlib\Src\system_stm32f0xx.c</FilePath> + </File> + </Files> + </Group> + <Group> + <GroupName>Drivers/STM32F0xx_HAL_Driver</GroupName> + <Files> + <File> + <FileName>stm32f0xx_ll_gpio.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_gpio.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_exti.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_exti.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_adc.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_adc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_dma.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_dma.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_spi.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_spi.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_tim.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_tim_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_usart.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usart.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_rcc.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_rcc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_rcc.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_rcc_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_i2c.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_i2c_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_gpio.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_dma.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_cortex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_pwr.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_pwr_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_flash.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_hal_flash_ex.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_utils.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_utils.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_tim.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_ll_tim.c</FilePath> + </File> + <File> + <FileName>stm32f0xx_ll_flash.c</FileName> + <FileType>1</FileType> + <FilePath>../../Drivers\STM32F0xx_HAL_Driver\Src\stm32f0xx_ll_flash.c</FilePath> + </File> + </Files> + </Group> + </Groups> + </Target> + </Targets> + + <RTE> + <apis/> + <components/> + <files/> + </RTE> + +</Project> diff --git a/Radio_LLCC68_Multi/MDK-ARM/startup_stm32f030x8.s b/Radio_LLCC68_Multi/MDK-ARM/startup_stm32f030x8.s new file mode 100644 index 0000000..4622872 --- /dev/null +++ b/Radio_LLCC68_Multi/MDK-ARM/startup_stm32f030x8.s @@ -0,0 +1,252 @@ +;******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +;* File Name : startup_stm32f030x8.s +;* Author : MCD Application Team +;* Description : STM32F030x8 devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM0 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;******************************************************************************* +;* +;* Redistribution and use in source and binary forms, with or without modification, +;* are permitted provided that the following conditions are met: +;* 1. Redistributions of source code must retain the above copyright notice, +;* this list of conditions and the following disclaimer. +;* 2. Redistributions in binary form must reproduce the above copyright notice, +;* this list of conditions and the following disclaimer in the documentation +;* and/or other materials provided with the distribution. +;* 3. Neither the name of STMicroelectronics nor the names of its contributors +;* may be used to endorse or promote products derived from this software +;* without specific prior written permission. +;* +;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +;******************************************************************************* + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; <h> Stack Configuration +; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Stack_Size EQU 0x400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; <h> Heap Configuration +; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; </h> + +Heap_Size EQU 0x200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window Watchdog + DCD 0 ; Reserved + DCD RTC_IRQHandler ; RTC through EXTI Line + DCD FLASH_IRQHandler ; FLASH + DCD RCC_IRQHandler ; RCC + DCD EXTI0_1_IRQHandler ; EXTI Line 0 and 1 + DCD EXTI2_3_IRQHandler ; EXTI Line 2 and 3 + DCD EXTI4_15_IRQHandler ; EXTI Line 4 to 15 + DCD 0 ; Reserved + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel2_3_IRQHandler ; DMA1 Channel 2 and Channel 3 + DCD DMA1_Channel4_5_IRQHandler ; DMA1 Channel 4 and Channel 5 + DCD ADC1_IRQHandler ; ADC1 + DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; TIM1 Break, Update, Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD 0 ; Reserved + DCD TIM3_IRQHandler ; TIM3 + DCD TIM6_IRQHandler ; TIM6 + DCD 0 ; Reserved + DCD TIM14_IRQHandler ; TIM14 + DCD TIM15_IRQHandler ; TIM15 + DCD TIM16_IRQHandler ; TIM16 + DCD TIM17_IRQHandler ; TIM17 + DCD I2C1_IRQHandler ; I2C1 + DCD I2C2_IRQHandler ; I2C2 + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler routine +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_5_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + + +WWDG_IRQHandler +RTC_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_3_IRQHandler +DMA1_Channel4_5_IRQHandler +ADC1_IRQHandler +TIM1_BRK_UP_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM3_IRQHandler +TIM6_IRQHandler +TIM14_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Radio_LLCC68_Multi/Radio/KWireLess1.c b/Radio_LLCC68_Multi/Radio/KWireLess1.c new file mode 100644 index 0000000..184a407 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/KWireLess1.c @@ -0,0 +1,1127 @@ +/** + ****************************************************************************** + * @file : KWireLess.c + * @brief : K-WireLess Protocol program body + ****************************************************************************** + */ +#include "KWireLess.h" +#include "functions.h" +#include "string.h" +#include "PLCFunctions.h" +#include "stm32f0xx_hal.h" + + +/************************************************************************************************************************************** +Demo 绋嬪簭娴佺▼ RadioEnableMaster=true 涓轰富鏈虹锛屼富鏈虹鍙戦�佷竴涓�"PING"鏁版嵁鍚庡垏鎹㈠埌鎺ユ敹锛岀瓑寰呬粠鏈鸿繑鍥炵殑搴旂瓟"PONG"鏁版嵁LED闂儊 + + RadioEnableMaster=false 涓轰粠鏈虹锛屼粠鏈虹鎺ユ敹鍒颁富鏈虹鍙戣繃鏉ョ殑"PING"鏁版嵁鍚嶭ED闂儊骞跺彂閫佷竴涓�"PONG"鏁版嵁浣滀负搴旂瓟 +***************************************************************************************************************************************/ + +#define USE_MODEM_LORA +//#define USE_MODEM_FSK + +/* +#define REGION_CN779 + +#if defined( REGION_AS923 ) + +#define RF_FREQUENCY 923000000 // Hz + +#elif defined( REGION_AU915 ) + +#define RF_FREQUENCY 915000000 // Hz + +#elif defined( REGION_CN779 ) + +#define RF_FREQUENCY 430620000 // Hz + +#elif defined( REGION_EU868 ) + +#define RF_FREQUENCY 868000000 // Hz + +#elif defined( REGION_KR920 ) + +#define RF_FREQUENCY 920000000 // Hz + +#elif defined( REGION_IN865 ) + +#define RF_FREQUENCY 865000000 // Hz + +#elif defined( REGION_US915 ) + +#define RF_FREQUENCY 915000000 // Hz + +#elif defined( REGION_US915_HYBRID ) + +#define RF_FREQUENCY 915000000 // Hz + +#else + + #error "Please define a frequency band in the compiler options." + +#endif +*/ +/* +#if defined( USE_MODEM_LORA ) + +#define LORA_BANDWIDTH 1 // [0: 125 kHz, + // 1: 250 kHz, + // 2: 500 kHz, + // 3: Reserved] +#define LORA_SPREADING_FACTOR 8 // [SF5..SF12] +#define LORA_CODINGRATE 4 // [1: 4/5, + // 2: 4/6, + // 3: 4/7, + // 4: 4/8] +#define LORA_PREAMBLE_LENGTH 4 // Same for Tx and Rx + +*/ +#define LORA_SYMBOL_TIMEOUT 0 // Symbols +#define LORA_FIX_LENGTH_PAYLOAD_ON false +#define LORA_IQ_INVERSION_ON false + +/* +#elif defined( USE_MODEM_FSK ) + +#define FSK_FDEV 20e3 // Hz +#define FSK_DATARATE 19.2e3 // bps +#define FSK_BANDWIDTH 60e3 // Hz >> DSB in sx126x +#define FSK_AFC_BANDWIDTH 200e3 // Hz +#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx +#define FSK_FIX_LENGTH_PAYLOAD_ON false + +#else + #error "Please define a modem in the compiler options." +#endif +*/ +/* +#define nChannelSpacing 530000 // Hz +#define TX_OUTPUT_POWER 16 // 22 dBm +*/ + + +extern bool IrqFired; + +//bool RadioEnableMaster=true;//涓讳粠閫夋嫨 +//uchar nRadioChannel = 0; +//uchar nRadioAddr = 1; +uint16_t crc_value; + +#define MixAddr(x,y) ((x<<4)|(y)) +/*! + * Radio events function pointer + */ +#define MASTER_RX_TIMEOUT_VALUE 80 //mS +#define SLAVE_RX_TIMEOUT_VALUE 400 //mS +#define CYCLE_TIME 80 //mS + +const stWLConfig defaultWLConfig = +{ + .RF_T_Freq = 430620000, // uint32_t Hz + .RF_R_Freq = 430620000, // uint32_t //Hz + .nChnSpacing = 530, // uint16_t ChannelSpacing; //kHz + .nCycleTime = CYCLE_TIME, // CyCleTime + .workMode = 1, // uchar workMode; //0: FSK, 1: LoRa + .nChannel = 0, + .bMaster = 0, + .nRadioAddr =1 , + .bEnableMulti = 0, + + .Tx_Power = 20, // uchar Tx_Power; + .LoraBandWidth = 1, // uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + .LoRaFactor = 5, // uchar LoRaFactor; // [SF5 .. SF 12] + .LoRaCodingRate = 1, // uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 + .NetWorkAddr = 0x00, // uint8_t NetWorkAddr; + .DeviceAddr = 0x0102, // uint16_t DeviceAddr; + .bEnableAddr = 0, // uchar bEnableAddr; + .bEnableEncrypt = 0, // uchar bEnableEncrypt; + .bEnableRelay = 0, // uchar bEnableRelay; + .LoRaPreambleLen = 4, // uchar LoRaPreamble_Len; // 2 - 12 + .bAutoPower = 1, + .bAutoReSend = 1, // 鑷姩閲嶅彂 +}; + +//stWLConfig * pWLCfg = (stWLConfig *)&defaultWLConfig; +static RadioEvents_t RadioEvents; + +stWLConfig WLCfg ; +stWLRunStat KwRunStat; + +typedef enum +{ + LOWPOWER, + RX, + RX_TIMEOUT, + RX_ERROR, + TX, + TX_TIMEOUT, +}States_t; + + + +#define WL_RX_BUFFER_SIZE 160 // Define the payload size here +#define WL_TX_BUFFER_SIZE 160 // Define the payload size here + +uint16_t nTimeOnAir; +/* +const uint8_t PingMsg[] = "PING"; +const uint8_t PongMsg[] = "PONG"; +*/ + +//uint16_t BufferSize = BUFFER_SIZE; +uint8_t KwRx_Buffer[WL_RX_BUFFER_SIZE]; +uint8_t KwTx_Buffer[WL_TX_BUFFER_SIZE]; + +#define WL_TT_EACH_SIZE 64 // transparent transmission byte size for each send + + +States_t State = LOWPOWER; + +int8_t RssiValue = 0; +int8_t SnrValue = 0; + +KWStates KW_State=KW_PON; + +void LedToggle(void) +{ +// GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_RESET);//LED闂儊 +// HAL_Delay_nMS(10); +// GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_SET); + + LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_13); +} + +int LoadKwConfig(void) +{ + stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); + + if (pstStoredWLCFG->BlockSign == 0x55AA && pstStoredWLCFG->BlockType == 0x05) { + WLCfg = pstStoredWLCFG->WLConfig; + } else { + WLCfg = defaultWLConfig; + } + return 0; +} + +int SaveKwConfig(void) +{ +// stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); + + stStoredWLConfig theStoredWLCFG; + theStoredWLCFG.BlockSign = 0x55AA; + theStoredWLCFG.BlockType = 0x05; + theStoredWLCFG.nSeq = 1; + theStoredWLCFG.nSize = sizeof(stWLConfig); + theStoredWLCFG.WLConfig = WLCfg; + theStoredWLCFG.nCRC16 = 0x0000; + EraseAndWriteToFlashMem(&theStoredWLCFG, (void *)STORE_KWCONFIG_BASE, sizeof(stStoredWLConfig)); + + return 0; +} + +int KWireLessInit(bool bRadioEnableMaster, uint32_t nChn) +{ + stWLConfig * pWLCfg = & WLCfg; + pWLCfg->bMaster = bRadioEnableMaster; + // Radio initialization + RadioEvents.TxDone = OnTxDone; + RadioEvents.RxDone = OnRxDone; + RadioEvents.TxTimeout = OnTxTimeout; + RadioEvents.RxTimeout = OnRxTimeout; + RadioEvents.RxError = OnRxError; + RadioEvents.CadDone = OnCadDone; + + Radio.Init( &RadioEvents ); + pWLCfg->nChannel = nChn; + KwRunStat.RF_Freq = pWLCfg->RF_T_Freq + pWLCfg->nChannel * pWLCfg->nChnSpacing*1000; + + Radio.SetChannel( KwRunStat.RF_Freq ); + + // Radio.WriteBuffer(0x06C0,data,2); + // Radio.ReadBuffer(0x06C0,test,2); + +#if defined( USE_MODEM_LORA ) +/* + Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, + LORA_SPREADING_FACTOR, LORA_CODINGRATE, + LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); + + Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, + LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); +// */ + + Radio.SetTxConfig( MODEM_LORA, pWLCfg->Tx_Power, 0, pWLCfg->LoraBandWidth, + pWLCfg->LoRaFactor, pWLCfg->LoRaCodingRate, + pWLCfg->LoRaPreambleLen, LORA_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); + + Radio.SetRxConfig( MODEM_LORA, pWLCfg->LoraBandWidth, pWLCfg->LoRaFactor, + pWLCfg->LoRaCodingRate, 0, pWLCfg->LoRaPreambleLen, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); + + Radio.SetMaxPayloadLength(MODEM_LORA,32); + +#elif defined( USE_MODEM_FSK ) + + Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, + FSK_DATARATE, 0, + FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, 0, 3000 ); + + Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, + 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, + 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, + 0, 0,false, false ); +#else + #error "Please define a modem in the compiler options.." +#endif + SX126xSetRxTxFallbackMode(0x40); // 0x40-> FS 0x30 -> SD_XOSC 0x20 -> SD_RC + + SX126xSetCadParams(LORA_CAD_02_SYMBOL,22,10,LORA_CAD_ONLY,1); + + nTimeOnAir = Radio.TimeOnAir(MODEM_LORA,14); + KwRunStat.nTimeOnAir = nTimeOnAir; +// KMem.WDT[38]=nTimeOnAir; + KwRunStat.runStep=RS_IDLE; + KMem.WDT[0]++; + KwRunStat.Tx_Power = WLCfg.Tx_Power; + KwRunStat.LoraBandWidth = WLCfg.LoraBandWidth; + KwRunStat.LoRaFactor = WLCfg.LoRaFactor; + KwRunStat.LoRaCodingRate = WLCfg.LoRaCodingRate; + KwRunStat.LoRaPreambleLen = WLCfg.LoRaPreambleLen; + + return 0; +} + +int KwResetRf() +{ + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + Radio.Standby(); + KwRunStat.runStep=RS_IDLE; + return 0; +} + +int KwStartRecv(int nChnd) +{ + Radio.Standby(); + Radio.SetChannel( KwRunStat.RF_Freq ); + Radio.SetRxConfig( MODEM_LORA, WLCfg.LoraBandWidth, WLCfg.LoRaFactor, + WLCfg.LoRaCodingRate, 0, WLCfg.LoRaPreambleLen, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); + + Radio.SetMaxPayloadLength(MODEM_LORA,32); + + Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); + KwRunStat.runStep=RS_RECVING; + + KwRunStat.lastActTime = GetTick(); + KwRunStat.lastRecvtime = GetTick(); + return 0; +} + +int KWireLessStart(void) +{ + if(WLCfg.bMaster) + { + KWLMasterSendReqPkt(1); + } + else + { + KwStartRecv(1); + } + +// while( 1 ) + // { + // Radio.IrqProcess( ); // Process Radio IRQ +// } + return 0; +} + + +void OnTxDone( void ) +{ + KwRunStat.bMasterSent = 1; + KwRunStat.bMasterRecved = 0; + KwRunStat.runStep=RS_IDLE; + KMem.WDT[42]++; + KwRunStat.lastSenttime = GetTick(); + KwRunStat.lastAckTime = GetTick(); + Radio.Standby(); + if (WLCfg.bMaster) { + Radio.Rx( MASTER_RX_TIMEOUT_VALUE ); //杩涘叆鎺ユ敹 + } else { + KwStartRecv(1); + //Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); //杩涘叆鎺ユ敹 + } + KwRunStat.runStep=RS_RECVING; + + KwRunStat.lastActTime = GetTick(); + KwRunStat.lastRecvtime = GetTick(); + LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_14); +// int us2=GetTick(); +// KMem.ScanTimeuS=us2-KMem.LastScanTime; +// KMem.LastScanTime = us2; +// if (KMem.ScanTimeuS < KMem.MinScanTimeuS) {KMem.MinScanTimeuS = KMem.ScanTimeuS;} +// if (KMem.ScanTimeuS > KMem.MaxScanTimeuS) {KMem.MaxScanTimeuS = KMem.ScanTimeuS;} + +} + +void OnTxTimeout( void ) +{ + KwRunStat.runStep=RS_IDLE; + KwRunStat.lastAckTime = GetTick(); + KwRunStat.TXErr++; + Radio.Standby(); +// KMem.WDT[44]++; +} +bool bThisRxError=0; + +void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +{ + KMem.WDT[44] = size; + if (size <= 120) { + memcpy( KwRx_Buffer, payload, size ); + memcpy(&KMem.WDT[64],payload,size); + }else + { + + } + Radio.Standby(); + KwRunStat.runStep = RS_IDLE; + + + KwRunStat.curStat = 0; + KwRunStat.latancy = GetTick() - KwRunStat.lastSendtime; + + RssiValue = rssi; + SnrValue = snr; + + KwRunStat.RSSI = RssiValue; + KwRunStat.SNR = SnrValue; + + KwRunStat.recvCount++; +// KwRunStat.CtnLstPkts=0; + + if(WLCfg.bMaster) + { + KWLMasterParsePkt(WLCfg.nChannel,size); + //KWLMasterSendReqPkt(1); + } + else //slave + { + KWLSlaveParsePkt(WLCfg.nChannel,size); + } + if (bThisRxError) { + bThisRxError=0; + // return; + } +} + +void OnRxTimeout( void ) +{ + KwRunStat.runStep=RS_IDLE; + + Radio.Standby(); + KwRunStat.lastErrTime = GetTick() - KwRunStat.lastAckTime; + KwRunStat.lastAckTime = GetTick(); + + KwRunStat.Tx_Power+=6; //涓㈠寘锛� 澧炲姞鍙戝皠鍔熺巼 + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + + + KMem.WDT[45]++; + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} +// KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 2) { KwRunStat.ErrStat=500;} + if (KwRunStat.CtnLstPkts ==3 ) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 5) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 6) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 9) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 10) {KwRunStat.Err3Count++;} + if ((KwRunStat.CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + KwResetRf(); + Radio.Standby(); + // KWireLessStart(); + } + if(WLCfg.bMaster) + { + //KWLMasterSendReqPkt(1); + } + else + { + KwStartRecv(1); +// Radio.Standby(); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + } +} + + +void OnRxError( void ) +{ + KwStartRecv(1); +// Radio.Standby(); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + + KwRunStat.RXErr++; + KMem.WDT[46]++; + bThisRxError=1; + KwRunStat.lastErrTime = GetTick() - KwRunStat.lastAckTime; + + if(WLCfg.bMaster) + { +// SendPingMsg(); + } + else + { +/* +// Radio.Rx( RX_TIMEOUT_VALUE ); + //KwRunStat.lastActTime = GetTick(); + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} +// KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=500; } + if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} +*/ + } +// Radio.Standby(); +} + +void OnCadDone( bool channelActivityDetected) +{ + KMem.WDT[60]++; + KwRunStat.CADDoneCount++; + KwRunStat.lastAckTime = GetTick(); + KMem.WDT[16] = KwRunStat.lastAckTime - KwRunStat.lastActTime; + if (channelActivityDetected) { + KwRunStat.CADNgCount++; + KMem.WDT[61]++; + Radio.StartCad(); + KwRunStat.lastActTime = GetTick(); + } + else { + KwRunStat.CADOkCount++; + KMem.WDT[62]++; + if (WLCfg.bMaster) { + if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS + // Radio.Standby(); + KWireLessStart(); + }else { + Radio.Standby(); + KWireLessStart(); + } + }else { + KWLSlaveSendRplyPkt(1); + } + } + return; +} + +int KWLMasterParsePkt(int nChn,int size) +{ + bool CRC_OK =1; +///* + crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) + { + KwRunStat.CRCErr++; + KwRunStat.ErrStat=500; + CRC_OK = 0; + }else { + CRC_OK = 1; + } +//*/ + pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; + if(CRC_OK && p1->STSign == enRplySign ) //memcmp(RX_Buffer,PongMsg,4)==0 + { + if (p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) + { + KwRunStat.bMasterRecved = 1; + LedToggle();//LED闂儊 + KwRunStat.lastRecvdtime=GetTick(); + KwRunStat.lastAckTime = GetTick(); + KwRunStat.CtnLstPkts=0; + + if (p1->Stat==0) { + KwRunStat.tRSSI = KwRx_Buffer[10]; + KwRunStat.tSNR = KwRx_Buffer[11]; + if (KwRunStat.tRSSI > -50) { + if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} + }else if (KwRunStat.tRSSI < -60) { + KwRunStat.Tx_Power+=6; + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + } + + }else if (p1->Stat==1){ + KwRunStat.targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (p1->Stat==2) { + KwRunStat.targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (p1->Stat==3) { + } + + KMem.WDT[41]=(-KwRunStat.tRSSI) + ((-KwRunStat.tSNR)<<8); + + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); + // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); + + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); + +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + KwRunStat.sentsize += KwRunStat.sizesending; + KwRunStat.sizesending = 0; + + if (KwRunStat.sentsize >= KwRunStat.sizetosend) { + //鏁翠綋 鍙戦�佸畬鎴� + KwRunStat.sizetosend =0; + KwRunStat.sentsize = 0; + KwRunStat.ttAirSize = 0; + // 鍙戦�佸畬鎴� + } + } +// 鎺ュ彈鍒板鏂瑰彂鏉ョ殑鏁版嵁 + + if (p1->bHasData && size >= 14+3 ) { +// int nFulllen1 = KwRx_Buffer[12]; + int nthislen2 = KwRx_Buffer[13]; + if (size >= 14 + nthislen2) { + if (p1->bHead) { + // 鏁版嵁鍖呯殑璧峰锛� 涓�涓柊鐨勬暟鎹寘鐨勫紑濮� + KwRunStat.ttRxSize = 0; +// SendPacket(1, "H", 1); + + } + memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize , KwRx_Buffer + 14 , nthislen2); + KwRunStat.ttRxSize += nthislen2; + if (p1->bTail) + { + // 宸茬粡鏀跺埌瀹屾暣鐨勪竴涓暟鎹寘 + KwRunStat.ttRxRecved =1; + KwRunStat.ErrStat=500; +// SendPacket(1, "T", 1); + + // 鍚庣画鏁版嵁鍖呭鐞嗘祦绋� ; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + + // 鏆傛椂娴佺▼锛屽叏閮ㄥ彂鍥炲幓銆� +// memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); +// KwRunStat.sizetosend = KwRunStat.ttRxSize; +// KwRunStat.sentsize = 0; +// KwRunStat.sizesending = 0; + } + + } + } + +/* + + + + if (KwRunStat.ttAirSize > 0) + { + if (KwRunStat.bttAirHeader) { KwRunStat.ttRxRecved=0; } + memcpy(KwRunStat.ttRxBuf1 + KwRunStat.ttRxRecved,KwRunStat.ttAirBuf, KwRunStat.ttAirSize); + KwRunStat.ttRxRecved += KwRunStat.ttAirSize; + + if (KwRunStat.bttAirTail) { + // 鏀跺埌 涓�涓暟鎹寘鐨勬渶鍚庨儴鍒� + KwRunStat.ttRxSize = KwRunStat.ttRxRecved; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + } + KwRunStat.ttAirSize = 0; + } +*/ + + } + } + + return 0; +} +int KWLSlaveParsePkt(int nChn,int size) +{ + bool CRC_OK =1; + pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; +///* + crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) + { + KwRunStat.CRCErr++; +// KwRunStat.ErrStat=500; + CRC_OK = 0; + }else { + CRC_OK = 1; + if (p1->STSign != enReqSign) { + KwRunStat.PktErr++; + }else { + if (p1->DstAddr != MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) { + KwRunStat.ChnErr++; + KwRunStat.nErrChn = p1->DstAddr; + } + } + } +//*/ + + if(CRC_OK && p1->STSign == enReqSign && p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr))// memcmp(RX_Buffer,PingMsg,4)==0 && ) + { + + LedToggle();//LED闂儊 + KwRunStat.lastRecvdtime=GetTick(); + KwRunStat.lastAckTime = GetTick(); + KwRunStat.CtnLstPkts=0; + int nSeq = p1->nSeq; + if (nSeq==0) { + KwRunStat.tRSSI = KwRx_Buffer[10]; + KwRunStat.tSNR = KwRx_Buffer[11]; + if (KwRunStat.tRSSI > -50) { + if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} + }else if (KwRunStat.tRSSI < -60) { + KwRunStat.Tx_Power+=6; + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + } + }else if (nSeq==1){ + KwRunStat.targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==2) { + KwRunStat.targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==3) { + } + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); + // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); + + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); + +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + KwRunStat.sentsize += KwRunStat.sizesending; + KwRunStat.sizesending = 0; + + if (KwRunStat.sentsize >= KwRunStat.sizetosend) { + //鏁翠綋 鍙戦�佸畬鎴� + KwRunStat.sizetosend =0; + KwRunStat.sentsize = 0; + KwRunStat.ttAirSize = 0; + // 鍙戦�佸畬鎴� + } + } + + if (p1->bHasData && size >= 14+3 ) { +// int nFulllen1 = KwRx_Buffer[12]; + int nthislen2 = KwRx_Buffer[13]; + if (size >= 14 + nthislen2) { + // 鏀跺埌涓�涓悎鏍肩殑鎼哄甫浼犵粺鏁版嵁鐨� 鍖呫�� + if (p1->bHead) { + // 鏁版嵁娈电殑璧峰锛� 涓�涓柊鐨勬暟鎹鐨勫紑濮� + KwRunStat.ttRxSize = 0; + } + memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize, KwRx_Buffer + 14 , nthislen2); + KwRunStat.ttRxSize += nthislen2; + if (p1->bTail) { + // 宸茬粡鏀跺埌瀹屾暣鐨勪竴涓暟鎹 + KwRunStat.ttRxRecved =1; + KwRunStat.ErrStat=500; + + // 鍚庣画鏁版嵁娈靛鐞嗘祦绋� ; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + + // 鏆傛椂娴佺▼锛屽叏閮ㄥ彂鍥炲幓銆� +// memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); +// KwRunStat.sizetosend = KwRunStat.ttRxSize; +// KwRunStat.sentsize = 0; +// KwRunStat.sizesending = 0; +// KwRunStat.ttRxRecved = 0; +// KwRunStat.ttRxSize = 0; + + } + + } + + + } + KWLSlaveSendRplyPkt(1); + // Radio.StartCad(); +// KMem.WFY[0]=(RX_Buffer[4]<<8) + RX_Buffer[5]; +// KMem.WFY[1]=(RX_Buffer[6]<<8) + RX_Buffer[7]; + } + else + { + KwStartRecv(1); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + + } + return 0; +} + +int KWLMasterSendReqPkt(int nChn) +{ + int len1=12; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; + p1->STSign = enReqSign; + p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); + p1->Func = 0x3; + KwRunStat.nSeq = (KwRunStat.nSeq + 1)&0x03; + p1->Stat = KwRunStat.nSeq; //0x00; + p1->Data[0]=KMem.WFY[1]; + p1->Data[1]=KMem.WFY[1]>>8; + p1->Data[2]=KMem.WFY[2]; + p1->Data[3]=KMem.WFY[2]>>8; + + + if (p1->Stat == 0) + { + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; + }else if (p1->Stat == 1){ + memcpy(KwTx_Buffer+8,&KwRunStat.sentCount,4); + }else if (p1->Stat == 2) { + memcpy(KwTx_Buffer+8,&KwRunStat.recvCount,4); + }else if (p1->Stat == 3) { + + } +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�1涓寘鐨勮浆鍙戙�� + if (KwRunStat.sizetosend > 0) { + uchar bStart=0,bEnd=1; + int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; + if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} + + if (KwRunStat.sentsize == 0) { // 绗竴娆″彂閫� + bStart = 1; + } + + memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 鍙戦�佹暟鎹紝 濡傛灉涓婃鏈夛紝缁х画涓婃鐨勫彂銆� + + KwRunStat.sizesending = thisToSend; + KwRunStat.ttAirSize = thisToSend; + +// KwRunStat.sentsize = 0; + KwRunStat.bttAirHeader = bStart; + KwRunStat.bttAirTail = bEnd; + + p1->bHasData=1; + p1->bHead = bStart; + p1->bTail = bEnd; + + KwTx_Buffer[len1] = KwRunStat.sizetosend; + KwTx_Buffer[len1+1] = thisToSend; + + memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); + len1 += 2 + thisToSend; + + } + + + crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + KwTx_Buffer[len1]=crc_value; + KwTx_Buffer[len1+1]=crc_value>>8; + + + KMem.WDT[56]=crc_value; + + KwRunStat.sentCount++; + KwRunStat.cycleTime = GetTick()- KwRunStat.lastSendtime ; + KwRunStat.lastSendtime = GetTick(); + Radio.Send( KwTx_Buffer, len1+2); + KwRunStat.runStep=RS_SENDING; + KwRunStat.lastActTime = GetTick(); + + return 0; +} + +int KWLSlaveSendRplyPkt(int nChn) +{ + int len1=12; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; + p1->STSign = enRplySign; + p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); + p1->Func = 0x3; + p1->Stat = (p1->Stat + 1) &0x03; //0x00; + p1->Data[0]=KMem.WFY[1]; + p1->Data[1]=KMem.WFY[1]>>8; + p1->Data[2]=KMem.WFY[2]; + p1->Data[3]=KMem.WFY[2]>>8; + + if (p1->Stat == 0) + { + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; + }else if (p1->Stat == 1){ + memcpy(KwTx_Buffer+8,&KwRunStat.sentCount,4); + }else if (p1->Stat == 2) { + memcpy(KwTx_Buffer+8,&KwRunStat.recvCount,4); + }else if (p1->Stat == 3) { + + } + +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�1涓寘鐨勮浆鍙戙�� + + if (KwRunStat.sizetosend > 0) { + uchar bStart=0,bEnd=1; + int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; + if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} + + if (KwRunStat.sentsize == 0) { // 绗竴娆″彂閫� + bStart = 1; + } + + memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 鍙戦�佹暟鎹紝 濡傛灉涓婃鏈夛紝缁х画涓婃鐨勫彂銆� + + KwRunStat.sizesending = thisToSend; + KwRunStat.ttAirSize = thisToSend; + +// KwRunStat.sentsize = 0; + KwRunStat.bttAirHeader = bStart; + KwRunStat.bttAirTail = bEnd; + + p1->bHasData=1; + p1->bHead = bStart; + p1->bTail = bEnd; + + KwTx_Buffer[len1] = KwRunStat.sizetosend; + KwTx_Buffer[len1+1] = thisToSend; + + memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); + len1 += 2 + thisToSend; + + } + + crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + KwTx_Buffer[len1]=crc_value; + KwTx_Buffer[len1+1]=crc_value>>8; + Radio.Send( KwTx_Buffer, len1+2); + KwRunStat.runStep=RS_SENDING; + + KwRunStat.lastActTime = GetTick(); + KwRunStat.sentCount++; + KwRunStat.lastSendtime = GetTick(); + return 0; +} + + +int KWL_Process(int nChn) +{ + RadioStatus_t rs = SX126xGetStatus(); + KMem.WDT[1] = rs.Value; + + RadioError_t er = SX126xGetDeviceErrors(); + KMem.WDT[2] = er.Value; + + KMem.WDT[3] = SX126xGetIrqStatus(); + + KMem.WDT[4] = SX126xGetRssiInst(); + + KMem.WDT[5] = GetRadioBusyPin(); + + RadioState_t stat = Radio.GetStatus(); + + KMem.WDT[32]=stat; +// KMem.WDT[38]=Radio.Rssi(MODEM_FSK); + if (WLCfg.bMaster){ + + KWLMasterProc(nChn); + }else //slave + { + KWLSlaveProc(nChn); + } + if (KwRunStat.RunStat) KwRunStat.RunStat--; + if (KwRunStat.ErrStat) KwRunStat.ErrStat--; + + + return 0; +} + +int KWLMasterProc(int nChn) +{ + RadioState_t stat = Radio.GetStatus(); + + switch (KwRunStat.runStep){ + case RS_IDLE: + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10 ||KwRunStat.sizetosend > 0 ){ + Radio.StartCad(); + KwRunStat.runStep = RS_MASTER_CAD; + KwRunStat.lastActTime = GetTick(); + } + break; + case RS_MASTER_CAD: + if (GetTick() - KwRunStat.lastActTime > 15) { + KwRunStat.CADTimeOut++; + KwRunStat.runStep = RS_IDLE; + Radio.Standby(); + KMem.WDT[17]++; + KwResetRf(); + } + break; + case RS_SENDING: + break; + case RS_SENT: + break; + case RS_RECVING: + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10 || KwRunStat.bMasterRecved){ + KwRunStat.ErrStat=5000; + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + + KwRunStat.Tx_Power+=6; //涓㈠寘锛� 澧炲姞鍙戝皠鍔熺巼 + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} + // KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} + if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} + if ((KwRunStat.CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + + KwResetRf(); + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + // Radio.Standby(); + // KWireLessStart(); + } + + + KwRunStat.runStep = RS_IDLE; + } + + break; + case RS_RECVED: + KwRunStat.runStep = RS_IDLE; + break; + + default: + break; + + } +/* + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10){ + if (!KwRunStat.bMasterRecved) { + KwRunStat.ErrStat=5000; + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} + // KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} + if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} + if ((KwRunStat.CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + // Radio.Standby(); + // KWireLessStart(); + } + } + } +*/ +/* + if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS +// Radio.Standby(); + KWireLessStart(); + }else { + Radio.Standby(); + KWireLessStart(); + } +*/ + return 0; +} + +int KWLSlaveProc(int nChn) +{ + RadioState_t stat = Radio.GetStatus(); + if (stat == RF_IDLE){ + KMem.WDT[48]++; + Radio.Standby(); + KWireLessStart(); + } + if (stat == RF_RX_RUNNING ){ + if (GetTick() - KwRunStat.lastRecvtime > ((SLAVE_RX_TIMEOUT_VALUE + 10 )*10)){ + KwRunStat.lastRecvtime = GetTick(); + KwRunStat.StepErr1++; + KMem.WDT[49]++; + Radio.Standby(); + KWireLessStart(); + } + } + if (stat == RF_CAD && GetTick() - KwRunStat.lastRecvtime > ((2 )*10)){ + KwRunStat.StepErr2++; + KwRunStat.CADTimeOut++; + KMem.WDT[50]++; + Radio.Standby(); + KWireLessStart(); + } + if (GetTick() - KwRunStat.lastRecvdtime > 4000){ // 200mS + // KwRunStat.ErrStat=500; + KwRunStat.ErrStat=500; +// Radio.Standby(); +// KWireLessStart(); + } + if (GetTick() - KwRunStat.lastRecvdtime > 12000){ // 1200mS + KwRunStat.ErrStat=5000; KMem.WFX[1]=0; + } + if (GetTick() - KwRunStat.lastRecvtime > 16000){ + KMem.WDT[52]++; + KwResetRf(); + Radio.Standby(); + KWireLessStart(); + KwRunStat.lastRecvtime = GetTick(); + } + return 0; +} + + + + + diff --git a/Radio_LLCC68_Multi/Radio/KWireLess1.h b/Radio_LLCC68_Multi/Radio/KWireLess1.h new file mode 100644 index 0000000..901e095 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/KWireLess1.h @@ -0,0 +1,344 @@ +/** + ****************************************************************************** + * @file : KWireLess.h + * @brief : Header for KWireLess.c file. + * This file contains the common defines of the application. + ****************************************************************************** + */ +#include "KMachine.h" +#include <stdint.h> +#include "user.h" + +#include "radio/inc/sx126x-board.h" + + +#ifndef __KWIRELESS_H__ +#define __KWIRELESS_H__ +typedef unsigned char uchar; + + +/************************************************************************************************************************************** +Demo 绋嬪簭娴佺▼ RadioEnableMaster=true 涓轰富鏈虹锛屼富鏈虹鍙戦�佷竴涓�"PING"鏁版嵁鍚庡垏鎹㈠埌鎺ユ敹锛岀瓑寰呬粠鏈鸿繑鍥炵殑搴旂瓟"PONG"鏁版嵁LED闂儊 + + RadioEnableMaster=false 涓轰粠鏈虹锛屼粠鏈虹鎺ユ敹鍒颁富鏈虹鍙戣繃鏉ョ殑"PING"鏁版嵁鍚嶭ED闂儊骞跺彂閫佷竴涓�"PONG"鏁版嵁浣滀负搴旂瓟 +***************************************************************************************************************************************/ +typedef enum tag_KWStates // 涓荤姸鎬佹満 鐘舵�� +{ + KW_PON, //寮�鏈� + KW_UNINIT, //鏈垵濮嬪寲 + KW_INITED, //宸插垵濮嬪寲 + KW_UNCONFIGED, //鏈厤缃� + KW_CONFIGING, //閰嶇疆涓� + KW_CONFIGED, //宸查厤缃� + KW_READY, //灏辩华 + KW_STARTING, //鍚姩涓� + KW_OPERATIONAL, //鎿嶄綔 + KW_STOPPED, //鍋滄 + KW_ERROR1, //閿欒1 + KW_ERROR2, //閿欒2 + KW_ERROR3, //閿欒3 +}KWStates; + +#define STORE_KWCONFIG_BASE (FLASH_BASE + 0x0000F000) //50k K //and +//#define STORE_RUNSTAT_PAGESIZE (0x00000400) //Page Size = 1K +#define STORE_KWCONFIG_PAGES 1 //use 1 pages + +enum enWLWorkMode +{ + WLWorkModeNone, // + WLWorkModeUni, // 涓�瀵逛竴 + WLWorkModeMul, // 涓�瀵瑰 + WLWorkModeThr, // 閫忎紶 + +}; + +typedef struct tagWLConfig +{ + uint32_t RF_T_Freq; //Hz + uint32_t RF_R_Freq; //Hz + uint16_t nChnSpacing; //kHz + uint16_t nCycleTime; // + uchar workMode; //0: FSK, 1: LoRa + uchar nChannel; + uchar bMaster; + uchar nRadioAddr; + uchar bEnableMulti; + + uchar Tx_Power; // dBm 5 - 22 dBm + uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + uchar LoRaFactor; // [SF5 .. SF 12] + uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 ] + uint8_t NetWorkAddr; + uint16_t DeviceAddr; + uchar bEnableAddr; + uchar bEnableEncrypt; + uchar bEnableRelay; + uchar LoRaPreambleLen; // 2 - 12 + uchar bAutoPower; //鑷姩鍔熺巼 + uchar bAutoReSend; //鑷姩閲嶅彂 + +// uchar ; // +// uchar + +}stWLConfig, *pstWLConfig; + +typedef struct tagStoredWLConfig +{ + unsigned short BlockSign; + unsigned char BlockType; + unsigned char nSeq; + unsigned short nSize; + unsigned short nCRC16; + stWLConfig WLConfig; +}stStoredWLConfig, *pstStoredWLConfig; + + +typedef enum tag_runstep{ + RS_IDLE, + RS_MASTER_CAD, + RS_SENDING, + RS_SENT, + RS_RECVING, + RS_RECVED, +}enRunStep; + +#pragma anon_unions + +typedef struct tagKwStatByte +{ + uint8_t nSeq :2; + uint8_t Err1 :1; + uint8_t Err2 :1; + uint8_t bHasData :1; + uint8_t bHeader :1; + uint8_t bTail :1; + + +}stKwStatByte; + +typedef struct tagKwChnStat +{ + uint32_t DeviceAddr; + uint8_t Stat; // 鐘舵�佸瓧鑺� + uint8_t nSeq; // 鍖呭簭鍒楀彿 + uint8_t Tx_Power; + uint8_t RSSI; + uint8_t SNR; + uint8_t tRSSI; + uint8_t tSNR; + uint32_t SendCount; + uint32_t RecvCount; +// uint32_t SendTime; +// uint32_t RecvTime; + uint16_t TxErr; + uint16_t RxErr; + + uint16_t LostCount; + uint16_t CtnLstPkts; + uint16_t MaxCtnLstPkts; + + uchar * pTxBuffer; + uint16_t sizetosend; + uint16_t sentsize; + + uchar * pRxBuffer; // and buffer max size; +// uint16_t SizeToRecv; + uint16_t RecvedSize; + + +}stKwChnStat; + + +typedef struct tagWLStat +{ + union { + uint32_t Status; //鐘舵�� + struct { + uint32_t bMasterSent:1; + uint32_t bMasterRecved:1; + }; + }; + uint16_t curStat; //褰撳墠鐘舵�� + uint16_t runStep; //宸ヤ綔姝ラ + + uint16_t RunStat; //杩愯鐘舵�� + uint16_t ErrStat; //閿欒鐘舵�� + + uint32_t RF_Freq; //杩愯棰戠巼 + + uint16_t nTimeOnAir; + uint16_t DeviceAddr; + uint8_t nSeq; + uint8_t NetWorkAddr; + + uchar Tx_Power; // dBm 5 - 22 dBm + uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + uchar LoRaFactor; // [SF5 .. SF 12] + uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 ] + + uchar LoRaPreambleLen; // 2 - 12 + + uchar bEnableAddr; + uchar bEnableEncrypt; + uchar bEnableRelay; + uchar bAutoReSend; //鑷姩閲嶅彂 + + uint32_t sentCount; //鍙戦�佽鏁� + uint32_t recvCount; //鎺ユ敹璁℃暟 + uint32_t lastSendtime; //涓婃鍙戦�佹椂闂� + uint32_t lastSenttime; //涓婃鍙戝畬鏃堕棿 + uint32_t lastRecvtime; //涓婃鍚姩鎺ユ敹鏃堕棿 + uint32_t lastRecvdtime; //涓婃鏀跺埌鏃堕棿 + uint32_t lastActTime; //涓婃鍔ㄤ綔鏃堕棿 + uint32_t lastAckTime; //涓婃搴旂瓟鏃堕棿 + uint32_t lastErrTime; //涓婃閿欒鏃堕棿 + uint32_t latancy; //寤惰繜 + uint32_t cycleTime; //寰幆鏃堕棿 + + uint16_t LostPackets; //涓㈠寘璁℃暟 + uint16_t CtnLstPkts; //杩炵画涓㈠寘璁℃暟 + uint16_t MaxCtnLstPkts; //鏈�澶ц繛缁涪鍖呰鏁� + uint16_t TXErr; //鍙戦�侀敊璇鏁� + uint16_t RXErr; //鎺ユ敹閿欒璁℃暟 + uint16_t CRCErr; //CRC閿欒璁℃暟 + uint16_t PktErr; //鍖呴敊璇� ; + uint16_t ChnErr; //棰戦亾閿欒; + uint16_t nErrChn; //閿欒鐨勯閬撳彿; + uint16_t CADDoneCount; //CAD 瀹屾垚娆℃暟 + uint16_t CADOkCount; //CAD 鏄鏁� + uint16_t CADNgCount; //CAD 鍚︽鏁� + uint16_t CADTimeOut; //CAD 瓒呮椂娆℃暟 + uint16_t StepErr1; //姝ラ閿欒1 + uint16_t StepErr2; //姝ラ閿欒2 + uint16_t Err1Count; //寰棯鎶ヨ娆℃暟 + uint16_t Err2Count; //澶ч棯鎶ヨ娆℃暟 + uint16_t Err3Count; //涓ラ噸涓㈠け淇″彿娆℃暟 + + int8_t RSSI; //淇″彿寮哄害 + int8_t SNR; //淇″櫔姣� + int8_t tRSSI; //瀵规柟淇″彿寮哄害 + int8_t tSNR; //瀵规柟淇″櫔姣� + + uint32_t targetSentCount; //瀵规柟鍙戦�佹暟閲� + uint32_t targetRecvdCount; //瀵规柟鎺ュ彈鏁伴噺 + + unsigned char ttTxBuf1[256]; + uint16_t sizetosend; + uint16_t sentsize; + uint16_t sizesending; + + unsigned char ttRxBuf1[256]; + uint16_t ttRxSize; + unsigned char ttRxRecved; + + unsigned char ttAirBuf[65]; + uint16_t ttAirSize; + unsigned char bttAirHeader; + unsigned char bttAirTail; + + unsigned char bttAirData; + +}stWLRunStat,*pstWLRunStat; + +enum enKwCMDs +{ + + KwcmdNone = 0x00, //Nothing + + KwcmdQuery = 0x01, //Query basic Info + KwcmdQueryRply = 0x81, //Query Info Reply + + KwcmdSetCfg = 0x02, // Set Configuration + KwcmdSetCfgRply = 0x82, // Set Configuration Response + + KwcmdToRunMode = 0x03, + KwcmdToRunModeRply = 0x83, + + KwcmdBroadCastCfg = 0x04, // + + KwcmdMuExchgData = 0x05, // + KwcmdMuExchgDataRply = 0x85, // + + KwcmdToSafeMode = 0x06, + + KwcmdHeartBeat = 0x07, // + KwcmdReHeartBeat = 0x87, // +}; + + +enum { + enReqSign = 0x55, + enRplySign = 0xAA, + +}; + +typedef struct tagKwPktStatByte +{ + uchar nSeq :2 ; + uchar bErr1 :1 ; + uchar bErr2 :1 ; + uchar bHasData :1; + uchar bHead :1; + uchar bTail :1; + + +}stKwPktStatByte; + +typedef struct tagKwPacket +{ + uchar STSign; // 鍖呭紑濮嬫爣璁� + uchar DstAddr; // 瀛愭満缁勫悎鍦板潃, 鍖呮嫭 棰戦亾 鍜� 瀛愭満鍦板潃 + uchar Func; // 鍔熻兘鐮� + union{ + uchar Stat; // 鐘舵�佸瓧 + stKwPktStatByte; + }; + uchar Data[1]; // 鏁版嵁 + +}stKwPacket, *pstKwPacket; + +int LoadKwConfig(void); +int SaveKwConfig(void); + +int KWireLessInit(bool bRadioEnableMaster, uint32_t nChn); +int KWireLessStart(void); + +void OnTxDone( void ); +void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +void OnTxTimeout( void ); +void OnRxTimeout( void ); +void OnRxError( void ); +void OnCadDone( bool channelActivityDetected); + + +void LedToggle(void); + + +int KWL_Process(int nChn); + +int KWLMasterProc(int nChn); +int KWLSlaveProc(int nChn); + +int KWLMasterParsePkt(int nChn, int nSize); +int KWLSlaveParsePkt(int nChn, int nSize); + +int KWLMasterSendReqPkt(int nChn); +int KWLSlaveSendRplyPkt(int nChn); + + +int KWMasterProc(void); +int KWSlaveProc(void); +int MkKwPkg(void* pPkg, int len); + +int KWSendPkg(void* pPkg, int len); +int KWProcPkg(void); + +//extern uchar nRadioChannel; +//extern uchar nRadioAddr; + +extern stWLConfig WLCfg ; +extern stWLRunStat KwRunStat; + + +#endif ///* __KBUS_H__ */ + diff --git a/Radio_LLCC68_Multi/Radio/KWireLess2.c b/Radio_LLCC68_Multi/Radio/KWireLess2.c new file mode 100644 index 0000000..9fced9d --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/KWireLess2.c @@ -0,0 +1,1089 @@ +/** + ****************************************************************************** + * @file : KWireLess.c + * @brief : K-WireLess Protocol program body + ****************************************************************************** + */ +#include "KWireLess2.h" +#include "functions.h" +#include "string.h" +#include "PLCFunctions.h" +#include "stm32f0xx_hal.h" + + +/************************************************************************************************************************************** +Demo 绋嬪簭娴佺▼ RadioEnableMaster=true 涓轰富鏈虹锛屼富鏈虹鍙戦�佷竴涓�"PING"鏁版嵁鍚庡垏鎹㈠埌鎺ユ敹锛岀瓑寰呬粠鏈鸿繑鍥炵殑搴旂瓟"PONG"鏁版嵁LED闂儊 + + RadioEnableMaster=false 涓轰粠鏈虹锛屼粠鏈虹鎺ユ敹鍒颁富鏈虹鍙戣繃鏉ョ殑"PING"鏁版嵁鍚嶭ED闂儊骞跺彂閫佷竴涓�"PONG"鏁版嵁浣滀负搴旂瓟 +***************************************************************************************************************************************/ + +#define USE_MODEM_LORA +//#define USE_MODEM_FSK + +/* +#if defined( USE_MODEM_LORA ) + +#define LORA_BANDWIDTH 1 // [0: 125 kHz, + // 1: 250 kHz, + // 2: 500 kHz, + // 3: Reserved] +#define LORA_SPREADING_FACTOR 8 // [SF5..SF12] +#define LORA_CODINGRATE 4 // [1: 4/5, + // 2: 4/6, + // 3: 4/7, + // 4: 4/8] +#define LORA_PREAMBLE_LENGTH 4 // Same for Tx and Rx + +*/ +#define LORA_SYMBOL_TIMEOUT 0 // Symbols +#define LORA_FIX_LENGTH_PAYLOAD_ON false +#define LORA_IQ_INVERSION_ON false + +/* +#elif defined( USE_MODEM_FSK ) + +#define FSK_FDEV 20e3 // Hz +#define FSK_DATARATE 19.2e3 // bps +#define FSK_BANDWIDTH 60e3 // Hz >> DSB in sx126x +#define FSK_AFC_BANDWIDTH 200e3 // Hz +#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx +#define FSK_FIX_LENGTH_PAYLOAD_ON false + +#else + #error "Please define a modem in the compiler options." +#endif +*/ +/* +#define nChannelSpacing 530000 // Hz +#define TX_OUTPUT_POWER 16 // 22 dBm +*/ + + +extern bool IrqFired; + +//bool RadioEnableMaster=true;//涓讳粠閫夋嫨 +//uchar nRadioChannel = 0; +//uchar nRadioAddr = 1; +uint16_t crc_value; + +#define MixAddr(x,y) ((x<<4)|(y)) +/*! + * Radio events function pointer + */ +#define MASTER_RX_TIMEOUT_VALUE 80 //mS +#define SLAVE_RX_TIMEOUT_VALUE 400 //mS +#define CYCLE_TIME 80 //mS + +const stWLConfig defaultWLConfig = +{ + .RF_T_Freq = 430620000, // uint32_t Hz + .RF_R_Freq = 430620000, // uint32_t //Hz + .nChnSpacing = 530, // uint16_t ChannelSpacing; //kHz + .nCycleTime = CYCLE_TIME, // CycleTime +// .ModemType = 1, // //0: FSK, 1: LoRa + .workMode = 3, // 0, None 1, Uni, 2 Thr, 3 Multi1, 4 Multi2, 5 MulMa + .nChannel = 0, + .bMaster = 0, + .nRadioAddr =1 , + .bEnableMulti = 0, + + .Tx_Power = 20, // uchar Tx_Power; + .LoraBandWidth = 1, // uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + .LoRaFactor = 5, // uchar LoRaFactor; // [SF5 .. SF 12] + .LoRaCodingRate = 1, // uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 + .NetWorkAddr = 0x00, // uint8_t NetWorkAddr; + .DeviceAddr = 0x0102, // uint16_t DeviceAddr; + .bEnableAddr = 0, // uchar bEnableAddr; + .bEnableEncrypt = 0, // uchar bEnableEncrypt; + .bEnableRelay = 0, // uchar bEnableRelay; + .LoRaPreambleLen = 4, // uchar LoRaPreamble_Len; // 2 - 12 + .bAutoPower = 1, + .bAutoReSend = 1, // 鑷姩閲嶅彂 +}; + +//stWLConfig * pWLCfg = (stWLConfig *)&defaultWLConfig; +static RadioEvents_t RadioEvents; + +stWLConfig WLCfg ; +stWLRunStat KwRunStat; + +typedef enum +{ + LOWPOWER, + RX, + RX_TIMEOUT, + RX_ERROR, + TX, + TX_TIMEOUT, +}States_t; + + + +#define WL_RX_BUFFER_SIZE 160 // Define the payload size here +#define WL_TX_BUFFER_SIZE 160 // Define the payload size here + +uint16_t nTimeOnAir; +/* +const uint8_t PingMsg[] = "PING"; +const uint8_t PongMsg[] = "PONG"; +*/ + +//uint16_t BufferSize = BUFFER_SIZE; +uint8_t KwRx_Buffer[WL_RX_BUFFER_SIZE]; +uint8_t KwTx_Buffer[WL_TX_BUFFER_SIZE]; + +#define WL_TT_EACH_SIZE 64 // transparent transmission byte size for each send + + +States_t State = LOWPOWER; + +int8_t RssiValue = 0; +int8_t SnrValue = 0; + +emKWStates KW_State=KW_UNINIT; + +void LedToggle(void) +{ +// GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_RESET);//LED闂儊 +// HAL_Delay_nMS(10); +// GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_SET); + + LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_13); +} + +int LoadKwConfig(void) +{ + stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); + + if (pstStoredWLCFG->BlockSign == 0x55AA && pstStoredWLCFG->BlockType == 0x05) { + WLCfg = pstStoredWLCFG->WLConfig; + } else { + WLCfg = defaultWLConfig; + } + return 0; +} + +int SaveKwConfig(void) +{ +// stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); + + stStoredWLConfig theStoredWLCFG; + theStoredWLCFG.BlockSign = 0x55AA; + theStoredWLCFG.BlockType = 0x05; + theStoredWLCFG.nSeq = 1; + theStoredWLCFG.nSize = sizeof(stWLConfig); + theStoredWLCFG.WLConfig = WLCfg; + theStoredWLCFG.nCRC16 = 0x0000; + EraseAndWriteToFlashMem(&theStoredWLCFG, (void *)STORE_KWCONFIG_BASE, sizeof(stStoredWLConfig)); + + return 0; +} + +int KWireLessInit(bool bRadioEnableMaster, uint32_t nChannel, uint8_t nRadioAddr) +{ + stWLConfig * pWLCfg = & WLCfg; + pWLCfg->bMaster = bRadioEnableMaster; + // Radio initialization + RadioEvents.TxDone = OnTxDone; + RadioEvents.RxDone = OnRxDone; + RadioEvents.TxTimeout = OnTxTimeout; + RadioEvents.RxTimeout = OnRxTimeout; + RadioEvents.RxError = OnRxError; + RadioEvents.CadDone = OnCadDone; + + Radio.Init( &RadioEvents ); + pWLCfg->nChannel = nChannel; + KwRunStat.RF_Freq = pWLCfg->RF_T_Freq + pWLCfg->nChannel * pWLCfg->nChnSpacing*1000; + Radio.SetChannel( KwRunStat.RF_Freq ); + pWLCfg->nRadioAddr = nRadioAddr; + KwRunStat.nCurClient = 1; + // Radio.WriteBuffer(0x06C0,data,2); + // Radio.ReadBuffer(0x06C0,test,2); + +#if defined( USE_MODEM_LORA ) +/* + Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, + LORA_SPREADING_FACTOR, LORA_CODINGRATE, + LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); + + Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, + LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); +// */ + + Radio.SetTxConfig( MODEM_LORA, pWLCfg->Tx_Power, 0, pWLCfg->LoraBandWidth, + pWLCfg->LoRaFactor, pWLCfg->LoRaCodingRate, + pWLCfg->LoRaPreambleLen, LORA_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); + + Radio.SetRxConfig( MODEM_LORA, pWLCfg->LoraBandWidth, pWLCfg->LoRaFactor, + pWLCfg->LoRaCodingRate, 0, pWLCfg->LoRaPreambleLen, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); + + Radio.SetMaxPayloadLength(MODEM_LORA,32); + +#elif defined( USE_MODEM_FSK ) + + Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, + FSK_DATARATE, 0, + FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, + true, 0, 0, 0, 3000 ); + + Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, + 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, + 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, + 0, 0,false, false ); +#else + #error "Please define a modem in the compiler options.." +#endif + SX126xSetRxTxFallbackMode(0x40); // 0x40-> FS 0x30 -> SD_XOSC 0x20 -> SD_RC + + SX126xSetCadParams(LORA_CAD_02_SYMBOL,22,10,LORA_CAD_ONLY,1); + + nTimeOnAir = Radio.TimeOnAir(MODEM_LORA,14); + KwRunStat.nTimeOnAir = nTimeOnAir; +// KMem.WDT[38]=nTimeOnAir; + KwRunStat.runStep=RS_IDLE; + KMem.WDT[0]++; + KwRunStat.Tx_Power = WLCfg.Tx_Power; + KwRunStat.LoraBandWidth = WLCfg.LoraBandWidth; + KwRunStat.LoRaFactor = WLCfg.LoRaFactor; + KwRunStat.LoRaCodingRate = WLCfg.LoRaCodingRate; + KwRunStat.LoRaPreambleLen = WLCfg.LoRaPreambleLen; + + return 0; +} + +int KwResetRf() +{ + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + Radio.Standby(); + KwRunStat.runStep=RS_IDLE; + return 0; +} + +int KwStartRecv(int nChnd) +{ + + Radio.Standby(); + Radio.SetChannel( KwRunStat.RF_Freq ); + Radio.SetRxConfig( MODEM_LORA, WLCfg.LoraBandWidth, WLCfg.LoRaFactor, + WLCfg.LoRaCodingRate, 0, WLCfg.LoRaPreambleLen, + LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, + 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); + + Radio.SetMaxPayloadLength(MODEM_LORA,32); + + Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); + KwRunStat.runStep=RS_RECVING; + + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); + return 0; +} + +int KWireLessStart(void) +{ + if(WLCfg.bMaster) + { + KWLMasterSendReqPkt(1); + } + else + { + KwStartRecv(1); + } + +// while( 1 ) + // { + // Radio.IrqProcess( ); // Process Radio IRQ +// } + return 0; +} + + +void OnTxDone( void ) +{ + KwRunStat.bMasterSent = 1; + KwRunStat.bMasterRecved = 0; + KwRunStat.runStep=RS_IDLE; + KMem.WDT[42]++; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastSenttime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); + Radio.Standby(); + if (WLCfg.bMaster) { + Radio.Rx( MASTER_RX_TIMEOUT_VALUE ); //杩涘叆鎺ユ敹 + } else { + KwStartRecv(1); + //Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); //杩涘叆鎺ユ敹 + } + KwRunStat.runStep=RS_RECVING; + + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); + LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_14); +// int us2=GetTick(); +// KMem.ScanTimeuS=us2-KMem.LastScanTime; +// KMem.LastScanTime = us2; +// if (KMem.ScanTimeuS < KMem.MinScanTimeuS) {KMem.MinScanTimeuS = KMem.ScanTimeuS;} +// if (KMem.ScanTimeuS > KMem.MaxScanTimeuS) {KMem.MaxScanTimeuS = KMem.ScanTimeuS;} + +} + +void OnTxTimeout( void ) +{ + KwRunStat.runStep=RS_IDLE; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].TXErr++; + Radio.Standby(); +// KMem.WDT[44]++; +} +bool bThisRxError=0; + +void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +{ + KMem.WDT[44] = size; + if (size <= 120) { + memcpy( KwRx_Buffer, payload, size ); + memcpy(&KMem.WDT[64],payload,size); + }else + { + + } + Radio.Standby(); + KwRunStat.runStep = RS_IDLE; + + + KwRunStat.curStat = 0; + KwRunStat.ClientStat[KwRunStat.nCurClient].latancy = GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime; + + RssiValue = rssi; + SnrValue = snr; + + KwRunStat.ClientStat[KwRunStat.nCurClient].RSSI = RssiValue; + KwRunStat.ClientStat[KwRunStat.nCurClient].SNR = SnrValue; + + KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount++; +// KwRunStat.CtnLstPkts=0; + + if(WLCfg.bMaster) + { + KWLMasterParsePkt(WLCfg.nChannel,size); + //KWLMasterSendReqPkt(1); + } + else //slave + { + KWLSlaveParsePkt(WLCfg.nChannel,size); + } + if (bThisRxError) { + bThisRxError=0; + // return; + } +} + +void OnRxTimeout( void ) +{ + KwRunStat.runStep=RS_IDLE; + + Radio.Standby(); + stClientStat * pClientStat = &KwRunStat.ClientStat[KwRunStat.nCurClient]; + pClientStat->lastErrTime = GetTick() - pClientStat->lastAckTime; + pClientStat->lastAckTime = GetTick(); + + KwRunStat.Tx_Power+=6; //涓㈠寘锛� 澧炲姞鍙戝皠鍔熺巼 + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + + + KMem.WDT[45]++; + pClientStat->LostPackets++; + pClientStat->CtnLstPkts++; + if (pClientStat->CtnLstPkts > pClientStat->MaxCtnLstPkts) {pClientStat->MaxCtnLstPkts = pClientStat->CtnLstPkts;} +// KwRunStat.ErrStat=500; + if (pClientStat->CtnLstPkts > 2) { KwRunStat.ErrStat=500;} + if (pClientStat->CtnLstPkts ==3 ) {pClientStat->Err1Count++;} + if (pClientStat->CtnLstPkts > 5) { KwRunStat.ErrStat=5000;} + if (pClientStat->CtnLstPkts == 6) {pClientStat->Err2Count++;} + if (pClientStat->CtnLstPkts > 9) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (pClientStat->CtnLstPkts == 10) {pClientStat->Err3Count++;} + if ((pClientStat->CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + KwResetRf(); + Radio.Standby(); + // KWireLessStart(); + } + if(WLCfg.bMaster) + { + //KWLMasterSendReqPkt(1); + } + else + { + KwStartRecv(1); +// Radio.Standby(); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + } +} + + +void OnRxError( void ) +{ + KwStartRecv(1); +// Radio.Standby(); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + + KwRunStat.ClientStat[KwRunStat.nCurClient].RXErr++; + KMem.WDT[46]++; + bThisRxError=1; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastErrTime = GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime; + + if(WLCfg.bMaster) + { +// SendPingMsg(); + } + else + { +/* +// Radio.Rx( RX_TIMEOUT_VALUE ); + //KwRunStat.lastActTime = GetTick(); + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} +// KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=500; } + if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} +*/ + } +// Radio.Standby(); +} + +void OnCadDone( bool channelActivityDetected) +{ + KMem.WDT[60]++; + KwRunStat.ClientStat[KwRunStat.nCurClient].CADDoneCount++; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); + KMem.WDT[16] = KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime - KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime; + if (channelActivityDetected) { + KwRunStat.ClientStat[KwRunStat.nCurClient].CADNgCount++; + KMem.WDT[61]++; + Radio.StartCad(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + } + else { + KwRunStat.ClientStat[KwRunStat.nCurClient].CADOkCount++; + KMem.WDT[62]++; + if (WLCfg.bMaster) { + if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS + // Radio.Standby(); + KWireLessStart(); + }else { + Radio.Standby(); + KWireLessStart(); + } + }else { + KWLSlaveSendRplyPkt(1); + } + } + return; +} + +int KWLMasterParsePkt(int nChn,int size) +{ + bool CRC_OK =1; +///* + crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) + { + KwRunStat.ClientStat[KwRunStat.nCurClient].CRCErr++; + KwRunStat.ErrStat=500; + CRC_OK = 0; + }else { + CRC_OK = 1; + } +//*/ + pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; + if(CRC_OK && p1->STSign == enRplySign ) //memcmp(RX_Buffer,PongMsg,4)==0 + { + if (p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) + { + KwRunStat.bMasterRecved = 1; + LedToggle();//LED闂儊 + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime=GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts=0; + + if (p1->Stat==0) { + KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI = KwRx_Buffer[10]; + KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR = KwRx_Buffer[11]; + if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI > -50) { + if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} + }else if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI < -60) { + KwRunStat.Tx_Power+=6; + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + } + + }else if (p1->Stat==1){ + KwRunStat.ClientStat[KwRunStat.nCurClient].targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (p1->Stat==2) { + KwRunStat.ClientStat[KwRunStat.nCurClient].targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (p1->Stat==3) { + } + + KMem.WDT[41]=(-KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI) + ((-KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR)<<8); + + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); + // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); + + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); + +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + KwRunStat.sentsize += KwRunStat.sizesending; + KwRunStat.sizesending = 0; + + if (KwRunStat.sentsize >= KwRunStat.sizetosend) { + //鏁翠綋 鍙戦�佸畬鎴� + KwRunStat.sizetosend =0; + KwRunStat.sentsize = 0; + KwRunStat.ttAirSize = 0; + // 鍙戦�佸畬鎴� + } + } +// 鎺ュ彈鍒板鏂瑰彂鏉ョ殑鏁版嵁 + + if (p1->bHasData && size >= 14+3 ) { +// int nFulllen1 = KwRx_Buffer[12]; + int nthislen2 = KwRx_Buffer[13]; + if (size >= 14 + nthislen2) { + if (p1->bHead) { + // 鏁版嵁鍖呯殑璧峰锛� 涓�涓柊鐨勬暟鎹寘鐨勫紑濮� + KwRunStat.ttRxSize = 0; +// SendPacket(1, "H", 1); + + } + memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize , KwRx_Buffer + 14 , nthislen2); + KwRunStat.ttRxSize += nthislen2; + if (p1->bTail) + { + // 宸茬粡鏀跺埌瀹屾暣鐨勪竴涓暟鎹寘 + KwRunStat.ttRxRecved =1; + KwRunStat.ErrStat=500; +// SendPacket(1, "T", 1); + + // 鍚庣画鏁版嵁鍖呭鐞嗘祦绋� ; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + + // 鏆傛椂娴佺▼锛屽叏閮ㄥ彂鍥炲幓銆� +// memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); +// KwRunStat.sizetosend = KwRunStat.ttRxSize; +// KwRunStat.sentsize = 0; +// KwRunStat.sizesending = 0; + } + + } + } + +/* + + + + if (KwRunStat.ttAirSize > 0) + { + if (KwRunStat.bttAirHeader) { KwRunStat.ttRxRecved=0; } + memcpy(KwRunStat.ttRxBuf1 + KwRunStat.ttRxRecved,KwRunStat.ttAirBuf, KwRunStat.ttAirSize); + KwRunStat.ttRxRecved += KwRunStat.ttAirSize; + + if (KwRunStat.bttAirTail) { + // 鏀跺埌 涓�涓暟鎹寘鐨勬渶鍚庨儴鍒� + KwRunStat.ttRxSize = KwRunStat.ttRxRecved; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + } + KwRunStat.ttAirSize = 0; + } +*/ + + } + } + + return 0; +} +int KWLSlaveParsePkt(int nChn,int size) +{ + bool CRC_OK =1; + pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; +///* + crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) + { + KwRunStat.ClientStat[KwRunStat.nCurClient].CRCErr++; +// KwRunStat.ErrStat=500; + CRC_OK = 0; + }else { + CRC_OK = 1; + if (p1->STSign != enReqSign) { + KwRunStat.ClientStat[KwRunStat.nCurClient].PktErr++; + }else { + if (p1->DstAddr != MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) { + KwRunStat.ClientStat[KwRunStat.nCurClient].ChnErr++; + KwRunStat.ClientStat[KwRunStat.nCurClient].nErrChn = p1->DstAddr; + } + } + } +//*/ + + if(CRC_OK && p1->STSign == enReqSign && p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr))// memcmp(RX_Buffer,PingMsg,4)==0 && ) + { + + LedToggle();//LED闂儊 + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime=GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts=0; + int nSeq = p1->nSeq; + if (nSeq==0) { + KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI = KwRx_Buffer[10]; + KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR = KwRx_Buffer[11]; + if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI > -50) { + if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} + }else if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI < -60) { + KwRunStat.Tx_Power+=6; + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + } + }else if (nSeq==1){ + KwRunStat.ClientStat[KwRunStat.nCurClient].targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==2) { + KwRunStat.ClientStat[KwRunStat.nCurClient].targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==3) { + } + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); + // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); + + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); + +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + KwRunStat.sentsize += KwRunStat.sizesending; + KwRunStat.sizesending = 0; + + if (KwRunStat.sentsize >= KwRunStat.sizetosend) { + //鏁翠綋 鍙戦�佸畬鎴� + KwRunStat.sizetosend =0; + KwRunStat.sentsize = 0; + KwRunStat.ttAirSize = 0; + // 鍙戦�佸畬鎴� + } + } + + if (p1->bHasData && size >= 14+3 ) { +// int nFulllen1 = KwRx_Buffer[12]; + int nthislen2 = KwRx_Buffer[13]; + if (size >= 14 + nthislen2) { + // 鏀跺埌涓�涓悎鏍肩殑鎼哄甫浼犵粺鏁版嵁鐨� 鍖呫�� + if (p1->bHead) { + // 鏁版嵁娈电殑璧峰锛� 涓�涓柊鐨勬暟鎹鐨勫紑濮� + KwRunStat.ttRxSize = 0; + } + memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize, KwRx_Buffer + 14 , nthislen2); + KwRunStat.ttRxSize += nthislen2; + if (p1->bTail) { + // 宸茬粡鏀跺埌瀹屾暣鐨勪竴涓暟鎹 + KwRunStat.ttRxRecved =1; + KwRunStat.ErrStat=500; + + // 鍚庣画鏁版嵁娈靛鐞嗘祦绋� ; + if (Uart1Mode == 1) { // 澶勪簬閫忎紶妯″紡锛� 鏁版嵁鍙戝洖鍘汇�� + SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); + } + KwRunStat.ttRxSize = 0; + KwRunStat.ttRxRecved = 0; + + // 鏆傛椂娴佺▼锛屽叏閮ㄥ彂鍥炲幓銆� +// memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); +// KwRunStat.sizetosend = KwRunStat.ttRxSize; +// KwRunStat.sentsize = 0; +// KwRunStat.sizesending = 0; +// KwRunStat.ttRxRecved = 0; +// KwRunStat.ttRxSize = 0; + + } + + } + + + } + KWLSlaveSendRplyPkt(1); + // Radio.StartCad(); +// KMem.WFY[0]=(RX_Buffer[4]<<8) + RX_Buffer[5]; +// KMem.WFY[1]=(RX_Buffer[6]<<8) + RX_Buffer[7]; + } + else + { + KwStartRecv(1); +// Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); +// KwRunStat.runStep=RS_RECVING; +// KwRunStat.lastActTime = GetTick(); +// KwRunStat.lastRecvtime = GetTick(); + + } + return 0; +} + +int KWLMasterSendReqPkt(int nChn) +{ + int len1=12; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; + p1->STSign = enReqSign; + p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); + p1->Func = 0x3; + KwRunStat.nSeq = (KwRunStat.nSeq + 1)&0x03; + p1->Stat = KwRunStat.nSeq; //0x00; + p1->Data[0]=KMem.WFY[1]; + p1->Data[1]=KMem.WFY[1]>>8; + p1->Data[2]=KMem.WFY[2]; + p1->Data[3]=KMem.WFY[2]>>8; + + + if (p1->Stat == 0) + { + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; + }else if (p1->Stat == 1){ + memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount,4); + }else if (p1->Stat == 2) { + memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount,4); + }else if (p1->Stat == 3) { + + } +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�1涓寘鐨勮浆鍙戙�� + if (KwRunStat.sizetosend > 0) { + uchar bStart=0,bEnd=1; + int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; + if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} + + if (KwRunStat.sentsize == 0) { // 绗竴娆″彂閫� + bStart = 1; + } + + memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 鍙戦�佹暟鎹紝 濡傛灉涓婃鏈夛紝缁х画涓婃鐨勫彂銆� + + KwRunStat.sizesending = thisToSend; + KwRunStat.ttAirSize = thisToSend; + +// KwRunStat.sentsize = 0; + KwRunStat.bttAirHeader = bStart; + KwRunStat.bttAirTail = bEnd; + + p1->bHasData=1; + p1->bHead = bStart; + p1->bTail = bEnd; + + KwTx_Buffer[len1] = KwRunStat.sizetosend; + KwTx_Buffer[len1+1] = thisToSend; + + memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); + len1 += 2 + thisToSend; + + } + + + crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + KwTx_Buffer[len1]=crc_value; + KwTx_Buffer[len1+1]=crc_value>>8; + + + KMem.WDT[56]=crc_value; + + KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount++; + KwRunStat.ClientStat[KwRunStat.nCurClient].cycleTime = GetTick()- KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime ; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime = GetTick(); + Radio.Send( KwTx_Buffer, len1+2); + KwRunStat.runStep=RS_SENDING; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + + return 0; +} + +int KWLSlaveSendRplyPkt(int nChn) +{ + int len1=12; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; + p1->STSign = enRplySign; + p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); + p1->Func = 0x3; + p1->Stat = (p1->Stat + 1) &0x03; //0x00; + p1->Data[0]=KMem.WFY[1]; + p1->Data[1]=KMem.WFY[1]>>8; + p1->Data[2]=KMem.WFY[2]; + p1->Data[3]=KMem.WFY[2]>>8; + + if (p1->Stat == 0) + { + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; + }else if (p1->Stat == 1){ + memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount,4); + }else if (p1->Stat == 2) { + memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount,4); + }else if (p1->Stat == 3) { + + } + +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�1涓寘鐨勮浆鍙戙�� + + if (KwRunStat.sizetosend > 0) { + uchar bStart=0,bEnd=1; + int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; + if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} + + if (KwRunStat.sentsize == 0) { // 绗竴娆″彂閫� + bStart = 1; + } + + memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 鍙戦�佹暟鎹紝 濡傛灉涓婃鏈夛紝缁х画涓婃鐨勫彂銆� + + KwRunStat.sizesending = thisToSend; + KwRunStat.ttAirSize = thisToSend; + +// KwRunStat.sentsize = 0; + KwRunStat.bttAirHeader = bStart; + KwRunStat.bttAirTail = bEnd; + + p1->bHasData=1; + p1->bHead = bStart; + p1->bTail = bEnd; + + KwTx_Buffer[len1] = KwRunStat.sizetosend; + KwTx_Buffer[len1+1] = thisToSend; + + memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); + len1 += 2 + thisToSend; + + } + + crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� + KwTx_Buffer[len1]=crc_value; + KwTx_Buffer[len1+1]=crc_value>>8; + Radio.Send( KwTx_Buffer, len1+2); + KwRunStat.runStep=RS_SENDING; + + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount++; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime = GetTick(); + return 0; +} + + +int KWL_Process(int nChn) +{ + RadioStatus_t rs = SX126xGetStatus(); + KMem.WDT[1] = rs.Value; + + RadioError_t er = SX126xGetDeviceErrors(); + KMem.WDT[2] = er.Value; + + KMem.WDT[3] = SX126xGetIrqStatus(); + + KMem.WDT[4] = SX126xGetRssiInst(); + + KMem.WDT[5] = GetRadioBusyPin(); + + RadioState_t stat = Radio.GetStatus(); + + KMem.WDT[32]=stat; +// KMem.WDT[38]=Radio.Rssi(MODEM_FSK); + if (WLCfg.bMaster){ + + KWLMasterProc(nChn); + }else //slave + { + KWLSlaveProc(nChn); + } + if (KwRunStat.RunStat) KwRunStat.RunStat--; + if (KwRunStat.ErrStat) KwRunStat.ErrStat--; + + + return 0; +} + +int KWLMasterProc(int nChn) +{ + RadioState_t stat = Radio.GetStatus(); + + switch (KwRunStat.runStep){ + case RS_IDLE: + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime > (WLCfg.nCycleTime) *10 ||KwRunStat.sizetosend > 0 ){ + Radio.StartCad(); + KwRunStat.runStep = RS_MASTER_CAD; + KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); + } + break; + case RS_MASTER_CAD: + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime > 15) { + KwRunStat.ClientStat[KwRunStat.nCurClient].CADTimeOut++; + KwRunStat.runStep = RS_IDLE; + Radio.Standby(); + KMem.WDT[17]++; + KwResetRf(); + } + break; + case RS_SENDING: + break; + case RS_SENT: + break; + case RS_RECVING: + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime > (WLCfg.nCycleTime) *10 || KwRunStat.bMasterRecved){ + KwRunStat.ErrStat=5000; + KwRunStat.ClientStat[KwRunStat.nCurClient].LostPackets++; + KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts++; + + KwRunStat.Tx_Power+=6; //涓㈠寘锛� 澧炲姞鍙戝皠鍔熺巼 + if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } + SX126xSetRfTxPower(KwRunStat.Tx_Power); + + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > KwRunStat.ClientStat[KwRunStat.nCurClient].MaxCtnLstPkts) {KwRunStat.ClientStat[KwRunStat.nCurClient].MaxCtnLstPkts = KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts;} + // KwRunStat.ErrStat=500; + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 2) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err1Count++;} + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 4) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err2Count++;} + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 7) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err3Count++;} + if ((KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + + KwResetRf(); + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + // Radio.Standby(); + // KWireLessStart(); + } + + + KwRunStat.runStep = RS_IDLE; + } + + break; + case RS_RECVED: + KwRunStat.runStep = RS_IDLE; + break; + + default: + break; + + } +/* + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10){ + if (!KwRunStat.bMasterRecved) { + KwRunStat.ErrStat=5000; + KwRunStat.LostPackets++; + KwRunStat.CtnLstPkts++; + if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} + // KwRunStat.ErrStat=500; + if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} + if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} + if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} + if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} + if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } + if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} + if ((KwRunStat.CtnLstPkts &0x0f) == 0x0f) { + KMem.WDT[51]++; + // LoadKwConfig(); + // KWireLessInit(RadioEnableMaster,nRadioChannel); + // Radio.Standby(); + // KWireLessStart(); + } + } + } +*/ +/* + if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS +// Radio.Standby(); + KWireLessStart(); + }else { + Radio.Standby(); + KWireLessStart(); + } +*/ + return 0; +} + +int KWLSlaveProc(int nChn) +{ + RadioState_t stat = Radio.GetStatus(); + if (stat == RF_IDLE){ + KMem.WDT[48]++; + Radio.Standby(); + KWireLessStart(); + } + if (stat == RF_RX_RUNNING ){ + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > ((SLAVE_RX_TIMEOUT_VALUE + 10 )*10)){ + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); + KwRunStat.ClientStat[KwRunStat.nCurClient].StepErr1++; + KMem.WDT[49]++; + Radio.Standby(); + KWireLessStart(); + } + } + if (stat == RF_CAD && GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > ((2 )*10)){ + KwRunStat.ClientStat[KwRunStat.nCurClient].StepErr2++; + KwRunStat.ClientStat[KwRunStat.nCurClient].CADTimeOut++; + KMem.WDT[50]++; + Radio.Standby(); + KWireLessStart(); + } + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime > 4000){ // 200mS + // KwRunStat.ErrStat=500; + KwRunStat.ErrStat=500; +// Radio.Standby(); +// KWireLessStart(); + } + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime > 12000){ // 1200mS + KwRunStat.ErrStat=5000; KMem.WFX[1]=0; + } + if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > 16000){ + KMem.WDT[52]++; + KwResetRf(); + Radio.Standby(); + KWireLessStart(); + KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); + } + return 0; +} + + + + + diff --git a/Radio_LLCC68_Multi/Radio/KWireLess2.h b/Radio_LLCC68_Multi/Radio/KWireLess2.h new file mode 100644 index 0000000..f97466c --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/KWireLess2.h @@ -0,0 +1,441 @@ +/** + ****************************************************************************** + * @file : KWireLess.h + * @brief : Header for KWireLess.c file. + * This file contains the common defines of the application. + ****************************************************************************** + */ +#include "KMachine.h" +#include <stdint.h> +#include "user.h" + +#include "radio/inc/sx126x-board.h" + + +#ifndef __KWIRELESS_H__ +#define __KWIRELESS_H__ +typedef unsigned char uchar; + + +/************************************************************************************************************************************** +寮�鏈哄悗锛岃繘鍏on鐘舵�併�� +涓绘満鑷姩渚濇杩涘叆 Ready鐘舵�併�� +鐩戝惉鎸囧畾棰戦亾涓婄殑閫氳锛屽鏋滄湁鍗犵敤/骞叉壈锛屽垯杩涘叆閿欒1锛堥閬撹鍗犵敤锛夌姸鎬併�� 棰戦亾鏈夊共鎵� + +濡傛灉鎸佺画1绉掓病鏈夋敹鍒颁换浣曢�氳銆傚垯鍗犵敤棰戦亾銆� +鍗犵敤棰戦亾鍚庯紝鍛ㄦ湡鎬у箍鎾甯冮閬撶殑鎵�鏈夋潈锛屽悓鏃剁瓑寰呮槸鍚︽湁鍏朵粬涓绘満瑕佽繘鍏ラ閬撱�� + +閿欒1鐘舵�侊紝濡傛灉棰戦亾涓婄殑涓绘満鏀寔澶氫富妯″紡锛屽垯鍦ㄩ�傚綋鏃跺埢锛屼綔涓烘瑕佷富鏈鸿繘鍏ラ閬擄紝涓庝富鏈鸿疆娴佷娇鐢ㄤ护鐗屻�� + + +************************************************************************************ +瀛愭満鑷姩杩涘叆UnConfiged鐘舵�併�� +鏀跺埌涓绘満鏈夋煡璇㈡湭閰嶇疆鐨勫瓙鏈烘椂锛屽簲绛旓紝搴旂瓟鏈満鐨勫簭鍒楀彿缂栫爜銆� +鎺ユ敹涓绘満涓嬪彂鐨勯厤缃俊鎭紝閰嶇疆鎴愬姛銆� + +瀛愭満鎺ユ敹涓绘満涓嬪彂鐨勫惎鍔ㄥ寘锛屽紑濮嬪惎鍔ㄥ惊鐜暟鎹氦鎹㈣繃绋嬨�� + +涓绘満骞挎挱缃戠粶涓瓙鏈虹殑鏁伴噺鍜屽瓙鏈洪『搴忋�� +涓绘満骞挎挱涓嬪彂鏁版嵁銆備竴涓护鐗屻�備护鐗屼紶閫掔粰绗竴涓瓙鏈恒�� +瀛愭満鎸夌収棰勫厛鐨勯『搴忥紝杞祦鍥炲涓绘満淇℃伅銆備护鐗屼紶閫掔粰涓嬩竴涓瓙鏈恒�� +涓绘満灏嗕护鐗屼紶閫掔粰娆¤鐨勪富鏈恒�� +娆′富鏈哄彂閫佷俊鎭�� + + +閫氳涓殑鍔犲瘑鍜岄槻鍐掑厖锛岄槻绡℃敼鍔熻兘銆� + + +************************************************************************************** +鍗忚灞備笌涓婇潰搴旂敤灞傜殑鎺ュ彛銆� + +杩炴帴鐘舵�佸彉鍖栧洖璋冦�� +寮傚父鍋滄鍥炶皟銆� +鏁版嵁鍙樺寲鍥炶皟銆� +鍚姩锛屽仠姝紝鍥炶皟銆� +寰幆鏁版嵁鏀跺洖璋冿紝寰幆鏁版嵁鍙戝洖璋冦�� +甯﹀閫忎紶鏁版嵁鏀讹紝甯﹀寰幆鏁版嵁鍙戙�� +IOCTRL锛� 鏃犵嚎淇″彿寮哄害銆� + + +鍗忚灞備笌搴曞眰鏃犵嚎閫氳鐨勬帴鍙� +璁剧疆棰戠巼锛屽姛鐜囷紝缂栫爜妯″紡绛夈�� +鏌ヨ宸ヤ綔鍜岀姸鎬併�� +璁剧疆鎺ユ敹妯″紡銆傛帴鏀跺埌鐘舵�併�� +璁剧疆鍙戦�佹ā寮忥紝鍙戦�佸畬鐘舵�併�� +鏁版嵁鍖呮敹锛屾暟鎹寘鍙戙�� + + +IOCTRL锛� 鏃犵嚎淇¢亾淇″彿寮哄害 + + +***************************************************************************************************************************************/ + +typedef enum tag_KWStates // 涓荤姸鎬佹満 鐘舵�� +{ +// KW_PON, //寮�鏈� + KW_UNINIT, //鏈垵濮嬪寲 + KW_INITED, //宸插垵濮嬪寲 + KW_UNCONFIGED, //鏈厤缃� + KW_CONFIGING, //閰嶇疆涓� + KW_CONFIGED, //宸查厤缃� + KW_READY, //灏辩华 + KW_PREOP, //棰勫惎鍔� +// KW_STARTING, //鍚姩涓� + KW_OPERATIONAL, //鎿嶄綔 + KW_STOPPED, //鍋滄 + KW_ERROR1, //閿欒1 +// KW_ERROR2, //閿欒2 +// KW_ERROR3, //閿欒3 +}emKWStates; + +#define STORE_KWCONFIG_BASE (FLASH_BASE + 0x0000F000) //50k K //and +//#define STORE_RUNSTAT_PAGESIZE (0x00000400) //Page Size = 1K +#define STORE_KWCONFIG_PAGES 1 //use 1 pages + + +enum enWLWorkMode +{ + WLWorkModeNone, // + WLWorkModeUni, // 涓�瀵逛竴 + WLWorkModeThr, // 閫忎紶 + WLWorkModeMulti1, // 涓�瀵瑰锛岃疆璇� + WLWorkModeMulti2, // 涓�瀵瑰锛屼护鐗� + WLWorkModeMulMa, // 澶氫富 +}; + +enum { + enReqSign = 0x55, + enRplySign = 0xAA, +}; + +enum enKwCMDs +{ + KwcmdNone = 0x00, //Nothing + + KwcmdQuery = 0x01, //Query basic Info + KwcmdQueryRply = 0x81, //Query Info Reply + + KwcmdSetCfg = 0x02, // Set Configuration + KwcmdSetCfgRply = 0x82, // Set Configuration Response + + KwcmdToRunMode = 0x03, + KwcmdToRunModeRply = 0x83, + + KwcmdBroadCastCfg = 0x04, // + + KwcmdMuExchgData = 0x05, // + KwcmdMuExchgDataRply = 0x85, // + + KwcmdToSafeMode = 0x06, + + KwcmdHeartBeat = 0x07, // + KwcmdReHeartBeat = 0x87, // +}; + +typedef struct tagWLConfig +{ + uint32_t RF_T_Freq; //Hz + uint32_t RF_R_Freq; //Hz + uint16_t nChnSpacing; //kHz + uint16_t nCycleTime; // +// uchar ModemType; // 0: FSK, 1: LoRa + uchar workMode; // 0, None 1, Uni, 2 Thr, 3 Multi1, 4 Multi2, 5 MulMa + uchar nChannel; + uchar bMaster; + uchar nRadioAddr; + uchar bEnableMulti; + + uchar Tx_Power; // dBm 5 - 22 dBm + uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + uchar LoRaFactor; // [SF5 .. SF 12] + uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 ] + uint8_t NetWorkAddr; + uint16_t DeviceAddr; + uchar bEnableAddr; + uchar bEnableEncrypt; + uchar bEnableRelay; + uchar LoRaPreambleLen; // 2 - 12 + uchar bAutoPower; //鑷姩鍔熺巼 + uchar bAutoReSend; //鑷姩閲嶅彂 + +// uchar ; // +// uchar + +}stWLConfig, *pstWLConfig; + +typedef struct tagKwInitStruct +{ + uchar nWorkMode; + uchar bMaster; + uchar nChannel; + uchar nRadioAddr; + uchar bEnableMultiClient; + uchar bEnableMultiMaster; + + +}stKwInitStruct,*pstKwInitStruct; + +typedef struct tagStoredWLConfig +{ + unsigned short BlockSign; + unsigned char BlockType; + unsigned char nSeq; + unsigned short nSize; + unsigned short nCRC16; + stWLConfig WLConfig; +}stStoredWLConfig, *pstStoredWLConfig; + + +typedef enum tag_runstep{ + RS_IDLE, + RS_MASTER_CAD, + RS_SENDING, + RS_SENT, + RS_RECVING, + RS_RECVED, +}enRunStep; + +#pragma anon_unions + +typedef struct tagKwStatByte +{ + uint8_t nSeq :2; + uint8_t Err1 :1; + uint8_t Err2 :1; + uint8_t bHasData :1; + uint8_t bHeader :1; + uint8_t bTail :1; + + +}stKwStatByte; + +typedef struct tagKwChnStat +{ + uint32_t DeviceAddr; + uint8_t Stat; // 鐘舵�佸瓧鑺� + uint8_t nSeq; // 鍖呭簭鍒楀彿 + uint8_t Tx_Power; + uint8_t RSSI; + uint8_t SNR; + uint8_t tRSSI; + uint8_t tSNR; + uint32_t SendCount; + uint32_t RecvCount; +// uint32_t SendTime; +// uint32_t RecvTime; + uint16_t TxErr; + uint16_t RxErr; + + uint16_t LostCount; + uint16_t CtnLstPkts; + uint16_t MaxCtnLstPkts; + + uchar * pTxBuffer; + uint16_t sizetosend; + uint16_t sentsize; + + uchar * pRxBuffer; // and buffer max size; +// uint16_t SizeToRecv; + uint16_t RecvedSize; + + +}stKwChnStat; + +typedef struct tagClientStat +{ + uint32_t sentCount; //鍙戦�佽鏁� + uint32_t recvCount; //鎺ユ敹璁℃暟 + uint32_t lastSendtime; //涓婃鍙戦�佹椂闂� + uint32_t lastSenttime; //涓婃鍙戝畬鏃堕棿 + uint32_t lastRecvtime; //涓婃鍚姩鎺ユ敹鏃堕棿 + uint32_t lastRecvdtime; //涓婃鏀跺埌鏃堕棿 + uint32_t lastActTime; //涓婃鍔ㄤ綔鏃堕棿 + uint32_t lastAckTime; //涓婃搴旂瓟鏃堕棿 + uint32_t lastErrTime; //涓婃閿欒鏃堕棿 + uint32_t latancy; //寤惰繜 + uint32_t cycleTime; //寰幆鏃堕棿 + + uint16_t LostPackets; //涓㈠寘璁℃暟 + uint16_t CtnLstPkts; //杩炵画涓㈠寘璁℃暟 + uint16_t MaxCtnLstPkts; //鏈�澶ц繛缁涪鍖呰鏁� + uint16_t TXErr; //鍙戦�侀敊璇鏁� + uint16_t RXErr; //鎺ユ敹閿欒璁℃暟 + uint16_t CRCErr; //CRC閿欒璁℃暟 + uint16_t PktErr; //鍖呴敊璇� ; + uint16_t ChnErr; //棰戦亾閿欒; + uint16_t nErrChn; //閿欒鐨勯閬撳彿; + uint16_t CADDoneCount; //CAD 瀹屾垚娆℃暟 + uint16_t CADOkCount; //CAD 鏄鏁� + uint16_t CADNgCount; //CAD 鍚︽鏁� + uint16_t CADTimeOut; //CAD 瓒呮椂娆℃暟 + uint16_t StepErr1; //姝ラ閿欒1 + uint16_t StepErr2; //姝ラ閿欒2 + uint16_t Err1Count; //寰棯鎶ヨ娆℃暟 + uint16_t Err2Count; //澶ч棯鎶ヨ娆℃暟 + uint16_t Err3Count; //涓ラ噸涓㈠け淇″彿娆℃暟 + + int8_t RSSI; //淇″彿寮哄害 + int8_t SNR; //淇″櫔姣� + int8_t tRSSI; //瀵规柟淇″彿寮哄害 + int8_t tSNR; //瀵规柟淇″櫔姣� + + uint32_t targetSentCount; //瀵规柟鍙戦�佹暟閲� + uint32_t targetRecvdCount; //瀵规柟鎺ュ彈鏁伴噺 + +}stClientStat; + +typedef struct tagWLStat +{ + union { + uint32_t Status; //鐘舵�� + struct { + uint32_t bMasterSent:1; + uint32_t bMasterRecved:1; + }; + }; + uint16_t curStat; //褰撳墠鐘舵�� + uint16_t runStep; //宸ヤ綔姝ラ + + uint16_t RunStat; //杩愯鐘舵�� + uint16_t ErrStat; //閿欒鐘舵�� + + uint32_t RF_Freq; //杩愯棰戠巼 + + uint16_t nTimeOnAir; + uint16_t DeviceAddr; + uint8_t nSeq; + uint8_t NetWorkAddr; + + uchar Tx_Power; // dBm 5 - 22 dBm + uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] + uchar LoRaFactor; // [SF5 .. SF 12] + uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 ] + + uchar LoRaPreambleLen; // 2 - 12 + + uchar bEnableAddr; + uchar bEnableEncrypt; + uchar bEnableRelay; + uchar bAutoReSend; //鑷姩閲嶅彂 + uint8_t nCurClient; + + stClientStat ClientStat[8]; + + unsigned char ttTxBuf1[256]; + uint16_t sizetosend; + uint16_t sentsize; + uint16_t sizesending; + + unsigned char ttRxBuf1[256]; + uint16_t ttRxSize; + unsigned char ttRxRecved; + + unsigned char ttAirBuf[65]; + uint16_t ttAirSize; + unsigned char bttAirHeader; + unsigned char bttAirTail; + + unsigned char bttAirData; + +}stWLRunStat,*pstWLRunStat; + +typedef struct tagKwPktStatByte +{ + uchar nSeq :2 ; + uchar bErr1 :1 ; + uchar bErr2 :1 ; + uchar bHasData :1; + uchar bHead :1; + uchar bTail :1; +}stKwPktStatByte; + +typedef struct tagKwPacket +{ + uchar STSign; // 鍖呭紑濮嬫爣璁�,鍖呯被鍨� + uchar DstAddr; // 瀛愭満缁勫悎鍦板潃, 鍖呮嫭 棰戦亾 鍜� 瀛愭満鍦板潃 + uchar Func; // 鍔熻兘鐮� + union{ + uchar Stat; // 鐘舵�佸瓧 + stKwPktStatByte; + }; + uchar Data[1]; // 鏁版嵁 + +}stKwPacket, *pstKwPacket; + + +typedef struct tagKwMultiPkt // Kw鍗忚 澶氭満閫氳鍖� +{ + uchar STSign1; // 鍖呭紑濮嬫爣璁板寘鎷寘绫诲瀷 + uchar DstAddr; // 鐩殑缁勫悎鍦板潃锛屽寘鎷� 棰戦亾锛� 鍜� 瀛愭満鍦板潃 + uchar SrcAddr; // 婧愬湴鍧�锛屽彲鑳戒负涓绘満鎴栧瓙鏈恒�� 涓绘満婧愬湴鍧�涓�0 + uchar nStat; // 鐘舵�佺爜 + uchar Func; // 鍔熻兘鐮� + uchar Data[1]; + +}stKwMultiPkt, *pstKwMultiPkt; + +typedef struct tagKwMasterCastPkt{ + uchar STSign1; + uchar DstAddr; + uchar SrcAddr; + uchar nStat; + uchar Func; + uchar Data[1]; + +}stKwMasterCastPkt, *pstKwMasterCastPkt; + + +int LoadKwConfig(void); +int SaveKwConfig(void); + +int KWireLessInit(bool bRadioEnableMaster, uint32_t nChannel, uint8_t nRadioAddr); +int KWireLessStart(void); + +void OnTxDone( void ); +void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); +void OnTxTimeout( void ); +void OnRxTimeout( void ); +void OnRxError( void ); +void OnCadDone( bool channelActivityDetected); + + +void LedToggle(void); + + +int KWL_Process(int nChn); + +int KWLMasterProc(int nChn); +int KWLSlaveProc(int nChn); + +int KWLMasterParsePkt(int nChn, int nSize); +int KWLSlaveParsePkt(int nChn, int nSize); + +int KWLMasterSendReqPkt(int nChn); +int KWLSlaveSendRplyPkt(int nChn); + + +int KWMasterProc(void); +int KWSlaveProc(void); +int MkKwPkg(void* pPkg, int len); + +int KWSendPkg(void* pPkg, int len); +int KWProcPkg(void); + +//extern uchar nRadioChannel; +//extern uchar nRadioAddr; + +extern stWLConfig WLCfg ; +extern stWLRunStat KwRunStat; + + +//int Kw2Init(stKwInitStruct * pInstance, Kw2Struct * InitStruct); +//int Kw2Stop(); +//int Kw2SendThrouPkg; +//int Kw2RecvThrouPkgCallBack; +//int Kw2Start(); +//int Kw2GetStat(); +//int Kw2GetError(); +//int + +#endif ///* __KBUS_H__ */ + diff --git a/Radio_LLCC68_Multi/Radio/delay.c b/Radio_LLCC68_Multi/Radio/delay.c new file mode 100644 index 0000000..6d54656 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/delay.c @@ -0,0 +1,32 @@ +#include "delay.h" +#include <stdint.h> +#include "stm32f0xx_hal.h" + +void Delay_Us (uint32_t delay) +{ + uint8_t i=0; + uint32_t j=0; + for(i=0;i<delay;i++) + { + for(j=0;j<8;j++); + } +} + + +void Delay_Ms(uint32_t delay ) +{ + uint32_t i=0; + uint32_t j=0; + + for(i=0;i<delay;i++) + { + for(j=0;j<4540;j++); + } +} + +void HAL_Delay_nMS( uint32_t Delay ) +{ + HAL_Delay(Delay); + +} + diff --git a/Radio_LLCC68_Multi/Radio/delay.h b/Radio_LLCC68_Multi/Radio/delay.h new file mode 100644 index 0000000..8a303bb --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/delay.h @@ -0,0 +1,16 @@ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#include<stdint.h> + +//extern volatile uint32_t TickCounter; +//extern volatile uint32_t ticktimer; + +void Delay_Us (uint32_t delay); +void Delay_Ms(uint32_t delay ); +void HAL_Delay_nMS(uint32_t Delay ); + +//#define HAL_GetTick() TickCounter + +#endif + diff --git a/Radio_LLCC68_Multi/Radio/gpio.c b/Radio_LLCC68_Multi/Radio/gpio.c new file mode 100644 index 0000000..c5fce29 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/gpio.c @@ -0,0 +1,101 @@ +#include "stm32f0xx.h" +#include "gpio.h" + +void GPIO_int() +{ +#if 0 + GPIO_InitTypeDef GPIO_InitStruct; + /**************************************** + RF_NSS + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_Pin=RADIO_NSS_PIN; + GPIO_Init(RADIO_NSS_PORT, &GPIO_InitStruct); + + GPIO_WriteBit( RADIO_NSS_PORT, RADIO_NSS_PIN,Bit_SET); + + /**************************************** + RF_RST + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_Pin=RADIO_nRESET_PIN; + GPIO_Init(RADIO_nRESET_PORT, &GPIO_InitStruct); + + + + /**************************************** + RF_DIO1 + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; + GPIO_InitStruct.GPIO_Pin=RADIO_DIO1_PIN; + GPIO_Init(RADIO_DIO1_PORT, &GPIO_InitStruct); + + + + /**************************************** + Radio_BUSY + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; + GPIO_InitStruct.GPIO_Pin=RADIO_BUSY_PIN; + GPIO_Init(RADIO_BUSY_PORT, &GPIO_InitStruct); + + + /**************************************** + M_CLK + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; + GPIO_InitStruct.GPIO_Pin=RADIO_SCK_PIN; + GPIO_Init(RADIO_SCK_PORT, &GPIO_InitStruct); + GPIO_PinAFConfig(RADIO_SCK_PORT,RADIO_SCK_AF,GPIO_AF_0); + + /**************************************** + M_MOSI + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; + GPIO_InitStruct.GPIO_Pin=RADIO_MOSI_PIN; + GPIO_Init(RADIO_MOSI_PORT, &GPIO_InitStruct); + GPIO_PinAFConfig(RADIO_MOSI_PORT,RADIO_MOSI_AF,GPIO_AF_0); + + /**************************************** + M_MISO + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; + GPIO_InitStruct.GPIO_Pin=RADIO_MISO_PIN; + GPIO_Init(RADIO_MISO_PORT, &GPIO_InitStruct); + GPIO_PinAFConfig(RADIO_MISO_PORT,RADIO_MISO_AF,GPIO_AF_0); + + + /**************************************** + LED1 + ****************************************/ + GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2; + GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_Pin=LED1_PIN; + GPIO_Init(LED1_PORT, &GPIO_InitStruct); + #endif + +} + diff --git a/Radio_LLCC68_Multi/Radio/gpio.h b/Radio_LLCC68_Multi/Radio/gpio.h new file mode 100644 index 0000000..f030b70 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/gpio.h @@ -0,0 +1,70 @@ +#ifndef _GPIO_H_ +#define _GPIO_H_ + + +#define RADIO_NSS_PIN LL_GPIO_PIN_15 +#define RADIO_NSS_PORT GPIOA + +#define RADIO_MOSI_PIN GPIO_Pin_5 +#define RADIO_MOSI_PORT GPIOB +#define RADIO_MOSI_AF GPIO_PinSource5 + +#define RADIO_MISO_PIN GPIO_Pin_4 +#define RADIO_MISO_PORT GPIOB +#define RADIO_MISO_AF GPIO_PinSource4 + +#define RADIO_SCK_PIN GPIO_Pin_3 +#define RADIO_SCK_PORT GPIOB +#define RADIO_SCK_AF GPIO_PinSource3 + +#define RADIO_nRESET_PIN LL_GPIO_PIN_6 +#define RADIO_nRESET_PORT GPIOB + +#define RADIO_BUSY_PIN LL_GPIO_PIN_7 +#define RADIO_BUSY_PORT GPIOB + +#define RADIO_DIO1_PIN LL_GPIO_PIN_12 +#define RADIO_DIO1_PORT GPIOA + + +#define LED1_PORT GPIOC +#define LED1_PIN GPIO_Pin_15 + + +#define GetRadioBusyPin() LL_GPIO_IsInputPinSet(RADIO_BUSY_PORT,RADIO_BUSY_PIN) +#define GetRadioDio1Pin() LL_GPIO_IsInputPinSet(RADIO_DIO1_PORT,RADIO_DIO1_PIN) + +#define SetRadioNSSPin_0() LL_GPIO_ResetOutputPin(RADIO_NSS_PORT,RADIO_NSS_PIN) +#define SetRadioNSSPin_1() LL_GPIO_SetOutputPin(RADIO_NSS_PORT,RADIO_NSS_PIN) + +#define SetRadionRSTPin_0() LL_GPIO_ResetOutputPin(RADIO_nRESET_PORT,RADIO_nRESET_PIN) +#define SetRadionRSTPin_1() LL_GPIO_SetOutputPin(RADIO_nRESET_PORT,RADIO_nRESET_PIN) + + +#define RADIO_BUSY_PORT GPIOB +#define RADIO_BUSY_PIN LL_GPIO_PIN_7 + +#define RADIO_DIO1_PORT GPIOA +#define RADIO_DIO1_PIN LL_GPIO_PIN_12 + +#define RADIO_SEL_PORT GPIOA +#define RADIO_SEL_PIN LL_GPIO_PIN_15 + +#define RADIO_RST_PORT GPIOB +#define RADIO_RST_PIN LL_GPIO_PIN_6 + +#define GetRadioBusyPin() LL_GPIO_IsInputPinSet(RADIO_BUSY_PORT,RADIO_BUSY_PIN) +#define GetRadioDio1Pin() LL_GPIO_IsInputPinSet(RADIO_DIO1_PORT,RADIO_DIO1_PIN) + +#define SetRadioSELPin_0() LL_GPIO_ResetOutputPin(RADIO_SEL_PORT,RADIO_SEL_PIN) +#define SetRadioSELPin_1() LL_GPIO_SetOutputPin(RADIO_SEL_PORT,RADIO_SEL_PIN) + +#define SetRadioRSTPin_0() LL_GPIO_ResetOutputPin(RADIO_RST_PORT,RADIO_RST_PIN) +#define SetRadioRSTPin_1() LL_GPIO_SetOutputPin(RADIO_RST_PORT,RADIO_RST_PIN) + + + +void GPIO_int(void); +void LowPowerGPIO_int(void); + +#endif diff --git a/Radio_LLCC68_Multi/Radio/inc/crc.h b/Radio_LLCC68_Multi/Radio/inc/crc.h new file mode 100644 index 0000000..49136fe --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/inc/crc.h @@ -0,0 +1,24 @@ +#ifndef _CRC_H_ +#define _CRC_H_ + +#include <stdint.h> + +// CRC types +#define CRC_TYPE_CCITT 0 +#define CRC_TYPE_IBM 1 +// Polynomial = X^16 + X^12 + X^5 + 1 +#define POLYNOMIAL_CCITT 0x1021 +// Polynomial = X^16 + X^15 + X^2 + 1 +#define POLYNOMIAL_IBM 0x8005 +// Seeds +#define CRC_IBM_SEED 0xFFFF +#define CRC_CCITT_SEED 0x1D0F + + +uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ); +uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ); + + + +#endif + diff --git a/Radio_LLCC68_Multi/Radio/inc/radio.h b/Radio_LLCC68_Multi/Radio/inc/radio.h new file mode 100644 index 0000000..eb61f7a --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/inc/radio.h @@ -0,0 +1,379 @@ +/*! + * \file radio.h + * + * \brief Radio driver API definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#ifndef __RADIO_H__ +#define __RADIO_H__ + +#include<stdint.h> +#include<stdbool.h> + +//#define USE_MODEM_LORA + +/*! + * Radio driver supported modems + */ +typedef enum +{ + MODEM_FSK = 0, + MODEM_LORA, +}RadioModems_t; + +/*! + * Radio driver internal state machine states definition + */ +typedef enum +{ + RF_IDLE = 0, //!< The radio is idle + RF_RX_RUNNING, //!< The radio is in reception state + RF_TX_RUNNING, //!< The radio is in transmission state + RF_CAD, //!< The radio is doing channel activity detection +}RadioState_t; + +/*! + * \brief Radio driver callback functions + */ +typedef struct +{ + /*! + * \brief Tx Done callback prototype. + */ + void ( *TxDone )( void ); + /*! + * \brief Tx Timeout callback prototype. + */ + void ( *TxTimeout )( void ); + /*! + * \brief Rx Done callback prototype. + * + * \param [IN] payload Received buffer pointer + * \param [IN] size Received buffer size + * \param [IN] rssi RSSI value computed while receiving the frame [dBm] + * \param [IN] snr Raw SNR value given by the radio hardware + * FSK : N/A ( set to 0 ) + * LoRa: SNR value in dB + */ + void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); + /*! + * \brief Rx Timeout callback prototype. + */ + void ( *RxTimeout )( void ); + /*! + * \brief Rx Error callback prototype. + */ + void ( *RxError )( void ); + /*! + * \brief FHSS Change Channel callback prototype. + * + * \param [IN] currentChannel Index number of the current channel + */ + void ( *FhssChangeChannel )( uint8_t currentChannel ); + + /*! + * \brief CAD Done callback prototype. + * + * \param [IN] channelDetected Channel Activity detected during the CAD + */ + void ( *CadDone ) ( bool channelActivityDetected ); +}RadioEvents_t; + +/*! + * \brief Radio driver definition + */ +struct Radio_s +{ + /*! + * \brief Initializes the radio + * + * \param [IN] events Structure containing the driver callback functions + */ + void ( *Init )( RadioEvents_t *events ); + /*! + * Return current radio status + * + * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + */ + RadioState_t ( *GetStatus )( void ); + /*! + * \brief Configures the radio with the given modem + * + * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] + */ + void ( *SetModem )( RadioModems_t modem ); + /*! + * \brief Sets the channel frequency + * + * \param [IN] freq Channel RF frequency + */ + void ( *SetChannel )( uint32_t freq ); + /*! + * \brief Checks if the channel is free for the given time + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] freq Channel RF frequency + * \param [IN] rssiThresh RSSI threshold + * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured + * + * \retval isFree [true: Channel is free, false: Channel is not free] + */ + bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); + /*! + * \brief Generates a 32 bits random value based on the RSSI readings + * + * \remark This function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * \retval randomValue 32 bits random value + */ + uint32_t ( *Random )( void ); + /*! + * \brief Sets the reception parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] symbTimeout Sets the RxSingle timeout value + * FSK : timeout in number of bytes + * LoRa: timeout in symbols + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] hopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] rxContinuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ + void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool freqHopOn, uint8_t hopPeriod, + bool iqInverted, bool rxContinuous ); + /*! + * \brief Sets the transmission parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] power Sets the output power [dBm] + * \param [IN] fdev Sets the frequency deviation (FSK only) + * FSK : [Hz] + * LoRa: 0 + * \param [IN] bandwidth Sets the bandwidth (LoRa only) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] + * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] hopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] timeout Transmission timeout [ms] + */ + void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool freqHopOn, + uint8_t hopPeriod, bool iqInverted, uint32_t timeout ); + /*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ + bool ( *CheckRfFrequency )( uint32_t frequency ); + /*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (ms) for the given packet payload length + */ + uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen ); + /*! + * \brief Sends the buffer of size. Prepares the packet to be sent and sets + * the radio in transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ + void ( *Send )( uint8_t *buffer, uint8_t size ); + /*! + * \brief Sets the radio in sleep mode + */ + void ( *Sleep )( void ); + /*! + * \brief Sets the radio in standby mode + */ + void ( *Standby )( void ); + /*! + * \brief Sets the radio in reception mode for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ + void ( *Rx )( uint32_t timeout ); + /*! + * \brief Start a Channel Activity Detection + */ + void ( *StartCad )( void ); + /*! + * \brief Sets the radio in continuous wave transmission mode + * + * \param [IN]: freq Channel RF frequency + * \param [IN]: power Sets the output power [dBm] + * \param [IN]: time Transmission mode timeout [s] + */ + void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time ); + /*! + * \brief Reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ + int16_t ( *Rssi )( RadioModems_t modem ); + /*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ + void ( *Write )( uint16_t addr, uint8_t data ); + /*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \retval data Register value + */ + uint8_t ( *Read )( uint16_t addr ); + /*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ + void ( *WriteBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); + /*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ + void ( *ReadBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); + /*! + * \brief Sets the maximum payload length. + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] max Maximum payload length in bytes + */ + void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max ); + /*! + * \brief Sets the network to public or private. Updates the sync byte. + * + * \remark Applies to LoRa modem only + * + * \param [IN] enable if true, it enables a public network + */ + void ( *SetPublicNetwork )( bool enable ); + /*! + * \brief Gets the time required for the board plus radio to get out of sleep.[ms] + * + * \retval time Radio plus board wakeup time in ms. + */ + uint32_t ( *GetWakeupTime )( void ); + /*! + * \brief Process radio irq + */ + void ( *IrqProcess )( void ); + /* + * The next functions are available only on SX126x radios. + */ + /*! + * \brief Sets the radio in reception mode with Max LNA gain for the given time + * + * \remark Available on SX126x radios only. + * + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ + void ( *RxBoosted )( uint32_t timeout ); + /*! + * \brief Sets the Rx duty cycle management parameters + * + * \remark Available on SX126x radios only. + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ + void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime ); +}; + +/*! + * \brief Radio driver + * + * \remark This variable is defined and initialized in the specific radio + * board implementation + */ +extern const struct Radio_s Radio; + +#endif // __RADIO_H__ diff --git a/Radio_LLCC68_Multi/Radio/inc/sx126x-board.h b/Radio_LLCC68_Multi/Radio/inc/sx126x-board.h new file mode 100644 index 0000000..0dbecf1 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/inc/sx126x-board.h @@ -0,0 +1,129 @@ +/* + ______ _ + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + +Description: SX126x driver specific target board functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#ifndef __SX126x_ARCH_H__ +#define __SX126x_ARCH_H__ + +#include "sx126x.h" +/*! + * \brief Initializes the radio I/Os pins interface + */ +//void SX126xIoInit( void ); + +/*! + * \brief Initializes DIO IRQ handlers + * + * \param [IN] irqHandlers Array containing the IRQ callback functions + */ +//void SX126xIoIrqInit( DioIrqHandler dioIrq ); + +/*! + * \brief De-initializes the radio I/Os pins interface. + * + * \remark Useful when going in MCU low power modes + */ +//void SX126xIoDeInit( void ); + +/*! + * \brief HW Reset of the radio + */ +void SX126xReset( void ); + +/*! + * \brief Blocking loop to wait while the Busy pin in high + */ +void SX126xWaitOnBusy( void ); + +/*! + * \brief Wakes up the radio + */ +void SX126xWakeup( void ); + +/*! + * \brief Send a command that write data to the radio + * + * \param [in] opcode Opcode of the command + * \param [in] buffer Buffer to be send to the radio + * \param [in] size Size of the buffer to send + */ +void SX126xWriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Send a command that read data from the radio + * + * \param [in] opcode Opcode of the command + * \param [out] buffer Buffer holding data from the radio + * \param [in] size Size of the buffer + */ +void SX126xReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Write a single byte of data to the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * \param [in] value The data to be written in radio's memory + */ +void SX126xWriteRegister( uint16_t address, uint8_t value ); + +/*! + * \brief Read a single byte of data from the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * + * \retval value The value of the byte at the given address in radio's memory + */ +uint8_t SX126xReadRegister( uint16_t address ); + +/*! + * \brief Sets the radio output power. + * + * \param [IN] power Sets the RF output power + */ +void SX126xSetRfTxPower( int8_t power ); + +/*! + * \brief Gets the board PA selection configuration + * + * \param [IN] channel Channel frequency in Hz + * \retval PaSelect RegPaConfig PaSelect value + */ +uint8_t SX126xGetPaSelect( uint32_t channel ); + +/*! + * \brief Initializes the RF Switch I/Os pins interface + */ +void SX126xAntSwOn( void ); + +/*! + * \brief De-initializes the RF Switch I/Os pins interface + * + * \remark Needed to decrease the power consumption in MCU low power modes + */ +void SX126xAntSwOff( void ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool SX126xCheckRfFrequency( uint32_t frequency ); + +/*! + * Radio hardware and global parameters + */ +extern SX126x_t SX126x; + +#endif // __SX126x_ARCH_H__ diff --git a/Radio_LLCC68_Multi/Radio/inc/sx126x.h b/Radio_LLCC68_Multi/Radio/inc/sx126x.h new file mode 100644 index 0000000..e15b2b1 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/inc/sx126x.h @@ -0,0 +1,1115 @@ +/*! + * \file sx126x.h + * + * \brief SX126x driver implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#ifndef __SX126x_H__ +#define __SX126x_H__ + +#include <stdint.h> +#include <stdbool.h> + + +#define SX1261 1 +#define SX1262 2 + +#ifdef USE_TCXO + /*! + * Radio complete Wake-up Time with TCXO stabilisation time + */ + #define RADIO_TCXO_SETUP_TIME 5 // [ms] +#else + /*! + * Radio complete Wake-up Time with TCXO stabilisation time + */ + #define RADIO_TCXO_SETUP_TIME 0 // No Used +#endif + +/*! + * Radio complete Wake-up Time with margin for temperature compensation + */ +#define RADIO_WAKEUP_TIME 3 // [ms] + +/*! + * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds + */ +#define AUTO_RX_TX_OFFSET 2 + +/*! + * \brief LFSR initial value to compute IBM type CRC + */ +#define CRC_IBM_SEED 0xFFFF + +/*! + * \brief LFSR initial value to compute CCIT type CRC + */ +#define CRC_CCITT_SEED 0x1D0F + +/*! + * \brief Polynomial used to compute IBM CRC + */ +#define CRC_POLYNOMIAL_IBM 0x8005 + +/*! + * \brief Polynomial used to compute CCIT CRC + */ +#define CRC_POLYNOMIAL_CCITT 0x1021 + +/*! + * \brief The address of the register holding the first byte defining the CRC seed + * + */ +#define REG_LR_CRCSEEDBASEADDR 0x06BC + +/*! + * \brief The address of the register holding the first byte defining the CRC polynomial + */ +#define REG_LR_CRCPOLYBASEADDR 0x06BE + +/*! + * \brief The address of the register holding the first byte defining the whitening seed + */ +#define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8 +#define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9 + +/*! + * \brief The address of the register holding the packet configuration + */ +#define REG_LR_PACKETPARAMS 0x0704 + +/*! + * \brief The address of the register holding the payload size + */ +#define REG_LR_PAYLOADLENGTH 0x0702 + +/*! + * \brief The addresses of the registers holding SyncWords values + */ +#define REG_LR_SYNCWORDBASEADDRESS 0x06C0 + +/*! + * \brief The addresses of the register holding LoRa Modem SyncWord value + */ +#define REG_LR_SYNCWORD 0x0740 + +/*! + * Syncword for Private LoRa networks + */ +#define LORA_MAC_PRIVATE_SYNCWORD 0x1424 + +/*! + * Syncword for Public LoRa networks + */ +#define LORA_MAC_PUBLIC_SYNCWORD 0x3444 + +/*! + * The address of the register giving a 4 bytes random number + */ +#define RANDOM_NUMBER_GENERATORBASEADDR 0x0819 + +/*! + * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted) + */ +#define REG_RX_GAIN 0x08AC + +/*! + * Change the value on the device internal trimming capacitor + */ +#define REG_XTA_TRIM 0x0911 + +/*! + * Set the current max value in the over current protection + */ +#define REG_OCP 0x08E7 + +/*! + * \brief Structure describing the radio status + */ +typedef union RadioStatus_u +{ + uint8_t Value; + struct + { //bit order is lsb -> msb + uint8_t Reserved : 1; //!< Reserved + uint8_t CmdStatus : 3; //!< Command status + uint8_t ChipMode : 3; //!< Chip mode + uint8_t CpuBusy : 1; //!< Flag for CPU radio busy + }Fields; +}RadioStatus_t; + +/*! + * \brief Structure describing the error codes for callback functions + */ +typedef enum +{ + IRQ_HEADER_ERROR_CODE = 0x01, + IRQ_SYNCWORD_ERROR_CODE = 0x02, + IRQ_CRC_ERROR_CODE = 0x04, +}IrqErrorCode_t; + +enum IrqPblSyncHeaderCode_t +{ + IRQ_PBL_DETECT_CODE = 0x01, + IRQ_SYNCWORD_VALID_CODE = 0x02, + IRQ_HEADER_VALID_CODE = 0x04, +}; + +/*! + * \brief Represents the operating mode the radio is actually running + */ +typedef enum +{ + MODE_SLEEP = 0x00, //! The radio is in sleep mode + MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator + MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator + MODE_FS, //! The radio is in frequency synthesis mode + MODE_TX, //! The radio is in transmit mode + MODE_RX, //! The radio is in receive mode + MODE_RX_DC, //! The radio is in receive duty cycle mode + MODE_CAD //! The radio is in channel activity detection mode +}RadioOperatingModes_t; + +/*! + * \brief Declares the oscillator in use while in standby mode + * + * Using the STDBY_RC standby mode allow to reduce the energy consumption + * STDBY_XOSC should be used for time critical applications + */ +typedef enum +{ + STDBY_RC = 0x00, + STDBY_XOSC = 0x01, +}RadioStandbyModes_t; + +/*! + * \brief Declares the power regulation used to power the device + * + * This command allows the user to specify if DC-DC or LDO is used for power regulation. + * Using only LDO implies that the Rx or Tx current is doubled + */ +typedef enum +{ + USE_LDO = 0x00, // default + USE_DCDC = 0x01, +}RadioRegulatorMode_t; + +/*! + * \brief Represents the possible packet type (i.e. modem) used + */ +typedef enum +{ + PACKET_TYPE_GFSK = 0x00, + PACKET_TYPE_LORA = 0x01, + PACKET_TYPE_NONE = 0x0F, +}RadioPacketTypes_t; + +/*! + * \brief Represents the ramping time for power amplifier + */ +typedef enum +{ + RADIO_RAMP_10_US = 0x00, + RADIO_RAMP_20_US = 0x01, + RADIO_RAMP_40_US = 0x02, + RADIO_RAMP_80_US = 0x03, + RADIO_RAMP_200_US = 0x04, + RADIO_RAMP_800_US = 0x05, + RADIO_RAMP_1700_US = 0x06, + RADIO_RAMP_3400_US = 0x07, +}RadioRampTimes_t; + +/*! + * \brief Represents the number of symbols to be used for channel activity detection operation + */ +typedef enum +{ + LORA_CAD_01_SYMBOL = 0x00, + LORA_CAD_02_SYMBOL = 0x01, + LORA_CAD_04_SYMBOL = 0x02, + LORA_CAD_08_SYMBOL = 0x03, + LORA_CAD_16_SYMBOL = 0x04, +}RadioLoRaCadSymbols_t; + +/*! + * \brief Represents the Channel Activity Detection actions after the CAD operation is finished + */ +typedef enum +{ + LORA_CAD_ONLY = 0x00, + LORA_CAD_RX = 0x01, + LORA_CAD_LBT = 0x10, +}RadioCadExitModes_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum +{ + MOD_SHAPING_OFF = 0x00, + MOD_SHAPING_G_BT_03 = 0x08, + MOD_SHAPING_G_BT_05 = 0x09, + MOD_SHAPING_G_BT_07 = 0x0A, + MOD_SHAPING_G_BT_1 = 0x0B, +}RadioModShapings_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum +{ + RX_BW_4800 = 0x1F, + RX_BW_5800 = 0x17, + RX_BW_7300 = 0x0F, + RX_BW_9700 = 0x1E, + RX_BW_11700 = 0x16, + RX_BW_14600 = 0x0E, + RX_BW_19500 = 0x1D, + RX_BW_23400 = 0x15, + RX_BW_29300 = 0x0D, + RX_BW_39000 = 0x1C, + RX_BW_46900 = 0x14, + RX_BW_58600 = 0x0C, + RX_BW_78200 = 0x1B, + RX_BW_93800 = 0x13, + RX_BW_117300 = 0x0B, + RX_BW_156200 = 0x1A, + RX_BW_187200 = 0x12, + RX_BW_234300 = 0x0A, + RX_BW_312000 = 0x19, + RX_BW_373600 = 0x11, + RX_BW_467000 = 0x09, +}RadioRxBandwidth_t; + +/*! + * \brief Represents the possible spreading factor values in LoRa packet types + */ +typedef enum +{ + LORA_SF5 = 0x05, + LORA_SF6 = 0x06, + LORA_SF7 = 0x07, + LORA_SF8 = 0x08, + LORA_SF9 = 0x09, + LORA_SF10 = 0x0A, + LORA_SF11 = 0x0B, + LORA_SF12 = 0x0C, +}RadioLoRaSpreadingFactors_t; + +/*! + * \brief Represents the bandwidth values for LoRa packet type + */ +typedef enum +{ + LORA_BW_500 = 6, + LORA_BW_250 = 5, + LORA_BW_125 = 4, + LORA_BW_062 = 3, + LORA_BW_041 = 10, + LORA_BW_031 = 2, + LORA_BW_020 = 9, + LORA_BW_015 = 1, + LORA_BW_010 = 8, + LORA_BW_007 = 0, +}RadioLoRaBandwidths_t; + +/*! + * \brief Represents the coding rate values for LoRa packet type + */ +typedef enum +{ + LORA_CR_4_5 = 0x01, + LORA_CR_4_6 = 0x02, + LORA_CR_4_7 = 0x03, + LORA_CR_4_8 = 0x04, +}RadioLoRaCodingRates_t; + +/*! + * \brief Represents the preamble length used to detect the packet on Rx side + */ +typedef enum +{ + RADIO_PREAMBLE_DETECTOR_OFF = 0x00, //!< Preamble detection length off + RADIO_PREAMBLE_DETECTOR_08_BITS = 0x04, //!< Preamble detection length 8 bits + RADIO_PREAMBLE_DETECTOR_16_BITS = 0x05, //!< Preamble detection length 16 bits + RADIO_PREAMBLE_DETECTOR_24_BITS = 0x06, //!< Preamble detection length 24 bits + RADIO_PREAMBLE_DETECTOR_32_BITS = 0x07, //!< Preamble detection length 32 bit +}RadioPreambleDetection_t; + +/*! + * \brief Represents the possible combinations of SyncWord correlators activated + */ +typedef enum +{ + RADIO_ADDRESSCOMP_FILT_OFF = 0x00, //!< No correlator turned on, i.e. do not search for SyncWord + RADIO_ADDRESSCOMP_FILT_NODE = 0x01, + RADIO_ADDRESSCOMP_FILT_NODE_BROAD = 0x02, +}RadioAddressComp_t; + +/*! + * \brief Radio GFSK packet length mode + */ +typedef enum +{ + RADIO_PACKET_FIXED_LENGTH = 0x00, //!< The packet is known on both sides, no header included in the packet + RADIO_PACKET_VARIABLE_LENGTH = 0x01, //!< The packet is on variable size, header included +}RadioPacketLengthModes_t; + +/*! + * \brief Represents the CRC length + */ +typedef enum +{ + RADIO_CRC_OFF = 0x01, //!< No CRC in use + RADIO_CRC_1_BYTES = 0x00, + RADIO_CRC_2_BYTES = 0x02, + RADIO_CRC_1_BYTES_INV = 0x04, + RADIO_CRC_2_BYTES_INV = 0x06, + RADIO_CRC_2_BYTES_IBM = 0xF1, + RADIO_CRC_2_BYTES_CCIT = 0xF2, +}RadioCrcTypes_t; + +/*! + * \brief Radio whitening mode activated or deactivated + */ +typedef enum +{ + RADIO_DC_FREE_OFF = 0x00, + RADIO_DC_FREEWHITENING = 0x01, +}RadioDcFree_t; + +/*! + * \brief Holds the Radio lengths mode for the LoRa packet type + */ +typedef enum +{ + LORA_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included + LORA_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet + LORA_PACKET_EXPLICIT = LORA_PACKET_VARIABLE_LENGTH, + LORA_PACKET_IMPLICIT = LORA_PACKET_FIXED_LENGTH, +}RadioLoRaPacketLengthsMode_t; + +/*! + * \brief Represents the CRC mode for LoRa packet type + */ +typedef enum +{ + LORA_CRC_ON = 0x01, //!< CRC activated + LORA_CRC_OFF = 0x00, //!< CRC not used +}RadioLoRaCrcModes_t; + +/*! + * \brief Represents the IQ mode for LoRa packet type + */ +typedef enum +{ + LORA_IQ_NORMAL = 0x00, + LORA_IQ_INVERTED = 0x01, +}RadioLoRaIQModes_t; + +/*! + * \brief Represents the voltage used to control the TCXO on/off from DIO3 + */ +typedef enum +{ + TCXO_CTRL_1_6V = 0x00, + TCXO_CTRL_1_7V = 0x01, + TCXO_CTRL_1_8V = 0x02, + TCXO_CTRL_2_2V = 0x03, + TCXO_CTRL_2_4V = 0x04, + TCXO_CTRL_2_7V = 0x05, + TCXO_CTRL_3_0V = 0x06, + TCXO_CTRL_3_3V = 0x07, +}RadioTcxoCtrlVoltage_t; + +/*! + * \brief Represents the interruption masks available for the radio + * + * \remark Note that not all these interruptions are available for all packet types + */ +typedef enum +{ + IRQ_RADIO_NONE = 0x0000, + IRQ_TX_DONE = 0x0001, + IRQ_RX_DONE = 0x0002, + IRQ_PREAMBLE_DETECTED = 0x0004, + IRQ_SYNCWORD_VALID = 0x0008, + IRQ_HEADER_VALID = 0x0010, + IRQ_HEADER_ERROR = 0x0020, + IRQ_CRC_ERROR = 0x0040, + IRQ_CAD_DONE = 0x0080, + IRQ_CAD_ACTIVITY_DETECTED = 0x0100, + IRQ_RX_TX_TIMEOUT = 0x0200, + IRQ_RADIO_ALL = 0xFFFF, +}RadioIrqMasks_t; + +/*! + * \brief Represents all possible opcode understood by the radio + */ +typedef enum RadioCommands_e +{ + RADIO_GET_STATUS = 0xC0, + RADIO_WRITE_REGISTER = 0x0D, + RADIO_READ_REGISTER = 0x1D, + RADIO_WRITE_BUFFER = 0x0E, + RADIO_READ_BUFFER = 0x1E, + RADIO_SET_SLEEP = 0x84, + RADIO_SET_STANDBY = 0x80, + RADIO_SET_FS = 0xC1, + RADIO_SET_TX = 0x83, + RADIO_SET_RX = 0x82, + RADIO_SET_RXDUTYCYCLE = 0x94, + RADIO_SET_CAD = 0xC5, + RADIO_SET_TXCONTINUOUSWAVE = 0xD1, + RADIO_SET_TXCONTINUOUSPREAMBLE = 0xD2, + RADIO_SET_PACKETTYPE = 0x8A, + RADIO_GET_PACKETTYPE = 0x11, + RADIO_SET_RFFREQUENCY = 0x86, + RADIO_SET_TXPARAMS = 0x8E, + RADIO_SET_PACONFIG = 0x95, + RADIO_SET_CADPARAMS = 0x88, + RADIO_SET_BUFFERBASEADDRESS = 0x8F, + RADIO_SET_MODULATIONPARAMS = 0x8B, + RADIO_SET_PACKETPARAMS = 0x8C, + RADIO_GET_RXBUFFERSTATUS = 0x13, + RADIO_GET_PACKETSTATUS = 0x14, + RADIO_GET_RSSIINST = 0x15, + RADIO_GET_STATS = 0x10, + RADIO_RESET_STATS = 0x00, + RADIO_CFG_DIOIRQ = 0x08, + RADIO_GET_IRQSTATUS = 0x12, + RADIO_CLR_IRQSTATUS = 0x02, + RADIO_CALIBRATE = 0x89, + RADIO_CALIBRATEIMAGE = 0x98, + RADIO_SET_REGULATORMODE = 0x96, + RADIO_GET_ERROR = 0x17, + RADIO_CLR_ERROR = 0x07, + RADIO_SET_TCXOMODE = 0x97, + RADIO_SET_TXFALLBACKMODE = 0x93, + RADIO_SET_RFSWITCHMODE = 0x9D, + RADIO_SET_STOPRXTIMERONPREAMBLE = 0x9F, + RADIO_SET_LORASYMBTIMEOUT = 0xA0, +}RadioCommands_t; + +/*! + * \brief The type describing the modulation parameters for every packet types + */ +typedef struct +{ + RadioPacketTypes_t PacketType; //!< Packet to which the modulation parameters are referring to. + struct + { + struct + { + uint32_t BitRate; + uint32_t Fdev; + RadioModShapings_t ModulationShaping; + uint8_t Bandwidth; + }Gfsk; + struct + { + RadioLoRaSpreadingFactors_t SpreadingFactor; //!< Spreading Factor for the LoRa modulation + RadioLoRaBandwidths_t Bandwidth; //!< Bandwidth for the LoRa modulation + RadioLoRaCodingRates_t CodingRate; //!< Coding rate for the LoRa modulation + uint8_t LowDatarateOptimize; //!< Indicates if the modem uses the low datarate optimization + }LoRa; + }Params; //!< Holds the modulation parameters structure +}ModulationParams_t; + +/*! + * \brief The type describing the packet parameters for every packet types + */ +typedef struct +{ + RadioPacketTypes_t PacketType; //!< Packet to which the packet parameters are referring to. + struct + { + /*! + * \brief Holds the GFSK packet parameters + */ + struct + { + uint16_t PreambleLength; //!< The preamble Tx length for GFSK packet type in bit + RadioPreambleDetection_t PreambleMinDetect; //!< The preamble Rx length minimal for GFSK packet type + uint8_t SyncWordLength; //!< The synchronization word length for GFSK packet type + RadioAddressComp_t AddrComp; //!< Activated SyncWord correlators + RadioPacketLengthModes_t HeaderType; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted + uint8_t PayloadLength; //!< Size of the payload in the GFSK packet + RadioCrcTypes_t CrcLength; //!< Size of the CRC block in the GFSK packet + RadioDcFree_t DcFree; + }Gfsk; + /*! + * \brief Holds the LoRa packet parameters + */ + struct + { + uint16_t PreambleLength; //!< The preamble length is the number of LoRa symbols in the preamble + RadioLoRaPacketLengthsMode_t HeaderType; //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted + uint8_t PayloadLength; //!< Size of the payload in the LoRa packet + RadioLoRaCrcModes_t CrcMode; //!< Size of CRC block in LoRa packet + RadioLoRaIQModes_t InvertIQ; //!< Allows to swap IQ for LoRa packet + }LoRa; + }Params; //!< Holds the packet parameters structure +}PacketParams_t; + +/*! + * \brief Represents the packet status for every packet type + */ +typedef struct +{ + RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. + struct + { + struct + { + uint8_t RxStatus; + int8_t RssiAvg; //!< The averaged RSSI + int8_t RssiSync; //!< The RSSI measured on last packet + uint32_t FreqError; + }Gfsk; + struct + { + int8_t RssiPkt; //!< The RSSI of the last packet + int8_t SnrPkt; //!< The SNR of the last packet + int8_t SignalRssiPkt; + uint32_t FreqError; + }LoRa; + }Params; +}PacketStatus_t; + +/*! + * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used + */ +typedef struct +{ + RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. + uint16_t PacketReceived; + uint16_t CrcOk; + uint16_t LengthError; +}RxCounter_t; + +/*! + * \brief Represents a calibration configuration + */ +typedef union +{ + struct + { + uint8_t RC64KEnable : 1; //!< Calibrate RC64K clock + uint8_t RC13MEnable : 1; //!< Calibrate RC13M clock + uint8_t PLLEnable : 1; //!< Calibrate PLL + uint8_t ADCPulseEnable : 1; //!< Calibrate ADC Pulse + uint8_t ADCBulkNEnable : 1; //!< Calibrate ADC bulkN + uint8_t ADCBulkPEnable : 1; //!< Calibrate ADC bulkP + uint8_t ImgEnable : 1; + uint8_t : 1; + }Fields; + uint8_t Value; +}CalibrationParams_t; + +/*! + * \brief Represents a sleep mode configuration + */ +typedef union +{ + struct + { + uint8_t WakeUpRTC : 1; //!< Get out of sleep mode if wakeup signal received from RTC + uint8_t Reset : 1; + uint8_t WarmStart : 1; + uint8_t Reserved : 5; + }Fields; + uint8_t Value; +}SleepParams_t; + +/*! + * \brief Represents the possible radio system error states + */ +typedef union +{ + struct + { + uint8_t Rc64kCalib : 1; //!< RC 64kHz oscillator calibration failed + uint8_t Rc13mCalib : 1; //!< RC 13MHz oscillator calibration failed + uint8_t PllCalib : 1; //!< PLL calibration failed + uint8_t AdcCalib : 1; //!< ADC calibration failed + uint8_t ImgCalib : 1; //!< Image calibration failed + uint8_t XoscStart : 1; //!< XOSC oscillator failed to start + uint8_t PllLock : 1; //!< PLL lock failed + uint8_t BuckStart : 1; //!< Buck converter failed to start + uint8_t PaRamp : 1; //!< PA ramp failed + uint8_t : 7; //!< Reserved + }Fields; + uint16_t Value; +}RadioError_t; + +/*! + * Radio hardware and global parameters + */ +typedef struct SX126x_s +{ +// Gpio_t Reset; +// Gpio_t BUSY; +// Gpio_t DIO1; +// Gpio_t DIO2; +// Gpio_t DIO3; +// Spi_t Spi; + PacketParams_t PacketParams; + PacketStatus_t PacketStatus; + ModulationParams_t ModulationParams; +}SX126x_t; + +/*! + * Hardware IO IRQ callback function definition + */ +typedef void ( DioIrqHandler )( void ); + +/*! + * SX126x definitions + */ + +/*! + * \brief Provides the frequency of the chip running on the radio and the frequency step + * + * \remark These defines are used for computing the frequency divider to set the RF frequency + */ +#define XTAL_FREQ 32000000 +#define FREQ_DIV 33554432 //( double )pow( 2.0, 25.0 ) +//#define FREQ_STEP ( double )( XTAL_FREQ / FREQ_DIV ) + +#define RX_BUFFER_SIZE 256 + +/*! + * \brief The radio callbacks structure + * Holds function pointers to be called on radio interrupts + */ +typedef struct +{ + void ( *txDone )( void ); //!< Pointer to a function run on successful transmission + void ( *rxDone )( void ); //!< Pointer to a function run on successful reception + void ( *rxPreambleDetect )( void ); //!< Pointer to a function run on successful Preamble detection + void ( *rxSyncWordDone )( void ); //!< Pointer to a function run on successful SyncWord reception + void ( *rxHeaderDone )( bool isOk ); //!< Pointer to a function run on successful Header reception + void ( *txTimeout )( void ); //!< Pointer to a function run on transmission timeout + void ( *rxTimeout )( void ); //!< Pointer to a function run on reception timeout + void ( *rxError )( IrqErrorCode_t errCode ); //!< Pointer to a function run on reception error + void ( *cadDone )( bool cadFlag ); //!< Pointer to a function run on channel activity detected +}SX126xCallbacks_t; + +/*! + * ============================================================================ + * Public functions prototypes + * ============================================================================ + */ + +/*! + * \brief Initializes the radio driver + */ +void SX126xInit( DioIrqHandler dioIrq ); + +/*! + * \brief Gets the current Operation Mode of the Radio + * + * \retval RadioOperatingModes_t last operating mode + */ +RadioOperatingModes_t SX126xGetOperatingMode( void ); + +/*! + * \brief Wakeup the radio if it is in Sleep mode and check that Busy is low + */ +void SX126xCheckDeviceReady( void ); + +/*! + * \brief Saves the payload to be send in the radio buffer + * + * \param [in] payload A pointer to the payload + * \param [in] size The size of the payload + */ +void SX126xSetPayload( uint8_t *payload, uint8_t size ); + +/*! + * \brief Reads the payload received. If the received payload is longer + * than maxSize, then the method returns 1 and do not set size and payload. + * + * \param [out] payload A pointer to a buffer into which the payload will be copied + * \param [out] size A pointer to the size of the payload received + * \param [in] maxSize The maximal size allowed to copy into the buffer + */ +uint8_t SX126xGetPayload( uint8_t *payload, uint8_t *size, uint8_t maxSize ); + +/*! + * \brief Sends a payload + * + * \param [in] payload A pointer to the payload to send + * \param [in] size The size of the payload to send + * \param [in] timeout The timeout for Tx operation + */ +void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ); + +/*! + * \brief Sets the Sync Word given by index used in GFSK + * + * \param [in] syncWord SyncWord bytes ( 8 bytes ) + * + * \retval status [0: OK, 1: NOK] + */ +uint8_t SX126xSetSyncWord( uint8_t *syncWord ); + +/*! + * \brief Sets the Initial value for the LFSR used for the CRC calculation + * + * \param [in] seed Initial LFSR value ( 2 bytes ) + * + */ +void SX126xSetCrcSeed( uint16_t seed ); + +/*! + * \brief Sets the seed used for the CRC calculation + * + * \param [in] seed The seed value + * + */ +void SX126xSetCrcPolynomial( uint16_t polynomial ); + +/*! + * \brief Sets the Initial value of the LFSR used for the whitening in GFSK protocols + * + * \param [in] seed Initial LFSR value + */ +void SX126xSetWhiteningSeed( uint16_t seed ); + +/*! + * \brief Gets a 32 bits random value generated by the radio + * + * \remark The radio must be in reception mode before executing this function + * + * \retval randomValue 32 bits random value + */ +uint32_t SX126xGetRandom( void ); + +/*! + * \brief Sets the radio in sleep mode + * + * \param [in] sleepConfig The sleep configuration describing data + * retention and RTC wake-up + */ +void SX126xSetSleep( SleepParams_t sleepConfig ); + +/*! + * \brief Sets the radio in configuration mode + * + * \param [in] mode The standby mode to put the radio into + */ +void SX126xSetStandby( RadioStandbyModes_t mode ); + +/*! + * \brief Sets the radio in FS mode + */ +void SX126xSetFs( void ); + +/*! + * \brief Sets the radio in transmission mode + * + * \param [in] timeout Structure describing the transmission timeout value + */ +void SX126xSetTx( uint32_t timeout ); + +/*! + * \brief Sets the radio in reception mode + * + * \param [in] timeout Structure describing the reception timeout value + */ +void SX126xSetRx( uint32_t timeout ); + +/*! + * \brief Sets the radio in reception mode with Boosted LNA gain + * + * \param [in] timeout Structure describing the reception timeout value + */ +void SX126xSetRxBoosted( uint32_t timeout ); + +/*! + * \brief Sets the Rx duty cycle management parameters + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ +void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); + +/*! + * \brief Sets the radio in CAD mode + */ +void SX126xSetCad( void ); + +/*! + * \brief Sets the radio in continuous wave transmission mode + */ +void SX126xSetTxContinuousWave( void ); + +/*! + * \brief Sets the radio in continuous preamble transmission mode + */ +void SX126xSetTxInfinitePreamble( void ); + +/*! + * \brief Decide which interrupt will stop the internal radio rx timer. + * + * \param [in] enable [0: Timer stop after header/syncword detection + * 1: Timer stop after preamble detection] + */ +void SX126xSetStopRxTimerOnPreambleDetect( bool enable ); + +/*! + * \brief Set the number of symbol the radio will wait to validate a reception + * + * \param [in] SymbNum number of LoRa symbols + */ +void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ); + +/*! + * \brief Sets the power regulators operating mode + * + * \param [in] mode [0: LDO, 1:DC_DC] + */ +void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ); + +/*! + * \brief Calibrates the given radio block + * + * \param [in] calibParam The description of blocks to be calibrated + */ +void SX126xCalibrate( CalibrationParams_t calibParam ); + +/*! + * \brief Calibrates the Image rejection depending of the frequency + * + * \param [in] freq The operating frequency + */ +void SX126xCalibrateImage( uint32_t freq ); + +/*! + * \brief Activate the extention of the timeout when long preamble is used + * + * \param [in] enable The radio will extend the timeout to cope with long preamble + */ +void SX126xSetLongPreamble( uint8_t enable ); + +/*! + * \brief Sets the transmission parameters + * + * \param [in] paDutyCycle Duty Cycle for the PA + * \param [in] hpMax 0 for sx1261, 7 for sx1262 + * \param [in] deviceSel 1 for sx1261, 0 for sx1262 + * \param [in] paLut 0 for 14dBm LUT, 1 for 22dBm LUT + */ +void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ); + +/*! + * \brief Defines into which mode the chip goes after a TX / RX done + * + * \param [in] fallbackMode The mode in which the radio goes + */ +void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ); + +/*! + * \brief Write data to the radio memory + * + * \param [in] address The address of the first byte to write in the radio + * \param [in] buffer The data to be written in radio's memory + * \param [in] size The number of bytes to write in radio's memory + */ +void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Read data from the radio memory + * + * \param [in] address The address of the first byte to read from the radio + * \param [out] buffer The buffer that holds data read from radio + * \param [in] size The number of bytes to read from radio's memory + */ +void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); + +/*! + * \brief Write data to the buffer holding the payload in the radio + * + * \param [in] offset The offset to start writing the payload + * \param [in] buffer The data to be written (the payload) + * \param [in] size The number of byte to be written + */ +void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Read data from the buffer holding the payload in the radio + * + * \param [in] offset The offset to start reading the payload + * \param [out] buffer A pointer to a buffer holding the data from the radio + * \param [in] size The number of byte to be read + */ +void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the IRQ mask and DIO masks + * + * \param [in] irqMask General IRQ mask + * \param [in] dio1Mask DIO1 mask + * \param [in] dio2Mask DIO2 mask + * \param [in] dio3Mask DIO3 mask + */ +void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ); + +/*! + * \brief Returns the current IRQ status + * + * \retval irqStatus IRQ status + */ +uint16_t SX126xGetIrqStatus( void ); + +/*! + * \brief Indicates if DIO2 is used to control an RF Switch + * + * \param [in] enable true of false + */ +void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ); + +/*! + * \brief Indicates if the Radio main clock is supplied from a tcxo + * + * \param [in] tcxoVoltage voltage used to control the TCXO + * \param [in] timeout time given to the TCXO to go to 32MHz + */ +void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ); + +/*! + * \brief Sets the RF frequency + * + * \param [in] frequency RF frequency [Hz] + */ +void SX126xSetRfFrequency( uint32_t frequency ); + +/*! + * \brief Sets the radio for the given protocol + * + * \param [in] packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] + * + * \remark This method has to be called before SetRfFrequency, + * SetModulationParams and SetPacketParams + */ +void SX126xSetPacketType( RadioPacketTypes_t packetType ); + +/*! + * \brief Gets the current radio protocol + * + * \retval packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] + */ +RadioPacketTypes_t SX126xGetPacketType( void ); + +/*! + * \brief Sets the transmission parameters + * + * \param [in] power RF output power [-18..13] dBm + * \param [in] rampTime Transmission ramp up time + */ +void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ); + +/*! + * \brief Set the modulation parameters + * + * \param [in] modParams A structure describing the modulation parameters + */ +void SX126xSetModulationParams( ModulationParams_t *modParams ); + +/*! + * \brief Sets the packet parameters + * + * \param [in] packetParams A structure describing the packet parameters + */ +void SX126xSetPacketParams( PacketParams_t *packetParams ); + +/*! + * \brief Sets the Channel Activity Detection (CAD) parameters + * + * \param [in] cadSymbolNum The number of symbol to use for CAD operations + * [LORA_CAD_01_SYMBOL, LORA_CAD_02_SYMBOL, + * LORA_CAD_04_SYMBOL, LORA_CAD_08_SYMBOL, + * LORA_CAD_16_SYMBOL] + * \param [in] cadDetPeak Limit for detection of SNR peak used in the CAD + * \param [in] cadDetMin Set the minimum symbol recognition for CAD + * \param [in] cadExitMode Operation to be done at the end of CAD action + * [LORA_CAD_ONLY, LORA_CAD_RX, LORA_CAD_LBT] + * \param [in] cadTimeout Defines the timeout value to abort the CAD activity + */ +void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ); + +/*! + * \brief Sets the data buffer base address for transmission and reception + * + * \param [in] txBaseAddress Transmission base address + * \param [in] rxBaseAddress Reception base address + */ +void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ); + +/*! + * \brief Gets the current radio status + * + * \retval status Radio status + */ +RadioStatus_t SX126xGetStatus( void ); + +/*! + * \brief Returns the instantaneous RSSI value for the last packet received + * + * \retval rssiInst Instantaneous RSSI + */ +int8_t SX126xGetRssiInst( void ); + +/*! + * \brief Gets the last received packet buffer status + * + * \param [out] payloadLength Last received packet payload length + * \param [out] rxStartBuffer Last received packet buffer address pointer + */ +void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBuffer ); + +/*! + * \brief Gets the last received packet payload length + * + * \param [out] pktStatus A structure of packet status + */ +void SX126xGetPacketStatus( PacketStatus_t *pktStatus ); + +/*! + * \brief Returns the possible system errors + * + * \retval sysErrors Value representing the possible sys failures + */ +RadioError_t SX126xGetDeviceErrors( void ); + +/*! + * \brief Clear all the errors in the device + */ +void SX126xClearDeviceErrors( void ); + +/*! + * \brief Clears the IRQs + * + * \param [in] irq IRQ(s) to be cleared + */ +void SX126xClearIrqStatus( uint16_t irq ); + +#endif // __SX126x_H__ diff --git a/Radio_LLCC68_Multi/Radio/spi.c b/Radio_LLCC68_Multi/Radio/spi.c new file mode 100644 index 0000000..ca9ac90 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/spi.c @@ -0,0 +1,69 @@ +#include "stm32f0xx.h" + +void SPI2_Int() +{ +/* + SPI_InitTypeDef SPI_InitStruct; + + SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//鍏ㄥ弻宸ユā寮� + SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;//绗竴涓竟娌� + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;//涓婂崌娌挎崟鑾� + SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 6MHz + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStruct.SPI_CRCPolynomial = 7; + SPI_Init(SPI2,&SPI_InitStruct); + + SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF); + SPI_Cmd(SPI2, ENABLE ); +*/ +} + +/*! + * @brief Sends txBuffer and receives rxBuffer + * + * @param [IN] txBuffer Byte to be sent + * @param [OUT] rxBuffer Byte to be sent + * @param [IN] size Byte to be sent + */ +#define TIMEOUT 50 +uint8_t SpiInOut( uint8_t txBuffer) +{ + /* + while( SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);//褰撳彂閫乥uffer涓虹┖鏃�(璇存槑涓婁竴娆℃暟鎹凡澶嶅埗鍒扮Щ浣嶅瘎瀛樺櫒涓�)閫�鍑�,杩欐椂鍙互寰�buffer閲岄潰鍐欐暟鎹� + SPI_SendData8(SPI2, txBuffer); + + while( SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);//褰撴帴鏀禸uffer涓洪潪绌烘椂閫�鍑� + return SPI_ReceiveData8(SPI2); + + */ + + int timeout_cnt= 0; + uint8_t value; + while (LL_SPI_IsActiveFlag_TXE(SPI1) == RESET) {timeout_cnt++; if (timeout_cnt>TIMEOUT) break; } + LL_SPI_TransmitData8(SPI1,txBuffer); + timeout_cnt= 0; while (LL_SPI_IsActiveFlag_BSY(SPI1) == SET) {timeout_cnt++; if (timeout_cnt>TIMEOUT) break; } + timeout_cnt= 0; while (LL_SPI_IsActiveFlag_RXNE(SPI1) == RESET) { timeout_cnt++; if (timeout_cnt>TIMEOUT) break;} + value = LL_SPI_ReceiveData8( SPI1); + + return value; +} + +void SpiIn( uint8_t *txBuffer, uint16_t size ) +{ + + uint16_t i; + + for(i=0;i<size;i++) + { + while( LL_SPI_IsActiveFlag_TXE(SPI1) == RESET);//褰撳彂閫乥uffer涓虹┖鏃�(璇存槑涓婁竴娆℃暟鎹凡澶嶅埗鍒扮Щ浣嶅瘎瀛樺櫒涓�)閫�鍑�,杩欐椂鍙互寰�buffer閲岄潰鍐欐暟鎹� + LL_SPI_TransmitData8(SPI1,txBuffer[i]); + while( LL_SPI_IsActiveFlag_RXNE(SPI1) == RESET);//褰撴帴鏀禸uffer涓洪潪绌烘椂閫�鍑� + LL_SPI_ReceiveData8( SPI1); + } + +} + + diff --git a/Radio_LLCC68_Multi/Radio/spi.h b/Radio_LLCC68_Multi/Radio/spi.h new file mode 100644 index 0000000..e400bc9 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/spi.h @@ -0,0 +1,8 @@ +#ifndef _SPI_H_ +#define _SPI_H_ + +void SPI2_Int(void); +uint8_t SpiInOut( uint8_t txBuffer); +void SpiIn( uint8_t *txBuffer, uint16_t size ); + +#endif diff --git a/Radio_LLCC68_Multi/Radio/src/crc.c b/Radio_LLCC68_Multi/Radio/src/crc.c new file mode 100644 index 0000000..68ed1c9 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/src/crc.c @@ -0,0 +1,47 @@ +#include "crc.h" + + +uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ) +{ + uint8_t i; + + for( i = 0; i < 8; i++ ) + { + if( ( ( ( crc & 0x8000 ) >> 8 ) ^ ( dataByte & 0x80 ) ) != 0 ) + { + crc <<= 1; // shift left once + crc ^= polynomial; // XOR with polynomial + } + else + { + crc <<= 1; // shift left once + } + dataByte <<= 1; // Next data bit + } + return crc; +} + + +uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ) +{ + uint8_t i = 0; + uint16_t crc = 0; + uint16_t polynomial = 0; + + polynomial = ( crcType == CRC_TYPE_IBM ) ? POLYNOMIAL_IBM : POLYNOMIAL_CCITT; + crc = ( crcType == CRC_TYPE_IBM ) ? CRC_IBM_SEED : CRC_CCITT_SEED; + for( i = 0; i < length; i++ ) + { + crc = ComputeCrc( crc, buffer[i], polynomial ); + } + if( crcType == CRC_TYPE_IBM ) + { + return crc; + } + else + { + return( ( uint16_t ) ( ~crc )); + } +} + + diff --git a/Radio_LLCC68_Multi/Radio/src/radio.c b/Radio_LLCC68_Multi/Radio/src/radio.c new file mode 100644 index 0000000..76a1f2c --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/src/radio.c @@ -0,0 +1,1236 @@ +/*! + * \file radio.c + * + * \brief Radio driver API definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#include <math.h> +#include <string.h> +#include <stdbool.h> +#include "stm32f0xx.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" + +/*! + * \brief Initializes the radio + * + * \param [IN] events Structure containing the driver callback functions + */ +void RadioInit( RadioEvents_t *events ); + +/*! + * Return current radio status + * + * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + */ +RadioState_t RadioGetStatus( void ); + +/*! + * \brief Configures the radio with the given modem + * + * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] + */ +void RadioSetModem( RadioModems_t modem ); + +/*! + * \brief Sets the channel frequency + * + * \param [IN] freq Channel RF frequency + */ +void RadioSetChannel( uint32_t freq ); + +/*! + * \brief Checks if the channel is free for the given time + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] freq Channel RF frequency + * \param [IN] rssiThresh RSSI threshold + * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured + * + * \retval isFree [true: Channel is free, false: Channel is not free] + */ +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); + +/*! + * \brief Generates a 32 bits random value based on the RSSI readings + * + * \remark This function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * \retval randomValue 32 bits random value + */ +uint32_t RadioRandom( void ); + +/*! + * \brief Sets the reception parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] symbTimeout Sets the RxSingle timeout value + * FSK : timeout in number of bytes + * LoRa: timeout in symbols + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] rxContinuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool FreqHopOn, uint8_t HopPeriod, + bool iqInverted, bool rxContinuous ); + +/*! + * \brief Sets the transmission parameters + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] power Sets the output power [dBm] + * \param [IN] fdev Sets the frequency deviation (FSK only) + * FSK : [Hz] + * LoRa: 0 + * \param [IN] bandwidth Sets the bandwidth (LoRa only) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] + * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping + * FSK : N/A ( set to 0 ) + * LoRa: [0: OFF, 1: ON] + * \param [IN] HopPeriod Number of symbols between each hop + * FSK : N/A ( set to 0 ) + * LoRa: Number of symbols + * \param [IN] iqInverted Inverts IQ signals (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * \param [IN] timeout Transmission timeout [ms] + */ +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool FreqHopOn, + uint8_t HopPeriod, bool iqInverted, uint32_t timeout ); + +/*! + * \brief Checks if the given RF frequency is supported by the hardware + * + * \param [IN] frequency RF frequency to be checked + * \retval isSupported [true: supported, false: unsupported] + */ +bool RadioCheckRfFrequency( uint32_t frequency ); + +/*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (ms) for the given packet payload length + */ +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ); + +/*! + * \brief Computes the packet time on air in ms for the given payload + * + * \Remark Can only be called once SetRxConfig or SetTxConfig have been called + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] pktLen Packet payload length + * + * \retval airTime Computed airTime (us) for the given packet payload length + */ +uint32_t RadioTimeOnAiruS( RadioModems_t modem, uint8_t pktLen ); + +/*! + * \brief Sends the buffer of size. Prepares the packet to be sent and sets + * the radio in transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void RadioSend( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the radio in sleep mode + */ +void RadioSleep( void ); + +/*! + * \brief Sets the radio in standby mode + */ +void RadioStandby( void ); + +/*! + * \brief Sets the radio in reception mode for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRx( uint32_t timeout ); + +/*! + * \brief Start a Channel Activity Detection + */ +void RadioStartCad( void ); + +/*! + * \brief Sets the radio in continuous wave transmission mode + * + * \param [IN]: freq Channel RF frequency + * \param [IN]: power Sets the output power [dBm] + * \param [IN]: time Transmission mode timeout [s] + */ +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ); + +/*! + * \brief Reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ +int16_t RadioRssi( RadioModems_t modem ); + +/*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ +void RadioWrite( uint16_t addr, uint8_t data ); + +/*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \retval data Register value + */ +uint8_t RadioRead( uint16_t addr ); + +/*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Sets the maximum payload length. + * + * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] + * \param [IN] max Maximum payload length in bytes + */ +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ); + +/*! + * \brief Sets the network to public or private. Updates the sync byte. + * + * \remark Applies to LoRa modem only + * + * \param [IN] enable if true, it enables a public network + */ +void RadioSetPublicNetwork( bool enable ); + +/*! + * \brief Gets the time required for the board plus radio to get out of sleep.[ms] + * + * \retval time Radio plus board wakeup time in ms. + */ +uint32_t RadioGetWakeupTime( void ); + +/*! + * \brief Process radio irq + */ +void RadioIrqProcess( void ); + +/*! + * \brief Sets the radio in reception mode with Max LNA gain for the given time + * \param [IN] timeout Reception timeout [ms] + * [0: continuous, others timeout] + */ +void RadioRxBoosted( uint32_t timeout ); + +/*! + * \brief Sets the Rx duty cycle management parameters + * + * \param [in] rxTime Structure describing reception timeout value + * \param [in] sleepTime Structure describing sleep timeout value + */ +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); + +/*! + * Radio driver structure initialization + */ +const struct Radio_s Radio = +{ + RadioInit, + RadioGetStatus, + RadioSetModem, + RadioSetChannel, + RadioIsChannelFree, + RadioRandom, + RadioSetRxConfig, + RadioSetTxConfig, + RadioCheckRfFrequency, + RadioTimeOnAiruS, + RadioSend, + RadioSleep, + RadioStandby, + RadioRx, + RadioStartCad, + RadioSetTxContinuousWave, + RadioRssi, + RadioWrite, + RadioRead, + RadioWriteBuffer, + RadioReadBuffer, + RadioSetMaxPayloadLength, + RadioSetPublicNetwork, + RadioGetWakeupTime, + RadioIrqProcess, + // Available on SX126x only + RadioRxBoosted, + RadioSetRxDutyCycle +}; + +/* + * Local types definition + */ + + + /*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t RegValue; +}FskBandwidth_t; + +/*! + * Precomputed FSK bandwidth registers values + */ +const FskBandwidth_t FskBandwidths[] = +{ + { 4800 , 0x1F }, + { 5800 , 0x17 }, + { 7300 , 0x0F }, + { 9700 , 0x1E }, + { 11700 , 0x16 }, + { 14600 , 0x0E }, + { 19500 , 0x1D }, + { 23400 , 0x15 }, + { 29300 , 0x0D }, + { 39000 , 0x1C }, + { 46900 , 0x14 }, + { 58600 , 0x0C }, + { 78200 , 0x1B }, + { 93800 , 0x13 }, + { 117300, 0x0B }, + { 156200, 0x1A }, + { 187200, 0x12 }, + { 234300, 0x0A }, + { 312000, 0x19 }, + { 373600, 0x11 }, + { 467000, 0x09 }, + { 500000, 0x00 }, // Invalid Bandwidth +}; + +const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 }; +/* +// SF12 SF11 SF10 SF9 SF8 SF7 SF6 SF5 +const double RadioLoRaSymbTime[3][8] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024, 0.512, 0.256}, // 125 KHz + { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512, 0.256, 0.128}, // 250 KHz + { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256, 0.128, 0.064}}; // 500 KHz + +// */ +/* +static uint16_t RadioLoRaSymbTimeUs[3][8] = {{ 32768, 16384, 8192, 4096, 2048, 1024, 512, 256}, // 125 KHz + { 16384, 8192, 4096, 2048, 1024, 512, 256, 128}, // 250 KHz + { 8192, 4096, 2048, 1024, 512, 256, 128, 64}}; // 500 KHz + +*/ +uint8_t MaxPayloadLength = 0xFF; + +uint32_t TxTimeout = 0; +uint32_t RxTimeout = 0; + +bool RxContinuous = false; + + +PacketStatus_t RadioPktStatus; +uint8_t RadioRxPayload[256]; + +bool IrqFired = false; + +/* + * SX126x DIO IRQ callback functions prototype + */ + +/*! + * \brief DIO 0 IRQ callback + */ +void RadioOnDioIrq( void ); + +/*! + * \brief Tx timeout timer callback + */ +void RadioOnTxTimeoutIrq( void ); + +/*! + * \brief Rx timeout timer callback + */ +void RadioOnRxTimeoutIrq( void ); + +/* + * Private global variables + */ + + +/*! + * Holds the current network type for the radio + */ +typedef struct +{ + bool Previous; + bool Current; +}RadioPublicNetwork_t; + +static RadioPublicNetwork_t RadioPublicNetwork = { false }; + +/*! + * Radio callbacks variable + */ +static RadioEvents_t* RadioEvents; + +/* + * Public global variables + */ + +/*! + * Radio hardware and global parameters + */ +SX126x_t SX126x; + +/*! + * Tx and Rx timers + */ +//TimerEvent_t TxTimeoutTimer; +//TimerEvent_t RxTimeoutTimer; + +/*! + * Returns the known FSK bandwidth registers value + * + * \param [IN] bandwidth Bandwidth value in Hz + * \retval regValue Bandwidth register value. + */ +static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ) +{ + uint8_t i; + + if( bandwidth == 0 ) + { + return( 0x1F ); + } + + for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ ) + { + if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) ) + { + return FskBandwidths[i+1].RegValue; + } + } + // ERROR: Value not found + while( 1 ); +} + +void RadioInit( RadioEvents_t *events ) +{ + RadioEvents = events; + + SX126xInit( RadioOnDioIrq ); + SX126xSetStandby( STDBY_XOSC ); //STDBY_RC + SX126xSetRegulatorMode( USE_DCDC ); + + SX126xSetBufferBaseAddress( 0x00, 0x00 ); + SX126xSetTxParams( 0, RADIO_RAMP_200_US ); + SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + + //Initialize driver timeout timers + //TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); + //TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); + + IrqFired = false; +} + +RadioState_t RadioGetStatus( void ) +{ + switch( SX126xGetOperatingMode( ) ) + { + case MODE_TX: + return RF_TX_RUNNING; + case MODE_RX: + return RF_RX_RUNNING; + case MODE_CAD: + return RF_CAD; + default: + return RF_IDLE; + } +} + +void RadioSetModem( RadioModems_t modem ) +{ + switch( modem ) + { + default: + case MODEM_FSK: + SX126xSetPacketType( PACKET_TYPE_GFSK ); + // When switching to GFSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + RadioPublicNetwork.Current = false; + break; + case MODEM_LORA: + SX126xSetPacketType( PACKET_TYPE_LORA ); + // Public/Private network register is reset when switching modems + if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous ) + { + RadioPublicNetwork.Current = RadioPublicNetwork.Previous; + RadioSetPublicNetwork( RadioPublicNetwork.Current ); + } + break; + } +} + +void RadioSetChannel( uint32_t freq ) +{ + SX126xSetRfFrequency( freq ); +} + +bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) +{ + bool status = true; + int16_t rssi = 0; + uint32_t carrierSenseTime = 0; + + RadioSetModem( modem ); + + RadioSetChannel( freq ); + + RadioRx( 0 ); + + HAL_Delay_nMS( 1 ); + + //carrierSenseTime = TimerGetCurrentTime( ); + + + //Perform carrier sense for maxCarrierSenseTime +// while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ) +// { + rssi = RadioRssi( modem ); +// + if( rssi > rssiThresh ) + { + status = false; +// break; + } +// } +// RadioSleep( ); + return status; +} + +uint32_t RadioRandom( void ) +{ + uint8_t i; + uint32_t rnd = 0; + + /* + * Radio setup for random number generation + */ + // Set LoRa modem ON + RadioSetModem( MODEM_LORA ); + + // Set radio in continuous reception + SX126xSetRx( 0 ); + + for( i = 0; i < 32; i++ ) + { + HAL_Delay_nMS( 1 ); + // Unfiltered RSSI value reading. Only takes the LSB value + rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i; + } + + RadioSleep( ); + + return rnd; +} + +void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidthAfc, uint16_t preambleLen, + uint16_t symbTimeout, bool fixLen, + uint8_t payloadLen, + bool crcOn, bool freqHopOn, uint8_t hopPeriod, + bool iqInverted, bool rxContinuous ) +{ + + RxContinuous = rxContinuous; + + if( fixLen == true ) + { + MaxPayloadLength = payloadLen; + } + else + { + MaxPayloadLength = 0xFF; + } + + switch( modem ) + { + case MODEM_FSK: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength; + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREE_OFF; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + + RxTimeout = ( uint32_t )( symbTimeout * 1000 * 8 / datarate ); //( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 ); + break; + + case MODEM_LORA: + SX126xSetStopRxTimerOnPreambleDetect( false ); + SX126xSetLoRaSymbNumTimeout( symbTimeout ); + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 8 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 8; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + + // Timeout Max, Timeout handled directly in SetRx function + RxTimeout = 0xFFFF; + + break; + } +} + +void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preambleLen, + bool fixLen, bool crcOn, bool freqHopOn, + uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) +{ + + switch( modem ) + { + case MODEM_FSK: + SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; + SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; + + SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; + SX126x.ModulationParams.Params.Gfsk.Bandwidth = ( bandwidth ); + SX126x.ModulationParams.Params.Gfsk.Fdev = fdev; + + SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; + SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit + SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; + SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit + SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; + SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; + + if( crcOn == true ) + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; + } + else + { + SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; + } + SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); + SX126xSetWhiteningSeed( 0x01FF ); + break; + + case MODEM_LORA: + SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; + SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate; + SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; + SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate; + + if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || + ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; + } + else + { + SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; + } + + SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; + + if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || + ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) + { + if( preambleLen < 12 ) + { + SX126x.PacketParams.Params.LoRa.PreambleLength = 12; + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + } + else + { + SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; + } + + SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; + SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; + + RadioStandby( ); + RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); + SX126xSetModulationParams( &SX126x.ModulationParams ); + SX126xSetPacketParams( &SX126x.PacketParams ); + break; + } + SX126xSetRfTxPower( power ); + TxTimeout = timeout; +} + +bool RadioCheckRfFrequency( uint32_t frequency ) +{ + return true; +} + +/* + +uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ) +{ + uint32_t airTime = 0; + + switch( modem ) + { + case MODEM_FSK: + { + airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength + + ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) + + ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) + + pktLen + + ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) / + SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 ); + } + break; + case MODEM_LORA: + { + double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor]; + + // time of preamble + double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts; + + // Symbol length of payload and time + + double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor + + 28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode - + ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) / + ( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor - + ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) * + ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ); + + + double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 ); + double tPayload = nPayload * ts; + + // Time on air + double tOnAir = tPreamble + tPayload; + // return milli seconds + airTime = floor( tOnAir + 0.999 ); + } + break; + } + return airTime; +} +// */ + +uint32_t RadioTimeOnAiruS( RadioModems_t modem, uint8_t pktLen ) +{ + uint32_t airTime = 0; + + switch( modem ) + { + case MODEM_FSK: + { + airTime = (1000 * 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength + + ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) + + ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0 : 1 ) + + pktLen + + ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2 : 0 ) ) / + SX126x.ModulationParams.Params.Gfsk.BitRate ) ; + } + break; + case MODEM_LORA: + { + uint32_t ts = (1 << (7 + SX126x.ModulationParams.Params.LoRa.SpreadingFactor - SX126x.ModulationParams.Params.LoRa.Bandwidth));///1000.0; + + // time of preamble + uint32_t tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4 ) * ts + (ts>>2); + if (SX126x.ModulationParams.Params.LoRa.SpreadingFactor == 5 || SX126x.ModulationParams.Params.LoRa.SpreadingFactor == 6) + { + tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 6 ) * ts + (ts>>2); + } + // Symbol length of payload and time + uint32_t tmp32 = ( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor + + 28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode - + ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) / + ( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor - + ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) +1 ) * + + ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ); + + uint32_t nPayload = 8 + ( ( tmp32 > 0 ) ? tmp32 : 0 ); + uint32_t tPayload = nPayload * ts; + // Time on air + uint32_t tOnAir = tPreamble + tPayload; + // return micro seconds + airTime = tOnAir; //tPreamble;// tOnAir; + } + break; + } + return airTime; +} + +void RadioSend( uint8_t *buffer, uint8_t size ) +{ + SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + if( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = size; + } + else + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = size; + } + SX126xSetPacketParams( &SX126x.PacketParams ); + + SX126xSendPayload( buffer, size, 0 ); +// TimerSetValue( &TxTimeoutTimer, TxTimeout ); +// TimerStart( &TxTimeoutTimer ); +} + +void RadioSleep( void ) +{ + SleepParams_t params = { 0 }; + + params.Fields.WarmStart = 1; + SX126xSetSleep( params ); + + HAL_Delay_nMS( 2 ); +} + +void RadioStandby( void ) +{ + // SX126xSetStandby( STDBY_XOSC ); //STDBY_RC + SX126xSetFs(); +} + +void RadioRx( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRx( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRx( timeout << 6 ); + } +} + +void RadioRxBoosted( uint32_t timeout ) +{ + SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + + if( RxContinuous == true ) + { + SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous + } + else + { + SX126xSetRxBoosted( timeout << 6 ); + } +} + +void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) +{ + SX126xSetRxDutyCycle( rxTime, sleepTime ); +} + +void RadioStartCad( void ) +{ + SX126xSetCad( ); +} + +void RadioTx( uint32_t timeout ) +{ + SX126xSetTx( timeout << 6 ); +} + +void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) +{ + SX126xSetRfFrequency( freq ); + SX126xSetRfTxPower( power ); + SX126xSetTxContinuousWave( ); + +// TimerSetValue( &RxTimeoutTimer, time * 1e3 ); +// TimerStart( &RxTimeoutTimer ); +} + +int16_t RadioRssi( RadioModems_t modem ) +{ + return SX126xGetRssiInst( ); +} + +void RadioWrite( uint16_t addr, uint8_t data ) +{ + SX126xWriteRegister( addr, data ); +} + +uint8_t RadioRead( uint16_t addr ) +{ + return SX126xReadRegister( addr ); +} + +void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xWriteRegisters( addr, buffer, size ); +} + +void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) +{ + SX126xReadRegisters( addr, buffer, size ); +} + +void RadioWriteFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xWriteBuffer( 0, buffer, size ); +} + +void RadioReadFifo( uint8_t *buffer, uint8_t size ) +{ + SX126xReadBuffer( 0, buffer, size ); +} + +void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ) +{ + if( modem == MODEM_LORA ) + { + SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + else + { + if( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) + { + SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength = max; + SX126xSetPacketParams( &SX126x.PacketParams ); + } + } +} + +void RadioSetPublicNetwork( bool enable ) +{ + RadioPublicNetwork.Current = RadioPublicNetwork.Previous = enable; + + RadioSetModem( MODEM_LORA ); + if( enable == true ) + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); + } + else + { + // Change LoRa modem SyncWord + SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); + SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); + } +} + +uint32_t RadioGetWakeupTime( void ) +{ + return( RADIO_TCXO_SETUP_TIME + RADIO_WAKEUP_TIME ); +} + +void RadioOnTxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } +} + +void RadioOnRxTimeoutIrq( void ) +{ + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } +} + +void RadioOnDioIrq( void ) +{ + IrqFired = true; +} + +void RadioIrqProcess( void ) +{ + // if( IrqFired == true ) + if(GetRadioDio1Pin()) + { + IrqFired = false; + + uint16_t irqRegs = SX126xGetIrqStatus( ); + SX126xClearIrqStatus( irqRegs); //IRQ_RADIO_ALL ); + + if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) + { + RadioEvents->TxDone( ); + } + } + + if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RadioEvents->RxError( ); + } + } + + if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) + { + uint8_t size; + + SX126xGetPayload( RadioRxPayload, &size , 120 ); + SX126xGetPacketStatus( &RadioPktStatus ); + if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) + { + if (RadioPktStatus.packetType == PACKET_TYPE_LORA){ + RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt ); + }else if (RadioPktStatus.packetType == PACKET_TYPE_GFSK) { + RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.Gfsk.RssiAvg, RadioPktStatus.Params.Gfsk.RssiSync); + } + } + } + + if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + { + RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) ); + } + } + + if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) + { + if( SX126xGetOperatingMode( ) == MODE_TX ) + { + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } + } + else if( SX126xGetOperatingMode( ) == MODE_RX ) + { + + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + } + + if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) + { + //__NOP( ); + } + + if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) + { +/* + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } +*/ + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RadioEvents->RxError( ); + } + } + } +} diff --git a/Radio_LLCC68_Multi/Radio/src/sx126x-board.c b/Radio_LLCC68_Multi/Radio/src/sx126x-board.c new file mode 100644 index 0000000..cea0ae6 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/src/sx126x-board.c @@ -0,0 +1,216 @@ +/* + ______ _ + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + +Description: SX126x driver specific target board functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#include "stm32f0xx.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" + + +void SX126xReset( void ) +{ + HAL_Delay_nMS( 1 ); + SetRadionRSTPin_0(); + HAL_Delay_nMS( 2 ); + SetRadionRSTPin_1(); + HAL_Delay_nMS( 1 ); +} + +void SX126xWaitOnBusy( void ) +{ + while(GetRadioBusyPin()); +} + + +void SX126xWakeup( void ) +{ + SetRadioNSSPin_0(); + + SpiInOut(RADIO_GET_STATUS); + SpiInOut(0); + + SetRadioNSSPin_1(); + + // Wait for chip to be ready. + SX126xWaitOnBusy( ); +} + +void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) +{ + + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(( uint8_t )command ); + + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut(buffer[i] ); + } + + SetRadioNSSPin_1(); + + if( command != RADIO_SET_SLEEP ) + { + SX126xWaitOnBusy( ); + } +} + +void SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(( uint8_t )command ); + SpiInOut(0x00 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut(0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(RADIO_WRITE_REGISTER ); + SpiInOut(( address & 0xFF00 ) >> 8 ); + SpiInOut( address & 0x00FF ); + + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut(buffer[i] ); + } + + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xWriteRegister( uint16_t address, uint8_t value ) +{ + SX126xWriteRegisters( address, &value, 1 ); +} + +void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut(RADIO_READ_REGISTER ); + SpiInOut(( address & 0xFF00 ) >> 8 ); + SpiInOut( address & 0x00FF ); + SpiInOut( 0 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut(0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +uint8_t SX126xReadRegister( uint16_t address ) +{ + uint8_t data; + SX126xReadRegisters( address, &data, 1 ); + return data; +} + +void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut( RADIO_WRITE_BUFFER ); + SpiInOut( offset ); + for( uint16_t i = 0; i < size; i++ ) + { + SpiInOut( buffer[i] ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) +{ + SX126xCheckDeviceReady( ); + + SetRadioNSSPin_0(); + + SpiInOut( RADIO_READ_BUFFER ); + SpiInOut( offset ); + SpiInOut( 0 ); + for( uint16_t i = 0; i < size; i++ ) + { + buffer[i] = SpiInOut( 0 ); + } + + SetRadioNSSPin_1(); + + SX126xWaitOnBusy( ); +} + +void SX126xSetRfTxPower( int8_t power ) +{ + SX126xSetTxParams( power, RADIO_RAMP_40_US ); +} + +uint8_t SX126xGetPaSelect( uint32_t channel ) +{ +// if( GpioRead( &DeviceSel ) == 1 ) +// { +// return SX1261; +// } +// else +// { +// return SX1262; +// } + + return SX1262; +} + +void SX126xAntSwOn( void ) +{ + //GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 ); +} + +void SX126xAntSwOff( void ) +{ + // GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); +} + +bool SX126xCheckRfFrequency( uint32_t frequency ) +{ + // Implement check. Currently all frequencies are supported + return true; +} diff --git a/Radio_LLCC68_Multi/Radio/src/sx126x.c b/Radio_LLCC68_Multi/Radio/src/sx126x.c new file mode 100644 index 0000000..c9160d1 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/src/sx126x.c @@ -0,0 +1,716 @@ +/*! + * \file sx126x.c + * + * \brief SX126x driver implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + */ +#include <math.h> +#include <string.h> +#include "sx126x.h" +#include "sx126x-board.h" +#include "delay.h" + +//#define USE_TCXO +/*! + * \brief Radio registers definition + */ +typedef struct +{ + uint16_t Addr; //!< The address of the register + uint8_t Value; //!< The value of the register +}RadioRegisters_t; + +/*! + * \brief Holds the internal operating mode of the radio + */ +static RadioOperatingModes_t OperatingMode; + +/*! + * \brief Stores the current packet type set in the radio + */ +static RadioPacketTypes_t PacketType; + +/*! + * \brief Stores the last frequency error measured on LoRa received packet + */ +volatile uint32_t FrequencyError = 0; + +/*! + * \brief Hold the status of the Image calibration + */ +static bool ImageCalibrated = false; + +/* + * SX126x DIO IRQ callback functions prototype + */ + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xOnDioIrq( void ); + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xSetPollingMode( void ); + +/*! + * \brief DIO 0 IRQ callback + */ +void SX126xSetInterruptMode( void ); + +/* + * \brief Process the IRQ if handled by the driver + */ +void SX126xProcessIrqs( void ); + + +void SX126xInit( DioIrqHandler dioIrq ) +{ + SX126xReset( ); + SX126xWakeup( ); + SX126xSetStandby( STDBY_RC ); + +#ifdef USE_TCXO + CalibrationParams_t calibParam; + + SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, RADIO_TCXO_SETUP_TIME << 6 ); // convert from ms to SX126x time base + calibParam.Value = 0x7F; + SX126xCalibrate( calibParam ); + +#endif + + SX126xSetDio2AsRfSwitchCtrl( true ); + OperatingMode = MODE_STDBY_RC; +} + +RadioOperatingModes_t SX126xGetOperatingMode( void ) +{ + return OperatingMode; +} + +void SX126xCheckDeviceReady( void ) +{ + if( ( SX126xGetOperatingMode( ) == MODE_SLEEP ) || ( SX126xGetOperatingMode( ) == MODE_RX_DC ) ) + { + SX126xWakeup( ); + // Switch is turned off when device is in sleep mode and turned on is all other modes + SX126xAntSwOn( ); + } + SX126xWaitOnBusy( ); +} + +void SX126xSetPayload( uint8_t *payload, uint8_t size ) +{ + SX126xWriteBuffer( 0x00, payload, size ); +} + +uint8_t SX126xGetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize ) +{ + uint8_t offset = 0; + + SX126xGetRxBufferStatus( size, &offset ); + if( *size > maxSize ) + { + return 1; + } + SX126xReadBuffer( offset, buffer, *size ); + return 0; +} + +void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ) +{ + SX126xSetPayload( payload, size ); + SX126xSetTx( timeout ); +} + +uint8_t SX126xSetSyncWord( uint8_t *syncWord ) +{ + SX126xWriteRegisters( REG_LR_SYNCWORDBASEADDRESS, syncWord, 8 ); + return 0; +} + +void SX126xSetCrcSeed( uint16_t seed ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( seed >> 8 ) & 0xFF ); + buf[1] = ( uint8_t )( seed & 0xFF ); + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + SX126xWriteRegisters( REG_LR_CRCSEEDBASEADDR, buf, 2 ); + break; + + default: + break; + } +} + +void SX126xSetCrcPolynomial( uint16_t polynomial ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( polynomial >> 8 ) & 0xFF ); + buf[1] = ( uint8_t )( polynomial & 0xFF ); + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + SX126xWriteRegisters( REG_LR_CRCPOLYBASEADDR, buf, 2 ); + break; + + default: + break; + } +} + +void SX126xSetWhiteningSeed( uint16_t seed ) +{ + uint8_t regValue = 0; + + switch( SX126xGetPacketType( ) ) + { + case PACKET_TYPE_GFSK: + regValue = SX126xReadRegister( REG_LR_WHITSEEDBASEADDR_MSB ) & 0xFE; + regValue = ( ( seed >> 8 ) & 0x01 ) | regValue; + SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit. + SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_LSB, ( uint8_t )seed ); + break; + + default: + break; + } +} + +uint32_t SX126xGetRandom( void ) +{ + uint8_t buf[] = { 0, 0, 0, 0 }; + + // Set radio in continuous reception + SX126xSetRx( 0 ); + + HAL_Delay_nMS( 1 ); + + SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, buf, 4 ); + + SX126xSetStandby( STDBY_RC ); + + return ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3]; +} + +void SX126xSetSleep( SleepParams_t sleepConfig ) +{ + SX126xAntSwOff( ); + + SX126xWriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 ); + OperatingMode = MODE_SLEEP; +} + +void SX126xSetStandby( RadioStandbyModes_t standbyConfig ) +{ + SX126xWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 ); + if( standbyConfig == STDBY_RC ) + { + OperatingMode = MODE_STDBY_RC; + } + else + { + OperatingMode = MODE_STDBY_XOSC; + } +} + +void SX126xSetFs( void ) +{ + SX126xWriteCommand( RADIO_SET_FS, 0, 0 ); + OperatingMode = MODE_FS; +} + +void SX126xSetTx( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_TX; + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_TX, buf, 3 ); +} + +void SX126xSetRx( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_RX; + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); +} + +void SX126xSetRxBoosted( uint32_t timeout ) +{ + uint8_t buf[3]; + + OperatingMode = MODE_RX; + + SX126xWriteRegister( REG_RX_GAIN, 0x96 ); // max LNA gain, increase current by ~2mA for around ~3dB in sensivity + + buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( timeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); +} + +void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) +{ + uint8_t buf[6]; + + buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF ); + buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF ); + buf[2] = ( uint8_t )( rxTime & 0xFF ); + buf[3] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF ); + buf[4] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF ); + buf[5] = ( uint8_t )( sleepTime & 0xFF ); + SX126xWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 ); + OperatingMode = MODE_RX_DC; +} + +void SX126xSetCad( void ) +{ + SX126xWriteCommand( RADIO_SET_CAD, 0, 0 ); + OperatingMode = MODE_CAD; +} + +void SX126xSetTxContinuousWave( void ) +{ + SX126xWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 ); +} + +void SX126xSetTxInfinitePreamble( void ) +{ + SX126xWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 ); +} + +void SX126xSetStopRxTimerOnPreambleDetect( bool enable ) +{ + SX126xWriteCommand( RADIO_SET_STOPRXTIMERONPREAMBLE, ( uint8_t* )&enable, 1 ); +} + +void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ) +{ + SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, &SymbNum, 1 ); +} + +void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ) +{ + SX126xWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 ); +} + +void SX126xCalibrate( CalibrationParams_t calibParam ) +{ + SX126xWriteCommand( RADIO_CALIBRATE, ( uint8_t* )&calibParam, 1 ); +} + +void SX126xCalibrateImage( uint32_t freq ) +{ + uint8_t calFreq[2]; + + if( freq > 900000000 ) + { + calFreq[0] = 0xE1; + calFreq[1] = 0xE9; + } + else if( freq > 850000000 ) + { + calFreq[0] = 0xD7; + calFreq[1] = 0xD8; + } + else if( freq > 770000000 ) + { + calFreq[0] = 0xC1; + calFreq[1] = 0xC5; + } + else if( freq > 460000000 ) + { + calFreq[0] = 0x75; + calFreq[1] = 0x81; + } + else if( freq > 425000000 ) + { + calFreq[0] = 0x6B; + calFreq[1] = 0x6F; + } + SX126xWriteCommand( RADIO_CALIBRATEIMAGE, calFreq, 2 ); +} + +void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ) +{ + uint8_t buf[4]; + + buf[0] = paDutyCycle; + buf[1] = hpMax; + buf[2] = deviceSel; + buf[3] = paLut; + SX126xWriteCommand( RADIO_SET_PACONFIG, buf, 4 ); +} + +void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ) +{ + SX126xWriteCommand( RADIO_SET_TXFALLBACKMODE, &fallbackMode, 1 ); +} + +void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ) +{ + uint8_t buf[8]; + + buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF ); + buf[1] = ( uint8_t )( irqMask & 0x00FF ); + buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF ); + buf[3] = ( uint8_t )( dio1Mask & 0x00FF ); + buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF ); + buf[5] = ( uint8_t )( dio2Mask & 0x00FF ); + buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF ); + buf[7] = ( uint8_t )( dio3Mask & 0x00FF ); + SX126xWriteCommand( RADIO_CFG_DIOIRQ, buf, 8 ); +} + +uint16_t SX126xGetIrqStatus( void ) +{ + uint8_t irqStatus[2]; + + SX126xReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 ); + return ( irqStatus[0] << 8 ) | irqStatus[1]; +} + +void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ) +{ + SX126xWriteCommand( RADIO_SET_RFSWITCHMODE, &enable, 1 ); +} + +void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ) +{ + uint8_t buf[4]; + + buf[0] = tcxoVoltage & 0x07; + buf[1] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); + buf[2] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); + buf[3] = ( uint8_t )( timeout & 0xFF ); + + SX126xWriteCommand( RADIO_SET_TCXOMODE, buf, 4 ); +} + +void SX126xSetRfFrequency( uint32_t frequency ) +{ + uint8_t buf[4]; + uint32_t freq = 0; + + if( ImageCalibrated == false ) + { + SX126xCalibrateImage( frequency ); + ImageCalibrated = true; + } + + freq = ( uint32_t ) ( frequency * 4 / 15625 * 4096 ); // ( ( double )frequency / ( double )FREQ_STEP ); + buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF ); + buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + buf[3] = ( uint8_t )( freq & 0xFF ); + SX126xWriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 ); +} + +void SX126xSetPacketType( RadioPacketTypes_t packetType ) +{ + // Save packet type internally to avoid questioning the radio + PacketType = packetType; + SX126xWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 ); +} + +RadioPacketTypes_t SX126xGetPacketType( void ) +{ + return PacketType; +} + +void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ) +{ + uint8_t buf[2]; + + if( SX126xGetPaSelect( 0 ) == SX1261 ) + { + if( power == 15 ) + { + SX126xSetPaConfig( 0x06, 0x00, 0x01, 0x01 ); + } + else + { + SX126xSetPaConfig( 0x04, 0x00, 0x01, 0x01 ); + } + if( power >= 14 ) + { + power = 14; + } + else if( power < -3 ) + { + power = -3; + } + SX126xWriteRegister( REG_OCP, 0x18 ); // current max is 80 mA for the whole device + } + else // sx1262 + { + SX126xSetPaConfig( 0x04, 0x07, 0x00, 0x01 ); + if( power > 22 ) + { + power = 22; + } + else if( power < -3 ) + { + power = -3; + } + SX126xWriteRegister( REG_OCP, 0x38 ); // current max 160mA for the whole device + } + buf[0] = power; + buf[1] = ( uint8_t )rampTime; + SX126xWriteCommand( RADIO_SET_TXPARAMS, buf, 2 ); +} + +void SX126xSetModulationParams( ModulationParams_t *modulationParams ) +{ + uint8_t n; + uint32_t tempVal = 0; + uint8_t buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if( PacketType != modulationParams->PacketType ) + { + SX126xSetPacketType( modulationParams->PacketType ); + } + + switch( modulationParams->PacketType ) + { + case PACKET_TYPE_GFSK: + n = 8; + tempVal = ( uint32_t )( 32 * XTAL_FREQ / modulationParams->Params.Gfsk.BitRate ); + buf[0] = ( tempVal >> 16 ) & 0xFF; + buf[1] = ( tempVal >> 8 ) & 0xFF; + buf[2] = tempVal & 0xFF; + buf[3] = modulationParams->Params.Gfsk.ModulationShaping; + buf[4] = modulationParams->Params.Gfsk.Bandwidth; + tempVal = ( uint32_t )( modulationParams->Params.Gfsk.Fdev * 4/ 15625 * 4096); //( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP + buf[5] = ( tempVal >> 16 ) & 0xFF; + buf[6] = ( tempVal >> 8 ) & 0xFF; + buf[7] = ( tempVal& 0xFF ); + SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); + break; + case PACKET_TYPE_LORA: + n = 4; + buf[0] = modulationParams->Params.LoRa.SpreadingFactor; + buf[1] = modulationParams->Params.LoRa.Bandwidth; + buf[2] = modulationParams->Params.LoRa.CodingRate; + buf[3] = modulationParams->Params.LoRa.LowDatarateOptimize; + + SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); + + break; + default: + case PACKET_TYPE_NONE: + return; + } +} + +void SX126xSetPacketParams( PacketParams_t *packetParams ) +{ + uint8_t n; + uint8_t crcVal = 0; + uint8_t buf[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if( PacketType != packetParams->PacketType ) + { + SX126xSetPacketType( packetParams->PacketType ); + } + + switch( packetParams->PacketType ) + { + case PACKET_TYPE_GFSK: + if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_IBM ) + { + SX126xSetCrcSeed( CRC_IBM_SEED ); + SX126xSetCrcPolynomial( CRC_POLYNOMIAL_IBM ); + crcVal = RADIO_CRC_2_BYTES; + } + else if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_CCIT ) + { + SX126xSetCrcSeed( CRC_CCITT_SEED ); + SX126xSetCrcPolynomial( CRC_POLYNOMIAL_CCITT ); + crcVal = RADIO_CRC_2_BYTES_INV; + } + else + { + crcVal = packetParams->Params.Gfsk.CrcLength; + } + n = 9; + buf[0] = ( packetParams->Params.Gfsk.PreambleLength >> 8 ) & 0xFF; + buf[1] = packetParams->Params.Gfsk.PreambleLength; + buf[2] = packetParams->Params.Gfsk.PreambleMinDetect; + buf[3] = ( packetParams->Params.Gfsk.SyncWordLength /*<< 3*/ ); // convert from byte to bit + buf[4] = packetParams->Params.Gfsk.AddrComp; + buf[5] = packetParams->Params.Gfsk.HeaderType; + buf[6] = packetParams->Params.Gfsk.PayloadLength; + buf[7] = crcVal; + buf[8] = packetParams->Params.Gfsk.DcFree; + break; + case PACKET_TYPE_LORA: + n = 6; + buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF; + buf[1] = packetParams->Params.LoRa.PreambleLength; + buf[2] = packetParams->Params.LoRa.HeaderType; + buf[3] = packetParams->Params.LoRa.PayloadLength; + buf[4] = packetParams->Params.LoRa.CrcMode; + buf[5] = packetParams->Params.LoRa.InvertIQ; + break; + default: + case PACKET_TYPE_NONE: + return; + } + SX126xWriteCommand( RADIO_SET_PACKETPARAMS, buf, n ); +} + +void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ) +{ + uint8_t buf[7]; + + buf[0] = ( uint8_t )cadSymbolNum; + buf[1] = cadDetPeak; + buf[2] = cadDetMin; + buf[3] = ( uint8_t )cadExitMode; + buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF ); + buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF ); + buf[6] = ( uint8_t )( cadTimeout & 0xFF ); + SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 5 ); + OperatingMode = MODE_CAD; +} + +void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ) +{ + uint8_t buf[2]; + + buf[0] = txBaseAddress; + buf[1] = rxBaseAddress; + SX126xWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); +} + +RadioStatus_t SX126xGetStatus( void ) +{ + uint8_t stat = 0; + RadioStatus_t status; + + SX126xReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 ); + status.Value = stat; + return status; +} + +int8_t SX126xGetRssiInst( void ) +{ + uint8_t buf[1]; + int8_t rssi = 0; + + SX126xReadCommand( RADIO_GET_RSSIINST, buf, 1 ); + rssi = -buf[0] >> 1; + return rssi; +} + +void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer ) +{ + uint8_t status[2]; + + SX126xReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 ); + + // In case of LORA fixed header, the payloadLength is obtained by reading + // the register REG_LR_PAYLOADLENGTH + if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( SX126xReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) ) + { + *payloadLength = SX126xReadRegister( REG_LR_PAYLOADLENGTH ); + } + else + { + *payloadLength = status[0]; + } + *rxStartBufferPointer = status[1]; +} + +void SX126xGetPacketStatus( PacketStatus_t *pktStatus ) +{ + uint8_t status[3]; + + SX126xReadCommand( RADIO_GET_PACKETSTATUS, status, 3 ); + + pktStatus->packetType = SX126xGetPacketType( ); + switch( pktStatus->packetType ) + { + case PACKET_TYPE_GFSK: + pktStatus->Params.Gfsk.RxStatus = status[0]; + pktStatus->Params.Gfsk.RssiSync = -status[1] >> 1; + pktStatus->Params.Gfsk.RssiAvg = -status[2] >> 1; + pktStatus->Params.Gfsk.FreqError = 0; + break; + + case PACKET_TYPE_LORA: + pktStatus->Params.LoRa.RssiPkt = -status[0] >> 1; + ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] >> 2 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) >> 2 ) ); + pktStatus->Params.LoRa.SignalRssiPkt = -status[2] >> 1; + pktStatus->Params.LoRa.FreqError = FrequencyError; + break; + + default: + case PACKET_TYPE_NONE: + // In that specific case, we set everything in the pktStatus to zeros + // and reset the packet type accordingly + memset( pktStatus, 0, sizeof( PacketStatus_t ) ); + pktStatus->packetType = PACKET_TYPE_NONE; + break; + } +} + +RadioError_t SX126xGetDeviceErrors( void ) +{ + RadioError_t error; + + SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t * )&error, 2 ); + return error; +} + +void SX126xClearDeviceErrors( void ) +{ + uint8_t buf[2] = { 0x00, 0x00 }; + SX126xWriteCommand( RADIO_CLR_ERROR, buf, 2 ); +} + +void SX126xClearIrqStatus( uint16_t irq ) +{ + uint8_t buf[2]; + + buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF ); + buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF ); + SX126xWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 ); +} diff --git a/Radio_LLCC68_Multi/Radio/user.h b/Radio_LLCC68_Multi/Radio/user.h new file mode 100644 index 0000000..ed78aa0 --- /dev/null +++ b/Radio_LLCC68_Multi/Radio/user.h @@ -0,0 +1,21 @@ +#ifndef _USER_H_ +#define _USER_H_ + +#include "stm32f0xx.h" + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> + +#include "gpio.h" +#include "delay.h" +#include "spi.h" + +#include "radio.h" +#include "sx126x.h" +#include "sx126x-board.h" +#include "crc.h" + + +#endif + diff --git a/Radio_LLCC68_Multi/Src/ATModem.c b/Radio_LLCC68_Multi/Src/ATModem.c new file mode 100644 index 0000000..61c776f --- /dev/null +++ b/Radio_LLCC68_Multi/Src/ATModem.c @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * @file : ATModem.c + * @brief : AT Modem Protocol program body + ****************************************************************************** + */ +#include "ATModem.h" + + +void ATInit(stATModemDef * pATModem, ATSendPktDef pFunc1) +{ + pATModem->ATSendPktFunc = pFunc1; + + return; +} +void ATSetCallBack(stATModemDef * pATModem, ATSendPktDef pFunc1) +{ + pATModem->ATSendPktFunc = pFunc1; + return; +} + +int ATParsePacket(stATModemDef * pATModem, char * pBuf, uchar len1) +{ + return 0; +} +void ATProcess(stATModemDef * pATModem) +{ + +} diff --git a/Radio_LLCC68_Multi/Src/BoardType.c b/Radio_LLCC68_Multi/Src/BoardType.c new file mode 100644 index 0000000..b803dc9 --- /dev/null +++ b/Radio_LLCC68_Multi/Src/BoardType.c @@ -0,0 +1,98 @@ +#include "BoardType.h" +#include "KMachine.h" +#include "KBus.h" + + +#define APP_ADDR 0x08001000 //应用程序首地址定义 +#define APPINFOBLOCK_ADDR (APP_ADDR + 0x100) //程序信息块 地址 +#define INFOBLOCK_ADDR (APP_ADDR + 0x1000) //信息块 地址 + +#define APP_START_ADDR IROM1_START_ADDRESS + +extern int Region$$Table$$Limit; + +#define MAKE_VER(x,y) ((x<<8)|y) +#define APP_VER MAKE_VER(1,16) + +const stAppInfoBlock AppInfoBlock __attribute__((at(APPINFOBLOCK_ADDR))) = +{ + 0xAA55, // StartSign + 0x0301, // BlockType + sizeof(stAppInfoBlock), //BlockSize + 0, // Pad, + APP_VER, //AppVer + (BOARD_TYPE<<8) + BOARD_VER, //AppDevice; + 0x1000, //AppSize; + 0x0C00, //AppDataSize; + APP_ADDR, //nAppStartAddr + (int)&Region$$Table$$Limit, //nBtldr_NewAppInfoAddr + 0x08009000, //nBtldr_NewAppAddr + 0xCCCC, //crc16; + 0xAA55 //EndSign; + +}; + +const stKMInfoBlock KMInfoBlock __attribute__((at(INFOBLOCK_ADDR))) = +{ +// sizeof(stKMInfoBlock), + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceType BOARD_VER, //nDevieVer + APP_VER, //ProgVer + 0x0102, //KLinkVer + KBUS_VER, //KBusVer +// 0x0100, //KNetVer +// 0x0100, //KWLVer + + 4, //nCapacity1 ?K + 1, //nCapacity2 ?k + + DINPUT, //nDInput; + DOUTPUT, //nDOutput + + 0, //nAInput + 0, //nAOutput + 0, //nHInput + 0, //nHOutput + 0, //nExt1; + 0, //nExt2; + 0, //nLogSize; + 3, //nPorts; + 0, //nManSize; + 0, //nAbility; + 6, //nSwitchBits; +}; + + +const stDeviceInfo MyDeviceInfo={ + + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceTypeVer // unsigned short ClientType; // 子机类型 + APP_VER, //ProgVer // unsigned short ClientVer; // 子机版本 + + DINPUT, // unsigned char InBitCount; // 输入开关量数量 + DOUTPUT, // unsigned char OutBitCount; // 输出开关量数量 + EXDOUPUT, // unsigned char ExInBitCount; // 扩展的输入开关量数量 + EXDOUPUT, // unsigned char ExOutBitCount; // 扩展的输出开关量数量 + 0, // unsigned char InDWCount; // 输入数据字数 + 0, // unsigned char OutDWCount; // 输出数据字数 + 0, // unsigned char AIWCount; // 输入模拟量通道(字)数 // 16位为一个字(通道) + 0, // unsigned char AQWCount; // 输出模拟量通道(字)数 // 16位为一个字(通道) +// 0, // unsigned char AIBits; // 每通道位数 // 16位以下 +// 0, // unsigned char AQbits; // 每通道位数 // 16位以下 +}; + +const stExDeviceInfo MyExDeviceInfo ={ + (BOARD_TYPE<<8) + BOARD_VER, //nDeviceTypeVer // unsigned short ClientType; // 子机类型 + APP_VER, //ProgVer // unsigned short ClientVer; // 子机版本 + + DINPUT, // unsigned char InBitCount; // 输入开关量数量 + DOUTPUT, // unsigned char OutBitCount; // 输出开关量数量 + EXDOUPUT, // unsigned char ExInBitCount; // 扩展的输入开关量数量 + EXDOUPUT, // unsigned char ExOutBitCount; // 扩展的输出开关量数量 + 0, // unsigned char InDWCount; // 输入数据字数 + 0, // unsigned char OutDWCount; // 输出数据字数 + 0, // unsigned char AIWCount; // 输入模拟量通道(字)数 // 16位为一个字(通道) + 0, // unsigned char AQWCount; // 输出模拟量通道(字)数 // 16位为一个字(通道) +// 0, // unsigned char AIBits; // 每通道位数 // 16位以下 +// 0, // unsigned char AQbits; // 每通道位数 // 16位以下 + +}; + diff --git a/Radio_LLCC68_Multi/Src/main.c b/Radio_LLCC68_Multi/Src/main.c new file mode 100644 index 0000000..92aa1d6 --- /dev/null +++ b/Radio_LLCC68_Multi/Src/main.c @@ -0,0 +1,817 @@ + +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2018 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_hal.h" + +/* USER CODE BEGIN Includes */ +#include "Globaldef.h" +#include "debug.h" +#include "Functions.h" +#include "KMachine.h" +#include "PLCfunctions.h" +//#include "KBus.h" +#include "KLink.h" +#include "string.h" +#include "BSP.h" +#include "ModbusRTU.h" +#if (BOARD_TYPE == 13) +#include "w5500_port.h" +#include "../src/Ethernet/socket.h" +#include "../src/Ethernet/loopback.h" +#elif (BOARD_TYPE == 14) +#include "FP0.h" +#elif (BOARD_TYPE == 15 || BOARD_TYPE == 16) +#include "KWireless2.h" +//#include "user.h" +//#include "../src/radio/inc/sx126x-board.h" +#endif + +/* USER CODE END Includes */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + + + +unsigned char Uart1RxBuf1[Uart1RxBufSize]; +unsigned char Uart1TxBuf1[260]; + +unsigned char Uart2RxBuf1[RX2BUFSIZE]; +unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +unsigned short Uart1RxBuf1DataLen = 0; +unsigned short Uart2RxBuf1DataLen = 0; + +unsigned char SlowFlicker=0; +unsigned char FastFlicker=0; + +unsigned int Uart1IdelTimer = 0; +unsigned char Uart1Mode = 1; //Uart1宸ヤ綔妯″紡锛� 0 : 鏅�氾紝 1 : 閫忎紶妯″紡 + +unsigned int Uart1Baud = DefaultUart1Baud; +unsigned int Uart2Baud = DefaultUart2Baud; + +//unsigned char Uart1RecvBuf1[Uart1RecvBufSize]; +//unsigned short Uart1RecvBuf1DataLen=0; + +//unsigned char Uart2RecvBuf1[128]; +//unsigned short Uart2RecvBuf1DataLen=0; + +volatile char Uart1BaudGot=0; +volatile char Uart1BaudFirstGot=0; +volatile char Uart1DmaInts=0; + + +#if (ENABLE_PLC) +stBinProg1 * pProgs = (stBinProg1 *)STORE_PRG_BASE; +#endif +uint32_t us1,us2,us3,us4,us5,us6; + +stKBusDef KBus1; // + +extern stDeviceInfo MyDeviceInfo; + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ + + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +const unsigned char LEDSEGTAB[]={ +0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, //0-F +0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1, //0.-F. +0x00,0x40, // ,-,_,~,o,n,N,<,>,J,r, +}; + +/* USER CODE END PFP */ + +/* USER CODE BEGIN 0 */ + +int HexToInt(char ch) +{ + if (ch>='0' && ch <='9') return ch-'0'; + if (ch>='A' && ch <='F') return ch-'A'+10; + if (ch>='a' && ch <='f') return ch-'a'+10; + return 0; +} + +void HAL_SYSTICK_Callback(void) +{ +static int Count=0; + CurTickuS += 100; + nCurTick++; + KBus1.nSlaveTick++; + Count++; + if (Count>=10000) + { + Count=0; + KMem.CurTimeSec++; + KMem.ThisRunTime++; KMem.TotalRunTime++; + if (KMRunStat.bLEDFlick) KMRunStat.bLEDFlick--; + if (KMRunStat.bLEDFlick >120) KMRunStat.bLEDFlick=120; + } + + return; +} + + +void PendSvCallBack() +{ +#if (BOARD_TYPE == 14) +///* + if (bSPI1RecvDone) + { + bSPI1RecvDone=0; + FPxParsePkt(SPI1RecvBuf,nSPI1RecvLenInBuf); + } +//*/ +#endif + if (Uart2Stat.bPacketRecved) + { + KBusParsePacket(&KBus1, (pKBPacket)Uart2RxBuf1, Uart2RxBuf1DataLen); + Uart2RxBuf1DataLen=0; + Uart2Stat.bPacketRecved=0; + Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); + KMem.WDT[2]++; + } + if (Uart1RxBuf1DataLen >0 && Uart1Stat.bPacketRecved) + { + int res1 = -1; + if (Uart1RxBuf1DataLen == 3 && Uart1RxBuf1[0]=='+' && Uart1RxBuf1[0]=='+' && Uart1RxBuf1[0]=='+') + { + Uart1Mode = 0; // 鍒囨崲鍒板懡浠ゆā寮� + }else if (Uart1RxBuf1DataLen == 3 && Uart1RxBuf1[0]=='-' && Uart1RxBuf1[0]=='-' && Uart1RxBuf1[0]=='-') + { + Uart1Mode = 1; // 鍒囨崲鍒伴�忎紶妯″紡 + }else if (Uart1Mode == 0) { + + res1 = ModBusSlaveParsePkg(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + if (res1 !=0) + { + KLParsePacket(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + } + + }else if (Uart1Mode == 1) { + // 閫忎紶妯″紡 + if (KwRunStat.sizetosend == 0) { + memcpy( KwRunStat.ttTxBuf1,Uart1RxBuf1, Uart1RxBuf1DataLen); + KwRunStat.sentsize = 0; + KwRunStat.sizesending = 0; + KwRunStat.sizetosend = Uart1RxBuf1DataLen; + }else { + return; + } + + //SendPacket(1, Uart1RecvBuf1, Uart1RecvBuf1DataLen); + } + Uart1RxBuf1DataLen=0; + Uart1Stat.bPacketRecved=0; + Uart1IdelTimer = 0; + } +} + +/* +KBus閫氳鍥炶皟鍑芥暟锛屽綋閫氳鐘舵�佹敼鍙樻垨鏁版嵁鏇存柊鏃惰璋冪敤銆� +鎴栬�呯郴缁熻姹傛椂銆� +*/ +void * KBusEvCallBackFunc(void* pParam, int nEvent, void *pBuf, int nLen1) +{ + switch (nEvent){ + + case KBusEvNone: + break; + case KBusEvCreate: + break; + case KBusEvConnected: + break; + case KBusEvDisConnected: + break; + case KBusEvClosed: + break; + case KBusEvStateChange: + break; + case KBusEvTimeSync: + break; + case KBusEvDataUpdate: + KMem.WLX[0] = KBusMem.WLX[0]; + KMem.WLY[0] = KBusMem.WLY[0]; + + if (KBus1.bMaster) { + KMem.WY[0]=KBusMem.WLX[0]; //KPLC with KBus Master + KBusMem.WLY[0]=KMem.WX[0]; + } else if (KBus1.bSlave) { + KMem.WYB[0]=KBusMem.WLYB[0]; //WireLess with KBus Slave + KBusMem.WLXB[0]=KMem.WXB[0]; + + } + break; + case KBusEvCmdResponse: + break; + + default: + break; + } + return 0; +} + + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * + * @retval None + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + KMRunStat.bLEDFlick = 1; + + InitUartstat(&Uart1Stat,Uart1RxBuf1,sizeof(Uart1RxBuf1),Uart1TxBuf1,sizeof(Uart1TxBuf1)); +// InitUartstat(&Uart2Stat,Uart2RxBuf1,sizeof(Uart2RxBuf1),Uart2TxBuf1,sizeof(Uart2TxBuf1)); + /* USER CODE END 1 */ + + /* MCU Configuration----------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + TickFreq=10000; //Tick棰戠巼 + InituS(TickFreq); + // HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/TickFreq); //閲嶆柊瀹氫箟SysTick鐨勯鐜� + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + + KMachineInit(); + ReadSysCfgFromFlash(&storedKMSysCfg); + + KMRunStat.bLEDFlick = 1; + + KLinkInit(1); //娉ㄥ唽KLink绔彛 + +// stPortDef PortReg1 = {.nPortHardType = 3,.nPortUseType = 2}; +// KMRegisterPort(0,&PortReg1); + + + unsigned char bKBusMaster, bKBusSlave, bKBusRepeater; + int nKBusStationID; + int nKBusChilds; + + KMem.CurJumperSW=ReadJumperSW(); + KMem.EffJumperSW=KMem.CurJumperSW; + +// Uart2Baud = AlterUart2Baud; + +#if (BOARD_TYPE == 14) + KMem.EffJumperSW|=0x10; + nStationID=KMem.EffJumperSW&0x0f; + if ((KMem.EffJumperSW&0x10)!=0) {bKBusMaster=1;bKBusSlave=0;} + else{bKBusMaster=0;bKBusSlave=1;} + nChilds=nStationID; + FP0_Init(); + +#elif (BOARD_TYPE == 15 || BOARD_TYPE == 16) + nKBusStationID=KMem.EffJumperSW&0x0f; +// if (KMem.EffJumperSW == 0x1f) {bKBusRepeater=1;bKBusMaster=1;bKBusSlave=0;} +// else if ((KMem.EffJumperSW&0x10)!=0) {bKBusMaster=1;bKBusSlave=0;} +// else + {bKBusMaster=0;bKBusSlave=1;} +#else + nStationID=KMem.EffJumperSW&0x0f; + if (KMem.EffJumperSW == 0x1f) {bKBusRepeater=1;bKBusMaster=1;bKBusSlave=0;} + else if ((KMem.EffJumperSW&0x10)!=0) {bKBusMaster=1;bKBusSlave=0;} + else{bKBusMaster=0;bKBusSlave=1;} +#endif + nKBusChilds=nKBusStationID; + + if (bKBusMaster) { + KBusInitMaster(&KBus1, (KBusSendPktFuncDef)PutStr2, nKBusChilds); + } else if (bKBusSlave) { + KBusInitSlave(&KBus1, (KBusSendPktFuncDef)PutStr2, nKBusStationID,&MyDeviceInfo); + } + KBusSetEvCallBackFunc(&KBus1, &KBusEvCallBackFunc); + + UNUSED(bKBusRepeater); + // 娉ㄥ唽KBus绔彛 +/* + stPortDef PortReg2 = {.nPortHardType = 4,.nPortUseType = 3}; + KMRegisterPort(1,&PortReg2); +*/ + //if (KMem.EffJumperSW == 0x00) + Uart1Baud = DefaultUart1Baud; + MX_USART1_UART_Init(); + MX_USART2_UART_Init(); + + MX_SPI1_Init(); + LL_SPI_EnableIT_RXNE(SPI1); + +#if (BOARD_TYPE == 14) +// MX_SPI2_Init(); +// MX_ADC_Init(); +#else + MX_SPI2_Init(); + MX_ADC_Init(); +#endif + + MX_IWDG_Init(); + + MX_TIM6_Init(); + LL_TIM_EnableCounter(TIM6); + + /* USER CODE BEGIN 2 */ + LL_USART_EnableIT_RXNE(USART1); + LL_USART_EnableIT_IDLE(USART1); + LL_USART_EnableIT_TC(USART1); + +// LL_USART_EnableIT_RXNE(USART2); + Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); + LL_USART_EnableIT_IDLE(USART2); + LL_USART_EnableIT_TC(USART2); + +#if (BOARD_TYPE == 13) + int res; + res = w5500_init(); + KMem.SDD[28]=res; + +// res=socket(0,Sn_MR_TCP,5000,0); + KMem.SDD[29]=res; + +// res = listen(0); +#endif +// if (bKBusSlave) + { + // LL_USART_EnableAutoBaudRate(USART1); + // LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + // LL_USART_EnableAutoBaudRate(USART2); + // LL_USART_SetAutoBaudRateMode(USART2, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + } + //LL_USART_EnableIT_TXE(USART1); + /* USER CODE END 2 */ + + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + + HAL_Delay(10); + SetRunLed(1); //Turn On Run Led + SetErrLed(0); //Turn Off Err Led + +#if (BOARD_TYPE == 14) +// PutOutput (0); //Clear all Output +// Enable595(1); //Enable 595 Output +#else + PutOutput (0); //Clear all Output + Enable595(1); //Enable 595 Output +#endif + + if (GetBoardType() == 7 || GetBoardType() ==8 + || GetBoardType() == 9 || GetBoardType() ==10 ||GetBoardType() ==13 ||GetBoardType() ==15 || BOARD_TYPE == 16) + { + displayInput(0xffff); // + EnableDisIn(1); //Input Diaplay Enable 595 + } + SetOutStat(0); //OK Good, signal + ShowInitInfo(); + KMem.LastScanTime = GetuS(); + + KMRunStat.WorkMode=0; + KMRunStat.WorkMode2=0; + + KMRunStat.WorkMode = storedKMSysCfg.theKMSysCfg.workmode; + +#if (ENABLE_PLC) + if (KMRunStat.WorkMode == 1){ + InitPLC(); + KMRunStat.WorkMode2 = KMem.CurJumperSW&0x20 ; + if (KMRunStat.WorkMode2) { + StartPLC(); } + } +#endif + +#if (BOARD_TYPE == 15 || BOARD_TYPE == 16) + LoadKwConfig(); +// KWireLessInit(&KWInitStruct); + + KWireLessInit(KMem.EffJumperSW&0x20,KMem.EffJumperSW&0x0f,1); + KWireLessStart(); +#endif + + + stPortDef PortReg3 = {.nPortHardType = 7,.nPortUseType = 6}; + KMRegisterPort(2,&PortReg3); + + while (1) + { + //int MyKeyStat1,MyKeyStat2; + //MyKeyStat1=GetInput(); + + //*((unsigned int *)&(PLCMem.SDT[10]))=nRunCount; + // KMem.nRunCount=nRunCount; + SlowFlicker=0; + FastFlicker=1; + us1=GetuS(); + int haltick=HAL_GetTick(); + + int thisJumperSW=ReadJumperSW(); + +#if (ENABLE_PLC) + if (KMRunStat.WorkMode&1){ + if (thisJumperSW&0x20 && !(KMem.CurJumperSW&0x20)) // Run 寮�鍏� 姝� 璺冲彉銆� + {StartPLC();} + if (!(thisJumperSW&0x20) && (KMem.CurJumperSW&0x20)) // Run 寮�鍏� 璐� 璺冲彉銆� + {StopPLC();} + } +#endif + KMem.CurJumperSW=thisJumperSW; + KMem.haltick=haltick; +// KMem.TotalRunTime=TotalRunTime; +// KMem.ThisRunTime=ThisRunTime; + +// *((unsigned int *)&(PLCMem.SDT[2]))=nChilds; +// KMem.SDD[13]=PendSvCount; +// KMem.SDD[14]=RCC->CSR; + + + int a; + a = LL_GPIO_ReadInputPort(GPIOA); + KMem.WDT[120]=a; + a = LL_GPIO_ReadInputPort(GPIOB); + KMem.WDT[121]=a; + a = LL_GPIO_ReadInputPort(GPIOC); + KMem.WDT[122]=a; + a = LL_GPIO_ReadInputPort(GPIOD); + KMem.WDT[123]=a; + +#if (BOARD_TYPE == 14) +// KMem.WX[0]= GetInput(); + FP0_Proc(); +#else + KMem.WX[0]= GetInput(); +#endif + + if (GetBoardType() == 7 || GetBoardType() ==8 + || GetBoardType() == 9 || GetBoardType() ==10 || GetBoardType() ==15 || GetBoardType() ==16) + { + displayInput(KMem.WX[0]); + } + us2=GetuS(); + if (PowerDownFlag) { KMem.WX[0]=0;} +///* + if ((KMem.nRunCount &0x1f) == 0x02) + { + ADCProcess(); + if (PowerDownFlag) + { + KMem.WX[0]=0; + if (!OldPowerDownFlag) + { + OldPowerDownFlag = PowerDownFlag; + OldPowerDownEventTime = nCurTick; + PowerDownProcess(); + } + }else + { + if (OldPowerDownFlag) + { + OldPowerDownFlag=PowerDownFlag; + PowerRecoverProcess(); + + } + } + } +//*/ + +#if (BOARD_TYPE == 15 || BOARD_TYPE == 16) + Radio.IrqProcess( ); // Process Radio IRQ + KWL_Process(1); + +#endif + +// pProgs = (stBinProg1 *) STORE_PRG_BASE; +#if (ENABLE_PLC) + if ( KMRunStat.WorkMode==1 ) //&& bKBusMaster) + { + if (KMRunStat.nBinProgBank == 0){ + pProgs=(stBinProg1 *)STORE_PRG_BASE; + }else { + pProgs=(stBinProg1 *)ALT_PRG_BASE; + } + nSizeProg1=KMRunStat.nBinProgSize; + // pProgs=(stBinProg1 *)prog1; + + ProcessPLCBinProg(pProgs, nSizeProg1); + } +#endif // ENABLE_PLC + KMem.ScanTimeuS=us2-KMem.LastScanTime; + KMem.LastScanTime = us2; + if (KMem.ScanTimeuS < KMem.MinScanTimeuS) {KMem.MinScanTimeuS = KMem.ScanTimeuS;} + if (KMem.ScanTimeuS > KMem.MaxScanTimeuS) {KMem.MaxScanTimeuS = KMem.ScanTimeuS;} + + // if (bKBusRepeater) { KBusRepeaterFunc(); } + + us3=GetuS(); + + if (bKBusMaster) + { +#if (BOARD_TYPE == 14) + for (int i=0;i<nOutputBytes;i++) + {BufferOut[i+1]=KMem.WYB[i];} +#else +// BufferOut[1]=KMem.WX[0]&0xff; +// BufferOut[2]=(KMem.WX[0]>>8)&0xff; +#endif + } + KBusLoopProcess(&KBus1); + + if (haltick&0x00002000) SlowFlicker=1; + else SlowFlicker=0; + if (haltick&0x00000800) FastFlicker=1; + else FastFlicker=0; + + if (bKBusSlave) + { +// BufferOut[0]=KMem.WX[0]; +#if (BOARD_TYPE == 15 || BOARD_TYPE == 16) +// KBusSlaveFunc(2); + // if (! KMem.RunStat) {BufferIn[0]=0;} + // KMem.WY[0]=BufferIn[0]; +#else + KBusSlaveFunc(&KBus1); + if (! KMem.RunStat) {BufferIn[0]=0;} + KMem.WY[0]=BufferIn[0]; +#endif + if (KBus1.nSlaveTick&0x00002000) SlowFlicker=1; + else SlowFlicker=0; + if (KBus1.nSlaveTick&0x00000800) FastFlicker=1; + else FastFlicker=0; + } + +// KMem.WY[0]=nCount2>>5; + + + if (KMRunStat.bLEDFlick) + { + SetRunLed(FastFlicker); + SetErrLed(FastFlicker); + SetErr2Led(FastFlicker); + SetOutStat(!FastFlicker); + //KMRunStat.bLEDFlick-- ; + } + else + { + KMem.ErrStat = KwRunStat.ErrStat; + if ((KMem.EffJumperSW&0x10)==0x10) KMem.ErrStat += KBus1.ErrStat; +#if (ENABLE_PLC) + if (KMRunStat.WorkMode==1 ) { + if (PLCMem.bPLCRunning){SetRunLed(SlowFlicker);} + else {SetRunLed(0);} + } + else +#endif // ENABLE_PLC + { + if (!KMem.RunStat) SetRunLed(SlowFlicker); + else SetRunLed(FastFlicker); + } + + if (!KMem.ErrStat) + { + SetErrLed(0); + SetErr2Led(0); + SetOutStat(1); + } + else + { + SetErrLed(FastFlicker); + SetErr2Led(FastFlicker); + SetOutStat(0); + + } + } + +// SetRunLed(RunStat); +// SetErrLed(ErrStat); + + us4=GetuS(); +// EffJumperSW = GetInput(20)&0xff; + + +#if (BOARD_TYPE == 15 || BOARD_TYPE == 16) + + if ((KMem.EffJumperSW&0x10)==0x10) { + KMem.WFY[1]=KBusMem.WLYB[1]; + KBusMem.WLXB[1]=KMem.WFX[1]; + }else + { + KMem.WFY[1]=KMem.WX[0]; + KMem.WY[0]=KMem.WFX[1]; + } +// KMem.WY[0]=KMem.WLY[0]; +#else + KMem.WLX[0]=KMem.WX[0]; + KMem.WY[0]=KMem.WLY[0]; +#endif + + us5=GetuS(); + +#if (BOARD_TYPE == 14) +// PutOutput (KMem.WY[0]); +#else + PutOutput (KMem.WY[0]); +#endif + //PutOutput (KMem.nRunCount>>8); + //PutOutput(0x0f70); + +// if (bKBusMaster) ShowInfo(); +// if (bKBusSlave) ShowInfo(); + us6=GetuS(); + add1(10,10); + for (int i=0;i<64;i++) + { +// ProcessTimer(i); + } + KMem.nRunCount++; +// int nSize=sizeof(stKBusChnStat); +// memcpy(&KMem.SDT[64],&KBusChnStats[1],nSize); +// memcpy(&KMem.SDT[64+nSize/2],&KBusChnStats[2],nSize); +// for (int i=0;i<128;i++) { SDT[i]=i; } +// SDT[48]=55; +#if (USART1_AUTO_BAUDRATE == 1) + if (Uart1IdelTimer>300000) { // 瓒呰繃60绉掓病鏈夋暟鎹紶杈擄紝閲嶆柊杩涘叆鑷�傚簲娉㈢壒鐜囩姸鎬� + LL_USART_EnableAutoBaudRate(USART1); + LL_USART_SetAutoBaudRateMode(USART1, LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE); + }else { + Uart1IdelTimer++; + } +#endif +// if (bKBusSlave) HAL_Delay(0); +/* + if (!IsEmpty(&Uart1Stat.QRx)) + { + unsigned char k=PopOne(&Uart1Stat.QRx); + if (k=='L') + { + clearscreen(); + } + } +*/ + +#if (BOARD_TYPE == 14) +const unsigned int pins[6]= { LL_GPIO_PIN_10,LL_GPIO_PIN_11,LL_GPIO_PIN_12,LL_GPIO_PIN_13,LL_GPIO_PIN_14,LL_GPIO_PIN_15}; + //process 6 output + { + // mapping bits. + for (int i=0;i<6;i++) + { + USHORT bitaddr = storedKMSysCfg.theKMSysCfg.OutMappings[i]; + UCHAR type = (bitaddr&0xf000) >>12; + USHORT byteaddr = (bitaddr&0x0ff0) >>4; + UCHAR bitpos = bitaddr &0x0f; + UCHAR bitvalue = 0 ; + if (byteaddr>0) { + if (type == 0) bitvalue = KMem.WXB[byteaddr-1] & ( 1 << bitpos ); + else if (type == 1 ) bitvalue = KMem.WYB[byteaddr-1] & ( 1 << bitpos ); + } + if (bitvalue){ LL_GPIO_SetOutputPin(GPIOB,pins[i]);} + else {LL_GPIO_ResetOutputPin(GPIOB,pins[i]);} + } + } +#endif + +/* + { + unsigned char pos,seg; + unsigned short val; + pos=((KMem.nRunCount)&0x3); + //val=(KMem.nRunCount)&0xfff; + val=KMem.ErrStat; + char buf5[20]; + sprintf(buf5,"%4d",val); + val=buf5[3-pos]; + if (val <'0' || val >'9') {seg=0;} + else {seg=LEDSEGTAB[val-'0'];} + + pos=1<<pos; + //pos=1; + //seg=2; + seg=~seg; + // PutOutputSPI1(pos|(seg<<8)); + } +*/ + +#if (BOARD_TYPE == 13) + w5500_network_info_show(); +// loopback_tcps(0,str1,5000); +#endif + + LL_IWDG_ReloadCounter(IWDG); + + } //while (1) ; + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + + /* USER CODE END 3 */ + +} + + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @param file: The file name as string. + * @param line: The line in file as a number. + * @retval None + */ +void _Error_Handler(char *file, int line) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- Gitblit v1.9.1