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>&copy; 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>&copy; 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