From d5e44abb694f1b0f1aaa2393ad808d60f3e77b92 Mon Sep 17 00:00:00 2001 From: armfly Date: Mon, 4 Nov 2019 01:04:24 +0800 Subject: [PATCH] =?UTF-8?q?+1.=E5=A2=9E=E5=8A=A0=E5=BE=AE=E5=9E=8B?= =?UTF-8?q?=E6=95=B0=E6=8E=A7=E7=94=B5=E6=BA=90=E3=80=82=20+2.=E6=95=B4?= =?UTF-8?q?=E7=90=86=E9=83=A8=E5=88=86=E6=96=87=E4=BB=B6bsp=5Ftimer.c,=20b?= =?UTF-8?q?so=5Ftim=5Fpwm.c=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/02.例程修改记录.txt | 5 + Project/MDK-ARM(uV5)/project.uvoptx | 506 +++---- Project/MDK-ARM(uV5)/project.uvprojx | 5 + Project/h7_tool_app.bin | Bin 0 -> 600144 bytes User/app/inc/main.h | 23 +- User/app/inc/old/bmp_file.h | 23 - User/app/inc/old/can_network.h | 31 - User/app/inc/old/form_ad7606.h | 21 - User/app/inc/old/form_ad7705.h | 21 - User/app/inc/old/form_ad9833.h | 19 - User/app/inc/old/form_ads1256.h | 19 - User/app/inc/old/form_audio_rec.h | 46 - User/app/inc/old/form_camera.h | 19 - User/app/inc/old/form_can.h | 19 - User/app/inc/old/form_dac8501.h | 19 - User/app/inc/old/form_dac8562.h | 19 - User/app/inc/old/form_dso.h | 85 -- User/app/inc/old/form_fm_radio.h | 55 - User/app/inc/old/form_gprs.h | 19 - User/app/inc/old/form_gps.h | 19 - User/app/inc/old/form_hard_test.h | 21 - User/app/inc/old/form_http_server.h | 20 - User/app/inc/old/form_mems.h | 19 - User/app/inc/old/form_mp3_player.h | 41 - User/app/inc/old/form_oled.h | 21 - User/app/inc/old/form_reserve.h | 19 - User/app/inc/old/form_rs485.h | 19 - User/app/inc/old/form_touch_test.h | 20 - User/app/inc/old/form_usbd_msc.h | 19 - User/app/inc/old/form_wifi.h | 19 - User/app/inc/old/status_menu.h | 20 - .../form_main_menu.h => status_tvcc_power.h} | 37 +- User/app/src/main.c | 6 + User/app/src/old/bmp_file.c | 226 --- User/app/src/old/can_network.c | 165 --- User/app/src/old/form_ad7606.c | 354 ----- User/app/src/old/form_ad7705_.c | 333 ----- User/app/src/old/form_ad9833.c | 828 ----------- User/app/src/old/form_ads1256.c | 404 ------ User/app/src/old/form_audio_rec.c | 719 ---------- User/app/src/old/form_camera.c | 478 ------- User/app/src/old/form_can.c | 501 ------- User/app/src/old/form_dac8501.c | 763 ---------- User/app/src/old/form_dac8562.c | 762 ---------- User/app/src/old/form_dso.c | 1221 ----------------- User/app/src/old/form_fm_radio.c | 1128 --------------- User/app/src/old/form_gprs_t.c | 660 --------- User/app/src/old/form_gps.c | 457 ------ User/app/src/old/form_hard_test.c | 601 -------- User/app/src/old/form_http_server.c | 250 ---- User/app/src/old/form_main_menu.c | 571 -------- User/app/src/old/form_mems.c | 662 --------- User/app/src/old/form_mp3_player.c | 799 ----------- User/app/src/old/form_oled_.c | 483 ------- User/app/src/old/form_reserve.c | 323 ----- User/app/src/old/form_rs485.c | 752 ---------- User/app/src/old/form_touch.c | 1187 ---------------- User/app/src/old/form_usbd_msc.c | 577 -------- User/app/src/old/form_wifi.c | 713 ---------- User/app/src/old/status_menu.c | 390 ------ User/app/src/status_current_meter.c | 2 +- User/app/src/status_link_mode.c | 2 + User/app/src/status_tvcc_power.c | 214 +++ User/app/src/status_voltage_meter.c | 2 - User/bsp/bsp.c | 4 +- User/bsp/inc/bsp_timer.h | 6 +- User/bsp/src/bsp_fmc_io.c | 6 +- User/bsp/src/bsp_qspi_w25q256.c | 116 +- User/bsp/src/bsp_tim_pwm.c | 592 ++++---- User/bsp/src/bsp_timer.c | 176 ++- User/bsp/src/bsp_uart_fifo.c | 146 +- User/fonts/hz16.c | 6 + User/fonts/hz24.c | 25 + User/lua/if/lua_if_gpio.c | 1 - User/lua/if/lua_if_tim.c | 2 - 75 files changed, 1046 insertions(+), 17815 deletions(-) create mode 100644 Project/h7_tool_app.bin delete mode 100755 User/app/inc/old/bmp_file.h delete mode 100755 User/app/inc/old/can_network.h delete mode 100755 User/app/inc/old/form_ad7606.h delete mode 100755 User/app/inc/old/form_ad7705.h delete mode 100755 User/app/inc/old/form_ad9833.h delete mode 100755 User/app/inc/old/form_ads1256.h delete mode 100755 User/app/inc/old/form_audio_rec.h delete mode 100755 User/app/inc/old/form_camera.h delete mode 100755 User/app/inc/old/form_can.h delete mode 100755 User/app/inc/old/form_dac8501.h delete mode 100755 User/app/inc/old/form_dac8562.h delete mode 100755 User/app/inc/old/form_dso.h delete mode 100755 User/app/inc/old/form_fm_radio.h delete mode 100755 User/app/inc/old/form_gprs.h delete mode 100755 User/app/inc/old/form_gps.h delete mode 100755 User/app/inc/old/form_hard_test.h delete mode 100755 User/app/inc/old/form_http_server.h delete mode 100755 User/app/inc/old/form_mems.h delete mode 100755 User/app/inc/old/form_mp3_player.h delete mode 100755 User/app/inc/old/form_oled.h delete mode 100755 User/app/inc/old/form_reserve.h delete mode 100755 User/app/inc/old/form_rs485.h delete mode 100755 User/app/inc/old/form_touch_test.h delete mode 100755 User/app/inc/old/form_usbd_msc.h delete mode 100755 User/app/inc/old/form_wifi.h delete mode 100755 User/app/inc/old/status_menu.h rename User/app/inc/{old/form_main_menu.h => status_tvcc_power.h} (58%) mode change 100755 => 100644 delete mode 100755 User/app/src/old/bmp_file.c delete mode 100755 User/app/src/old/can_network.c delete mode 100755 User/app/src/old/form_ad7606.c delete mode 100755 User/app/src/old/form_ad7705_.c delete mode 100755 User/app/src/old/form_ad9833.c delete mode 100755 User/app/src/old/form_ads1256.c delete mode 100755 User/app/src/old/form_audio_rec.c delete mode 100755 User/app/src/old/form_camera.c delete mode 100755 User/app/src/old/form_can.c delete mode 100755 User/app/src/old/form_dac8501.c delete mode 100755 User/app/src/old/form_dac8562.c delete mode 100755 User/app/src/old/form_dso.c delete mode 100755 User/app/src/old/form_fm_radio.c delete mode 100755 User/app/src/old/form_gprs_t.c delete mode 100755 User/app/src/old/form_gps.c delete mode 100755 User/app/src/old/form_hard_test.c delete mode 100755 User/app/src/old/form_http_server.c delete mode 100755 User/app/src/old/form_main_menu.c delete mode 100755 User/app/src/old/form_mems.c delete mode 100755 User/app/src/old/form_mp3_player.c delete mode 100755 User/app/src/old/form_oled_.c delete mode 100755 User/app/src/old/form_reserve.c delete mode 100755 User/app/src/old/form_rs485.c delete mode 100755 User/app/src/old/form_touch.c delete mode 100755 User/app/src/old/form_usbd_msc.c delete mode 100755 User/app/src/old/form_wifi.c delete mode 100755 User/app/src/old/status_menu.c create mode 100644 User/app/src/status_tvcc_power.c diff --git a/Doc/02.例程修改记录.txt b/Doc/02.例程修改记录.txt index 2201e38..571fae1 100755 --- a/Doc/02.例程修改记录.txt +++ b/Doc/02.例程修改记录.txt @@ -3,6 +3,11 @@ 2. usbd_cdc_interface.h 文件中的宏定义移到c文件中,编译过,但是运行异常,奇怪。 3. qspi_read(), lua连续读取存在问题. 2019-07-07 +---------------------------------------------------------------------------- +2019-11-04 V1.03b +1.增加微型数控电源。 +2.整理bsp_timer.c, bso_tim_pwm.c文件 + ---------------------------------------------------------------------------- 2019-11-03 V1.03a 1.GBK->UTF-8 diff --git a/Project/MDK-ARM(uV5)/project.uvoptx b/Project/MDK-ARM(uV5)/project.uvoptx index fe455f7..f353015 100755 --- a/Project/MDK-ARM(uV5)/project.uvoptx +++ b/Project/MDK-ARM(uV5)/project.uvoptx @@ -263,7 +263,7 @@ App - 0 + 1 0 0 0 @@ -435,6 +435,18 @@ 0 0 + + 1 + 15 + 1 + 0 + 0 + 0 + ..\..\User\app\src\status_tvcc_power.c + status_tvcc_power.c + 0 + 0 + @@ -445,7 +457,7 @@ 0 2 - 15 + 16 5 0 0 @@ -457,7 +469,7 @@ 2 - 16 + 17 1 0 0 @@ -469,7 +481,7 @@ 2 - 17 + 18 1 0 0 @@ -481,7 +493,7 @@ 2 - 18 + 19 1 0 0 @@ -493,7 +505,7 @@ 2 - 19 + 20 1 0 0 @@ -505,7 +517,7 @@ 2 - 20 + 21 1 0 0 @@ -517,7 +529,7 @@ 2 - 21 + 22 1 0 0 @@ -529,7 +541,7 @@ 2 - 22 + 23 1 0 0 @@ -541,7 +553,7 @@ 2 - 23 + 24 1 0 0 @@ -553,7 +565,7 @@ 2 - 24 + 25 1 0 0 @@ -565,7 +577,7 @@ 2 - 25 + 26 1 0 0 @@ -577,7 +589,7 @@ 2 - 26 + 27 1 0 0 @@ -589,7 +601,7 @@ 2 - 27 + 28 1 0 0 @@ -601,7 +613,7 @@ 2 - 28 + 29 1 0 0 @@ -613,7 +625,7 @@ 2 - 29 + 30 1 0 0 @@ -625,7 +637,7 @@ 2 - 30 + 31 1 0 0 @@ -637,7 +649,7 @@ 2 - 31 + 32 1 0 0 @@ -649,7 +661,7 @@ 2 - 32 + 33 1 0 0 @@ -661,7 +673,7 @@ 2 - 33 + 34 1 0 0 @@ -673,7 +685,7 @@ 2 - 34 + 35 1 0 0 @@ -685,7 +697,7 @@ 2 - 35 + 36 1 0 0 @@ -697,7 +709,7 @@ 2 - 36 + 37 1 0 0 @@ -709,7 +721,7 @@ 2 - 37 + 38 1 0 0 @@ -721,7 +733,7 @@ 2 - 38 + 39 1 0 0 @@ -733,7 +745,7 @@ 2 - 39 + 40 1 0 0 @@ -745,7 +757,7 @@ 2 - 40 + 41 1 0 0 @@ -757,7 +769,7 @@ 2 - 41 + 42 1 0 0 @@ -769,7 +781,7 @@ 2 - 42 + 43 1 0 0 @@ -781,7 +793,7 @@ 2 - 43 + 44 1 0 0 @@ -793,7 +805,7 @@ 2 - 44 + 45 1 0 0 @@ -805,7 +817,7 @@ 2 - 45 + 46 1 0 0 @@ -817,7 +829,7 @@ 2 - 46 + 47 1 0 0 @@ -829,7 +841,7 @@ 2 - 47 + 48 1 0 0 @@ -841,7 +853,7 @@ 2 - 48 + 49 1 0 0 @@ -853,7 +865,7 @@ 2 - 49 + 50 1 0 0 @@ -873,7 +885,7 @@ 0 3 - 50 + 51 2 0 0 @@ -893,7 +905,7 @@ 0 4 - 51 + 52 1 0 0 @@ -905,7 +917,7 @@ 4 - 52 + 53 1 0 0 @@ -917,7 +929,7 @@ 4 - 53 + 54 5 0 0 @@ -929,7 +941,7 @@ 4 - 54 + 55 1 0 0 @@ -941,7 +953,7 @@ 4 - 55 + 56 1 0 0 @@ -953,7 +965,7 @@ 4 - 56 + 57 1 0 0 @@ -965,7 +977,7 @@ 4 - 57 + 58 1 0 0 @@ -977,7 +989,7 @@ 4 - 58 + 59 1 0 0 @@ -989,7 +1001,7 @@ 4 - 59 + 60 1 0 0 @@ -1001,7 +1013,7 @@ 4 - 60 + 61 1 0 0 @@ -1013,7 +1025,7 @@ 4 - 61 + 62 1 0 0 @@ -1025,7 +1037,7 @@ 4 - 62 + 63 1 0 0 @@ -1037,7 +1049,7 @@ 4 - 63 + 64 1 0 0 @@ -1049,7 +1061,7 @@ 4 - 64 + 65 1 0 0 @@ -1061,7 +1073,7 @@ 4 - 65 + 66 1 0 0 @@ -1073,7 +1085,7 @@ 4 - 66 + 67 1 0 0 @@ -1085,7 +1097,7 @@ 4 - 67 + 68 1 0 0 @@ -1097,7 +1109,7 @@ 4 - 68 + 69 1 0 0 @@ -1109,7 +1121,7 @@ 4 - 69 + 70 1 0 0 @@ -1121,7 +1133,7 @@ 4 - 70 + 71 1 0 0 @@ -1133,7 +1145,7 @@ 4 - 71 + 72 1 0 0 @@ -1145,7 +1157,7 @@ 4 - 72 + 73 1 0 0 @@ -1157,7 +1169,7 @@ 4 - 73 + 74 1 0 0 @@ -1169,7 +1181,7 @@ 4 - 74 + 75 1 0 0 @@ -1181,7 +1193,7 @@ 4 - 75 + 76 1 0 0 @@ -1193,7 +1205,7 @@ 4 - 76 + 77 1 0 0 @@ -1205,7 +1217,7 @@ 4 - 77 + 78 1 0 0 @@ -1217,7 +1229,7 @@ 4 - 78 + 79 1 0 0 @@ -1229,7 +1241,7 @@ 4 - 79 + 80 1 0 0 @@ -1241,7 +1253,7 @@ 4 - 80 + 81 1 0 0 @@ -1253,7 +1265,7 @@ 4 - 81 + 82 1 0 0 @@ -1265,7 +1277,7 @@ 4 - 82 + 83 1 0 0 @@ -1277,7 +1289,7 @@ 4 - 83 + 84 1 0 0 @@ -1289,7 +1301,7 @@ 4 - 84 + 85 1 0 0 @@ -1301,7 +1313,7 @@ 4 - 85 + 86 1 0 0 @@ -1313,7 +1325,7 @@ 4 - 86 + 87 1 0 0 @@ -1325,7 +1337,7 @@ 4 - 87 + 88 1 0 0 @@ -1337,7 +1349,7 @@ 4 - 88 + 89 1 0 0 @@ -1349,7 +1361,7 @@ 4 - 89 + 90 1 0 0 @@ -1361,7 +1373,7 @@ 4 - 90 + 91 1 0 0 @@ -1373,7 +1385,7 @@ 4 - 91 + 92 1 0 0 @@ -1385,7 +1397,7 @@ 4 - 92 + 93 1 0 0 @@ -1397,7 +1409,7 @@ 4 - 93 + 94 1 0 0 @@ -1409,7 +1421,7 @@ 4 - 94 + 95 1 0 0 @@ -1421,7 +1433,7 @@ 4 - 95 + 96 1 0 0 @@ -1433,7 +1445,7 @@ 4 - 96 + 97 1 0 0 @@ -1445,7 +1457,7 @@ 4 - 97 + 98 1 0 0 @@ -1457,7 +1469,7 @@ 4 - 98 + 99 1 0 0 @@ -1477,7 +1489,7 @@ 0 5 - 99 + 100 1 0 0 @@ -1497,7 +1509,7 @@ 0 6 - 100 + 101 2 0 0 @@ -1509,7 +1521,7 @@ 6 - 101 + 102 1 0 0 @@ -1529,7 +1541,7 @@ 0 7 - 102 + 103 5 0 0 @@ -1549,7 +1561,7 @@ 0 8 - 103 + 104 1 0 0 @@ -1561,7 +1573,7 @@ 8 - 104 + 105 1 0 0 @@ -1573,7 +1585,7 @@ 8 - 105 + 106 1 0 0 @@ -1585,7 +1597,7 @@ 8 - 106 + 107 1 0 0 @@ -1597,7 +1609,7 @@ 8 - 107 + 108 1 0 0 @@ -1609,7 +1621,7 @@ 8 - 108 + 109 1 0 0 @@ -1621,7 +1633,7 @@ 8 - 109 + 110 1 0 0 @@ -1633,7 +1645,7 @@ 8 - 110 + 111 1 0 0 @@ -1645,7 +1657,7 @@ 8 - 111 + 112 1 0 0 @@ -1657,7 +1669,7 @@ 8 - 112 + 113 1 0 0 @@ -1669,7 +1681,7 @@ 8 - 113 + 114 1 0 0 @@ -1689,7 +1701,7 @@ 0 9 - 114 + 115 1 0 0 @@ -1701,7 +1713,7 @@ 9 - 115 + 116 1 0 0 @@ -1713,7 +1725,7 @@ 9 - 116 + 117 1 0 0 @@ -1725,7 +1737,7 @@ 9 - 117 + 118 1 0 0 @@ -1737,7 +1749,7 @@ 9 - 118 + 119 1 0 0 @@ -1749,7 +1761,7 @@ 9 - 119 + 120 1 0 0 @@ -1761,7 +1773,7 @@ 9 - 120 + 121 1 0 0 @@ -1773,7 +1785,7 @@ 9 - 121 + 122 5 0 0 @@ -1785,7 +1797,7 @@ 9 - 122 + 123 1 0 0 @@ -1797,7 +1809,7 @@ 9 - 123 + 124 1 0 0 @@ -1809,7 +1821,7 @@ 9 - 124 + 125 1 0 0 @@ -1821,7 +1833,7 @@ 9 - 125 + 126 1 0 0 @@ -1833,7 +1845,7 @@ 9 - 126 + 127 1 0 0 @@ -1845,7 +1857,7 @@ 9 - 127 + 128 1 0 0 @@ -1857,7 +1869,7 @@ 9 - 128 + 129 1 0 0 @@ -1869,7 +1881,7 @@ 9 - 129 + 130 1 0 0 @@ -1889,7 +1901,7 @@ 0 10 - 130 + 131 1 0 0 @@ -1901,7 +1913,7 @@ 10 - 131 + 132 1 0 0 @@ -1913,7 +1925,7 @@ 10 - 132 + 133 1 0 0 @@ -1925,7 +1937,7 @@ 10 - 133 + 134 1 0 0 @@ -1937,7 +1949,7 @@ 10 - 134 + 135 1 0 0 @@ -1949,7 +1961,7 @@ 10 - 135 + 136 1 0 0 @@ -1969,7 +1981,7 @@ 0 11 - 136 + 137 1 0 0 @@ -1981,7 +1993,7 @@ 11 - 137 + 138 1 0 0 @@ -1993,7 +2005,7 @@ 11 - 138 + 139 1 0 0 @@ -2013,7 +2025,7 @@ 0 12 - 139 + 140 1 0 0 @@ -2025,7 +2037,7 @@ 12 - 140 + 141 1 0 0 @@ -2037,7 +2049,7 @@ 12 - 141 + 142 1 0 0 @@ -2049,7 +2061,7 @@ 12 - 142 + 143 1 0 0 @@ -2061,7 +2073,7 @@ 12 - 143 + 144 1 0 0 @@ -2081,7 +2093,7 @@ 0 13 - 144 + 145 1 1 0 @@ -2093,7 +2105,7 @@ 13 - 145 + 146 1 0 0 @@ -2105,7 +2117,7 @@ 13 - 146 + 147 1 0 0 @@ -2117,7 +2129,7 @@ 13 - 147 + 148 1 0 0 @@ -2129,7 +2141,7 @@ 13 - 148 + 149 1 0 0 @@ -2149,7 +2161,7 @@ 0 14 - 149 + 150 1 0 0 @@ -2161,7 +2173,7 @@ 14 - 150 + 151 1 0 0 @@ -2173,7 +2185,7 @@ 14 - 151 + 152 1 0 0 @@ -2185,7 +2197,7 @@ 14 - 152 + 153 1 0 0 @@ -2197,7 +2209,7 @@ 14 - 153 + 154 1 0 0 @@ -2217,7 +2229,7 @@ 0 15 - 154 + 155 1 0 0 @@ -2229,7 +2241,7 @@ 15 - 155 + 156 1 0 0 @@ -2241,7 +2253,7 @@ 15 - 156 + 157 1 0 0 @@ -2253,7 +2265,7 @@ 15 - 157 + 158 1 0 0 @@ -2265,7 +2277,7 @@ 15 - 158 + 159 1 0 0 @@ -2277,7 +2289,7 @@ 15 - 159 + 160 1 0 0 @@ -2289,7 +2301,7 @@ 15 - 160 + 161 1 0 0 @@ -2301,7 +2313,7 @@ 15 - 161 + 162 1 0 0 @@ -2313,7 +2325,7 @@ 15 - 162 + 163 1 0 0 @@ -2325,7 +2337,7 @@ 15 - 163 + 164 1 0 0 @@ -2337,7 +2349,7 @@ 15 - 164 + 165 1 0 0 @@ -2349,7 +2361,7 @@ 15 - 165 + 166 1 0 0 @@ -2361,7 +2373,7 @@ 15 - 166 + 167 1 0 0 @@ -2373,7 +2385,7 @@ 15 - 167 + 168 1 0 0 @@ -2385,7 +2397,7 @@ 15 - 168 + 169 1 0 0 @@ -2397,7 +2409,7 @@ 15 - 169 + 170 1 0 0 @@ -2409,7 +2421,7 @@ 15 - 170 + 171 1 0 0 @@ -2421,7 +2433,7 @@ 15 - 171 + 172 1 0 0 @@ -2433,7 +2445,7 @@ 15 - 172 + 173 1 0 0 @@ -2445,7 +2457,7 @@ 15 - 173 + 174 1 0 0 @@ -2457,7 +2469,7 @@ 15 - 174 + 175 1 0 0 @@ -2469,7 +2481,7 @@ 15 - 175 + 176 1 0 0 @@ -2481,7 +2493,7 @@ 15 - 176 + 177 1 0 0 @@ -2493,7 +2505,7 @@ 15 - 177 + 178 1 0 0 @@ -2505,7 +2517,7 @@ 15 - 178 + 179 1 0 0 @@ -2517,7 +2529,7 @@ 15 - 179 + 180 1 0 0 @@ -2529,7 +2541,7 @@ 15 - 180 + 181 1 0 0 @@ -2541,7 +2553,7 @@ 15 - 181 + 182 1 0 0 @@ -2553,7 +2565,7 @@ 15 - 182 + 183 1 0 0 @@ -2565,7 +2577,7 @@ 15 - 183 + 184 1 0 0 @@ -2577,7 +2589,7 @@ 15 - 184 + 185 1 0 0 @@ -2589,7 +2601,7 @@ 15 - 185 + 186 1 0 0 @@ -2601,7 +2613,7 @@ 15 - 186 + 187 1 0 0 @@ -2613,7 +2625,7 @@ 15 - 187 + 188 1 0 0 @@ -2633,7 +2645,7 @@ 0 16 - 188 + 189 1 0 0 @@ -2653,7 +2665,7 @@ 0 17 - 189 + 190 1 0 0 @@ -2665,7 +2677,7 @@ 17 - 190 + 191 1 0 0 @@ -2677,7 +2689,7 @@ 17 - 191 + 192 5 0 0 @@ -2689,7 +2701,7 @@ 17 - 192 + 193 1 0 0 @@ -2701,7 +2713,7 @@ 17 - 193 + 194 1 0 0 @@ -2721,7 +2733,7 @@ 0 18 - 194 + 195 1 0 0 @@ -2733,7 +2745,7 @@ 18 - 195 + 196 1 0 0 @@ -2745,7 +2757,7 @@ 18 - 196 + 197 5 0 0 @@ -2757,7 +2769,7 @@ 18 - 197 + 198 1 0 0 @@ -2777,7 +2789,7 @@ 0 19 - 198 + 199 1 0 0 @@ -2789,7 +2801,7 @@ 19 - 199 + 200 1 0 0 @@ -2809,7 +2821,7 @@ 0 20 - 200 + 201 1 0 0 @@ -2821,7 +2833,7 @@ 20 - 201 + 202 1 0 0 @@ -2833,7 +2845,7 @@ 20 - 202 + 203 5 0 0 @@ -2853,7 +2865,7 @@ 0 21 - 203 + 204 1 0 0 @@ -2873,7 +2885,7 @@ 0 22 - 204 + 205 1 0 0 @@ -2885,7 +2897,7 @@ 22 - 205 + 206 1 0 0 @@ -2897,7 +2909,7 @@ 22 - 206 + 207 1 0 0 @@ -2909,7 +2921,7 @@ 22 - 207 + 208 1 0 0 @@ -2921,7 +2933,7 @@ 22 - 208 + 209 1 0 0 @@ -2933,7 +2945,7 @@ 22 - 209 + 210 1 0 0 @@ -2945,7 +2957,7 @@ 22 - 210 + 211 1 0 0 @@ -2957,7 +2969,7 @@ 22 - 211 + 212 1 0 0 @@ -2969,7 +2981,7 @@ 22 - 212 + 213 1 0 0 @@ -2981,7 +2993,7 @@ 22 - 213 + 214 1 0 0 @@ -2993,7 +3005,7 @@ 22 - 214 + 215 1 0 0 @@ -3005,7 +3017,7 @@ 22 - 215 + 216 1 0 0 @@ -3017,7 +3029,7 @@ 22 - 216 + 217 1 0 0 @@ -3029,7 +3041,7 @@ 22 - 217 + 218 1 0 0 @@ -3041,7 +3053,7 @@ 22 - 218 + 219 1 0 0 @@ -3053,7 +3065,7 @@ 22 - 219 + 220 1 0 0 @@ -3065,7 +3077,7 @@ 22 - 220 + 221 1 0 0 @@ -3077,7 +3089,7 @@ 22 - 221 + 222 1 0 0 @@ -3089,7 +3101,7 @@ 22 - 222 + 223 1 0 0 @@ -3101,7 +3113,7 @@ 22 - 223 + 224 1 0 0 @@ -3113,7 +3125,7 @@ 22 - 224 + 225 1 0 0 @@ -3125,7 +3137,7 @@ 22 - 225 + 226 1 0 0 @@ -3137,7 +3149,7 @@ 22 - 226 + 227 1 0 0 @@ -3149,7 +3161,7 @@ 22 - 227 + 228 1 0 0 @@ -3161,7 +3173,7 @@ 22 - 228 + 229 1 0 0 @@ -3173,7 +3185,7 @@ 22 - 229 + 230 1 0 0 @@ -3185,7 +3197,7 @@ 22 - 230 + 231 1 0 0 @@ -3197,7 +3209,7 @@ 22 - 231 + 232 1 0 0 @@ -3209,7 +3221,7 @@ 22 - 232 + 233 1 0 0 @@ -3221,7 +3233,7 @@ 22 - 233 + 234 1 0 0 @@ -3233,7 +3245,7 @@ 22 - 234 + 235 1 0 0 @@ -3245,7 +3257,7 @@ 22 - 235 + 236 1 0 0 @@ -3257,7 +3269,7 @@ 22 - 236 + 237 1 0 0 @@ -3277,7 +3289,7 @@ 0 23 - 237 + 238 1 0 0 @@ -3289,7 +3301,7 @@ 23 - 238 + 239 1 0 0 @@ -3301,7 +3313,7 @@ 23 - 239 + 240 1 0 0 @@ -3313,7 +3325,7 @@ 23 - 240 + 241 1 0 0 @@ -3325,7 +3337,7 @@ 23 - 241 + 242 1 0 0 @@ -3337,7 +3349,7 @@ 23 - 242 + 243 1 0 0 @@ -3349,7 +3361,7 @@ 23 - 243 + 244 1 0 0 @@ -3361,7 +3373,7 @@ 23 - 244 + 245 1 0 0 @@ -3373,7 +3385,7 @@ 23 - 245 + 246 1 0 0 @@ -3385,7 +3397,7 @@ 23 - 246 + 247 1 0 0 @@ -3397,7 +3409,7 @@ 23 - 247 + 248 1 0 0 @@ -3409,7 +3421,7 @@ 23 - 248 + 249 1 0 0 @@ -3421,7 +3433,7 @@ 23 - 249 + 250 1 0 0 @@ -3441,7 +3453,7 @@ 0 24 - 250 + 251 1 0 0 @@ -3453,7 +3465,7 @@ 24 - 251 + 252 1 0 0 @@ -3465,7 +3477,7 @@ 24 - 252 + 253 1 0 0 @@ -3477,7 +3489,7 @@ 24 - 253 + 254 1 0 0 @@ -3489,7 +3501,7 @@ 24 - 254 + 255 1 0 0 @@ -3501,7 +3513,7 @@ 24 - 255 + 256 1 0 0 @@ -3521,7 +3533,7 @@ 0 25 - 256 + 257 1 0 0 @@ -3533,7 +3545,7 @@ 25 - 257 + 258 1 0 0 @@ -3545,7 +3557,7 @@ 25 - 258 + 259 1 0 0 @@ -3557,7 +3569,7 @@ 25 - 259 + 260 1 0 0 @@ -3569,7 +3581,7 @@ 25 - 260 + 261 1 0 0 diff --git a/Project/MDK-ARM(uV5)/project.uvprojx b/Project/MDK-ARM(uV5)/project.uvprojx index 35db5a0..75c4627 100755 --- a/Project/MDK-ARM(uV5)/project.uvprojx +++ b/Project/MDK-ARM(uV5)/project.uvprojx @@ -452,6 +452,11 @@ 5 ..\..\User\app\inc\main.h + + status_tvcc_power.c + 1 + ..\..\User\app\src\status_tvcc_power.c + diff --git a/Project/h7_tool_app.bin b/Project/h7_tool_app.bin new file mode 100644 index 0000000000000000000000000000000000000000..1500953e650e90a5119aa45a4619f5db10674576 GIT binary patch literal 600144 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

M%#85r4401lyy@S7T4@m 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%0Awh|jNyElHHN;jLt#L6M+UE=Y)IZTu zYjcy9TAP=+e>&bE5hO~#OizCT>7zRIgGdwAp=*8(`a!>sr*7$U# z$Ycc%cMIm1V_6U zrrm%c%X-?1O5+4sBRE0y>@X+LY}^&|J{KlyeK&S+R0T;$3Ir6yK*GyasQxiIgKW^VU)m{%48ck4#Tj0_YeDrf=zARht49*kb~PD-~a z`5?!01AbZChqxtVtox+Eo3(UDi0%qu6(^FN^DNkgkyurW9lx$t*g?T7;*!^q_$W#H zc9i07Xj6*iyjFX67$-g+jA567`RL{dUPK^D7pv7Z#9P%n$$Fcwg>I}Ax0q5f5Q-6F zNyU);N-d9x$B3+fm+s-EQynNj-O$!jiAbfc3GStO;>Jp<&S;jS`7cx~u_uE5pMVuP%ykVQEc)lTC5LinZ}Q-@Y`kPRH*2ES-WH};%(9lv~b zDPm-_%8p+x?Be8&fXR4^LNZY$s3W1t*sM*)oGCEoy7HT5ahMJwwYXoX60cjQkC+CO z%o0J^fjXB$2nW8T0Bdf4>rnW+mtx{A@Ld^_epn{T(XcXuV}(kmK18b&36@c&4!zCC zc|N48ym&q+mu}Nf&}mnKAMd=uGQwD2Ur#G+0EBQermyG4z9Ol==Y_s}H5d8D$FuoP zB*vNqJrZ^tNamC9#q%z4Ajh+mx5N(LGkupK?^AeXPB~~UY$iPtgRBKV$yTnHehpbY z45$x7)_a=QM_^l0vYx<%5mGW~A2r$3h!G%*W0nq^cAf2!a0lcOO(sN39vYSj@nyid zU#mNCf;%{R-Dx(|;?eft+^|XdLRgS4g?m}pE?pj;`$8>Ra*Eod%+*6yAf&Ue# zoq>BLvb!4hN^o-o_zU?3Kf}!u?OsVqwHbFx09iOt{e(+cp6vO?AYK{sNq26-{St;- z8nk;g2UwcXN5A9x*kr4lFg}^%J*RJrdIK=j4-9!ZhC*yX3PYh(%Lp$rDAd4^5tEJ~ z?6B!t}Bm+zz7I5Ni& z-MsntFmx6-6SC7VM0k0&mwuai2|Gkn-|D5`Q12DHHQF-nRPSRZIr2Mm;V_NSTQL~R zo;%}0i?db0?PXYHNH#!6X57wv6kn|E)|JmC1JZNJI*GM4)9xD1TjbSBt@5WsuIG~V zEMFZ$Y(2|Un*+YqJlLMmzFq1D9-fJCNa@Q&=*MA zVTp{7&-_3{$-`J>309@xJsR{R_;7weLMWvORZ$A7s>OtP48!X@CaIZ^XD87`KE1L^ zR4_aT!5Z|UQGv!hVKQ;D2l;(#V?H7oi`F&7btKOHT`(S^GT)Z z`DAq!@l7}9OQU`6H3yfE!mn6EzXxkDe}Mx}37ES)rc1m>R!iW;1%t9gT$M1O!6FVt zluCS?NpGSRuY)iC3_S4&{wj6eh?ivpcGx|##A)2wDtwO;kF;X$wZk$ZW4F<~N_<2z zE!E~$CJAau{=q#~Pyc(E9bekKo3%|O%mA0r%j#=W+%zA-Q{>c$k@c}e_t?nNp$Thw z7x;?_D@TlfvJVoZFXC|jOiDb4c-+U3f^ecCNOm^uyBX@nX%Y3JJ7F+`QW$(G&u3|1 zMH5sD+Krh)!g@AjRwZe4#S{5rXsBl=-Z*1HoX2@|sOMSk$E!(?DmF_t*`yO^{p~$i zNgZ-YB0`6Ho*WwLX~N&*2r(lM$r@Bn9^FAhxx#dNT$sF3wq1X5!-O*H^%H_NmA*~* z{ub7jqj49U(octEBP5^BVKmQTj`$9i;8Zgm09DmfZ9CJS8? zD}Fc0(Xh4pV%$V@1me}>E1sC-Xv%$@q^Kp!>1>E2uyy%p@Lt3&XYSE}$J+4vMu1K4 zk7dJ>My^s4SfVrrwkih#aYd-j^_SEx@i*3P^&hB>gKye+4!pj>bFj9TK^rq+Cou6V zbKw|l@j;JU`P6RAHsSlxw=Ce~R>S3hBkXKuz;4LniaT^)Mtn8kh)Vt9RX%&T-WRQl zo(?S#khf0Hi}PieJ1?Bq&+{samm#l$bd=YGykax7>oKv}ggvlYI>{Po|- z6_I|y^@n37*Cb!)38{jq9u?`?fpPR+0$Ggx052nd(sQu?Q7^qPVv2v-^A}jV8@uRM zuON*|>^SQJ%wc%X;~hu;oAzc&yjzfbcSohByLY)S^BsUSHQ}Ci zcga0N(%g!sdxqR|d-kmBD8oj7oVG^oHs# z+$|0zZ*d9kQ1Z*JTKs;+H6-OCZYdjb=OFG@S19>aEZ{@QueqX<6EU|Tmx!3#d9FJU zzsvl33`zYMSaPNkDBis<& zO1K-~R>6G)?h?2U!@UXadbnSL`w-ll;nu*t1#UImFT-69_bbkplMc8`@l9}Vh5J>w zUxm8{?$_Yn1@|_%tKr@bw;t{ta96=y2Dc8b0`~^EezO-&Af5TqD*#pB>C%H z`P288M3Vb*D?k0h+(`0eSaN$KHr2rFn*s~_GuaN{ErSJmb>87jfj6IcgKlQsLy?6TACCN;5E;;2j)OtD1M2*H`6v& zbr!yO+_k}axVX@A+;y)xnJZh>67F|iLtj`t7Tv&V@+aPML;jIHTT4HFub6B^m*8CX ztZ{#3Q-`LpLR#nIC8?yVg=Us%UK&lNnceRRvn}yom73!EJHt4+%cNe?!lFKN65mXU zt(a5y-}vbdf^!nB{Hv#9PU3Oy`?MqAos%f!{(p7|QYYqQ!JFZ$!kg2q)^WZ0_yO~? zO?fh4Oom0`$v6vl`~VBB3*%iFoK`Dmc%yUMa+^qR7gKq4UctS*Rthwi(+s%=T7-G~ z&kyVFV3@~ossu9o$&Na_$uly~KPVo19VDq2#K^DRN`jR|3J)TD14;NXo=%Gs;%4cf zmQRnjNYM_f^jp9$I0ycVI()I!CjFB9iF}+pA&5WGzeIeQrHKAD245CwJD`0>d(mVX zwUyyEp@MUJH^(CZu_Y1+l}nPOu%gjwop+Sm<6T~x!h%gysgweopEkvd6gJfiiFb8= z!K`D4Nheo;T~O$*Z8yFGS+SJ4r|1|gdM_O}7rz&&4VBxyxhlC){(`gPPpeY)k?b% z!E!MWR;~}UEB_t%lK-i|Xn#iSxBLw6(2$;kPEDMK{bJaIEr)ffu2GC7X2N#gkSIOL zj>py>I8|y>nyb8FlTEjaC)5q}SrB z`w+gAC)`h#EU@+q?D0M7lPvuAC!{B?^3KHw_(LCV!9PKA$+n~|`tt=-0$)nblunJ` zzDIfjH88Wpl%$s9)A6MXwjy*9a_#9Od0RsHufEUPV3Bq+>Rh5}qw#tt`cr!oM1Vaf zme>hx+CU>oq(9kh^EP2M^`_XM8rrF2_D6m!V32jY@R0- zV-BmS7|MgaE@tEs!Y?OHjG+#~+z*bKC7j;uqxemGGSt?t4LRaFK5t2WL0@C9{e_&H zu{KLOn1WhDVqP^f{!&dCCN)0y8722Jt zjL{cQnVBhNhO?lVv0`Or2~SsDBfi~g9{;9Q8(AS4kJS~Wr*8|sbJgqcU4;^8XVi%h zQB}?fA>ouC6^H+8hN(Y9F8=xu;W?tcbm3vrj<#r11@2Hb9h^`yl`A9 z$0(j-qn?99H#xR1nefz}&D%>BH0>b>ETQyXcjU^3(42ezDmII+Fv%WvH{|?uo;M@$ zi+-sAb|_;~gVmD}zhjOmo-bvGGu5nSeUu5=TdgC%nr-3zs(sD?bk_Fp{rOimNDZRL zP4;9n^3{yvPq}Ec37xVP)?QgbU#R~vpM3j1tjZs)2;_^mWdRqB2pIx?Ht>)k=q8zZ zq+^;YHP}6c98v*60-mlv586FCw6!|44D~J!%@(iMp|GhD$Yl*?{#v3C zGdHu=@2KgMJQS^+vH ztG4D0a7cFiFw1#CybW3p6RZ-IU>~NXy6FR)VZ_YX=THq=v&4R=hxYbn;Ps}^o{X@g zOK@a2H!eKfP7t%zi&Lp>NS(300u<#0J*mBvQf=}rJbB2;^E$&uZ)Y|?y70yKjx=RA z3kwXIy+6OWfviOD|0Qe7I-T(_t=Jg*KfJvQd{o8xKRoB`C7b&u1PLL8vq``O0mDU& z)!LJb%LdQ@qQxs4Zf>}Siy9DRL9jujhE`kfQbQ{(sK1s(sG!n>i;7z9E?`wI_3Wk^ zC5jse?B=@f_nC7xSprepe?PCdlR3{k^UO0d&)lDRX3n3CrYB!8YWDNG-(QM+L&@M@ z(nj|3x^2*@Z!}$u z0$MY*Upg25PhwgT(;ALxXBBj=ax3;m(C-(o!3!mKpdSz_A49E$0!Kou@|coSZm_vV zEIJ-F0((<<1L48+Ys#@|M*ZcMM_bEyk2R-se%aE84YAj=ZA}s@DKg!|Dpx49E;e`w zavz6eQLN|;CAx7vT1Qd1b?8wa)Ye*Vx3hbJuu5Kn;O^pYk;h@RWAG}0BGh3|YH@l3UXN$4Jt&84oY)%tenA-;+Xbg^ zQ#pk)ch%l3ga-wGk9a0eKP8e5^CT)%H+s}fO9g|R3cPO>(3`1pdL_mhVKYYRr|dCN zrtSEVoSI^zOeC|UClCs>hYbF|wPJktF9@3V#n?m#vqUR8%o!{>1ImY7C3x}{>y!!U zpVfqho;v|K%R0FDvBj#6fp@uMxty^&Kk>M-TuxUOE6cYom(whmw}>aI0I6C`yRWO; z4Ct+t#p>6JHubDj!I4k=Da6ZA;~~y*#K};x?r$?=E<|CD;@t+=O2G2Zn#&voAxkB0 z*%V%o9AXwM_4LL3#GtdA{f^K|tgToolj+Qc)*D9ta?e2M__C2d#SGu?K~rINVi)u9%zIO))Sadn@jSy=Vcs!@!Qnc zU1#bxG@UWG>P}#-^o_WoY~PFDrgTALPE7tLHTFzkU?&@}BToR%H&{twMI?O%{luZR zGlBMwyl>3FKO9R`gii(O1VTTq-9iAeAR^MK9HEclN;u_3_v2{wnxl zJ;%Og=Jf;iLbC z{i|Wu89UFH;AYY%4Li@+V?p0yhI|;XvJ<2af%QSd50%lNA5liJr_?gq&>^Kg&?qqB zxPTX%Nb8454O%IcUR+8?1iTD|GZK{250_C|R~g0eGFqJW5Y;16q58UfDgFBUOX<`P zl~O36;EjrKDXC}gMqAXC46n$<*>i$@*-or>hr@b@GksmnzWiqDC5DTq92skC1nl~* zt@$qSN~Z|S6h<6A=)j#tv^~h44DA6I=Be1pr`Ed}ni3-R`C%W6_Vb~O7RHO>cu|Cx zZ1ArQDm4cG>Mm?F(H{60)1BXinWo`I_8SgomOs#vS}kssY$^Wib~;m7w&a0@GfS4C zb*b+U3Yn$oUtno61gpVVvzvEg_h(5lPCTRRDgMt}>GlA2Ch-=s-fglW501{j4y^lV zUxxH8;`rP;7xv|x={PAX)*a1p4)PywV;IF>VJtJrM&DI!(#+W?u4D!Fhog1tL_l`zEk@a8rKMR2SFx9Kq?#*+joNCh2Vf_lmD&Y(D`}6u^MfX z|J!fBy{{@0eYsS;60Dk4HJ|O>HjCC@LxPSO^fxnDg}QwmOJ)P1L zTB(HsM?2NO-}1lAzbB}!;BMi6LxH;?KeX?p*JO8HC)=F6FC7q*23gsOcguzJi(pGS zUqD@^qYapMmt`{815NQSYDu)qB;Q!u3GU9ofwnk%qW@sqVeH?VmNi?V?Rm>KT2?P( zP9e^SGX+*5#OUq9144P;1ED}EG}~zJ{-lwgVQF<63RH(KuG`yMNfNs2wtuU0=9vZ@QFx0o;4>js@^3Hxb3Ns!5<29pfR>+tTgvKm?DIR+h(}ffAh0wB8 z|23gHi_mzpaJVMbuLF(gAt^c4-`Sb!zbm8w)&k${fd3ToW!^0o9iA5qJcl_|J8XX9 zOv>W^T9=hppmQE~xW6{Qcd!&+bJGe6@H>c~ZeCi!V{`9@E^p_ur(0iY-qpIc`42K+ zPKuRQlJBfR4+$$2&g9a3zno7nmZ@{zRgyoC4U0W4I;WK8H@h^*=h~WG*G4)2Hp8IM*AVSXyabC~gr$B(Ip10E z=nOx&!WLsFXZNq6UxYU$VQp3KpVgX*y-Js(52PKhTl!zYZO!; z0{Eso6&JtJsq?=_nh=XA{n1GO-s)UCbVl&*FXfo@M{^i|E%Yh%l}g}3KO^$3PeC$5 z@1OG@BCd7*FF@y(>LHiVIo>c-k??*l&Jg5^YIY^;KtUo_!utOkO*x4=j{$GSVZ?T= zN;h5IbTp>P6cY@XTdEpkG3#ST?%NCf7tWdNXL6V~o%9#=CUgjl^pOvGp501v(l|G61j2QO(2)}`S$3t8PwCOv$?*I zaR%+v?$mw(OWz6AIX0Z9@S6J~Xmv2@TS$Vz_Dv}pf}PTGRyivj?iSoj#CpEVFGu(t zJ;5*!vj~SsmB}%YEx1>P%YT*8UtZ_2-|NmhWM_zYC9T$WhrrY^WaXyU;LltlT zikedN(}f{_HO)H(you)Pr*E9HX% zj1@nVoSre^5BRHVie{^)M(09*qCC~s9U2*SDfIEFEIUyVwhQ;hM^KE3ph$c%MX&72 zZ#=>L4~1YCugHY=vC~6z${-u`*))Gp%X?~9dFyz26GpLC;y0qiCu${rE#_c;t&~4B zvk^ZzC637LQO>XOavr8!ua$FUXSkd*{;P5Z-_WcuEzv1zEgs<|eI+1Ny8f=xC0#Y4 z{C`!x>wa|kzRJt@-Oh0N&WAqceGOE;v@gk|EnQ`+%5sYGG%wjR(7-a-Ht~|h?nFp$ zlh1aHdNN;kN+&&uI5g8Ct4AbBkGOI3Yz6eHJ?pq6t%D>z7E$l6hRRh6@_ zB;`+a7=?t(%h+z%C7W_$_j!4G@$qfv+2ki`Hi`e}Cp7-{p*PKJ$c;*W+uiBT;;6>e z?A`KNMb*KW!}z5ZrGFk=yLvl(rlx2?2*#EDqCEQg?$F4PalM8_^%}A`{g+tn{!&@5 z=o^nc^w-Aw6W=)DQg%a2su;Xh6;A}OuDr|fdXvWM^%wE_sVkDB|2?l^F87@np|BxC z6{~G-`ZMTlM1LONk-7r)nu2j2y-sqUi25@})E|ZJuep3Jm8Cyk^GEbG%>PtJSl-5V z&>ncWJxdz}=sJnnL7c=xulJ%}G)0j$$(w=^**1P0ImXpqJXrY}uDyMz_Pv!KER!(j0;c}{Kr}yo{ z>o&gOxO`d=6k;LOO`1foB45b?9xo&aWyqc?6uVGyjEl7dT8r+&HBWum2J3 zoAw;Qux?u-Dj2Wum(`NSDJ!>EV;5ruRz?2bba8Swc0-5{;$cV+9R3;$?mHrl_Lmlm`?m!vCK*jc$?)p=5YW$@2y>BGPEIEgcJ$Q>yu$C&;LY-^k7vU3%huX)_D9_$Fh&%_fP!P{%oGcag3E6pRL@laXS>R@xYoM z=Qa!P;*=ow>y|t0t1ApNzTsA&PPzv%Co19bV|SxBk)S^ZG*7|Vgp)Nznb?TyFs59C zF$Ma`K_NCCdm5y3@+$4NWDiloBlSS+K3!&4eNwRJL z#GsU?|DuMd?#llsA5E?Wl+}*aWPXNwG?)3iJULwEuZGNzh>-bVKT_tYJ*@6^OlQvh z-xDS*zkCnC+gLAQ%)geOb*baL755hcd>m58c|Yb=S0kS^uZo4949%;GunPda{Ic+m z^mZ%K&jj-EvUj#tn>WJVrUfPQ&Oq$=D>>Ma9)njWXmrnm1pYiorP?2K^~zt<)tdSS zdzF1PY3##gFFTmrLmCr)t|KevdHdu5??}7EISi;ukDE< z)9MQT9gpvK+a51EjCn2H>oh&UYFBHr@u+(hmyL%#k8s&|1hTOrLN*?XkPU|=I``6< zn>yF~|5Glw9QGnJ6t@3+!h{u(awsS(m4}q@d_tSGUW9RR*y`^I+y6ab!o!iNUQ9FZ zd%{+KPuTwN2@_UcK0W3?(Gr$HR}1Ytu3ua+c1)+rUW4ir)*Z6#os5iy?<4H;?coHnAKt*ZezP0J87&^ zXUoqJY|sw^G|T@E+BDs>V&!G8r9loInEj@5IqVNP>>DA6$q{lms~0)MndD{VlXODD zxi++{3<5OEKdaX~q<&8x zX7|QxZ*YHSFr0@!1k-sQ!u*?eXMz(M`aoH3<4L1+G(Te>W$trD|8$2n6V~Jtt?97e zJj8Q_GRr#9JsTP<0~PG82D9PLX|cdfYR!NP?%ei7xPR%u zTgQQKI-}vv4jB~z`qwBmtikSr-2l4Zs>+jSiyo#sj=rW$;M$G2`%&A9lQTM5RBD<6 z@3vYggzIL~S?K_~(eVoxL$6D#O6t$`7>frheeIROWYeU*ea3I9Fgwo#9!Af7bF~4d z(3!z2lmxr0!j&FZRN;z6?)Bxdc6mirzUXcq&fHPpa9N1q%&5W@*60-BXSKnG?l}|f ziiYJ)U2XLyan!5GCWf$Ty8T#^D%s{CdPz`8Dr06LxBJ&Y3`eU#$3?`Bj);A^Hn4VTn2uTtF~ehz z3nO$Ms*M#Gl@w^>GzA`LrCK3vRGb^_4g{h)1!*H@@3LK}jDpX^bZ}!CK@%B+o4_^( zUsUw4sX#Q&<)Kb3bdDA}i-)r2RdW7mmRZ7arfWF&YB+a?aajIo zbLKRTbBBgARl}LWaS-k>Rua-6Xm4rY{;iY3P`uM`UMPbWDHl_Tt~m4b1&y^cciFd{rc zd{~Q$9w9!4@X%~66g?J&S|q#t2<&-i!0k)* zrlJS*rmrsOvd=HmLr;tL7;%0Ljd41^PT}X*gK>UMyEbp}^J^#c$PBhU`3&c#-v%az z==8cTKfPv5J--(1fj}HiS8(?HzWUZ#6wYZs2{IRSLk4fP{oeLY<2ynWe`|WR{up+o zZ%(U%%@KBFoAax5+Wp(KxcKze=rpDGu-uie)SRthm9ow2jPh4>C{Amk;;1UM7FLy* z&YK;q(Pnm)x@zn<8$SaTGxn~JI7*rIV-Fh)=y(oeq7x&Tew(>~=@lxO-mGWjD;!nNHz{a~*rQk0Lnrr_u^&aj$24aqD!23)Z2S zb;K#@3DUTe)|9NT$RBdT0Ud89Noxejv1E|qSV6Wo!x&qE(f5RcSn;PEJeFgP7ck)j zVl0tp-6>VAhQ>PLJC;a9srEg7!WPy+j^9gry|hM)A$=XcW3>@}@>Q*FSk2=hra;tq z>;|rZP1K1m^FG=oCp`k46g57{S-^Ce&&rz$$N~$!tea%RZNhO}KR|-*n{jmh`80O! zb1la0-voZumTGa@z6t!Y4QKvkah1ieL?4a4`-IA*%H+yE(5yA$D;^q*uChepN$-O5B|S>>Fg!< z%vf4>&(b9`>F@N#OUp{9KQ#K9#iOsecH~UPSkCSVbH`NIG|7u}?hQCg(>t?DHk7if z7Q18Tva9Uw4NkqYzT|__t6uYb9XmFwVB$Rd=4KV(Wl6&`t=rD;Ze4eNV(F`LRzX}T zehB%y6F>N$q;L596zH8ZODF}=Jpt7IQ1X@XqiJ12=Y8da(ySlm<$L+~o5sgW(C7R? zPKeSaT>L_bo!j_YxNHXeFh5ilJ$ULa7l+2rJwMEiMu#a;N|-B^&P^zn*dOMjR~|An z9@3Nva}QSkC#9mMpTp08htEgbo2ks87f(&rMBMWr3u}@SGb32yQ4GNvv zrFzdr9b#eoHUGmtkB)`=c{IQ)Mjl=Hn|ZXlV#>L{$n; zllHoyveafqJDb)f!MepOixbe!4q_%7gOxn9wz&}#D|uS+N7+Mx7_8(m+GruTe_WP; z7I_jng8xaI{2cgYoNv-d%;o*XgWw%Eu*)vb^*7+!2%UUcjH-0$pk4nP;ThPB9bIZm z1n+-pCEowNI3B#uhE7KeVDEMktYNVUu)C2T+&9v=#!d>j#vG5G`VaXw@2=dLYZ1}Q z4dSJ1;-zaq>BgXB6DkucU*xtXqIvHY3wTte4)+I$Q*lQUxS9e^<+C?i62X<3UdbIT z?1%-tvxDH{EzyAMgD(X2m}XI&kI2#{nbl0Gs^luDQ6nL)ptcV+l((HL+i{{ zJ)-(T;O$nrrLa9e`ZKajn#V{M1<0bhO2C-l%#lsif`rowX-|GV_7=}#JP7^KZfV530$5Q|&C(l_|4BKKJVv&ooXh4X9ui1-iK?Vl zqe>r*P)_g<8^K9B@H!+!?cqO3o8}L}KpMZBNb$mT#;&wueMEN0ba+Evt(gM56>BgF z`U!bOR#+yv5KwUHYg8@-PPTN}^KJME$AWb(2drwsBFMF%gO`!eJ3)$aMq|IMszT;A zjJG-?Z5VG|-)+O#va;KP@epn$h1F)$Jzu0=$6tVu_!|$jVwC(6+X_or=^Qe0FTv0o zO8i~)ktPrJun|vgcA5Kdj40TMQ6bEn$RY8ZW2`J4v0A>CY56Ma%GaX}`pA5_b8Qba z&|8i_s=OwJ%ge6OE$pIux~sfooWOULmw#oMr2^$O>AxwjR9HFeDz9eQQG(KmC@;*e zE-fz?Y)s&#?uhbYtVem#jOpU?niMXtlib4mg}|p>7UsLli|4DWyi}VP36KfYNEvo% z9aLWoe$2wKe-XB9q0`zdS+mgD&j;4=RRUBH$vzL}eRwgm))YFG9HnQ2Rv57cnK|6t8^ zHnU=AiX*k0I0v+zW|=D6f-R=D{_H@FBLjYp6Nj59#s0LI=(d=aVt-7`mbTWG;?uqr zV&k*;y&O|~y8dBZ<8u$kG`=$EW+xoohDcoDQ1Mw1D*EdD)jj|*uY-r4Jdw#J$ zsw<7UrYI)V=#?mGlge3=0L;TRm`mgC3fp~fXCUxKXPlISKHz%HRY&9RHI+HrTLM|3 z)au!m{?z_E&=WGD($!}~rLa91_^LCtdcGwYA^khBw}+WQD#Lp_yv)%?WRs(>9p_>W z2J1JgEPY`8CZxSPO_qUL19h#b)lXPN#BXUY;C4fLnfJ~tdtmyKWi$Ddmz7Z+$!wba z|6osy_IF?#yAFMc%&PV}Gib(gK5!7{)KSX$KrQUh_q4|=vu=C5Brj=pvWLAA?+I<@{s#)$Lxl)3CYfyezwNoz{o=4&~UN zjlbP7@1Zpt1LvF1oo(`ecjnt~8c%=yRl}EG{JY-gRX+dMsgoy;fA;Ao|NQva(IX!B zKR){K?;pJX-r;xOdHc}81N-Z0|F-X~H{aO1=k>qt-t}5d_0GTi`Tt&h<>ejQ|MbUg zFa6>7TdQ9D-3!k@_w1I{O7AbQGcxd!}@pX zYwP#aSJ&^Tf1!R;{kr<)^$Y4t>ZjD(>YwmE>RaNQ_j#vy3%u8PuksG^_VGq}+m!E=dgT-41Ep4Z zP5G1Zobr_N7*15?DbtnPlyS-p%GFAi(hoNjLk-XN$kVQNedP@ePXlU;$mxrK<}^Ij z1Nu8a2REz-bX)}PdO*_}*7kr_0GinFD4_NT+@*l(8@i&;wsi>jBLH^z|>N06H-OcL1QT zetAm|Xd0k@RK@{%O9ZX~(C3u=9#B1?mCB8P-Wq}XU7NmgopN0d=ovs)D5C%^j==p4 z&_&Ad9?(w#ouv!`bW#NFK|t?REIptH0KHWi0O;fh-2Vf#0O$J`Lth0n7ZxQeVM(OB zt^O9!5!f%k82TGPTj~vf-WGwo8qhQKs-25KkFZA&rqrJWbZSHlC!inKf71hcKcMf| zHvoEj1nv|-YwNu|ppyaJReuuDJ0fsz1awFJKYKuL0Q7hD9zcH{fjb1yU)O)o13DPc ziu!i|ofd&>2K15ox*pI(K$q0N3Fw^>xUH@F%KPhg_kgwldQbgMK<|pc{WqYK>tF5x ztq0UrzYWm4BXB@W&~~q zpc{PD#v`Ev0d@JPjn9g}H39m7kJ@-7Gz!qUK5FB$BXG~Q=qsoDsEtQLn*g2aqc%P# z0{0}KMLufdk-sGb;et!h+JAjVyQ5%nhz743=M{V30fx8pXfj(;EkETB<7YU7d6Er7Or)i&OOu(=U2RwL|;x48$@1!%qZ450HOaOVN~srTz1(7Awq z=&c8Iegy9AfFAJvs|R!{ps#yB#VOn_f$T?AdmYNh`1&jVdf9sf{yp6PlJ_6*zrp># z^Zp(Fx43_^_dWRk#{IwYz5{<9_dn@92>$`@f81LK{~_*od50>Q*w;*f)m9@$)V&CK zhlecn{uTbi+`qv48vO5b|NY*b@c*6rOT7OF|3}<^xA$fE-Q0h>_fPO2;r?Q;0eAG} z;zcJWo|Of|=8F8e$F*5ojjmF+87C5z&`2(;GYb)4`^^ltANIrc16E9%P1Z;G>`vb& zbCf)3`oc=Ac!e#jQ7~7+`qoDLaCZo^u$P1S%2HgbzkKL6gx&?)3EiPWMBFD4Izd_9 zOXx2UdLv#@?T#x(#9fHc5z0tqZZF|Zgb!3^M1<-hVizMc0k5cb(~b-sk5F1kzO01H zk4nqK{53bx(%UJk_JU>>)3mu6%ruE zE&9zSmw*>jNJBpnTE=-v&a{pBOWdE!AWE8J^FEO$RPqTIc9#86M85Bj~Umb$mW z0w1%Mxdm&pr`@Nw&WEmsV4dq0t)+O){IsXjXRyw88?Ce4Keg6-w$y)Ub-2f!EU?~( z97S92ahu`(>WHXptWWjjdO!cl?7vRfpnFocQTI#TQ)rx(4BAHYywq8Dcs}s0^&LRG zgVs6jL)NVxx9^?YDC;4fZ*5`5iZ2|TvO29Y{}J~iCt=ZSNmZjLROXLXp7O2smHHO= z%0T0B-*djFe82KN?|azyzVDv;pJJ_XWBo4g%ib#QZ@f=pEm7`W=$+-g3u}q%y;pk& zdk1)vu$t&l&M99jpDXVxyOn2@P0B`P4fL~?DhrhRl@jG{WkCI6_b8-#NK18|JL{wy zrB`)fKlZN{p=1}LG}n4w@%5?iSN{N3Hd*x>efRoi`|kH8`1DxU_`P3xPkN7d4`XF> zF+al4GPgK%ky|(PU!MQ--FhJ~r6O%pzT}QQDGZ&Bka_N{=WopmT+fDnH9ijbV zy#lHAN8P>c8K5K$C7Bca3kDAxd(ldkL2D6qGuGBL`B?3F?1SjzzJc#7v{%;FG{EP_ ztx0{H558~hZ2j7rQ@+K%+k9j3{k7eNkdNUjZazKB;~R-JS}|^~tljVdVDzB{qgceU?2-vnQWx5azj z+vNS$`?dEA?*xiHBo482Y#o8&U2%8vxMU^GJko#SSH3kIk5V!6RQg>O^Scv|_};X; zzr7-6=NU(gKkz!VewX=PkAUm}WS*}EkbWA@Hb7?h{u}}MBOrJBb^wy9;rtqqNxp3n zkf#9|=c@vwzlO6KkehtZM?ls9a*gk|fTU|UivSt!`*j4Q43I3}F98{-;oJ*In(t%p zhu%Y2{gS*s=iTIe$h!bC^NM$?_pu1v$-ve7RsoWs#l8uUHt&iE$j<;d>wOTAK^o3* zK)&`aj)05+MDZ>FBu&Ff1LPC0GXgRIkdM5x02!d+m;ia(J3Rst4ai&Gy8)3joD1!G z+iTuCA|L@kUiMA_#G>K+8<4HuTOuG|0J7Oz1W2Zaa|Dp5yoC{vqkuf_l>y1paOwbg z#Ct;oWIrIwyw?FTM8o+rAoIMVBOrePWQKPnAXjQQ&jWI&cW4CU1wbZw2Loc&aGn5U zoL7o~YyjjYZ#p2^8csPN*LeFyK$ZhC+}j6`!5YpSK(f3E5s>=7&nu6> zy75_MrCmmgKclSRE&sGq&Rh4Fc-xd(y-!(YU%UQu%v$79ecTD9%ILn*NrKJmIT z-M;pTUCMp-Lr+vI_t^Ct{*1Xx;f7a~JJEY=SEktyZP=#VVb?$Tdxh2B4jrSZMeA2! zt|qOm*#gL9d)~wBVWAPWscSaj`xa>3Oe|WzQpKnM#BR@fggv5SxbR&F{h)%P^$)8U z4*??E^H#EzD#jvw-w0mj;qP_O9J;nBTB9`skkR)2E1^NeQ@ab_BO_=}!3?JE(Gf-K zA5|%jSBBa1R7l@EkZ?C4|HFHeQ9qdm!9xV#U1!S)3E+T{tjts@slV^-I|*5w;cUJq^8 z&Ol{{AmKI!Y0lN&h`C9yfn?&IO*-6N(QzG9+OO5wVh~1FaRe#O|336@Ro{p3u^*B#jMgfz3Vo*Bu)EUZi2?>~ns{l>a3y=q+YtP0VtH zQwsByH7FJD1>HJ|)z+PRPsGbv7nG&C(|LVx%2}vCy=GZfK|d{4pN!u(3E~+~Y{u3m zL1@6K+{Jl_n^1Pc0B1q7YfSXSvKuc=DU2V^qj}$2*t>QhpW%=&PvP${CX;Y?XMk{`q^8#f8*rXc_n0XLRxG&j!~E0R z$X$W6Nvq9(o9AVCpH59fpftow)3CKsO22^4xk|k|Mlxc6cG;zIhI78io+$Ir>Ef$9 zW>T*)6M4)e9oTge-S}(C^&JK(fC!_ z$!j%^hphnQdL_<)Da?g1RgReVyrH`U`uEDsAfA){oS!={$%*iEYOgUx9y684ys;}L z+6*idn4FVl*qxO#JYS1?3EFc~!9@IY1@5_$Kg3cC+%s^C4Z2Qr7F}m5ZeFo;XWKbH zq-6|i)18H82k$e<#sHJc#@XjF;G-24w4Rl0Xn7qY_r0& z7Vm_%BWsI-<_~PevF%NQNyjOXW~6i8-FSnS&N!W*s%PeEy|jI1Qv-bo_!97Sx?zgl zm9u>&$y-T5! z5ISA(xL`#XVfb=Q2QFI69tw3J6c!Ok=W-{7c^Y$9=QYh2~l z@7fTKmg@<+n5zG)w)aYh=WFPxK|@w;?`Z2zaiS!ntrNw4bxLPQ#EXmv5RcwpB)T|B zhu&6WV1LlMmvr+@i$DJk^$hnzM}e#hrPzcabYoU6 zX=pEFq`9VA7-4jaBVygU5vi~P$%gb(oS?QUXxJ>lezuu^l?RQRB^SNDL1ByWCC5;x zpy-FtTq(y!R_BNp^flwwVEnJdxChIg(fr1-W0)-uBY9)sLeTZ*xjPn%AL@#5A)XVBHlpH^b+*_h@uS4iLJw6 z6Og!lJt%|Qzaf2AOPmq6uXm+%{wVd#Dz_=%HkNbyCtw?t(}Ax;6avfB;O>R4IA^=K zvvS^W%PsrxJbmM&K8Kz8>F$9COk$hPPxZ>}ZQ0q=x(dBrtY8)sr2mUx?!HMVX0olS z>M4x^2c%7lJFX63K%zya>M23{i1f_(dt_>exkrc$jVd)n?h)eZ3L#w`s$Ws+2WxsV zxvsDV6j_CK=}7-6*?uly=zzsN_~YRZwaeTeYfsHRhc%Ilf0_7KlNM$KUSm7ouT^!X zV52V;wlV3wAExJeYuw(As<%Qnzs=7w|L=mkV9RwMEbFLNYZxg15jH~q*r+!N%1ez# z6YTS!_*0`HT2Qt%MnxaKIqtY%5jRP;;Wh*2E;retY=c@W{D*C;QKx^*7fwOD9#&pM zImXJrM0^=4e{U0>DL!2U4VN8|4VmdG^<=v`HiKJ<6_4vTKUQc^3|q)jDxGsYRw!=H ztsd0+M3eArWexFa4`ToC*-bTo`RQ9mt65W6bMwEjx_OcABaCywnh(tnO~1R!mT4>E zcI}2jbC$`FB^TYT$BRu@8kL-6=D#}VuYtw);Hq?eo58;)zxh+u!XZg|x6Q&(;9Mv3 z&u;OP^+Ol^NR~)mNNz~KI)QqDtTfnnw?d-M;(gQBz+%|n!t6mzt9E4;Pe^m=6j$ag z6P`;?bIF+#_}}L;(p=1slc%9Nk1LZx^ol%Gguejza%O%PR=&}kaCyw@Ip%dg0&^tC z9PuMCvpHtwkHGBDF;jm8W+KOo{}Gsaj;ZUyq`sbHxD5SqT(vMf-Gkeo6|iSeQIQ{Y zJl$@nz&+NAG}KC(-QXI#_gbkn@Ifbo`+Vn>3Vj{wtb_YZr=*C(1-A|q(8pBZ^-Q90 zDi#!=>05zU%3RT)pc`)VP^=xDRd82y8aR#LcRKL3w6m7p^1bhG2*^G^`OwNF%?gTf!|yBk$p@i&q9vL!fp)g^2!oyLAz3<82?Q8 z@5Ad^;jp_~sWdWqiJt5D3H<4u2DsmL)WE$0x{0lUh7NN7-9e@9?HB|1U)(*>@jCqa z&THU)-0>#d&W`?Y|ItA;66_#8-|IL4_iTp%_h83CxZiXn!`;_$2=13165Q82-hr!h zB*LxkaKk;`@eUcc`68QjW_ zsc<)TOoaPHM=IQ3aQw9$vGA|%7zFpxjx4wjcX;8x#3?_(DKFtUUBoHR=afr%F6MB` zGdl`_@93Be_uh`H;oilm{hYf~d0r-S%C~k{5c&|Ov#et%{EK0al;k`O{WQru&9%|j zIO@#Q;{cM&WV-)Eb9USea~0#odJ5<5gZg)bQyXz)9I8R@EPWdo-%*Hl0BKPQ650oJ zw_zhvGC2~5>rXMf^hO%PF-jEwN~SOLQ8Yh*uM8H{?QuC6`@jXW2HmMrwEAwP-I`-? z8u?p{G;6{=WYEQJKctrotBYm(OyDCwBj3-a^qY|8IG)mXg6W1d$CUImhkQZEOmmp6 zx>M%ysiTt|CdCAQ{Djmo{avCGOMj7W^!T{Z$xgA^HH8gBx|xOv<}qmw{dm()lAW1; zK@>PWyz8OmH{NEn%jHrvjb_Ymg3UzL7uC|z;NC*Ell;>S7!$0v?*e(SZ|aid)0l9c zzM0w5N7+nLD6kzb*4bfaTf_`{zI#bg^ds-#wZ2eb8Z0R-!Y#)`vfdx17luFLF$4P+ z*k&ySPSPmCv4x^+v5ir-D6Bh7)fnH%x_L|v(u!@FbhF?#WeW=IvpGW0*S!a~s!iO+ z_;5FFKUbS9)5a$~25aP&JH}6bjMZjfU(F=Jf|d*WzeRQ@X*;vp@fk@Ocm)AIlXMGj zm#ntvl2BS}l6~@1(Ap=;`5I-JQ&vcy_{AH+b@V{ux)GLoawBq<>LGijpMg)}{LjHP z7|AHF145(Y#KxGs5#yO+RFYRDjdmlp8FnWB*+6}%e)u&WDz}~0gk9H})m1KUbcO;i z;}$dVGDzcPpvKFdh7kJZRNNb#R86sSVf%*S|GN|ROz~II;w5SE618~GHxSmw&X}%L zet}dT(y$F0wob!dhq*J=KV~!2(&EHvI?UH;p9pgkynFz@q)yDf$QFD%%?Nn;w(_!X z#knBiK;r^X2K%G%SzEO_XwvF{P7g1S6}8!bS0H#8S_q|7uchSeN=e}XT(mSKwyGbJ6~X^>4l(|kuu^H5is2YH$YdZk8bzM-YLw^yw0G+mdZxkF3yPhDyL zk*B$>S89~z3tF1b_lnh>X5A%e!onG^#V5MbT+h?2=#?6!>C)0%)hkvwP2EK`xmZhW zQ8+cr0=t0rx}aA&l-evUwVAzQg=O+ijsDNW^rhQ*Zf@^2Ceg>q5XNg(JE2#sZmE~G z6mIHD;io)>8+(mQDU8)p7}G0Odmy9rD)cF0<(0f2gIzsvbY-vjL^VUBIGc-Gvvl%W?TCog zvnPOVK}0%dwRD<#jX^Ie$*1!er!RfU^YKNm*my}jlD_4*-IYOd_F1nnRQjty--tJW z9-$XC`G~e0V-2+KDHWNUMb;ZDKc&8O)YP4^co}FR`lqH`0G!Ce0qNw zUaIY?y#u`Vw)2#?_ezJ={{EtrpVv};uGbipvR$UV7rgl;8Sw_HwOUXry!R?5(pGY8 zjF8CxO~25cCz42-jXj85=`gA+#l8XF9NCO@t!1^$HdhqTR~{3j3Yl#&;cIRY15YNK zOn4Sya~NwD;C2VeD~&`aadzC@j<9QtdcV8Z5};U9v~rryPH(5y!~dC= zwQ+M@O*Az4jGIMRHZyM4qi^^l=3W)AsXc`AH4ExXDR1L=-p2Kc)15b_Fy%;homy_t+Ryb} zb(+#}4a(M%6CQ7KG!Cxrl{#^tj>;Pb|iD4opLrX zrj1S}$es)BQ<5Do#wPN;8{9s3mRDmR$m!s2JnX^YHOEI^_(k*B$146Oq?R_{sR$@uQcfj)n#hMm22z0FUmAn(?X(_NL3o5)atBV2;_C7*;8(E)X;dZC)4kfUmARFo z^pi>vDX*SkuwDXNrja<>1L#8t3;nr zDNFXsB4~Athi^iq9{E2X_&rwW>DB+TBq4=sLkaeixPvd_EIO{}B<;7rQbsCvXXun7 zitpp7XAa?Wil)HMwu!I_5N8*soy5J|9`{6HvqrtMOSS;z<}wERwT=v4LIQ&=4+mMr zFr!>a7GRN6h7P;e^L9e0pKEA9*Au$asVHe@9|}{i$yNv zgZ8c}pwq*^h0bJ*_g3Fg zU3{UVOe#^F_`BF7D?AsjafGGkSb7bsO~Y#ASac$+VwpIWNy7?gSOJa|--Tu7SY{3D zI}PhQj)hhVTF|wD{Eo#h7rz_v8-%?$l2y{X$+Tx7*Sq$j2d49+xp`-kl1#F5??A+5 zbJv?qa_(N`E7f)di^`yD&~ z+!?%SAM`inozU4MexUc3DOL=fusJ`$y%QP@vFsS4~Ado$@G_r6YwfY z2EO`n+!S{@{7LQsa1*#2>rR8;#9f2CKl~zh5xZGl@&RIJ`dzw-r3I(;qUhS-JUAn^ zLbom&c(Lv{9y1oM!A-8{j)5z9VxQ1GE@Tyy&`2W4RGy3uv*Pg6<6FkB5I?&h=Rk)~ z$kw+C=k#-*FVN4>&lOvR^TXlG*@qXdYk5gy=aAYQuV47JU8hW=Wf@Mr=Xa8OXJ=nK zY%}BDK6Bz7yb`JzIRo}_9HT6W_Wcej`S>D|fH*Dz7XoWSWFI7JR4n?BD>{rQ?Ohx) zY?Kj@_zu%PKkA=&rS?VTJ_+MmL_hJs(iyX+KUlhC*#jl>r_Wrp;2sW`Icw(h(uK=r zFPT#^bGF)tAdlI2T|3J#cd%bD7-oob3!H09rCWx}*?yfq-Z>m4EQ%YQ!wS-GfqgZc zh7aI>W0f@iH%jTx|LT-f{57Jl&h(qa4}qWQ*NcgO#kv#Vnz(Cl$HOmjH_DUM>{^=D z%$D9#dR4(j{0bavOKx%AJX1vZJ{9T=sr7S7opkYQ?&3F#_-&S##XAd68?rNT)VI-@ zf7+0ofz*iSf&6c*qUM3ss(E0wl!qvfQGpbJXNr;Omqjz6v2JorZpwjyyCTm)G;uu> zT+h4(QnyaGk-IAA>p16lxdzPt0PoGN2h_4YRGRHC(|471Gh4zr&%AtTvs$&Zp(zmN zyqV45oM&b>yJmb}d2`Nh1LwC9=Y~GSxuH*i;}FXHZH;r3^`&h9(g7>na|buOZa2)( z%`J2uD9vnE@~H*JQ<-HF&5ce_8$-2=md8tuT(ms6B6szk>}FTtEv1F0*QFFX4j@&- zEFEf^;lInKn+3U4)4hhus?b@mAj@B-i+5gCkO>P{@#~RxKBW>)knp#*vsMPjngzcgTwg6Xi=38bHfqhh zqyo`7*`bDrT_LVf2QCWHcZXQS`H^u6zXdiRBVhtZzFAtFb|X?W*N$ZEyvn zndsVJIsL8uyn(a;UY*CJmx6QIOF<|Z+AaiEKm$O9)7jJR4$+$Jej2eYcnOp2U6F2~ zwVL7(KD}V~H0Wk_h00p!Tpl_ss4ODQ6XkxQJ+X`SSEbO6TZOfSN(Xc$(8a4i4$2X| z;zw5DL`8ya*cV%gBfV|gJS)Cx@Fh5-QAd@FMQ4&jaH75-A)<4WL$bJnE6l346wx8= zPi|?B=bvaTZ{_+}6dyVa6rbWOM;uzU;iZG%{4zB^W02c*PgXg>=k#cgRGPbY&O*cK zD3;@LEOezi<`|S^HHE-Z!1Cx1W}XtO zhFe=TcPG8{h0(`STIDnql)!qDw-mOR3{`Ut1;oX-mgGzYU{o@fXdIrwYCqvLvOWK_Ge|}*OSPuB z4JYl@CTk2VNcZ!^D3Ue7ZM7zQ5^%;Sn8?+eV&Tdr6I>Ifvar}|65&cFR@=|}Hm5ky zbAVHfVn*u~{6?Y97#)|GjC0B#q;X!^t2#mPm?)u4DPJ%X%Z97?mc*wGzqRLaU|Zm-qR!{UWqR`F%GT^Z)ayiGj9&8 zJmHP(?dJjyg^Vv`DB||!Kt)jZLVw(6o{DvB-8tDTSEp+u>x5GOP#cK7~(*8Nm?>J?10sR=S69?nZF#rf}|-dVZ(;%!@hs zv~#7Qe}tMtNz5$BQ)$jyh7LhjRQ~iC?8#$D)7AC|{58d`;!~`ot6M zJr`*0gx;8~t;jKVRM1>E!*&C7->$cP8JJ7{H?_G8t`) zQ}4=yHRR+u&e5cuZWFeA8JL1G>EFD38aht}Q|lU3iaYNDhQrn$6!VDUN|ssG7I%Zt z7FW&ML^IL5FIC2^-(x{NQfFB?&^B1Eys3N{7z&DSqMXkKj)hJIlNtG;6V|#O7+-b%{ChCUxs>hdFmAbZyaRO1th&vQk^Evh zv$^EF-l^MC_&r!tl$$h(sH=vZaxM`+u^*PN`=0cZl|m&6b_xb5Bh~U|Ba1G_LAEkP z3%~NR;VDXn7LK~gyBvkc+9$jTkn%D_(B z_h6{C@^!m$%Z(A`-II=5E8leJwv726tSPV(rMA<$>S0=~3`MOBxg>p2>8D($3|2^b zR8A9=bgfj=d8zm0AX`b%!uwt}JVlA?Q7b(uMAnLFb2M46d#Y!73bsvrPJF$m8uQ@8 zdvSvRV=0@IQ*ENTY%^oA&dm;kLU5Yd#yV3SdvIzAhP%#~W@?On6XJ^4p5LvL!J^9a$-oEHKMu)9g? zvhZ8e!)z8?l>N&3T zPfW!MVt+72#GMOZ(Cj|Jb}X1WWfa$k8`l1IFiym`Xs`Y_sE02-`F*G1yl!#jIHKAe zhYeoMZ-e}-P2hiTXj{YoUe`vkC*fozJ=u<(PWsaMKgF#35PYQZM{AsqgQ@u+2h+v! z>ZgND3|V8b(h)Mr4`}iRr^U8;TnKY^Ci1-4VkGFi+iCxIEcTuRTS3?NTRpzZdwhd} zX0JBU#)e2M%l4vASSn_!+?&yd)0diu==NAe&I*T#?c`TO+S^Q7x=b~P7hp9$s?6X& z&_+3;{F(L&L(*}|lsbiS4LL+vy^S({8)4E)nWso}P@RH(ajZ4UV^D-lW04gr)-6F=J9YhoJTX?lWjZVosbVE0Cq;DP zEa?#b?h2a4$7)tvtdLO?%C3#)nPgj(!Y|bj{!m-K6UQT5MoFgQZBGZ=1vmGpfm@}=+^4Nhsg zcnet9#`xdWZR+Yd0d#aow^=A|UR!3E%mx}JUxn9~RIJajE~b~a^)>^?VYnC2pSQ&$ ze8sG`(7vc)qOh&xi<0iR%Xr!pSKlM<{Rp8w9lE=;7A0X>PNk%l5#{)1ew%kdR|@gA zuTVaEHCs20FOXIq3!0N-@EUvNID_p$g=C!gT0Pfks{ll_l$J%I9i@o- zBOo)Bop>>6thyGB?K2?jDwWQ7jm~h;A-Yd!-`U#t``UN9_8n8IrkkRDkJrBA!tu3l zy+VCq2sfl)DWEnBp*ft(ym=~@X+18)aQ*xr?BbJbcaL9eNP9Kq^!<>CH{xZM>-tG~j%{)J zM>WHy>N3N=7$qerTowLeU2yajutgp2x#*72)V&E+qJLy3xmR`efots)A>CA?W{f-3 zqT{R43r$g_a!47;Vk`3fO~cJorW8;4iNuN)K3Fopbe2>&8?Ug>mYgLEXU(6DB8tIJ z&HYgH1(MhlNRDWEVHmZUa1QCNEgLx%wB86BP=tC$Gd=A42Ob2p*!}4 zU?P{{I-HJEE7Do@9xl`9Zz{%7TBc4K=>%(vhw|^k*hnK?JdY)p+O=2)9&3~>zf|qn zsHCax)LX>&y=geVX4%Kcm(Dr{yGClh=&zhs`Ft64JT23?7~dhl2^hkLWwYA^$fwX8vgwy`yKmd)CJoM4)Hqw zcPGZ{#U^`GU}1|ZlUa=1SKR!@62YQ_--)s`gSuX(cYNrM_mQA9TELj*vPOFZ|0-73 zSf|(VcYM||7jAEM!Opjru||S5H;6nxs;jn^MD*bq7!5{a1+V5j1vwAb2<46}JKuot za4sik;gnAqCkv{yd>WE1#myCE!eoNcco7PG1ej%p+9GH+VXcnrttme==j{+yqsGGJ ztjd*%OGsU*#K+A2kdq43ka?eIOIk*lk?rMd;9j&dbwr}N(4QB}n161N#@S{;KARx1 zyGf3p4w^*fAH<|;!D@1g*guR_fV-F^b!tnWF8}D(_%8qImMDxD6wie|2fN~Y6pc(x zEweMI9d)du@3Vnx!I3&jso%N$n{wNZ+;#|hDV*o-J}bj!@UIfkrg2wPFxwnsY(MEL z^LEguI*BP4%f^@Imu)D2zg*WSX6CzMmycggzBR55%irg|11>5bng_8VDb<**xe&r5_j;DF0T_`6mJ_w2E zsnmGCMY;s@w9!dGDDYw1wFGlvlVd z%Lz8J4SGkwOwcg5M5Hmh?eDl_9tymurSV)_c%+(!mm2BcTUh_(U_P(rk7jT&o=fL% zp}?cy){J&W)ZDmv7M|g(Zc(}SKBfb)i*daQ1jg#O4WQ1 zwDr+^w)O6T*&Ca30)=FhIL+PDj zE~i+&SC4+sUah8bdwWlcpCETC#iu#N>mw*$1s*AOsunvDcP90`cQtwd7YtgvG!T}6 z5ej{(V2;9Cl{mbvBehzPa&fu@4LJInsg6qL$HWZV4>YR$7DY8y)NSeFad zxRcZp!t?j9D&)O4@jLeq<9$R`dUHWf^^H;KX}wNlze=)l0An|e7HU5*VsEC+SY)gU z1s0-AVf&;=2fwoo>rUXLex%F3qhOL$uxR0&()$?`ZOL70&?mJuOq{Ko#>5C3wjMN! z!YUD%(}r8`vZ4CG+Jq(w`XNu>)V`)$%Ki)PXEiuH

&8*bDNT}Gje)ifwOn2T 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

D>BP1sm~Q*voQzi!k$&yk5JT?JA!+ z<%m1~=DZBl6X_z4#+Wfw`8JfB+?AzmjC{2RsbUm2`oP)YcJ#mT-K58!BnJ^If#mvC zU$fPaPp;2lg=FojRnp4Bht^Als~=oP;ucz#?&r#y;7fRwSg0 z4g1#PHe!9)&V(mf*J07?F$P<_nwpW`Ayt=K(uz)^{|M=thSSiR06l<+d%lIoG|q=+ z307qBj;iq_lY5HSlYBbpESn#6c%u(%tG;T{cUYLeg-Ot$hd+A;#*c>zS1yHAM08N5 z%74aJ=3sSmfjk8(IB|RhXO8c7%iu?BDD8A(BhBajsQ5C!&`W*97T8A<$de7pj1O^?CZxs+9gXAh>xd@8RYXtb%3U@ z^F?KN+gOr3M#YD3k}1|`7AvQWoB(M!LeU0EV|l{ih^i_twVoDZ4p|yz5p+LwgLO(N zvsd~(G}}d+(;sB~94+UG*`SnIWdv3Z4;AHsCo3O*x#pmpJ%6By&25caz*XFH~@t;2-xnRQN0oZ*Oq{GmQolJ6+%q zTv~-p6ImlNn6!BwvmDaApbYTsMm+EkF;X@CtTB`;~OO_TckruC7y=vXs;)ghVAU!2n zv3AYi)L~wohOamY`?FT)w;`Jr)F#nff}=K>(`kSd+}|b{nE5%-CduJ80R`Dm`{8=U zHLn^6mo>F)K3b_DXo(E-B?)|KLQ$0ROfOonmP1DRE(oLRik>_l&CYuTiL6*zrpV9( zB^OQoFKsDl(4MeLM6DU@gQio&S6g!CMm}>G<$hC!jkVDNW;sKZ{XHoI?l*ccDvNV1 z9`Lhodh9hRsC9B532J2;)jeqG4|}VUXf2%Rvnpwcot+qd*fAo{sFQDi9Ob~+FcdOz z#sJR8d#>iSt_SUf`5)o@82HI15V@ZXT7jSDQp0escQA{U+DE#opD8SRnnnWA1u_G(O(RZj^A{JuH5-9t6j@2 zV3Ld^+8p4wxAq#``V@h?zv<1YxdHPvqVx&9TGSS~hrz9L4+Vu#PYO#@zYPj0UTe0C zpr3bptsS6m;&EXfz-&=y#i!ll_Db$Efw4W>T&Z*%w8k&766e!Ezj7vOV~O=lAP;kT z8$PKd>eJu`XyCQL_V4Bm zv>spm?WPS8zN$+)OVMGyTy<%vWlBvXv`j@q@$fksHlEh@W1c{SRUA^3&_rL$K+SSWA}N-;wDd3QRG@iazs zt77W)7U_1CFPh|bUWypvPo}ipy~H=6!xr&1%A(F#NI7ekuHfsM8@N95BHa6j#V+qM zH+^3yuq3F3juQHQ2Ff7W(xg;n( zpcU_mvSQ4lV@djYmF)1bMXQ$hVY zy4`DH%H+-$c`n17UO+6;(ZZB}cUK_HhFCT=*4>@YAY`~n+q50AL>|lEy%k|8h?Szo z8rB7!QYc}Eyb-Z9Jk}q&e}=Hph&5V`wY+mZLPnVWM=nJytzGgPQL?wY*B~?%@lrFY z+ZSc5_W0ULGnDp4iN3Z+DFp9F$d4H7$ZwJZ?V$&dCed_QUJ6V)U@`#Hlih^~O+&mi zj%gt9f#0q)9TpAm0v5dSKE5leha;gpL8GF&xt^z%*aQbeD?h zP8HJ~DyG*%*+^qGt&*LwsxmH)i(RrU5b*&x*EtP4BlKH_@#YV}q~l?rjxq z_w4qy-MhP@ZNb|k+K<37Z=|81k3fs)*Zu=^3V5Mkc8vFnbK%u1|o zFHTh2^G((5MW~_sLdnQ;q^SbGGoXw2+hv}s=1ZLU;8c?&4?{VP_Thd#%GuI21o7?o zVmmN+f#J?j6he{_lB|aOF%*H2Q6?kOIjwaEpt+;OXvb-837UXw|8!1zR+9>HW~8g< zb?EFNy_{eC^=5vaMZ`%I=eFUVjpf5VWIw5*O@mUq5{DpUh#Deh;LJy2G(w`)5P{;D zA`k+dA3PPKI4F-NLk_g|DZokJOLsjiM=1YqkSF!0{``*qD8HjW%J1lp@;myI`MviO z`K{1}^F#kdS==7s88=Frjqei&+R@tJL^!Ad;l4JuZ906@)mXyrsqjrzVdCy<;k#Ca zY2MD2C%`{J^=k)Vgf5I{GW%0)v%_caPqjN0zEl;a-ED);Q zjeu`NKXmsn_&^mLrr$jTK585K8pGQ^O=sy;CvShy&P-R@>)s~1CJNJ=D73nLnaYPS zexPl7P*+4BSKB8J^q$MJrf^Gt*Gny3*=D3%wtX*`ZCBf$ z=xz6|UHqI?33xKjD$bAlrp{TL5hvqk9a!Jc(Ni6FIMglcW6GmtKsC!wD_5+ehHu0TPe6H;P@ zM$%NU7ihe=5ZD)_^FyQ~GracVK+O4AdlQt*poqBG%SC)`1!4FwsH+fO5Z-bi9V`#4 zL$U~+(KmHHavrxV|liy!IU zX4oH<$E+)kx%IlDm^mMG2fovHYp&30I3_#A7R+DdG1as}=ffQE%jm?3xuQHiF*vk(?dft?RJ~kI`s?K~@=fwnyw7;N zm-@0~`7vfsZx5&T*bDfZv=8g?v0eY1#YYntam0$51WuTw_~B^ z{xrwB0&)^st z-avR1&NV-av(L)`|2+7gKsE0AJPh~#F64f2Yc(t@L$eiGiL&7|lhMs!ImLnPe_6@mJ9r8W{Cu~ZE6!)wW?^f=&UR>0 z{|ntLE?Kv5N#Wu!-8_SM3-GfXGzKHMJ zq1mC|QD!sj5cahNzU!50oR=2aVnH$6x!*eT++k*Qz69qt$X^dJq;LqDa&4(cmqoCXY_ zf!-e26LC_{(ZTm!PlPh7i>QFpx`gtA4xpD#xsmQ51gY;og?feFP0`#{zB-b>kFPd`A#1`o|J|TZSz<%S zQWo@*OMvSx^fuyuG|I|BywsOa^S(`sxOWnVgsK8|ThBZHl@C3*AU;Oz-90{(p)N}MA(E1l(ytj;9xJ{x1s+cb{R$_vP@EU zxvs!?SPR#sz`uH|M=+Ak_xx6q>Lc3bv^kd3hLNT9*P&wkKCeQZs=R8Tc8Q{l4o=ff z(A0zhxHC-EqNIU*7v}RiNw4zyDAfJS-Ng4POni&@+l$>;L0)r@1#(!n!GrN9Ncwpr zMjE|?+9(obCEA|CoS?1IiP-o z)3L%LwCtjdi;gaub49iZi{V?maq-c`!jkMI8(!jEQ**}5j(_v?76)>6AZG`1&hj|^ zS2?GsIoo*7-LVGbycc%LqaY^{tt@~%|H7-O+bvqRCOrNVEtMetTKus6 zpDNqIYbFcMEpV6P_Y8hz`3NfzoIBzEHGWn2Nz3|qQY^j^wjCKX`>HY!?3wbh4V=5c zly58>%$1lX%*zv}oDalwg#w3ruhM;@QJi0LkfjcjF}Akm3O3BlHVPguxye;N;PRC4 zu%L|*_ta*cYrrZ)(VQ!ft*-9A)Zt04?kL;9P9({mWc0I?g2IB~F)5_GG|n(GI(qg< z=q`;jBu7Wi#_ox3+^GBSz(_1n%!)#TWGSTeNm}a&1rmEo(BEkOM`K{We$$)r{g#8B zfz4g*frg$-fe3Ir=u=MD`N4OJg_M+w7D%>C!ulqoevCexs^vDw=XZv=eOOiyu&#>} zrL$r;Q*3d5zkjakXPD0=U?tKYN~ocCOGuRI-5O#?^!cAXrkhnTFV_9pWBJz44)|A_ zXijVMuP&KMV@Bkx=YrWb^X$>Vi7e4gZcXba;#_aoeVg^m1Dg?M&k!3}3c2WvTHQ9> zyFPe-KIUn#s(T-#_-w58-#aVT8|#Kd4>#MvYTuIYQe({HF+}0Effyo>u~RNkW8BPR zXoXn=F|<6!R@tM*$l)=JLiRumBaiWjoUO)~#$#CiFV@}!KC0^OA3k^H&XUO_nJhp^ zLbwSDOdx>?Y8w!663Ar&YH(|*8#6#;CTw9fR4o&50j+IlU81dZLR&@c!cb{ReJHqV zt50XdDiWyIx(twNZ`fug%gp=zojViJw|zeU|MR~3A#?6I=bn4^^IN}1m@$&W#&fhN zGg3LG^Bj`k7|9{=9M>z;Q#mH{98SSLlEcY!%vC0*a+L8LeqsDb4nNN^T_M~v>W{IM z12@TzN#{VA`lC!KPUW!i9Bf_oNDjtx*l?%3R)$$C!vl^->(g_750wF`g!Xl&Tg>Si z5qm$@0;6+)==l__%SsTYbD;wN?7GEtx7Rk%fKmdx!fG&*y1wR z(MlEA<|gxu^jg(&eWgPrE=NWqKk6bc&;BSi&D9oQn@5H|Ds$H&*cZEnbr%CxuJzR zHfN+4w3?HQR%_okQ{_0>Wfzs>^G3K0dxSSam~vEts@H0rN3}l39N^`&9TZ{8QNSe+G`bd^!!H3rIhDgN zQ4YPbwagayIQp~UIzE2{r%H6r#c~B3D4+uTBbxsIlYAi={mJl$(J}GOxQql3(>LAk2OEBcbohGEF-(*iBCAo zvi6*aPDzxM8Sy(Q(Y!F{FT!tfUL%W8@r3itsN5^jzNy2LfIIjd`1&NGGZW7O=VcuC z2W~iHTQ{j|M}sk}rBx%XaIYFEhYcs?txGhbk26E`*BqLMzXtwS7n+N(K0FuwI^PWI zYW};t#_~?XnVc;swe1h!wDu032e)%htZHT-J ze&j!#`(Ke4{U<)Jjmy$S`AMz?aNb|hL#KENPH~crg+5;ijZ<+^#}}koT4nKn;fEfg z9+KKI7I;iTdP`E&Qi0V8M`dIGIv>bW$gmLg&qWNJ3u|uSgS)1We$~bKKDQL&nD0MjZ1Fx z-L{q}qk8W(!Fq2~X}!C)M<}ar6WWC;A>09Z7S7lG&p~&`>?^|0x}N1L@{?%&AbqE@ z_Gx_QeYD8w!0j)fV|RnPe$g#*PD$8QzX=*f(6Pep0w`QRDC{>`$5K70+~#xsYlzDB z$7a|B{H=pfseaif(Fcd9+{l*XAPca|3#*5P5YNX)Ds2kk)+eu5}iqJux7a z=QWwo3#<5^FkEXu?2kAf&h>PX&MAHWKk@`56Z9-k$plX#pY$NnxNq}$?hU`?dMh;_ z-sYv}*T0FVJ-WqX#~W-k7AB{%q6F&?o-m)M3uUm%k*H%yc_fY0r@UF;}zl)k4;j`k0o_55( z7&l3N)ZnYDcO7!w$lG&w{aWPuP5i^?nFO_Gb5kqY^If#(r&zf^tY3lDC*v^5|=yGu5Zu(!(^clRRFW1k-SH8_#>O>oE z9mAG?d^`8Sa3Q$E7))nAHSGvcB&3%O{HPea=KJnck%4brB>4HBp} zw;pMBq`k@0KB=FGv~lRisYnx%R)(|}cv@fmc%ag?q|thV{|nYzz(ecp(^y-1KGxeO(dYRNn{f@Tw_{vB z!`GWzxA^Y=!}Uh%Qp9?bvIMT9%96!uV{hJqyzZhvJbDsV(20m34MlH_gX?AEAUE{0 zM&gATh3>(gLEP{djazPm9E$j5@W$Xkqx0fz2j~8eG=V0!Z6rh9nbK`O_>WX>sFu=p z^?0z;701K_lidqhESqt=ka@d9J|DetpvFbLZk9iVBw`9?W{}UeD{`yQ8`nWL0o@_z zIka3PiPbm`c4&$Vw6%LK`qo)ig}KPE>tcp`1WywHRXaRy+FtZD>4c@9MqfY=NRSNf zz;{ZUb}VCuMw500a|HV(v?QNI1AGjYS;ILljl=jjdOCqy z(9Tp{lZ709X!gu}_s9&JTqZu6A4fmn=guY9h{&-vso7e9_xwLTLu~uMUa!5WdNuKS zHU8Ur{fyV^I$p0!|82b<WA-cucx#Hzg8KysZU^!UsJTbUOYB? zxAsO6v}E_fhiHovH;=#?Z#m^P(3dib_tal|tSAN^UOmkG@Nr)V@9^{!?lSGBn#JG) z0^hoknw1{Qg+H>6|ful=L9NZDMv0;yIiqoffv`SObwLRuQ- z-dTJAZD3te5w-9nq+IDXn8O9|B*L5e26#^8tB(%q6#5Op#{Zc}+u992@(q$;K1|Mu z>pg2$kP$K6E9Qec(@45+gXDpk@fsKzZ}RXrmTuYD0^0}JJNonrgZ1A(qOpX14YSAK z=RtP+R@~I(_OWqpPr%!mvPpLb174@k787BWeFcMWX4w6G(n7iK7AKNDEm`tsss(Yp zH{R{h%Bj9`m4WNb(oaj|X(}lz`Cgm@y^5 zU{5NL=N;a&chh@ng7Sn1;E}z@y^&EXIYBiQtw-{k!|pO zw`B>0+)Z!~T)&CCjImXlJWHC^Y;0N4vYv;p-n4otf~;lDav#jlTQ+R?YS}0f4h^?E zZ(Fq%pZ#}V*L<&Nc03fD!vy=N&}ZIvPnm2l;ZETntq=C?hM)JOR#V^mZS^)gJlTFS z@R4_CvD;^!=Z4goG&S1Xs+|RF(q8*rfd=D=i|2;DXK9I^&xuQ7Z3iV-(5B}_YCfP_ zxHo7e+`-5np;^-ry&rSc^6bZgYg<<8+s`ecX=5XN7XS}$J6MAGJ!(8^! z#-}#gVI^n|KOeU-O40L_+I?l)D!i;(36te;KD_2&2^eM)Qw-8Jc!aXf>G0Ze%FlVN z>PIo5%n7UDW!PJ3zo2!Lg*-|dEOnOAEFA^=U2{;B+760mrb`)W_rQV+HL7n#eu-M;NQEx?l9swRe0cv1@_c{sXs=+%9Y z)!YbKO{N2T=M2#4={?T6zzR>Je0Y46gWgHj+T}cTCb!wA*cGsTCT{}@Z-=Kc?K>Cw z2XY_8a(ODgc|5v#$lG%q*ptj_YA@%WCdZ?zV9%cwoGRJdzMT8yF-`kqzM6=68tC`6 zIQhzG{X$+YCiG_kq(Hc@?F4y*)?p0)JVa|Jv7gf5QHSqU!FL7T07(5J3cNdR(|tTT z8`d=Bk)l(#3?;a4h>@3e8GMPU?XSR6k9;u551yVE!)uO}Q?KQ#*J2J#kQ-!uH!S-e zwW{kAKxtsy0Zzh(upB<_((1L#H-UhjRJmc2bldv1t2KI>9%ouID#gFzavG`b2K!j_^L-QNIoi#^d5xc*m@FH+U6>OuCCM9^{8X&! z$w9l^7y0RgO!LUzw02E;``&;hrWvCE%x)1>bbVD|^Q%b}#EQ+L-r1 zgDqU;75a?14|u!Dr&H%zY3j~WtKhF*FT*cO9hYQ>HkWvzU;X4bjXtoXJWE?vX`Sy` z1zY>&Ti`%+8y4eo2`5KtRbDg(PeCS3{e-obEbP%?1gz?P!)*uQK)!6Hv=(*7PJg?$ zrxQh1z~^ngDkKc{=^>$#{H5~L#|9n06T#Kg1-&H(Stl2uoMiN|#L=J#O+-4@#$$hw z@FP|niOuG*+Y|O6`BTv>`*2WH4CPd^RehT8pK8aFC45(BOO~u@xm^n)ysBjl+Cu%O z)s1GbRXsHb-^0}V_YFG9drrg?j(ie@^QDc6?R+HFA_ zPKbEe)($i;@H}r9{mR_J_6?rDU>F=-Svq#l*z`V85EF_kt8}58s>*>wv zlvVu@HZwS>+Hd8)E)4$Zl$OWS!b947`Y^?^50;lm?YG!J$DO60MkM*;$ZF3jI%F|? zX{yJLqj`gLyKkeH<_}H$f0GCFzy?~3lWsu5rTLF#nY`h-5`*vou5Xi;4dev$$_*VXNV<{*>yxc7K% zJ$CqdoQq4BUDf#ckxzX8)$kGbwnAA;wqZ_p%2mqLi_0ozlQI<*Gu$+`3Hk}Mddnc; zxxER`-mN8jG3V8zm-?(q!0W<(MCn&Se!`@Hn|w+R$E8beZd8wa?rUs3Lf?5(8~fW= zUIs6Gk}Z)Z&hKM(yq8Saft>&?c(eXU9rl$kxW~NRx1G6t+gP1khBIwnTv}%LxjkRa z`N2re0MFTtoKM69$QkgQ)XH3aiImIb%uh+4x&Ue^LH)z$#7WFaU8qmz99k0@d)3Vi~wt?cbz|-w-F+XEL$Ps+3 zbsM~O*@O<{$Wo`piLSk2uxvb=(0uOd_3#{Y@10Nk;}E}Nc$ZwaQs``lcaK$+FmmS6 zjyoRXcZZKYR(prgWl&!k48>T$0sZMj0Pkv@ zSLn)A`xA|Frb49|a&@w|1aq_Grzf+pV6tqhOWZ(@+0*c^N8r$tvsSFd5m32d z&PBw9)VgVP+Xj$(NZIIZkv1$_+r|-CR;^tI)`pG+oC!pUO6{zt?I2-OWU4j8Op@B% ztixqQv5sMecemhq0#MxPGb?`3*dL0K=kwrxW`JvEu2`U6gKU=#XQ!m?t^z7QH{BwWKHHfb@0Es5%g7+ zytLQFau>A@|nuw-nz50oI2LXpiSSyOwDQ29>mnN)@ts>6-)v;toQ z*M2B+Ws}Jq!?~|nLe-%yr-w-Tqc5wI*&~_iPX=Rj&VL1WhP?MOfd$jS{U9^dDMQ{v6@b*a{eUN9S3$?f_ZmSVP zxiy)gyqdyrhB6m*8jsVJJp#|Jc)(o@j@i(k171C8xrF26xTwBn6k~8)~qp8 zrcB8l&EN-(G9=W2{?{X1q|iH~;O#yNu@n~62Z!lbRIRX-Wt}>?82$2dFXq~S)}xHS z@Aj4XJRa;Avd1?@y%GKrW%&J8lJwa%rxK8l=$<9{h*kYz%#YSUqs*TSLxj1ddwe|j zRvHV!*dZB*RgDd%Q$7Z^Qcg-PA|9K#o8HV+yOOXB?(!G+K&DW}An_>qY4_>nP-K`%5867CIH&kqs`qpz#ZbA<@4|5y4SQ;cy)_x8@tK2)&p%(ozPJ!w4chU{MP)sd`jT}5gU7lA%YoM+ zyS{)NMy&f2(Wgef^-#>dC=0t!9J^06q5|H-pZBl#za3Mc%hfd7(Aac)gv+B zok^LnbFg%pADxcfvJNvf47`q9S+~cC+aSP|V;&!k-vOBt-TFso_FbSJ^A+7QNuK};I(ur^eQa-*Y<&oNSik0SL8Vl~w)2l&?wXlg9%D;S77`gHABPNUzAczeJ z6K9v64YR5Lo`tasR~2rkoGg`-%{M)kyr6Zm~6M zi;O=h#MwnIIH7xe|jlfbU zakvHUKTila$P3ito$|35bJEFf3{Ucn2?l%z8b%!zCgm$cA&crGz|hc5)xE>tyRQw> zQHLCl1h8KSA2{T5k!E=|{Q6gy1RwzwkLoH9BA(Dns`%Tt<85P4h9XQALfX5%k%JAG zA=3NsawC~6jpJyX8QOkr=F%-gXfofOMyvl!#b<>pJ@1|}*!-m(4Z5RlA1E^q{LaAj zN$X4suv2rmABF=+o)Ya{d(gVG&4e8$b}_He35-`3B6LZ~NOJi@cI*hkW7eA`U?kNm z)2fBg&DFU32nc^bIlN_>eIP`?Hv^4!x{{o#KVp;&+}`PveI3>Ly~@6X-F93nBj;vQ zpD5kE&j}37?@cqD@Z&czO*mncK8*-i0Xp?YzIPcRDf8n#r80SKAQ{buOvNa@8*#{+ zOD4x`&flXqgs%FrVwd2Ss)b`BSjp&G7-raebn1JM2)TfSnXJw|@m#;abdN#md6eFNJ7(Vdr$~98 zuB#r1sA!2`xqhrt0Um4;`l>xv7+g|8`Er!{YO(jmYTfbqs?KCqJkTS3w_3!LVERSB z#O~hrWeL{nA4Z=(7OP;NVqZ5%I}v)J-<%_asdgsS%B*&M$fW9-9#R*oml@K6#XS^5 zs2wiVW~N*s51Y+9W7Dvc4t`cXdFHG+SKPT3E1ONJzI^sgw`j6{+CNE>aSbpj7{)zU zy)wqiElm{qLn320p>{~1KAs#%hnfcs3yet51BGTgc*{egdC8I$%c$J649^BW%Gyom z%ee$e|EMf)(lS!k7T9Q*QGylUN|(A7c7bVpqqN-Ocy=ayWZ<96Yi3iENy2c*RkM=X zTe<4&R47js2h%0pmWlEs9mxgmQYCmT;H6JVwVc&PbwpQ*3#Ofzlz}|1>P_?kJ^L3+Q3Ss&g~V8(KW; zmwBOpz_)0JBRK*2T{wZ&H5a_iEVsqg?!GEWedI*>?(GIMG&l>p3jvFM7GDLj{uF-qg>tE@@ zxx-XTtjwF?ebc)WXPU%p2T=pZU__8DUY9S=`;IqnrN2lhf2l9P+U9FA!b;ie_0KPt zbxn3}v3ior8Bg6ncu}#r26>!oZ~V`~o`#IxB7|P^?2W&&4lx~j<8SO51E1Hu@&D$j z`IHZ-Zy@!*k^0syvyx4zhTdnW`7Z%-bbDE;pb4bE;MM>@)NTm6|;ytFR~sirsU`^3*YJ{D41} zL#_2MFZor&nIl<9^Ax-0zS{2>$ilR)h;s1$Kn{QPzm7DYelt(&k1Fbq`?UUmPX*b( zc;JcI?g$D1ebCv9fnZr5u2z^T$IMb0>^WvCrA@)O2)^-}*xmbz5!NBRFm}(rLRXc% z%}dnSwaH1!s8p^w$d#AMRfk+TuI)S1`3iyXmzl~p8Trhqd=;wy9p1FG-pQ|(@_jj9|2Q&Ve~;PsJZ9e?G5Zdr z=IftE=IbAkdH|_^Lh65|=Ifsj_g{#632}$NGG8CXsrf(6SI7PrLF2MR<9C;Lm%E}- z(@>cUJisAo!9baAk4~Kfd#KWG-JWCc)*x!T9@qf%bRvm8N-FyKWLftN1Abj5uxngM zC*L+5Y*qxsg5U2EOv{AbiH~6^0!?Pkl3XC_*~SEs*%BGJ9AkC!JU#`t2dw^%e{X)o4Khu!#SQBFNzy%oX zw(xZMI^LQU_`a5ss}2ncJa?YDZy;CEVl&l-7$o|@TO{<~za{OwPja+*!AlXNM+xhOE%JS<3eMs8cR=DLlW7@LEMmzGVeZ6o^$#x|_ow0;@n6C1p1VO0&t z0*o7JU{VSh=xR1>y!iQcuLs(B;JX*l2w%8%LxEh+w zv6v%t?&rmgxa~oE%2m|?prUb#VjUzaGeFztszF$x7IDr{%Vi-71$I0$`09BP$a)34 z(xv!=OEK)n5$jq_-m!T8VGH z5kcP(y5`pmSvXBqMv|BJ5(0j0>U9YlpQDTL7WwyLh4Z!gAb%#@*7Q4r(eHukOF!kQ zkH$=(M``6vAJ8jWX(*NBUC~}^;<{8({SJDKp{MH5Q+L4%6*uJar(AVg0#c9)Rtec; zIYYmaM1Fsw1KKDphef?2$;$Kb_M1q{#99QWbTwhT<*9ejZhNS5!NjII)W9}qdx8Aa zX?2|-_Lo^b3u+R%@Cs&!N6FbMhcfp2=qp z=zH{31;;a|dcMJBtf0!{g7jYG-^~%CiFKI2x$0A}61y}A?2nKMl2EE?{;-zvOJJ!{ z4jHSO&f+yb%(V3>F!8jN1KLirMbGEk&%jej;PG$f9`~Ybf{vW#;nfKp|NQ|z-00cO!oya{C5cn5Ca(df)fbq)~PNm3Bo-bQnu*D4WR9VeVas$nj$htp@y12JkX z*|etfeFt`TVmY-i5xoxY&>MsWEd{N+wf22?h*E9pXvCQyJEk_b4e5dUM(OO~Ty-Hd zDP&^`Go~+XXur~jI{CWNB3U%1u10gXto0bMXA{v^fisVrDHv0d60{xWVn|!)UUI2*teTf_ zHL~znMJrc;7%8({1otkr=7ZZZ_gEDX-dX87Xst7n{Bi1IA;J%TkjtP%$e=2{u*vI} zOp4DI`~&Vc*Buc_PIcewXW^}A_l6Z{J{3>ESJz|Txwr4zWZTz<`sC{JsGDZ8cr##wQSp$k^g$HdDs6_KTX(^NLqrO-|eIZVy zxj_B)vV5JQjd?jJC1bF8WXu&HoQ zKGD0M#`GP7I-c2rWZ|QBw0NHOj_+{*yO8z%p>=+b1LJzbcp9~TMfO53U81z@Y(DL@ z=hEFE&{$p@Gs*3IG(W_B<+>w#A*ZC=M#*x1M6Z8sHFFQ~JEg@~Kz8!lAxaJMOJf$@#a0?yM+mNJzG?N+Xqr;?+ zyMgQDt~X_8jhj&Gx*q?*&Jc72?u0KP+<;c6_IT(prWmM1zd};FwqWZ%GtH{RNYZI?sRGV4&T33Sghzc+B{CBs0 z-pdX>k6#wPR8djGDadgj>Qkc>#tckUC*XN2uYX&~z5Bc+_w2i>@h_;!l2rLuBwoL$ zd@FK$|3mpAYBNu(|9v9%ja2;cO4V|&cj?4|)y*I7u^)19m-?XaO_kf#CSh(S3ZzeoC)AF>Im6yfV zQzQs9P`3U=Vu<|W+A$<`#j(l122hhR;D zyKas}tFhxSzOr-Gf&u89&2vGYW^|MFp-s);oHeaioBANwo3e3l zIPDY$*u`c-|D{n=*{W%nc2(RT@}*rY-Xq&vvV#iHy)&JXcYbS5PiBBHm9x6Z=Ai*T z4^u$B<=_eW%s?irPpQNJFuDKEZ7o)NaIH<+83}bs2QM;(VI!E}__%$QZ?zAX;-KBj zt6&~OO;4}I&wC{3paPJbmU&03@5KHmJKAh@^swZHM{gcUD2(dE=p!y)uEBbKSc zv2**zC_Vj_9Nn=DH7RD}6sIsO(?qlKM;^8yOnCZ9$0MMH7<>yZqgDuHtM{T{_qssy z(zBjFySBOaZ37=n{b|EFLAA63najc4{H+Z1LoGB=z;WYm85T6)SqtlU3Fb{UtVw!b z1r8Kh3IjQ($3!0Chwk)BJNAMKH;1JyM!O;GhNc!hy~7NixDHbO()j7fyRmF$>TkHU9Q=K_eGGm5L)aobi?)-@&HxInK%Rv2Sn?Xw zV{u#X!L48VBsGcCyl&$Y(#h zOJ~pREpN(b2Wl!u>v>VA^ERPRjNuZOuDuDTHB;+iA4S;2BE{Gzv%-=0Y`u6E3i!xq z@0h|lP1$W{_Gxd8i@gR)Sl(xu`j6fPTz zXP6i3Sp|)6jN6D5@Ht{1`Qi+|UTD<roDD0(Dddg#}(hdEC*Xm0(GgK(%F^l*_2qq~EHix)UXi zo1zAYS4{5_etvS9`>Qf&Rq#9hEcLPj#x>A5oX#bIcg=r&sxzM_X@A548dCUoZX2wfpw zO6^Gh<@HW$vbKHMo+%^kq4A+NzcnCq&gVT=k$Ow8UjgqCmN{ECD)u{I;R2pO$kZt{ zURHAf)cOnfvMp4#la=cv_$UB1eRYszZ29WpgcG&{`Kl+$D)q{2#1*KMW54A4oVM;A z7p?nz^{S-S$MrGCBHCHCorQ3ygszpTeS_u)?Zs)m+lf=w=lCvMUQ$NiUxDwB<9itO z>nd+fSFXBdK=I>VG!}3lz^V##^dkI9ERVf_CuJLK7x0wLvZ3VE8Yg0J zc<^K;)9;#&`-n*k^F)%6>ERQFyo8t4!u$LZ-sgt9Sj|l#>I-eA45dQK|6fTw4U%m^!eMMo>>C0*_~3R9@ln~dI`)XtShN6t;6i^w;iOTHzD69K*( zb}wkfq|{?itpp-hXdNqI9`g`5!cF*v>=VC=xo``=Nm$uS~{I6v;r=N&Q{xhK#i%#VlIrTH9@>rPin4dG*gb8J<+{0+s=+( zr?hzY$E<#;w}5i(Kyl6pd)s&P?1623cG!If;mEo-WGKe+vL?IyK{PT@*h8^q#2$d< zfIf8K{EKTRhYOTPW7D9SgJhz|uDEyZZ7}qrp|fLVT6$AJGJSO!CxQ_}?dooJu+`v(F3@j;Ub(#s>oYx6N)sM$+MqG(GP9 z5pl<>0X|;Y3i|ik-(x~$w!$W1Mae=XZs37vhDUsI z2Evnu%=o*Wf4z(UT|YDyXZ*$s`ifOp|84kp^gLu}^D#ou#%i+*c6C^vx$5n)ZE`kb zq4}y0{gbb(^8Nx=JGA~KZT22l78wy~^M z5^fM(Zja~+c!+*H1?d~nAJ427&9DAl#JUA1jQEu#P2=|24sgVs;Bd!5_Li@HI>aXG zTpvX*KtuX3%qgwT4p1(d)gV*-(4t8z&Fb8Q?g>~NL%&G$wk9#qteF$gHcIW8pl4u3 zAQ0bgR<9j?_mn8?XqZjXnQtBd|4`=3QqxQCUY1DPOcxeQk3g))RcZF9 z_Gpp;NC~))U^d2@sBNa^#mwZBht|D2ti@!+R+m&mK3Sq(3k-5KOmYB?uBUpDf5fev z=W^`di5{w4Nt(?tLh;ir4>U=NZF+RxFRy1S+0QmmILxQ*Mv zoUuyhBzYq0{Xz6S+yqtv>6FyA9Cy`7&~AJXeG73`9>*$X^O%>x^<9COx;99g`rCy1 zSS7=(FGHA0gMWan238c+e?0CTFSGz-J>1H>3*EJ+UjW^la+i2Vaf(8I>K~zisbm+^Q`A-APcpNt<4yJC-RK zu*P#>!&B+30Dm_W)k7X2wduOZM?v=(?yYEoZ5H}c*9C7vSOYTH$ARj2M!$#QZZ#7$ zxhEopz<4~nzXSOF**zIj;vmKmvjsM?>H+AgSk0U;e9+z4i`p1;PbN91Cl|K^u&&qL z4q5jYQ|FT2{Do1_;u#UIi|K2NJTLyh?BYlH`FGgL*J7*08XllI)IYtb*7NK*wO-Wx-ZRg7nE% zT8=x}YB3VzRa)-VyhV+k^L9IN59d(y;Gk39y|T<}QCrDEUdc|y z2L}Ty!Ht-(TjjV9x-`v<@BxETN@TjHD0^Jv9#Rd@jA-2AfaZhXt>jl7%JEaV^3e{duedqnHl~ zC_SAq#w5vteI^yQ6M_J;0erT~4MMx@*mEeGU2LkXtzkAllZ$GiQAoe4rZnuxB)AE8`J( z9Oo{?JjD9QP;nnNZggeWLhHkye++*T3(aZia_FF4yiPPXwRH*4Hb@aO;FEw_ZMz=j zy6}(IXGUs$KFaSNlzL3vbf@6A;8~b~P`NipJq>+u+lZYW2Ys<~4`yy4qCHo(Rb4c$ z^;iJ{YL%m|0ERfNSwa0d#&_FZ^0p{bnN#R|;&Ya%+e>#o^3ydXQ3ZuWv690NK_`@{eEB3C1E;TK%gceN@ELfHOJS!c;4Lk; z00{)My1Ary;0d#NGyI9PeJdKhgz&fd9(F$Z!2on``ynG(A{?u@iYXOWRY87G8w18m zu(N?3o24Lpc}ZUHzP}aT)8IIfQB9sRqH4&<$sbcZe!?VnPf;zbVat?ziVUh?Xe{2d zuUNqiaE3jQlt3no-+cT!@SB6*BK&45tlx}Z6P_30SFZ%le|*E9ePlC*GokuWSm>K8 z5Krtl_`NgW1IA8pNtOe;%$a9}pD;%M9r>Lr7Eg+c}DqM?jbXyK5^ zLk6`1I#{ylqMJ~NkD0iV=mxW@V4Y^Edj@=Xb13?Byp`(|%($tL?myAV_v21VT6MtJ z1Fk{Msc7^4dx5=ND9E~X}! z721#Xpu0U0HNe9w1C*Jw$J!+Yaib&r#w^l@5kd{1cALB0ZItijK`oy-sE5zl#d+V1 zut_vi3Hb&4T8$8zdaOoa6AQ3!eb~m}oh)*#PDW=&7u$kwbeSCnbt>IQE$N=Ahp)@# z5^?IuBW$8E2+Qe1x;=|x6Wb<%$E7kiBtduMeAU(Hd)rE&d$xaZM64ls(t{Cvt2ay9 z33P)im_f}QAnB11%98wuS%4Tb>@YMBBe8!mp3i{}dj&Tz&x4LN&=vr9A%+5^1;RVG zMFQ>SK^Ch=8eDO976#or>r2f}b1+LgKtZn($Xys;?o$hgJUIhje3zDL|vw~ypg ztnV7+{m5tRVrP=JVBex?RL`TI(VTO`1I-VfU0+j;Z!Smai{pZQVt7jl*$n)A$ovB4 z%R0iUFsKXT8dk*^)^MbnI8F!F`_-Lz1CB|eto@1LYVe(^5mi2if|Wl)YlRQj3!q1 zL3&yet4moo=cqji(Ow;H7*8^#95p-c2!bCGD12Z@kUonn#XaZ58UHQ$29*YTJW5+X zn9lXfp=^FaG{SbA?2mHP<%9Y%!YBFfm>|6tN$1-|w>+ZUY*mDH#v$yb2O?7$(IUjB z(_PRdkmXx(<8-z<3Am1gp^&5g9u!VxPlIggrd{Cu;Vjrba;xBn3e;a=|Br2dA9hKT z+Te5VSznUjwWZ32@lxF2p&&mNxzd^)WWCvKs)`^vbS)8Vrh&ChKw33|=*-i`bXD^OdN zdT2CEYWcwNh@sCl>VpxSmX$4A2+v{C8qiIXc;Aur#r@!Q;2+{|S#=Vvv5Y+$6Wb;z zd!Riwjdpn9J!0F@P!xvWF{`};NYW>|Vp$M1ob(|dQVb`i-vRGp8}Uoe#t4UnX4cO@ zZ4+<0wd5pp)km?@M36Vgpw#V7Mdq<7icY(@ldQBauyw= zHLS*XtU>lQ5O4aY81?EzA88mDKwdx=_}9vBc&ot8{}r6F4l;FyJC(`WBR|~k3qV5< z^9qXMMc>Oiiud@G-clpbnBIV-!6pAU+Gd|j*dJ?Q?zn}> zFkmuV<1;Dnze0^{*rQ3$OkP*#`I*i60mwCXV8@{SOp_h6%A1rAAdLV8*=AC&$b9|m zeWPFKugJ0EhRzrI#T-lMh5pi<8R07Bh5pK%Qan}VOb^=>Aeq|O>Gv10P9S6)XI+kY zfd;Yn8oq~284^0DDtk-r9*HSOOeLg8&yU26MNEm3w?KFL(doGh!$qwni$D{J$DED2 zhVutwtVts113It z5^I0UIB%iPS^P?$gf$>wemf2#h4up69B6Y3feXAJHJefDM4In}1=QkuIMt8#p!fR{ z`V$+8Pifg7mzcApt_S{IUU<0Tel(9yfgXxZ>nXlxeO-_jL4V(8%)5m2FBtC^;CD%Q z1De!jIqpifgouyJR{Qy0Nuj^Omb2|3g>(bX;*=jfr;VYdh6f_+yT|M;nN#E_1(d-zRxV}Q(bB39>rFXjl){t}Be#++yLxeicB-9xmS z8bcEomdkeVXeRYFAiUA<%frOi3C|G9x1Iai$D&pErL;*&DrL_Q`44_~xQWLtOi)Rt zP(DhU#7pWP+%D%TYyuE&@XQ_thdVff=Y46&vT%3FWS;8>$OV6G9pQ zG$_!iF)xW1PkUIChb}ODF-nlx$eyB2pn-&AI!ICkiTtbyqh-uc;Dx+tafMa?P z|8PTw;^S$z4{4{YS3p!07B=!Af(1HQ7?9WxR2Oz0}l;%dz zeRQhis)m8hTn<;P{s3spYPk8_z3YgUeQR)qmt<~_B*tRd(*pdpTCc3tM$w!H-JE~X0 zTFReUUIw})S3Mg~hrWng&;p7(6(^b}SN(N-HoiXybZfGgTQXeDpEmKQ#r&xlR9YeA zSBdDN;T%N(!T_x8)$f6Kz&C6Q&}x(V_<(@cnA8Etr1Y?UsOOr;Wb~(;e&KcIE@-Jb za~p(_wzLof4ZVSyc%VuhBTQO|Xlqwr7TB0sWF!mBl9hd|6L%v|7s|XiPqFVo{zo&U6C9&3Xl{HAy^I^N6&Jq#UaY>v7$UCm zR}B}!+&<<$rFie)1y%F6rxTMwMo*qUM7TmiDlt6ah#X#G@x2Ms6=B04qp)Hpzc#FrUzL zmMdbK269=<1f2%yB5#dpDL2w-okG=#~`9WvP)!<9+~xTOO7 zH$xNcbAYx%6r@r8-QWx!N=Cn*yi}n!FoE?;yba`0o|mXf<(!eINQKzocsl3%3rBJ# zhez|Y4E6p2Wee-i9Z5MeoWb*c8FPx?Cr`YyaL&JeK@V(@r288T$2()y(zT_2{6*S) zE|F+uJ+KzT?h4KYb=^B4tZF@kR5Fj}AZ|a4hj#l0qgV5FdL`)3V!rNv1pNg&wBMW79?);L zrZ1V1$#n{aL9Oh~abPamyd~XzEJG*Z6wyzXD?kC$cbh>uUMpweywgD^Lvz-o-W&Ip z?0^-hwliLA>$HBwrq%F@xyZJPcSs5atp zh&%fY zqjvfwm(N*LKX1|e1y?Ovl$XC~(V}A9q$t03_P)F(zWNs@dm|H2T6q9xA4ZG554jC~ z1xpov|K0!irqJD=#X80bK-C$IJtxnSkH7gAx;0m{WZ~~AvGh4RyQaZ#=}|w(sBiO zYMC?ewsrVdkmhM}J&o=q3Uv&(6vJNwJm%8NNo@M?kdW3SK zzVg%|NbEP2ELCRhHuV<>L`mWHj*81*UrrQTHgFd8(EV!E+m4~MWQ*P{QjbHj*Z{hL z%DErq)WHKp%Xu$yc7gtxj8lSa-YI;gJul?3j|r^;e&`ze*s%6q2)c$MobB4vew31r zQnaVv;K{0J;Y-2k8kI4-tMD}wkltu6(p&*jRq50Hf(i1M>R*Oo$$_2N4i8Pz3z*bD z44;n7;v6xxB{9f*A-Sg*lEyD>6XCa}tzkCeE2kmIYP2xjVBP_|2$K1@(2M^Z4D^W> zp>iHh4;M;(eOPa|hbf$;o*HuF+gki5;J0T2gQl$8A)k%Dk^n83O1X3xx3N5M-9HPb zl<>6QC$`I#K`x0qA*3{W1xhRAB_yd(AP2c22rMb+X4vD&=sO7pe1x=Z8%aZ!mp~H8 zp6wSb`@=P`bQAW{Z7t}bAJTYG8J7&7i&U;!g&7Sy(5bbTuD~zNPz{6Br1oMIux9~Z zatfb`S!y&%bS?2l_0Us^>Ve_31mLDY4OLo0wf>ajGSPfX+jfzDhv>@B2T2#1rIv6B zgHR3*3N~R@_4NdmOtPxU!*zUYDC~e1UUJ6{YH3-jZ>X>*x0}j&V8~FuYdpPqC%2}h z++znJ0Yd57>h(jPTs)R=DkR+3v@I$L4+w4&TAp;2Cc;|Z0?usB#bPYp9~w$2Y3^_< z#RZ^D2d^)&Wh>dIA3bX0{BrF^)lpo5KCv${-V#KrXUEgg(^;%^w4b zzS$ciEf}O+Rv8kbMY?L;kv)(;=#FC7GvA86Dp^NXCt^rvuZGRVHQ`x6IyClu%jgC2 z-nYUO$`3{6IXU z`~|!;6Y`glG$B_wJx>Q;6Jb%I9yfyf<4cByKC0{QMA#b0l{OuQSm|9Ndiv1b* zGX7#BoBWhxbofAjeNImAf&LqFtjF!G?2Zi7%T~q|bD7y$7&HS{g#4c9yY$Z15+Jxu zJ$!`Tg+)WEbb62Vz%~ZY8SKRy?C{8v)>pL({UuC~9bR%%cr?Pw@HY7uF=L?lbdfXQ zXNQ(R-=pI)qfy>ZgSlR&G?iqvOEtP9S?x1xVqyB56E5)LWVz{={SLilis_y2L(Zz3 zqJO7QzN(~39_5B!9`kk(Gm~~P5$Dy!0U#_`4t()OCh2@^;F@T!Ao~~E4@~k<>vR|M z#)9-$3D)B88$ni?uS`VmNua3ET4ue7|672HCg~i^k`AP?!I;%@6k?)>{ zNUxUflGxLB@f|H(6JyHLQifglAOpCcTHJ(-(#P?1qnuYhs+({O-;2JRoQ_e=6~z8( zJiVPX0y~esX`YwcZSm^d_wU%|-?^n@9V<8XkL4+r>&^0exI5h_f7Ss?FcN@G(H{K! z1^&%iI%o3a$v0fR@apDoUoBlt_WF$!p*yRt3_Gwgit~09?P_p_a*sRDjLGZn)3IF* zQpj+;`;1`o|1QTqBm50Tuus66zBF8c&?KzzQap`@Rn?U6D9|Tu^KpL&tlC*?#4LRg$$&4LMLHeH1a^`YIs=>ZNd)&?N3ta)Vo-9RG0T;DBYE&; z%ZEInK>Ax`6tKQD4la!iZB?s*b%1@w!Ts*|?%M%-e%jM%7hM-4st`60Ju0MlWZ`(@ zD$DOa^p>n*Wx$>4dy%m%c39lK$ede98fxHi&Mh~@(23r=WgX`*%Mf;Ryh!z6Q%O(5 zKj3j(;{S60*a#`EN+O zaOYcn$y#tcor7mp$p20N`BD|2XMuKGHp~CSH%Qk(QWU~}A*-=8((=c!A#q?=GEK9E zu{*UpgQVXidGUJ#K==v4a-?Sz>LYoL@Ihr=!1y_#pGKU?o1j|8!h?#Rx5w~{T?oA9 zV`irm%uBs72X7$mG;IDJGZ!^McSmp4L6#QV{v|y@It58{z$bM2ba2w*N#G?ktbEUg zl^b}PXO(Zo8saG=l7hFby&Z=au1J{9@E`56BuggWss`E{YF#)N=RmI0ntIAs_rSIQ zdiAcZ9?}mQLk++^CK@0Dej7JLOf^7WK8DBqJ$62FDI{&n=xX?BEX4WwOqqe zeo%6g&x>(^?Pll=1jBBU>fWA^ye436(thl>W}3Y%?I2#3`GBP?E%&W}`%Fs;+Md=F zaSrf10^M&_XARSAAbQOQTNSTY>M0*5g1R)SeM!5Q))?^v5Z|p??pePazBd{GI(l8R zE@AK?*U2_Wy%)vGnDI*Sbf;svO<%mYMB6t&&6E_*8$>%v=5Nzv{g9A%=!7auZ(izV z4e?3|t?`5Iu#Ja>2CM~8E_4G_cBj|5ig~YZwa#nH=iCHx*SlHg~98=hi|JE=~oAd6CubjQlwyn{4>~hE*XwD_0uO^Q~JPJGX z%Gn*bZ#13nK)(rCe3NBMzaThZ?a=}}h-;9)SiLE}9lAYwmp!gi&m@QjF@`FEaQYt5 z{>(iUf#)KXfoCGAlCGh5>f?3b!k+|xOelH!aG8spe#l``yd~3DUW!*11Ooz8A?>EchRFotbWdPTiZx4XooFKIk-Q6~>6eA7kAw zX}tPdwEkDDTD#N(JP^JI;5mhL&gU0I%QRKF{aTtAPmeEdA;7F~xO3WxHm{SHPMZ-b zJ?^qMgtCv%wr_w2O|q{GmD$@uv+Qfboyr{h>QI9{9-g9HX|D^3$D8cm2`#Yqhi59+ z+h>Iq+y5E9Lus{73uPP+^e&9Q3k`F&3FK~*@sjpw3*yA?9D-d=FSUn`a zg#D?s9pjna*!l9ILoIcXrH;8t%O)|7ahb-S`C4)%rE63QQ3hG?KQ#m2lxn6uUx3_; zM%XS705@$yl{HjTWej}}|GLlQ*y`ZLt@-l`7tu~MM>Knf|A(}9fsdj(`+(2v&R%od zK!6aIFq;c37%<#4qR0}$l3-hdmzGwovyi}S2oP=>)M^4Kp=u3QZNOSLs5MxvS=6_t zO2JB7tF0!WtrB=0v?V~qP7s()Hk{qaBEoZ$>10R%4aBZDXjk*YLq#=z}N+_A!zr-0&z6!tqOJ zEzsR$F+5&|M;L1XWq2bi1o;mvelxg`$u{i(M%VNLX~0&^3=05lrD<;=Kj))sNQWH_ zei>5>EWdRmpNM^_%>1NF^T)@_%Vp?IvN_L;7=u*p1;o#aoXN)VEOEe*Y(5+uD{0zB ztVhoW3YF22p;Or~ZD7DCX9*%RJyC0JYG(+U7aW~Gm&eP=XJl&Ea%=laH{~Px>>wcy zKH~NvgTZz=GPK_hZ_#LQW&kw|JK_{raBQ&DI<=q1oroy4AvU-HzBri>9>Ud-J_vDm zGsmEk4^qLr8ri%AV%!RRcH_H_SEvVzD2vvgqz*DtJA*7VqImqEwz@%^8nB`JnI`5&#Df`@Enrv}YnTc>TSHaCiAa=s3$`t<3s$hVS;v?T)k z!zO<1hqyMSi?*%WWyxz7di+`Cf6;gJzj}_Xwtn*T=?s2fHSYVYC(oaTFF67cX?&+cL!*-59+z!>z%FkF6 zb)>drxC*}E3;&UgC)Gc4;Yi*`9dYWZV>n`jwth2Y^}4%U3nc~Xhl`G!jLAXfwROuu zgFlRpJsLBq^!pwnS%_K91iL%&55EzM>`n6dxWG$k^m)=ntQ})vC$i9JYot+@tvwiH z+5wD%EUwd>>G^wrJVPV3!T|?rmaTmrwc~fBb~YyFS+O-r`y^)JXI9{;hkK$giuS@b z(Y_nM=fV{8L9&z_^mY)+hym|QXf7E@{5q`XY_jEuaeOY0pXm{xnI)|5u&;<;URYp)-ZCEQ~d#ZHi3^(;bySoY6bdwi`I7 z!Z0{*Fy=?WSMK%q;X6=$jVIG{4u%0~X}f_I3O@;%@)7|E6-vw+2S$ zW@N#0TZ;a8h}Im^Wmb31@z`2E(ud*+J2bEoO_<5a!c4mD0z@t?fc>H56+iw;udu?g zY8kg%%yiLxU&TWmG@B3VeM6MVbT-Zr?|`kZ&TQ)|M#2ZXUqIG{_64?P5nQ=5aQ^<% zqtIeY{I(tF3%s88j$gx`Z`)1y{{VbNRI?J)#N0fom7elce6yeAFB6VEh}zkHW@|Aw z7qk}pKhhr|P88Mr#2s#l?{CFEn}T>td?8klqGlnJH?g6bTVMeNV;I%|-U?#T8MJ~? z>KtCG(IR4(QID~xhe)f6eG%U8=t()5=WPnZcgRXB5wvqO4yDQH~|I zX~N*!>x>h$o|0BN3jCT!PujP!$Sn2oobRO9M6 z0Mv+C1?Hm0rH$(M!7BRdfK?EV zt1Xy+lSFMte=fG8p?ekiuR#n6X)vo%Cu26tig>}oA=Tm6L8}tYq;cRq82Eg?fv;H- zHs;oEL|oxw%yr8#%kZd?1r)uN<=^3-pRgB;;SC)#!k%r#m^)K}i~z$UVw9+~5|l== zm~n0>q68xyhW#h5r-47Ger$2rTO;A03vo?oi6wM5>z~lUbtWx6VpWmJie>ZtxbDIl zMOXX-bvc-@rLpk|D??2&Rtb{K{|3#90pSky0q;Pw?;LPgi5yh`ogUkAO(igELps(I zFRdYT*ErO*8~om%^hEfogILP*@ilS{&6;uz5ENimZ2$^HtwB5#_Xe3^-GR*_$h3R0 zD%{*5OxO$DX$ZLqLjl^7YkWEKk`h19rvg4eSbxU1`@g99RYYdM^eDT7O{J4RpihEVRvnz5xli zk(gMz8Ia?+t99G27Y+DEPLZW^-B+)e{5S*>8Qi%w$^Pv%!sU+zEckHjzWG7 z)<=p9PxkE4HtO3LNsVUywWxhiK30wpVkg;@IcFdJCG}|7>(NW7?i2n$jHF!`p7-xY zlFxtZamLE97MJ56$-M?s5@b5`I+6$(;w`<*nCo80{BahtAo!TIR}dFqEf*APIn%~O ztmW2))_1M@1&_UiX^x0%?*Xj!lgF6s@8I_ylxkx#UyzFNwTB0_ZEjj)aqXGykp05PHU zZlwcPvh46{ktM{3*DZj}91*St2f4^O5R%BInYUs&@0jJB?OZHhEfdmnfN z0ks(gF3HL~TLooH)u125acrcPg0p6RY#pNS;L|wou*bkr>Us_SVxJRnB}|(hX^`w- z^hRtXwya>zX4=FEoi|l%%e6PSa9>WAX)$7y7L#0`LJ}&@HiVt!3^Q^ATO4NEU1(q8 z|7P0ru=O(SN60J(WE%WPuEf2r*KE>x$kkMy@qCJFi9-TzkSut9T>lbVW;{O*Y?W(o z_JwB>Pi&SdTgCJSDTQD8NgU7SwXlbY1%gVT`~DnP+`rpnpM0X*@ZnIM>G@P|RtSC; z)K&`9yJg_n@H=5EwPKr_>hUt3jut^FFJQ}#@@$9 zf#cqX;#8(3QRe*@-l&1w&%b^jy+5@$-B-u&Gg>^Z2XS?>&5dWI^0vC|LLC>!ZRHqI zi8c@l7#Q4=t+x<;_0sku{g`r`ku>mI&Km;z5IClO=)bkR6WJ`DM4w`|2hy{qu){xB zm2IMz9oz*_omih0win%twc`o((?~gTU1T{b%h?YMW*OG?nEH){nMx)4z)Rpicv$sf zO<@P`hb9d_RzD;gSYuiUU;4DQFP#Z{X#c~(`d7T$ipv`JAdXea&?p#=tK z`yFb$ho0xdU3BcpK^C5)eiRWKrtiCGZpB4vB=(ODYAB^fhRW|Sx+*N^@QeW zLat|MIfD)0<;>7V4&K9mhXI3oXU{cV#PJp9w!G~?r5AVvw1W>)R2t9;@vVQ2h@o0# z3y=a^z^#K760u(!l^Vr__HpNZr2jZVT&K`-5z#)M=5XjKa)Tf-)Y<&PpHB)_ww>zx z!4N(BW8knZdR|k|2jcpEXy_4)2#U5O9hEf)p}A*+k%w^Qw6$o!cgB(_VP!erSpl?g zHe#GymWdeS{H1Rm}NYlhT;1dW>V47$-n3E`hdCzy5CIXcK0!)Jczy%o|43>dj`7}5hdil?qdqsW_PYH5IN9q9U&f|DjJ{f7qk$ zIq;RuGxro$a&R;Ky=y}F;t_RT!yauf`qgxEU|v9|+k_RIU4~~`RZIXpNmXDZep#Q;lIbeF3e(yp~zdvAH%$Hu5ku~9xD=tG+ zFv%o#*}QOA{X*RRLoPQ^J}dGILNSEaeSmoe#Ix?3%G~On=2E?zR_{R|pePOsQ6(px z%U|zH&$z+xilw?nEm|~gLebPKX8W%Tjh^3Y6A+8CH8iFgTm3!HMy-M+iiqB*E%OZQ zs+R%N23yB+hZY<-b;-U}v&7+7Ib~&*Q#RpfPZ_r6W9#FdE!esrTZek4!A~Z^^6t>| zfj{-I{I#V^du?Xp$d?0e_aKI2OrX~y{Dyl`www}J(Dyq0#Df1dd_!v6lwwJtGqcAd*SH!rvj9|5;)uLPf?lR={TqMUM<;Er#?tg|Z%sS$&N>f! zYv!_Y*o7xXFMZ0@VA!6DmhIQ?g(O3^JBrKq0 zhfLA#iFm^nU^A)byaxNRncGFPz`Rtqch!cKO8{Y@fwyY)1^R`x)gZK72b4p=$VxzR ziXmO4g3}N70%S!d3CoEnEsCHBAmSgs!;0%~hm*E$13ZH?mPpnhP6c}IX~cnh6`EuJ znTf#yIr$=|0^LJ#8bkW`NtZxx{bxQEi}ob0zw}vDH`6XN?uzM!kg5nMOy`5EcvZN+ zgDlgj;Q92yV@~$$TM(H-M}8G)>B!zS2G(cfpaAdvcEs^IwULP!-xSQ}B%yx4pB0P* zLX_?iwd2J8v5Tzp>DpH09x(111S3A-byBn)Ly$uDkv-w8z8f}rl9Mj2548=|k-uxA zeQrbh*vb`|zE|3S74MRwjUJ!~IL4B^Fq8vnX-ztJa>?GB&+-a8ZRp6mnkewO6-M|>Q<{#5D@fz_?3$fdnMz(-i8 zcss_omY_x{#)!JU~y=al}H?&nI+9W?>ZI8}-1 zLciz_l+u}pIAW!{M<_}Kw)_Cl19bFP_nOa4IegI*3y28}ogt?TU|ls2{b z-!My%_F`OTjDT6O6ns}N`qky6eew~tC*s7MYOtojUlcK`Hhi-bWY(q;ko?|8T{yf2 z*aGUc#yBv(NfmlY@|(CWe3N8<%7z@k9_^gR!cN%Uv-fW2d~POKwrIvK2g@tTM`yq+ z^q`XML)^@ad|wOv%1uh%DaIaBKA+dZk=e(vVtmTi3;lW{<0d>Y_Wp-j`?AgcU!^iD zu1-12DqXNvTi6${;Y!=GO2!Q|478~BmS6Yo&kzn*`UPz7huzrL%<{54Cg|vIQ`Bh3 zLuyu@qBwSZ2yGs+I($RU=J{%1o7iH9wFJ`c4ktW9!eJ+TIOZ0^*FtzWvAIB*s)FAR z7W-U$k#ulFFH-{w?kk&)81lKaD%(Xo=bN#V=9HFV;CPsJet@oAIJ5}5cDgnqzCPeB zFAm_l?MT;F#hfjnUOVdOY<6-+D0&9lhbMdgr%METMZ+GkIr30eN#%U#>)aY@X|}fP z|0*@b0*;I8&azu5i?7nZ8|`D;ku|kxPpTHco{2GOcf`r=Mn2FIfBMdr1yl>$kimUH zEoI+fMZFvLSewa%bKlveFEeQYt@_1fJ>&kweeOIb*apR0FXD?x<1C#tzx^HKfYw&x z3(T;SwU(V~vMWugS|KuCOx;#7-+Z)!&xFCDI7e>Nc7*GCS>F` z11&N12(5R7YA5~-_^l$|_SBz|*Q%rwF-8tT(x+>Av22V%ff2TnG)a3XrA1y#@{$w) zFVv}%YaG4XG1|8Zb2Xpfse_)`?%kHEWklo#Siu@bfOjNSvqwS=!#D#;CTtJmI$W^0 zsImYC4Hep!4BKR_B7vR%gkO88JnY@p_YiSQl!E_@bj&}+_Vtu<^w&B>!qXi6J=pcg z{xtby-}Rf?O)c}$hcC`7tn(xFL{kbfF=8As@(2j0_B#|DIS`*%FK8J;sJ9Vg61h2B z(zSgU?SXQkscE#+>qJy1>ATkEZ*iH^%Z~n1{T}*OrYZ+dqBlCg@G=qFtOZu{ z-AxxGRT#X!)bDzM+@As7Fe;}5Yt&;MKjO7{fY)Ymhq^6AYv9}7a28fiimmuie?M}f zN$_}1RgNJqC}R0{RFpOCDW7ldzW#hKJR0oi3RrEw2MLt;-rj~k6eu}F!OJR;?5O8d zv@6|dPuv;W+tMk|$NjSlAVMFsnGU85$&F;aG#L%vZ92aJLIy$l8xYLJy{B zGvf-r*@*_FQC3XN>EzjCLi1{ExZtCHI5-!`9x$*(!O)8msHdFn%EFi2LaW9Erz*O;3j@eJ*R-Th);6PkaG863>_Lznc)lzR|&BgxN3#CD-&aT)Rb zip?{@oFU4grZD=}n8ODU8*+a*)N~Si=5CcAWk(hDa`{A4D~>rjA#XHW)#RC5)OR9c z-AL8ApLN}ctv+1G4u4CX96rJC2PPc%fTN*#Cigu49$$%Y6V9&L;bgfYzeeDti9nFI zL~{AeT>c7ciG-^Y8MPyf0Bg1+&d@V7ifh@&TC&5) zS8S~Pz_$_B8LJrbWLbFsFr$Ca{?h}rUY+9of@I+|NciA8hPTX8fw>Jc2;?l;;}@k= z$e49|sqc_1md=m-3DQ_qVk9n!w4?p#y0>uD@N`NZ$$v%&o{wWE@b@S2*>vJGW8|XWU^C6MsTDOYoa{cE`~vWim3X&}T+=aOJ4L%OQkEOQd&1_D;NvhM z3vHp_1!fcp5ebZ?9IkTD#}$MGqTk}%m*Hwh7iZdeLha@NIxBMYA++p@^JJ=WR@E+Q=72gL2fjxy(7Vikm?t->O^jPN>wR~-dyyknEp6e zEyjgQ>X&+17qVjR6A&@M_VxAH z*_f2jA$?}7DJ=2tUgZ{~#bH}3%^Y_jewluYWB2o30}U9xX6>B;w&cQdGC1>!S^FMz z-ZcLfFn>-2@245rENLV>0^1MS&DIB3R(~x#1UjXGC*9Oev9v;4`3;@>P>>{y5fhJ@b?p^egwf$XcD-=W zjvV&y%!97S|5N8Ce&0^~&LeIanth?U!#DUD@(Hp+_Jr^gcvRKffH=04Rk=+?{f92$ z)tUDSa$IinORZkCNP0LJfv>| zCYOGj2H)|TJ|_7Bas?v7CISO{NdLv)A${}!yj1mVuwSM{1V&{jC?geRWQ7&Klv6eu znj$=!Q|cG5`W9X!*;nhQh+RQ^t3LSS48KI5{#^Wiutu;JV#&h#v)7~|(ur_H;3h)c zN`)Pf9*BDKeg*DbR*!k6zRVTh>hk}XROzdK%q(awkL|<}gc|g8`>tEj&FNQ3X%Gli#k)6zuXtJaqg>)E?g8W-594pDX=Gx138%^2WL+ zgMkGr9xy+qPN_Z}GcMk68qHm1t$831h(YX6Zv@WMtmOmChuL^ZDzda>a}1YBQ{o?< zwC9I{#udXLcl;Ie9r<+$L&CIdXuV!!rz7t6EbO}?{!M1kcj|vwUwVp33;ACs z|BDDue|dd!n`T#w{|n`p$nyj))Vmd|!)9OrZ2r8vDZhpp9vkC#A9Blt?j}s!SNf0R zl5#@!+)eZE^8=5A%i?~pkpz^w+P4A{c)scFQnf3hscI{Zv0!7V?QmV~eq|Th*_27B zy3cqPD0(`5)e&gNrOK{ad4);)2=8-qnAVw5+VhaO=u3(~{EM0oIW^@Kg7yXH1VYHz zD$x4zj8#T^&{GF=N57}W`pjyLm3mj4*P}7Cs9Rbh2(G9{Ye8pz+7IL}EQ%(e*eP?|V$N}8&7j+4-O@-d#YbRo=Mp9zj6KCviW5R4iAdaVELnViMY?q znZa59h+SsBx0Kc$Je|(GHvoHlLR$G9;#DY0qXPA1Pr!Q*%ijpR6QT9!>8Tgq;Oc%8 z%?1p5B*z5P+MbRz?bwQP$OMuy&0F6&?ns{Z4n#SpcxQLoj?ndY6?DS7p-N$P}>6z>v_{`)dO|6P6hi{4Z0D(_nGJB9kDGpqL>{Omuzq!ZVA zmm^|p7UJcuLG0FS?_auhsJD3U>%7<7)ivfAtyV+&@kkH0=>Pxb0k&z*xFjDu_TR6G zaL@8&#Qjc&Tzv7`Md8p2VrbvBf*9JZ>Y`)Aj@@$XHk4-5{+Hi#i#Mx_X0-reZj9EM z?ChR|RgUbMKZlG&E%xZKtB*Cp5&_2O6$04bcdc;A6<;gcqQ0w^sz3#zy`s)K}F#m%RVKtI>=LWnYaF5J~U4vgcY};&i@0&UJau zwbJDOqlTF%<#K*kHot3>E34;nY1sd9*ZEkoHDW+o_|A-V^&h`i(vSc5Htfb-v-q<< z!(CVb>;CunEa}K`wr?7~jt9|K^-=mhhmO-;hPJx@znAw4%A3N=`}II&*w}iF*JrdV zeEj;e57qthIQ56w38})~F-3arxX}}y9|+;O|NOskZpXl*$9-o!u1EOY$O!{EO<>^Q zz*wSs<^Lb`T8?_rbI0*J&5&k3>rz)(-;oeQ9>6RzQzj|I*44I=I8yNUTtnS=kAn~7 z?4xxzAOG*j4x3hj(!Kt<#}EEJ>FcXqy=pm;Wd`w6g}m@c5?D<>wuJ11TnfaGG!|G$ z!WwIh&y@K*P${*A~teNcDD?HzTwr+a?hYi9*H?cis=sy+|$%0b-{ zx8|PeB99EkI-~)C@Nma^jyiWB`heCG(z4Sd5@(~KJgX<;q+`=oed4@Bdw$5oahF)P zIG!lWKl+)`+#6>G=eOt|6%y(tJndz8n0^A2^ zaw!Iyu@;DRt!p;y5hJx_@a_j8;q*gi0mc!!%ERQTDp&!1k}Mf#^xwsd-%Z#b|``SbWDj>nTa#W)t+?K5|mvXqbn&+ zkXi@w7~%#fiw@y<=L3tJj!4ks$QWWshUqx}Y0o{Rw-;Uwe+Jd`s&XHG1$Je51Aa|x zX8C^nn%Q)C7bqj&)N&twEv&e_7(RrzA|f*XPAM1GPN@(AQ!3t)uRps#FgMVxe;Bg@ zKka2tq0B9jiTD*SGvW?XATW7Pti`qW_X5`AJkXGJdz8wy8f)M7+wv@9!RT5 zFaKQsU?3HLzdt}$f`Ng1AZH!10#(#t@=-n_M7I{p_yS_>g01J?vwYYl+zZ z`L~x$%~^Qrs3F%Y=H2xCj|WY=UHF|7!y7M3FF&DoN7GT4ccCSxm4n9)?O>)TBf-?t zxF;VTKe88o2VQPOyP{Vy*s6icpywx^`_ao5!ZXi%nDb{5>M7(e_6ThU_4wdS|7EIJ zBpzC=r7)g1U^6m*3Bn7CQX26vAS1D7>TMLtWo4VK>?WS?OV|xOj3DQ-ULP`OHn2vH zC4ldT-$_?D$yIK`Np*Eu$`{B&n^@5#vph52>P_e>6lFsg>lR#~{bm z?XB9lDzGxR6u_`0;CBvI8{8JvtB9bw>S}4JQoVGAv~l%@wGw5K4^ohNZEXU1fU%$?bM+3oMY}IUk@|niv)gtN^u(l}n{24H!LKaVy~>_*vYjVdFsa;lE~|p~n!D?L&z7rWWWP z^yf~4UCWEvi}4mrIZQYbyY@=l&|Vx`L)6H2PHkz|p2u<7J-3uvb6r$+_Zb#8?A1aB zB%Q;qJsvl(I>kKi8(9T!!fN~?aE_z-7oQ%P1YE8|D~=V11#fQG2!7NX$pw>~@$|Wa zv|m|GnJNe$uLJ+Dov#X5yNNE)Bq5$!=awI2)9Jxs&>yNqZMw z3u;RTaQMb=G$wk}x>!-lQA79N!SPtgTNXEZ>tvwj?b?kT148wt+Q60p);g;9-BGE7 ze(QPtiLZ#xz7-RI1A%^aJF&$Wy!99FRgqbNFl%=0J@`53_h+a#S%~f0D0op^dr!Yd zxPn2*4`dIg_3SLZA^ z4FcFckjLAf4Yq98F5~?7aGu5+U3=r8g_qVC#T|K0pn2F6cEr8oOYAGmf8nA8*#DI^=4#XBGg@~76tl? zu|NM!wBLSvT_Cu29iuhg_$md7Qbg#q)Jq&%7or2v=Ftao?d8Z+<6oGIRm(*Zk{$C2 zTAcT|0sSA5d-l%V%D)M0={%zXu$TF*wDoMiP%sV131Zc;Ba??QH@t>u71H-J(KCzD zGvy)S1>+iw8+^;j9V2nKNh<~xf3Q&~vK$?I9bG*(G@zf0KOCT(57ZuSLtZszm@4${I_|+uey8bCD`BvDKX!}t-g=SkmdWZ=-A^TrsHZs0_ zvJQQT8c!Xd{$|o9^IwNHDp8jVK0=MUP_{U`HU@Ev#^~ygim?BYO@zkUwNX}|5B{3E z+_y)GkX`B8>k_pw#>*(k@ra(h;EysNo&hxS@eLML8#NWyVd3z(Q8WAo^QCy0W(68$ z*Yp>UA^%ZTb$yaTXl-EC@@i^#ShuRHq>J;` z5c0p#jN#Ch!OH46V!X?}cp4qMHEM8k(Do8Md1$XGF=IW6Hu?s%Cpr`BH-Qhy@Clyo znFfYOwq4k6%tLD+%OlSfZ+jEs#FF>ljjz+1OWr*ZzPk_m3WT<~;$dnFYRf0Ur%NO4 z4DyAVc1$g6LdI%}XlMDzM>Qx&zlOJpzT1n~ezj*wU>)}h5kXp_$@#ot%nRB5hBeHj zU76^we9hqB;|sin43u%Qr+zO&s|4m_)Q&8V$T^26kp1$GK<$R=OL(_v-l1`G0y>wK zTi#5tAtuIBVkX)(Xv(ABYS$i$+sjQJntj5#ru@T*@33p%f)&!p)Yh;6a)@MinuBPJ z(%Co3>VtWf#-u~L3H=~>h9dEek@`rK>PDl_U=N;&ycx3@7(|bd)RCqgi`i9qBXH^* z8!iwwe4f09Mx7~m-A1z(HD9-8_{#SJnbk(T0O{Bx;dggc%J2@`S$#)(2LnqZ<&6-* z=7n67YO_@OT|@plhqz}di=JunW_8oA#p^oquTNBJk)H(2^ugLp?Kd%{%F^evF?EhY z7?>!0qa|`%tt7u#C2#cMsqz|?SVZa0$9U_R zj(FjJ)rT6;L&)>CT5G@^6rtziM+zgx8BfG`9@S$pxNYb=P}Fs^|JtBM%P`Hu3_^YR zeXPt+Q0?Gvm)8`oDaO0bs4_g7^i2^H6r?zFV5VbFL}t4LsmbT{G4Huf>UYN1oe?Cv z^PP~GAB)Uk-i{HFFPQcVzM_)$p0169yncGjh;#3(HXo(;u)!l|{F-5}1mpY??KP}w zNzQ&5(Y>-PE0rCD(DEpaKzy^vGrCasd=5U9M7{#PU5Izw))XYmWqCE^9swN!9> z8Z{Zw?}DUdhK$Fr%cZM~K5yJxi+i7q)Usqe|A)8^$8cROt~1(+EY=fNjVRw*Djv0> ze=zOQ0ZH}LsERMgiYzp&&tm@pO9NvZJBmE3^V#9~$Vq&EspF`<;vHE0nKq6i;+Zxw zW@OOA7Cb-nw!YE~20ago-|9Q6*DkAF4G=ooYQat(V?!MGi#gWoiq6L(>siYy)j@i0 zs8?_(il+v@PT>jbPewm}Oi>YOP1s&(oEdEp*LNYy9NVWV>|Cf$k*QCuXUao9j5uWr zWqH}ZfO_Y8Ce>7y0k>aMUZ%>F6^G8VeL3VO-s(a>GD;RMDS1PpWLL2&ll>)r{btm* zi8EvRnm>$Wg;3XaYDZJEx>9I95V^G(92b7eP9zAxEb|f~bGME*kZC_1AYF^T+4=qh zxDz!3qL5mj+O54G`az3Y4W?#}RxSfmd9-^xN^W6OlNZmH(yz08@^ zUgP@WxCDkdr2xRBmsZVY9dx2<~17E^T zogVv>hPuNV9lZT5|Bfd-h+Gqas4c`TVY2N zq}NH$Y;L*dS|+7!|MAPA{SkV)Y&cr{pf4~qONlO zS4ZGEw*B*)RetTwt_;|EQ(SejDuesqwI%>f^THcuBWs9+xpol{z)$vE+SgpD@#Q&} z*7rHom*(fV4*P!1??zLbQr{V&l}8uyUKH2I#_Qo-*5)>&M^Zl-hxs8n#)Zc-o=E=* zR-0z#v2C|+cWzJFp0?f8EN)jyPp16GVILH0>~H*@GtBBW|~~ zlrrd3ehZGJ4?0^+Joknjd$z%}#9j*a*x(k=W6Gk4YcgUWuKc6YaN;5M7VbTDU7bNTn=}}yjt2WHc{R$X6YR6Rn_;K_Vm^KwL^!@ty z7|XwhGaZ@`4@kOC=SkCyoYC-R&pVX!Ab5spt1IWmoXzrEm`SOO+F%N_?Secn=3Uq< z22S7^CmN2+ugWtp?z6+H@_U6%Aygl=F3A}lHKZs@WW*C)Tp#xjj0At5olQ`F^g+Xk z9|7boDGYO(kClg$>#5j9YiV4cHb{L)smTu4)= zw?;{|Cd6Q~{K|x^FbgeD+2fF{$djoeBdFzL%Du)K5N~5YT9rGa!#D;$Rpjs}2DfxJ z*m7(~FJ9@xm7g7D;ANv$F&J=$tHv9XB<6s$FG#XXEi0k_AVZ`~%#gmwc;6jhfNU>4 zaU|KM6ej=+GtVeA9&%h<&p_Xs;(v9Gk+s8k0$tOV`WEorNwo{k0Qwe7IolLu=Y{9BYG#w8#+S9@c?qR!!&bjUa3U{`~K(hNHU zd)$O9*qNB0koRHTtiq~U9KM0EMS8;se-aleb{bn|-~o&LW_YzIzGFSNjRCZ=6vWM| z@Q;s4b)^4On($1K0KmFB|BA{Le8i4?w9z_~C3>nV@pda{`;UA?j{ zK#BV9Tusc#T;l`65PALn^%|VNGq_$c+A-r*LeNzQFI@xkAvfCF$ZpAY+OX2RhMoay zPP36shvXkGX7}U3Z2$!YnT4c;O|{e_uJ}~Hh}ri|WFCv_74gWMw?(p|H%^6B_ON@v9=j;xTyaB5s8cb z4J>zc5E4#ZXcZWImLcK}+F6o~%7_Oub;_$k%fN$2`XOn9TaEYg0ryTast+>iS3QJv zvmja~KF!R(`O*QpzU~!z^WQ5Dk&&Zd7tr6N1e5ZNnedbpBqH*0yc(u)!^b0g- z;6kTK#yS$0q%ZvWMnP)vmGT+V6BM-H$3seDzElKlA8cY0p8*A}1K51}#Qe@?(w zLZf0p|4IL6J;Xmy_nP4UcJ9(XCN?R>IqUH&9{iJ1nJa>)plhoqno_K0=_EWkSO2bBQ6P49IRN5yeux_s_w!4l~%;h2HtNg8Vh~zW4Dp zUjkl%c;{#>{V*=VQ>kFKK=$&DrJB#QNe=Qhvhf*qy^BR3R?OQAJP zQsodli8M13pRd7rgRwGiD}0;e+ipW-YDH@~o^dudR&B#*+5d;bCnnoySTU%`41QnEWfj${FYF&``YfKI4^ zWgU|+!DrN zyJCN*o?n25Y_ zEFbTa|3hVyO!}CQ)rDK&M<<&RqSO+R22z;nIHdn}h{}NMhi_vTFAa++!iZtg{Fh_j z3IL#-T+K%&=KqL(0;}dIpkFDQYy%>eke$xW@{+CUDyF_Cx_^2i-PM49hNT%C&#*WB z?c+A3AZLu~rCx-4+i>qh@GF$LkDL_qkDRo+_n$Q3A3Q0=#_@}#bORrI5zTr+FI*o$j`{Yw#u{>kvrVKDLs8C zsb!d31me;~+g>Kj5{@afzdfePU~jb#SDn4(W4e(CPey!;%S2CP+B9g?tmR3xPYC~@ zb>m8!DNh`x*a^zUQ!$L?FT%BgRvR<)ddB{kZuo>~jv9&i?b0_kP@~2OTZb8vbg87A zG=k5has3f^ge=fk5}21p1H%#5ZyVD2{6RcDjffO8@^=)6Ci$mh9gpkJVJ=Q7Z$Ms= zGJlGy`0<6lO(UoVo+cV?v&qA{Z|8{&wgvx))yEk7q(7unrcieOXp*hlfQgMyHg}s_ zLyASaXTYPRttFZ2LSiTw)nQHtE5$l;lCP?+uDXOOW^MKIAW};u{7&H8RR~R26_vn; z5yT3Wc63w-y24zt^iEu{OA+%cS6Gl&Q-FunyVSeF6ZAzqGF?p^a%o3XFI>I*!qwTh zdevat(hwMBcCW|_&P6U{DLB{d3EYEvuC62HXx%04N_kGQ8_G`I@A94ceWmYI(^P7& zmwEeNZ2ernam54tZ0N#SLymm)T*KwI!};*l34GT3-1vIj+ep$wH}$K3wQi8cad+8YQ7?IpA{p+kY`tMU7YPBo=norQn}2?v-!=h*$ru)wmYyr66>%-dj=)rZBLpKtMJVJ5H!!nPMgNGe>pdW z*5#*hghr%@dWV!a?D8SShZr3`GH~2jmtj9b1{OohGRDr@IMpPRR$PI+Dj{U<0NUFX zQs4*arfYT~{^#TVkaDJn_L!C#2`OJB%8vK7RIijb> zNd7@K)&UwJrMYxg*M9+t->8pK12Iv`ONa_F%JZN+lk(#grr-^^^CEdJLbuz4O2}wtL9QdQGX>x3ImL;Vnkz0lC>Kwv+4vw?A zgv2hE15_K5dyO(bACl@Da-H5`{7a>0rlh82;y(+Wb!b(C&ncB4hH_&s;Et~L74=^?g9YNR$5x*Q(L`gLrr6W=pgrxE@UMa8Iz zsO5}tkCVpcdh+rM3P)Vd|4X6uk)HH)JYO}o>Ja5_Y+V^2ov0_h{n!3SPaCe?GnC|^ z{ROymjC+0#dnM(ct$VEr8X$2fiESd{;1P;UGva(>Mih4!`~LwM#|{~X@D|TetOIh7 zTH!~} zBFN_;hH!k>q^92@V+q)fhfh+>rw-nbnT=d_M;5vtE43WmQaa)Y__$5YrI|+%=X_Z7 z&qZGOCjTU*>Z^x`O_JMsMe`(O=~tiLFi9p!8gC`toeL&>;OD8mnj!z3K@=k8E87A) z9K~@d{)W@+K{KE8NzVO;z7$fNk+;m~ts{{;E*+L%%3f2zmVNcGYog*>Ot~BVz^dK${o9u;m65P#*>dHwyYKnIz4tYwj6n@(R=z)mXc3{rUlYWN z7c;yho%+)LT8t|?k1Ruw-AeqEaQ>SY&fnO7YvMfYsfZ^W+f{;hY*kzl52UO)Y%DP8 zq!%NvTXfhm}Hkt5%R!fARCR>H;HD`U=Bxjc`&sk?uhOKx|nHI^HFj9y85Lt(v_34u` zx{TvD@Z%#*rCP&UvodDIL(05Jfs~5-To+cxQHbwM1J^ylc`Ku?U(irn$ zI~x&G>F9m5-wGME(OU1Gs>ok`x@ao$1{b-Cl>kOzF|=%YqszF}nN~k)DZ}D}^&e}4 z1H2$k#QkOC8&g02Ef~E^(8lNWYS_Ocn`ti&8?<3VndWz(-;z{tPjrMzQh?Cq1oFr( zk-kn>4x=ldfGkkF>n@Ty;^0j*dW}*3qwrT9>@oDhuWNxdm=(R4TV}>cLo_4=vM|*G z>p*kF=kT)73{m3$05S=*y)sy$(ZiGeP;jE@ZvekFjY}1A{eQ7il6C0sijkX*a+${9 zbs^n}yrn=H19?t)V(vmOBWqDyKM<$0dCDe8$;2vR*g^#2wVFm(Rwpu`+O(DkqJ&|O z+lkeHq%q+I;?uGsdv!?%#rYEVJJU}0=ipt07jm#?(S8yi-D+<6KwlmAb&yr{GUR~+ zR%s{GKIuONmI=8-!203TZW!{0S>7U`;%z`dF?D1JzLm%G{3GbDS(+How}^|0I~{mh>uuNcL#lB8qR zy1=KA#Bq`J>>eO0l36|I3gpD)EOh2wv=`SG;%ojZ7KCP*46w74cig7+BF+}*p_c3p z+K(bPG(~eJrA>;ZG;p;xtshqwbQpP?GPI5G8&W?i=Br*K_dXdp3T@!RqZN>H6dIg* z8L&uEth15hw-|LoPhHS}sN#{339bN6a2jI1eE9a?j*74i(so?`4Po~R9O}(j5wAi& zU4`5d{Fz&;+;oglJ}keb)rXeZJwW--jr%?r`r<-dd@`>SJ`MWaMeD0YON~}`6os)y zw$eCx1+y0Maxv|fod5RgzH{TNe*GBr0l%^}#xvA=vo0zqt;9E(RV8=Kw0;3McYutqiPRs?35oS~n%3e-yPl5GtTlxD5AYyh;+D6_#d!OY##5>AlmkgZLu}Cu9qK0lOa~T?*$dutU?|?q~_O zDw98e+MQ+(*K@Ml%h}kdJ;vgzdF!hovln!bPH5E@_nVMY*Q%Z2*%qwYP=6lBMq9NP z`_0HA#8`E`5o<}aCV5{*`oGZOb5Ul72~B3zuIx7~F|_?b|F?l;|3Kdcy`C(qj#fIl zs^12W`v>~HI7;)jReO&=g|;^0DWCShf5DCJhCGphnVCkJMf-US)(D$TZbZpjCsSDEiBq&gBGkUf>f7?0kvwM zBF2SUun_nN!z*dgmJ|O9@FN&C{l=YE#C=j$Ng9 z_uZO|-#6;@<&d$?P;HO{i#T^M6Iokn_BzRPG|`!RV#R1TT02%RsR1NVs;yqN9PSLV z!hy^%unIjHc@eAEVqO{II>89|n!tV4AUtMz{A#Q-lxLpgKa2Kztk6T7Uw)k1h48lG z4=BU+NLXbo+IM3Ndc=&5t6|l&YJZPhU2X;gPM&`j-@h|*73zh)xesh}$oy04zXHe4 z0m+btQs~`;-KMrw?Kte&PLFA4r5hN4w#J*LgjhWg7Nx_w9tuxJ3Fe*2GQ22b5-+20 z5RAM0?mvKu$>#Ywq&a<) z+b*rzvB6TTepJKr(U*uLZW`G%t;p>}eT}v{VI2we%wD&?Du@N}R$y;^7+`BLPAOmu zKWq%fKK-s;LOIEeqbt#Nl=+s98@aV;475-zw3N>!2}2^h3Y;K@rjv&(aAZ*~LxeI* z^iD6H-webd*(ogA*nW~%kfki*+(osc?KM&Ar?ho*1nlG}!HOtr%07sA9q>8cemmk` zfLBFM0gt8JqK$)1%^enjvk(yrhgekfmksZW_Uhdhj=Q&iBSjTpss9kxY^MDlNIBy< z-yF2hkb$w$pl1~%a(GcsBz=`et5qu=0s`jBFF}Tus zWJY)_JQ^S9=_JKTl5F@<^Y}G!{f0sC=q7Sor|~(T#)4G?ZU#0NS|>?MtmA8bT)!Sy z8+J*u41O3%ZTRq{Aoz0HON$PI?~8>LFSdn)A?5zj(3nci9~(!^2Q#rU#&tjGXk2!) zbxtCgY^o0|HnS0}?tt`4cK3&Y#Uts}qkN!m7?>beLqcptq`$q4-WIaXhGomDf!!ss z9kLTzoaSJX5lOG`z%DtGOMoOFW^^*n`ug=8A% zpKzHo=}|4%RS3j?T;Cou@<5lMcX;`XMYC$-AbW$#qU|+^Tp;<_qOAhXoqkingPN3& zh#~X~9@kE1X2kRSG^f&i^Qkn{jJ8Mdn$gz6sGm?#us5PN#;H8y*Mmm=&vEU>T9M@+ zwu`QTZzh_hvhkuytfdx>#qV(cyfo5HIPD->#xoQ`gbXxf3D2q>oWtmauAngku(m|}O{QDa5Z$_C5$bv!TZueJkCf~Ro9$3uVg-YlL z=K8L#`H+)H58R;A^Q>AcB6P0m6c9^qhUZW8mUNBdXDr&AQ5iD1an-LlKSGLs4(_&S zT`^d_5@&3KB=?Zqauq-Kc5Ff7{_hTzCZ2IWW{zngrcMtLQyY~qa%hG+jbEQRbh%ob zsO@!V2eAm4&b+zfsBTY3?THe;1#NgPukUTpiHtg(iPCC53$YVa;?~$r92aNwS?7f| zpAGLU+qaO99V!#CCm5e-JFI25-<}L^0Ke|Voqr$cfbUvZfqxK$Kq$e-(Xv48I@%y- zQgS}yG6R5m_{P`ofS-;e6E|O<9K^8=8U44AH(--uBarpmDJ6Z+tAGt3!lNdJH3qaUeyNqKSVr_j+aUvqE#`E|8EaG^fkY8Nhe##$qvuG4{5!9Kts@Gh*9 zu!(EDxM)4%0wq$})?tTKIq>4|xI`PVfTge=+0&g^c`aI9gx<_{)bWCi_Mfz94-HbB zn1!Ex0Dg77=SKMT61Wp8j=sa~q^l5q1sw1-*51FY^(f)qB^l0cLN-~tr$hG`hS@fz zFN)9fi>icqS)2?zVj*Uf;`XTCr?@F|1!*{y5v&ROEK%E6@b5%zXGmvZ+HmACE0hi1 zn+x*+y!2ikT26uvQau}W;c?vCfr`B*Nd7OO6OsT{nN9FKQJgkbxBV(I&OFueMEJu< z1FPiHY)n@pUq3&#gJQN~`r<)VDJ~23I)T9C>l8=ln$R9G{nQYxp)0Fbu3ozlw8@kV zna5%R^R{~JENKZ2tl;aylHhWqziw^cjFuvAnCqvz`$XpSD%|dU&DF~-R-4_i96UYA z|Jyh!5d{MkBJQRr&0j{@EA9O3U-(&5;;adpz8Pb>DLesR!o<-e75>H87V`)6 ziIG3x>fzx2H@ttV(9Y!1wseut`r*@J3i8dV#uIv@ABWrdxhMEJ6F+B^e>AF~{HNd< zc?$PX`F7~!TXCHkWq0+&wVn7``z zPqk?KFSXeDZ)%Zxp%xDlhGAd1zhUftST{+EXU&VLAHfoRUk_v8X3DF`1()(PhciAg z`ms>%yVX@zx1bXE0$Mu^sinmKzWyeprjq*Ec#{`PEg$D`UV``aHACM~YjTOB;C+3? z5ON2XA-7-MH`S7QpLgWfuDlgPG z*Y5@Lb#zEjrpj}bH8Q)ac&+1#jM*=iIu24VwsslP(fh#QjxQUo8a=zM*CxJL%04NA zZHT0<_w_=YwO;Zx+l6hzsztNLEs5ByJdBsT+o&z<6NSTeKfFGOEwL91dB5#FW@`4G z=j~)&Snj55_9g_owDuLVx&?DJiG8PJfOCRTJK}Ees?{wpt3qD}6CA_FHcae4Xj04F zbL}^{T@wcmwgRDdquY1tZPtr2NykP03h217CqTDl6q`zVLo+wAc6b9(aE&9WSXbj3FzVL)#Wp>Z`zGV?R>p{Xu7ix2*GK@XajsZiEeT znfIHWb>5|&>%e4VZ>fxk589h~`*mfUsmk`Dw0C0$hXa*V6}uM<+pdT>#@_tS9!v8L z6;A=H0dFYUKm;;e$g=>&@6ak^78Pft>o5~Q_lqxuf8V~tq1bm08*6{`-BIx0a7@Tp ze*BMPJ(>;N;6PV+>`&UK+kcGn9`f%1m4W+`=fhu^QtaE|8A&0}2q7y5^+=qsc7Q#g z|2`AB9JMpvVV-}=u56Fu?*;b))jx=qFsZ{;vpPz3Xe^e4D^2g%p<^-dK{cSoL%nvP zl($#kAY}c#aj3gP>m9VHHT7fpj0X7;<7S`xm+plaL6_pfDY{`0TuBVG27Q5Id;#(# zPzmo2vdhg!H@c~Y*J8e`jJQ%=#XM6f?C9QA8)|DYITQECHMbU4U5kEKi1oV=ze&E3 z3wEeNq!1_c-UP5>++Md~owCg6trHkC?7Jq+fKm8ut+~hsNVD7p^o>g;TW?gKnK*}h z(J9H6G+_lG3vk^SpBv1pv}OUTP7zXsy>oKxUCu5--%azF+j{kLzzMmz1&MHrBX=1` zPvPi@R&(3?x;|*$ZNGJK$NT!i0j8Mhz5bPM^KR!&#d);lylFhz#tf?fqJ+S{b){Ug z(FY_=yPU+N7uMEt{jhM#)EUcZ-720sZTgIvS6o?g6=YkJU&wF3sOnlX0tirGqqI3< znbu%+`)_d{=(CF>Z{Ftc*&9pGe0*Tu+*4)Z+kJM+O*gZB*}#($*C&%k!M{CBHJy84 zow;|v`NoK+_!h)onax*+lgAE5w)o~nJU+@7bgJ9up6UI2w+s3xSxlrL@xg8e3&~gd z5+EJVA&V?|De2sC<;7BG=LyP2j=Uv6#0sQ8y$>zl;4mdN$U5MDHzCW4P-y90lx0)r z3zpty>o;?6yKQEf;&Y5?Ej@S8h)E4?^dZs+8A(o>JaMcFAz1(}E2Pl6O5ezaRlEW7 zBce7UnRywlwDrBnfyfqUCm%+(xCZq@gRC$O8irjJ&pl8_nSbdxFu<-m+@>jKyH~nr zPX0$XN%CY0sa~~u!*WG3mTYQwSaitiH&gnbsMg1#nMz5J@p9g=u!2->TP18f_4waJ zvpdMHN|G(HKx)V}XHn(cn4pm5-yG(t$N^f8qb&~4~!t=UFqs? zmFN0|)XnfYrwaKB_0+fJeE6&s>tp%p{qR0J#j| zOfE3t=74B}Hzpwr30eWGt=0<@NZ^bH5-uvJtrJBFsBLJ~25D=8Skbm`NtCywN(t5r zR&5h#t#YZyYk&w22%O1WGXH1ob0(RH+V}mwpZ_oXNY2@3pMCaq?X}ik>si_rcs#30A7H%02<1I79*NiNR^l5NHZ-c3iX zHnO0$+V+ByqfSr48WdW6I)CEYx8}K^pF|_B23^^X*co#nyV1Re->VwX$a;ZmjY>SA zP7S27_!&HpPQ%`Y^c{qu#2zD!x#;-_{r5x5lN$$?pwSwbW_ZuCiS!5eYy;usw4_b$$QO4;Z>;co^6{_n_M(kC1 zQ%Mi_%=BAImR-K1E(b@b1upJ<+C^r!yL?Tq`N8p!uA_=h^=_;T589Qoq72#0BV&`i ze8~Xt<)_l=zLURIgtsEFr?0VRPwG2FI(pa0c>H*x+OyFr`u;_otQAlX%8d(2Pbd_>6=ld4|eXRr{Z^zkM^Vv-c|80skYz^aAX8@hq%bM`cB^}xKJZO zl}GBit}^}{7&xmX9OmIHgFm40eGnM7q~)b~>GBJY=^oer;%&swCa*049#Xr*!n3l} zqr4HKGf5Ga_-n$(mL%?BrRtPPA1H$R)d8RLa*T}^+FcXQlSj5ugkW9INIGwnb&nF7 zt^~`gB_YZ4KK##UoXBqI3Q)WNFti1)r{F&9HxZl$)9?AQqc|m$JjbN>l^P(7lXiMY z@4Cphyc)9CAeaKt^NrZoffl|8=%j94@wQVUW7_y9br0R?A)#yob&WsE#_3kb5WpNhHW&(^;?0Wx?5@#=q2vCRJ6**OO(zb$C8syO2Bb|>EJfvG_E z#CcMCm!Kb*^R*u51(tW!bIjAqtnek^I_YUMPUy{u_d(Z3py>vRt&V8qX=Q4dN|}mr zjaz2JmOme{&r>iywl>(5?*oc#C(zbsD&ziOrWv)KLFd7t(;XbEOiAGS%2W$6c)Lyhfbnx*f_20nO1$%!#X6Hs_5_FQ1SioHI=^R{vt+O7?r2ag-{ z>yI1Rya2O4-)9vX`m8Md;83pjBg`?^eWg1W=+#2uu0FlVcZ#LBA;bO)^diAupvFgM zc;ce9;$5{X>p5Q$)9hnJ%)Obc1e9?mtp6_2d~)bM9rv(y=W|o<)OQnyO0+4_8)Qhb zCl7{>a2F^B`HHAo0jA0QD$RH*T-gq5^l2pdU+-SvHo>xA5dQ&+zrRmW1T>!ujqSv~qT!od4>jQ&eaR@?L;V zB%Q0$7oNhCwq8*xfjuMLZ^8ZMg!`Z4epABzL%83NaDPAU8+%KjQHKq6=$?cpck~is z!78Nqd5ns5>@|ML5ASu6;};~$Q+++bUxLSIl8oRVe-6#%o=zw7P-O26d4yaE`?0Tj z19jzZ+=Vx;K&kP%U(UaH34M{BzVeGc`r;4q{vYUzT5h^JKQ~I}xo07Fa>Cb= z&~gLhtaQ|t^$L!FL{=Uog{WsJzX}IXdv`nird>Rs?c&Ejg@@UvQ+GbTV^oXVm(`rr z;)WNDNyus`gAaLD3q!ul=FFBZY45EgHf6O4zKl(jUhc~nQ&w%0Y|W!unz^sD72M3I zmI#n*@Rl#5`N%Pw4RLKUC@N-pvki9TGuZ{s#(;DE`$uho3)mHG0lSU)+0WV2>~r=V zVTbUZaFuSOPS(}x`}F@x(wkNp?nr*maE0+HV@lHUB%i6n^ohxsG8%#6A54K;i}_je zY4g>VyDj|)0sD^izSK8UKT7>>+McxH^z@drX4oHQ*jj|+-3u~WP=~Cvmi)K!yM(~e zKlfKrdh^r~lx|CFPH#y?ZBs!l?VMWLK`oE>#@kpQxTnk}A%Dh~^TW4wmRWj3>cU^0 zcQ5o+!@rx>BEY^Wt)Pd$D)0cJtHVjm`?vTZl_c-*lfht)(nK zZ4+~z>DfLk7u7Pe#pX)e46cY7q*UIX$A|JPpr`bVNonYBzlFh~*ws$oUaz&)D66B= zG?iMO+ML$nC+-LI!rE+=(=ghW=2Rd-z7fSep2dB-=C`M}SkOn7VSQwltt||xX_=`{ zjDjz~$pLkKT$NBK-uLL^|GWA${vXxnH(GrRy}S=>jf{H8eLeNhyfgk4e0I!tx5pgn z)!q(ugp=jL(NX6Pdg^~te``X2TAE$FKh3;99X#HdN_mQ?*FdS=@Zq8!cY_8Q5U~rX znnz42PZvC9tgSGtlNt0R)c4T%Oz(ko3w_UY_@X$7o3QW^uue{k)J%vda@ zXVh<2^xN=tO8utJ+|+65yx&G@{r34MgZ+kesjk{olo?TUn1QqgtcZmN8Bj2JXFDud z*=dL}m)atsE(3}mqnw7n_e9O`Pr!&xr8mRTQJ{xiIE_p_l8*T|YV$rX_3K#B$uenF z%U-WaFWZN{{lA=bG;=Jdoy|qF&D@em$5IFTHw`PCdd%ExLI2(tq4_X;g`3gy!{0X3 z9BxkEf?jmc{E9}@6@KF<-_C5H8fC&Sj%u9=?RQ#>e&5^2l7v+L*C3>~=$j4CroEBe zawB3a=mdQW*22_G_(wH*XP~ZroHHcht!D5RkDM@bDaiaR=x|_rEPydmpQmciP5im( z*;G7li8WvjB{%;HZ~f|oDbIx%A;~SO&Mz6Io8=^EmE*K7reyW2J@L-R-)2wbX+1Ie zD|_O|G2=AD=H!-Za=m?ewJ)Ft{?C0;@E`hO#Cd&D_NBf^9@ZB>395ZD|6A>gFp z{;+(D{qc44eENTAOVO9w;y)=&#?K zjvu>y=EUAz<5PwL|M}T&@1>d;i{~^4c_X$zTuiEjS3_G8vot}35rENfdwNX{UiJTX z@9|Zu@=CDQNa(!*<$-~r-kbT2y=M!H-`IOB+#2VX(1WIljVE>7?t|<&jw|!}hwqQp zVLfvPxJc3vEdLgJ=Ii#yZJ}@8>mLop_xkwED2WVji+NaEY+74P9}h|n8uza9*O|@{ z8oy!&_nN|2pxN<6E>@tBqS3_^%%Ab+jfRzTr&i9rR)xIiZ3||d)zS_`2#YrJNCGj- zBh(rdW_U(H`glF8_HOal)(E>TpCeXnH&ws!Y(MQmmS#Hh0lz<@%w6ubv?O(9ayiE= zXAb+yquN(~@HJm?wG%fE#8Iqj2928_LW&h3eYRM^MO$qqXhy84{ddlLU*~~FhD&AL z;G<}sB(x+!Dofq0>K0Uqiu5<`T(@170S6ROlT?Olq0+Q>R9WuJ`i!`omU+awIUNzs zbq7eMVvyHWnJuKu28~aY+2VIIK2|jhH0JZ6?4IiQcWl?on`AH(o=Al*-RuB}CP zyxDb)&7Vt=3XoQv_bsgg^ay0O0pr$DqAa>rJw@T5s!M zy;WKI_mFeSd~YYz8-1+Roa+ZMJ|bHGpS4Z@d!37bxa=5{z%{Y|+=8#~`Kx#fe)Wwl zDEgLL@Z`Y%O$++44$6FW-`IkQAFA34TEl+H#edW4BfSW%zBH^pEA%UV=z!@r>45pO zc6DWngSyEt&yBC|*(Z6uJYQ3<4?j4cBF5`TwBdXTq1KU}xi#vcQ>n*!b)1BjoUgMT zKBrTgQ?)q_`CeO#R=yTz@p@-}O}+p1(O|s?sf|0Ibfr$5i2x6!PskvxP3jXwr9y~p zL)ssBEgZrqCFpaKH64_yS07Mrcr%LmzRSm)Nk@>wCwP+4){ycx?DS2|nX(C*9n$$GH=8!& zJ?O)eTW~Tn71lCE#xbK_)q73wg)zmSW?)Y$|M-CV6;rN|!QajRb*M($B}>at8uf*> zrOca(If}p4R(^sY3b zH=i(pXR?ByguV(~l$A#wA-xr)81T#lZq#atbE4KGaqZL#C-CG&!=EinJ9P!c}Qntq~38DHQtAK=QQxs))wnN@c6=gxz*5R zB|g0cTFc>jySQ~RR$btwXm;nX+h~Wa3Szc`L&8&yI}%Vf)sc8XtETgdTOVVM1b&To zf5G3K7{tuRyLg)L?w9q6Nt`1~0!PLIe!Tlr{%&dzdp(y2$d1{C)6B#&Xpb!Ot^SJs zf9eD3bE2*ydNvgtNB1#PdG|513-hLY?=hVVYl8Zm>+22WJ;#!!LXIwn=6`A$sGpk7 zkgiKecX9nPr?dP_Af#Lc&V#t9_!^0yYth-=aPA26We?VmuNgZ8jX0f1<-d{NMJ=fK ziWZa)QTRbhNp!NbGrop7j9+6Wroo=^!^BB#GLb2I1>=1f^WEEEf^n^K_DraUJ?NatrOYuYU>>dDId zcBEqC&j6w~)c?%6|8Tr_-j#_qmEC62+DjHaY0a6NZBsLzNNYK(+#4in z-1_2lna&r+!%Aj69DNa!PF!~Ts@38mil(36xl+ohP1@g4bolhJga|%G7p!Lq2V-H#}Corx!$wR+Km-@{Q*?J4jML2Vr-&881{m^SD$gtB(u!;Sds zTL(T(%R%3O{L$?Lx9+RH0(RZ7ok<2?Vq?eOx$zm;3Yq#W8SdP9$HkmyVEyw8&9;zi zUyMfxQ?-g)STBoP6H1coO_S-jMScxu)L4m5;U9F5Gc@W6 z{u{O=+~Sb@cSm!Sc&C3JqHOBR}~*sBB{;o^Zjva{e8 z4K{v777YToxG>4@1#PyTU=!I~_?RQAyazOfF*xtr0jtZ%dO{3L2ZDP_k04$OTLx~m z=%ufGCw#JZ61Usa13MHky+yJY5~Yx`47Pgj!Ve^VZtVnyU))CXAH8OHWc}%EsD9fa z1H7q1usdga-caMR&{|!%kOK~m7Z*#_@Oz45r(7yF)C2O3{PyeW>lgQbc0!zJApNV|Aj)8t*;c0;GxmK@|QeOMG6yL?fl7FJF9FJ1=BI%CgVSmw@0 zU5=yXj{={r3ICb6YXw=^0E@Jp;wunZqBuywD1W~)k)O(BQA+-++(QX0H4d-Id{2qguYAhSr{i@OMArU%ujQ0rc@aGwJGbf&Mp#dUl)K;!@C>)t%-OCCZWM)aM3gn)cj)woipU5U_aQ9VZ+X zMEH$}$9hKs2ZOvDql!P2oG%*Woc+nQKbQ%fb_(#Jz*CZ4yx~> zufpk&tzJfnU4yo*anxk0qdJGFj%2}hM7f+J3&-mie@^J5WU~}ha{9Z{PxNLLl7*%V zb(@B|84jv&vSFR14f-GO);L-M5Gaz8d}w%$ub4333}O zR71*VkvF(E*Be;HLAU4`RqLwzPH-+@KzAqI{0UebI?ZSLfc|2M?oz^<-_Ak%H(>dc-5*J=wUZ zociWXWqLobDILgpiZLC3`Z+La)n}vok8$5~1IH;N&r;QX_o5!Me1jkEmK`UnEJu}2 z;I+6P0=mc+(l)1dkHfkn^fCkd(uFC;BY#9R!csLN;X_ZJ$OjHd*F%&u{m_#q#thz> z_AmG>+w!KeI`S&|PrxcXj9GcGw-p?^iU+Nx_i+2Ybl|jQ^*AIT=P(~^8}A$tKtIVg zlq{jU)(W82UBGQ@gcV+$hph5;qQ~e*{)_f^*1g<^gUU}KpBIM>{o&BQPX00RS?);q z&aAKfPFjzyg=z|`LtauOEP&f%f?Df$Py<*WYGY(5NNXc|-n)TXqxwFa3$r3%jd2Tb zdNKnRz=R0~uLwj-+`gj5K5CNcxdGek*;jv`+E9~jG1<@t!zm~Hp@PcK`^81#tsLP> z^ZUH#HuCZ$>wFJzn`E-%*L~ig+2tXr@RI@UP(Yo7FE? z$9-9bEUdHrKs~6gUHl3VH`F(NvluCh1)$ltdY`E=6r{l8IHG(qAlH0!+Y?fbBo=ya zizv;Z4{kGgMZ_d;;yw;T{i6Ej5WOn!DatvHYoz+f0}J$Cwe-h$x-S^;>Y9nqL0txPo11Fh4zBi(eT+Gd zRhLxzyl)3ttFGk|PujEhbM*AZG2OFi+x3Av`{QF!z%7Ky`(d2#R?HUYLZ-IBpEtFg zwZwfN7-R$yI1SZ^{qFUe)|>_Qps9MJ_f0Q+dc0Th=s6S@iI6FZuxcdWCQ*zFx7~)B zKsLD8x$PJX9t}x^--&PlzKY06NMNO&YUxd-p&vX_9_4XWc)j1L_r<^2cT{40cWqGFrS zcj_K76k$c+4HlS;D2f828q<7N>k!9aXaP=Dvb^&wo2TFJy169BGI##96d&>Ift1QF ztN|t_RVB|IAvIl_gpy3{G!`u2KvV$2*QiT16v_A&l}Xq}gkOYMl!#>qE)&;b<-4JH zzr5NZ$N~^lD5jY%@G;Lr*J0(-!91_z4{7L&Rc^YO6E0d602iGK%PlkxZFX0-#kus-R% zCr_kXT&UYQ;2SmUX2n+dEPQLNRh8Fy^S48mIjd}p3P^iBN^>A^0C-?P3K9apN6DX} zU*bPB4`|N8D*@hUh$M;_jfn2eqYH)=AJCQ5^gOfzv4%wf_*U>O!YYclwyT3RFY^fF zSdm$F-h5VhEqYcdK-vAR5+D;@UEv6amy#Enz=ys+civ2h}w;W@Z2*jOy*9^cvI*D8xGvf#$e8mR|9EnrndbW6;4Pw} z^r-zr^JI8^M5cNt~55?h}Rq+8#iA`3s4gIw$j)bum(FqYQ*YF3*v|c%C+whjU+F4b?ln8 z@+qoAZ!A9c>pFbcC*N1r#spBh-9dCADE}^;BvTKM0TSSoC-nS!G)gT+iRzEK4%s+$ z#VyjxCO*A0p=^pp_r7u^c%*836TbAmGCSs~c&$S>C6#|`chEqmCdK&X596!tqY!=5 zz*pXpkh=2XUyYCNI^guNVwFZ04fb0IeBV&J^!(eY;P>d;x@X^4l4H(_S37i*^YLvf zV%5bv%OD1G^ztP+AhdqO@ctY=29c76cd0=NzqyN446~^-oYc;>QUmDqch2 zU=@6)s+6zbPx`;pb`igNAN%XYRnz$O!T#xOE`Ie7q+VDxnP30Ce_GoFe)R@Yr&f*U z*RS+n&{oW^{*2TMstWjZXaAJ8vHS{qYQdB$JHP&~{z+}Q{AxQ=CsmE+*H86N)b{0H zA$4Mvx-Yl%m$aqx=Rb?Gz$XJNFefGiF2H~IeFlDt|M!Pj;HMEGFavw!p?*g3mIGrV zEbxBVwtLJ7gNf+TqT1R9YWLr(4W^pfy6UyJuVU@->t(B0e+MwXD5kJfyN2>jU6^Fz z{KLY<1X{vUUovtGGwqgDwHQp0y%r)~_-Y?O#SYChm=;U5i*FlDVLV3bhswIJ0o3%5 zpr%64hsp}fOq%ONE8}ZI0OzO+j0)zJ=pFO?z)f%RHh)QW!(=3dv~@c7Y+(^~HMmm3nk{CYxewH4I~U)~kn zt#OdXj%PbW&!@^;Un*;ELRoEtWj&zv$fbCito6vx;$_WsSe+>8nNVBDt@h@QPnE4& znM3=N5Xjfcr54>jSnfKMOVlhKPmP@C3MosXG#h~PX6{xVfL|eLiau4=gw&J=kwR2s zD$bc_s3FDve9fxNfjlWj2ct0OV$UR|L?gx7M_WfD za*yY^p;Pd%65ZjXO32}d2^ZyizHTW`>VoZvXj8y55k48wB6F1m>l|?fV&*nPGzVX? z8HjD>D&p!{;L(_=jd&H%GOX*W9~$|(Cf<8tbw?zZ>wB=8Pzb=Wcv6mvx z@F;&I0Z%^m1!S8gJ`EjYGsQj?4hqGiWi>Xd(SeqZ&ZrV_9=xj@rxC>|vhZ9Qa0i3R zrLnkG5k(2O8UE?QW;$6|0pCHxd-1ylFG*n$@ctCfuydP%%lxA6m3q;0Qh6PG8_A<8 z=F}MAjxlo;bVp~EBNHlS?99pgIm`KSl^qY`!kzKM3HdUTTwhlm11lzsg+`A40fLa$|M z6Tx?-Lbox5^#O?$I(>MW561osDltUMP^B7GFJc5j!6@#jeirM;fVxo}v8~WvmO`_v z#=D_-kl6=GGeh1-5-fli*DD(+>Z+z;E^RMB}_W+i`pcWPw=& z*DO#vP^j&Ih}u<9z;{5B4IOPcJnwjgp({&5g`^C4fT*>e8T-_5_-?4b{LKMT;{lnAvtBE-AN9oKbR)?hD2CW7;BaEr1~M2H;0`)LQG-o66(#U!_|0IW%9ghk(yU!<9Sy{bF^Muj?`?e7k$yu8m(E3)KMC( zxh0yV_2TvD#mmtT#6#4sSqMnymAr4NkjC$EmhyM?x~Bg2)$G|Dc{;~Oy%;J}(695t0gT<#!?F79jaLJ)bC@pqs?KQg0+znJT-Lq#!FWVuUGHi>=+* z`l&J|s`3$&fWdmx*%VXVV}_z73zyY{9r^U}^&h|Z-@VVj*!$v>pKNPC`ohx~yhQr? zc_dC>kD=TYt<4`tlC?JfJ80XTvs7*K5*#NH>hY;1M$?joH9ndML~B$$Fi@J5=|1xX zH{)b7Ibcl57-cWG`kI?=peWBX*>yN4BpUZR>Pq+D#XZHcdA`4r;>rl7ih0MIOUh+& zL)!*ZMb{T8DVNFf0)h!Kz+2TfF7LE+D)}4W`399^{c6mp2b`qO3@TfqE{&4V(}U26 zvpx7uE75eL7A0KhL5V3gMD1y4E?#QI-_^}dAniGeYnK{je5qN7Z^mZOyOkPk>*|li zbe@d%Oy7-?#hdBNmelz1D$O8DcUHL}n2b40wBfii3-J-+kxB_G=)qfoQd>xR+dmzq|40-K7?uDDNYG1~P8^ zj)W3F86-TD$26*_QZAb;!;_aSB_u74mOaMxyZT(N1s+g-OqxRt6{CoM;LZ6+tE(!S8v>IZwiVaa{Q> zkhhj#l;2Q(9Xr2vgx{4CcrbJo&+$ksyL|z^dQwU4r@jyVG>+jyxmJZ9>?GtYlhxxC zx>@m9Sv`Sf1^Ym)gUSuiRFA~>S@Uf`ArYdZp_YiY6>U zKY{`t;}|ySd{&)NoT$+b)vuY)fe)pvuw-%JeC=k)i8!Bb7q~TYDbDECXr$`y2s?wp z5hqR&_VU4@5fAPbJb#rcu`}9SHdv?8{3FdQX?~%tY^E7~hM(hdWZdTnC(w;KJ{o%M z@AIBDoY%8-4iIT<0JTcxI6!BVzXF*XT5zcccuSa#g&Wt#ch;erkWPT8Gf9Lj@N_7T zQ*v;B1C*-nhfjoZ_^MitmRk@MENo()Po(A>fno zFRbF&l$ZZNrE5zYeDw<#FIft5#!{{~n)to85$;4Dey=HZKLJhWeB~ktjri%m#b{au z*^hQXx~F!G)M{LY@6q1F0+*r|BelKf;!vhmV;530wY_IzXawJT7$Tprf)N@W7DG0z z#<{5Rb=v;zo3?mx^QlIfdXLQqKkuRb{JwU14c)KM?pM|>_T2#mILQKOoRd1EM57dM zaTMlwtF#1bn4~Nfp=@aM`Vhm8uqub1-jh(mVO|1BC-DdZf_TqvAD?O0hx(yi9s1g9 z$QwUF8;ZU=RIcD@2j@*3aKoH0*J3+rF%6}DAPp!}h-QIz~2)wal|9V=@E1eocCpWfY?l@Ek9+9VtUX%n2egtJ9G6aQvo!Z zo?UYqc|=zo^rpzSKIN3bm~zT*V4~A&5}hk(SG$ZoivPetW6}ybyEhc!MA<7Z*(Zuiy-V3RBlcaxsiPDJ8W?aXQj zR_P&8A49;^@2nS>O3S@Vwl6~+5l>efd#Zjx&|nw5w3j9YW<@E^DA5m^r6f0ufPP%& z*hg~)dGaCtTTwoS%?n~xF+Lyoxe~p1M)?WwLME46| zH?=r!os}y*mj^yYQFaeB;{2@E_iE6#!`iaFnx49Ik5+%M%vb$sEkz6#F#4-)rdilj zV5MP0oL<_ygw2X_C`!*MMe@nD#96UDUnOzUPC4+?7weit)-n{VOd znver&Zzc+fAIHnmCheOIbM{J&ux8K~Y#dBcXJbCjIzB)Y^)z6D)3+MV`xZ(~Vtda2 z;?MC#!iW?+`y{hR=dCQf-@6a#A3Aff8xnr`w(e&BtpUEDs{2q(i4Mf~AqCQ*x(~&a(*yB+=rg3M`w-%O4aE1M z50I+vLowy>Kztv1CuG~*^CxxRT(PRbw~#hNUk$58+TcC9^lbcI+eatI?*Y5Es&@Kq z)a^7kiDqVj8>N_QJ0bHBs@oZ52XN_fJ( z+|{uiRt_{iF-~Jq=UO1-vm{8ayseQvl;4rO-x6IA_gZ6RPgJvSPm28joh;>e-D9W{5 ziy})Rs3_H3m0U<)GnUI1XOzEjx@{|E%_Om?-+mDIx9S-D=Pwj$Um!ZI$|ls$wDMKH z^w%g~@+9$ozEvy#3Luy9+G=e}=xsjo|M{y&x#cfv$-f%I*=by-6N8kY>U3D(d(aPz zt8#$1iz!z}i?~jQ1uBtR#Ch15GAmlB@vxWkRN`S{N@=t}<6);EwSe=mF=cYpp>c%c zk?P zC3W@Hkl|Bq()d{Q6;_>ak5|}x3HRD7>^>v~|- zPG{9VisLZ}lvxk#|5y7}yD5r`I#o-1vHwi(nD(8)<-m=GwnyBCs~7NppVN5ArR8}R z(c2lG)G_^YF20-oKEe>enQTyW*hBJVpfY23u_Ua<|BwA zw(>*7EoPgI0b8^hwn~*=;@^sbb@kpRcfQwOcNuH>9eAC^)yoM27qO5L$qIpimQP-F z`zpk-sj00I5sC`x9N%)X9~qvn2E=dJV>SzLi-S5Jw#BsV^9xqO!;q~%eGT!H+M2{bQQiwg9UCwKxfEm zukh9Q)>Svw&RSBjeBF|NbQqSBW?9uw5T{gyHTMN}+(gNABDBP_JS3OSQgsv9GaYi` zns;g1+4HH&R8W-??!}O}f*%0AJn9w1Y~tLoCbLi)q{ua2)@g`(=oWRfGe;2vEKZk# z_mdWZH2s|O02cq%Ayq?AvOIvOqlhgJ%c%2h$klI&$bWGN`XsI+AT1Z!=6#`5#|%K@ zgj`@ne7$0wOxL!XRM|$=7)9I`U62jXE z5v+z}FkukCOXZFW`7CjH;(KOXR`^1B6g)oP{aJ~Wi19o$16v07wFZ25XkRN;?`L`w-7ns>%K_ zW!j+Z5Bjgk{xN0zpzII&ugU%~#SYp3ZJhHEonLilji!YK+xoP@ME5v*1_uURgm$m7 zTj z7{x7tU<1@X&P!IVqy-}Sr0Ry%b@OV12EeXieL{E84eLb6#9T^lBrEZd^5@`?Hus$J z1tdzJce+Dqe?P3#(Y?#8R3`6 zEL3ws#aGYP(4G7zvA=4y`V%f_Hn2i<_-%BibSDAV%OsneR$zphy2m-wd-Pb##GggL zmxYKo!~b*mpY8erzfWOr`#eE6@&)(;(!^9c1>hE{?WU$|Kh##8_A80B`&Bw&h zu#z&7*HF2xT(9+S!)`)9P;sSo9^I9d_V2;}t6`3c;~cj^WJLzpm01Io177>Oju(JN zuAhsOO0iG*yNXQBW?aShFU@XJ9gQQ9i&ZQ6Bd3{Y)Y%R3drv zDW0hg{!@sWA)dh)1?SPc;MTH1Cv>*u+B+{HawRLA%PpNxD?9t|(`e<)frHR^ix^`! zY)>87#YLjO!1RO8)FDcHaX&;a;?E2{Dy6k(o+Ux(Y6MS8r>?SLjtLqdKMVEREEZE> zXQrpAob?2Dzankx(`UT`Ol6DwmIR8~r-KA6+t%U#Tas=1Ti$EzPn4fJ#P%Eo&!FzV zgfrgasrAvhF+wySfizZ6(L6K3%P5G&tC#cm)go9|h%23vss(_r6!bni#@f?lXbAkI zb70+ns3ti)2^@eEXcF}PGdTUCUQF;=SnI2;Lm=A4E8)Z=R*SPHQvf4z5srIm0QZbp zdtTlpE9;kuU}07f4sZ1^hQ$V&MtZPx@KT7$4NjBJqWhI+DNa1%JjRrrT2wu{el2W5 zTYzaFH1SA#bo~;yF`={6Z1m;AIgC-r&x@v9$QFKo_BG$Dns+rVB>GO1<4O4RlFngU zG#T6m>7!@jiw6G1hJJxt!yt3Ry>2(+VGMs~W7MX-Q#|<2_lLdHlsfcICjU-D)S|s( z!8_E(e&w=$5n8T)1yi3&+nRxt6UvSKwx=?-X7TIm`ZJ$m1?u&@q0)Js?m>J%E!-hn zSTzrHxB;hpYV1R#(~%!f#|3}j#d#dk5%37M`M8d^XDqK~kE3OSYQrrzbo{C?Ad!^ge7=6pC*TlnOvSm2-(?Vo^X&k#E@&3ILZBWPY z;b7u-+?nc_h=`ARDn>J40&o3Ok@yV2`EJ2@-un6=jmDy2(Urwp$77xu0)LB*ztXvN z0>9oDqrU@6X>8(Pn|>UcuyqpN4Js|sq107K9mi82iB1^ID}`vDi%5?t0*~KFrFmjP zK_UOTOG}F>i}{S!`UG?Fu+3s>6)mQ#t}9zOzwFvddeTt6TB5(J9cub4?ZIO0!3E|^ z%`?po^JFt*hWh18D8|*otLBwe%&y=zE|9_?S|DxyHM1$1m$|Z*l9?U$6!E!Y=DlT& zWbnBXRi25lf+XIycVpD2n_&Z{jVhm`hOD7?)wOmqtoC$N*?@OxjDpIahTcN^b|t)% z#=rNEaFX`Ddc0%i@3h9!;CVrPcKLv1uvd3~X^k`^KERD^^1UxlK6CSp{>gi8o`CjC z)hp30t7}&-2mLiA31{vtcOTb@_^WdtA0fJrXFyX)PnZ?gV#6Fr-9wlfd&c1)78U%D*YK!25>=ggp#C>F7CqQ4qY2 z*)x&z{>-5d2uX+*J;87!GYHhHpun!lw|n&R^q}tU85KXv7bf%{W)pNr#5Ip#uOW+4 zp`xjS^<|W)zsI%j>)886^7uK&nWL$LVmsP)#+2t`hm_mHr~J8>C~zh%#1BHXXWaa?;_7fS9ziT<8|C?+da(x~)B|q!(uf z=eQn+xV2{Ng8P&toMMdDJTNACtg^UfDq;sDBZ@UiJ^Pf&i1sadKJTrui)+MoImd{2 zMor~??=kTc^vN;hPoejeZ3BpwU6A3KTzN>5BY#!4$BrpA;lCn=iU9wxzbZ%ZS10~e zfo}kI|Gz2&_)GVpu>0J{?&HeE;h3^67DGG&J4*OB?BesPO#Z1d>^GY%PAB(CPD-(+ zj~JPqm+vTIM#O4x$i_f028liJVmJ@Ki^AD*QlPAVB(ATGjllH-ILk*Yy^s~xp9fQL z{o_~?u5S+NWyl`*0%?`s>b+^3z6k52$hGq!9+4sGIXW{D0<)un=#ciUUy1d*;a>tQEv2cUk@fNe4ee2RxA7wuaq=`Mv`v31?t8C3rqWo@Tc@ z-wpl#rf}di3y-j=Igj-^r4QFOO6qgLjdP~HGTXnA+OH%>@SbCnyDH!0R&(#~jh9p+ z#q;hPOrz3Er1oLucYfp3=f3gj7I2YCkZxGfVw}gnuDlvEwO0fL!%BYlXMU$M)bYDN z@;ifpO%{$+1WX1xv2pFBlQ`HX1i<$-vm%VkvyKXrw`hzscx9@LrzHJ zN>}_Iky7-5{m~kG%A})+l%n%=lcj>Bzx$!`@L{2F)++Ukgw|P>r^Hv8@2t-0yuIxx zbQrJ0ie$UgTD}%hJBpkI-Nl#(PH?&<&J{gbvUg1hY$M=lq~B^+wK7$ZgOkaEXI0PT@*>n?iL;_7MOMGf0zZHZmeyW0<~O~U$lE{xZiE+f zC2vIykB;1@G(hj`y<|% za#W^v+DR)g{%_G5YA*|{LhI7nx7q7@5xWHWJor!J)Tdm6Z;^*P^m_W8YR+(bkLoZ!srp6Il7Plh}-)0y9MmwknuqTXB>+i{ASgl>;V zknge2=*^Pvu(Lh!a#X7F$Pa#oJ{B!!;c4sx&B+yxpwg+)Pc#2(L z2lH;kpkL)%zEm84<9M-p3AQM4d~xxT@f0RBzGV&a`6IcWtxs76-4?}&qIgaKI%*yEH}m71JC;G;k7`!l}pp7Z_ruPbZAkZ*2gffnNe`E_NbcIP(E#ocZEPUL6w zG?$E?nMn0&dH!T9#oZ0soyj;Ach_ilI^zV~U8&s(#zNdxXm>WF9e0;&ccsRWxVsp4 z$v3Y*z8Yexr&7RklvB>R5oe90b={eP#irgn50e;r2 z%1#tFX(X%*-0-H-znjq(z?w@9ifc+JCJrQF>b(hTZd)TbEZFT@fZtx3FXS5$J?B)f zxTYBrTb12wH+b%pc9owb-zV&J%c|=r&JVP<@zHk1hZy0fq1#=)dKC|$S6sYke2H2Q z)%R2w?_F~X`jCys4vOy;V|CZq9f)2RQ^v-2wUZxVpwWxDYwc;ZBf{JMZT767&bqxk z<*>MBdwCK(?oXgz@Q3Uv^&IV`n(Zh*c!2!rKR~PB2Zbe@Z`Ce6s$3P@(as74P}Bis z4m66Oz1V|QA8q|X=CI~f_Zf|9yp;j?f|+H?t0=YbuI?gl>xbyg?fr2pZ}K28z^g`Z zklc6;`CxDPSoxx#auV0}bDq=i5b;lmIWO089)}INn)AoQawZLy>EwRhzK)DQ_ZK)m}$47|cA=nb|5DY!JTPddkA9Y;p}DC_tP z%8@%x8qRxmj{KLlSY)-tzf*}Xs`KoP*h44T7Pg1b2Ke~%dYbr{syatPn%D&GlrUbH zY&dA$s;-<5!nz`pENB`kj9-u;R&R~{cjae}kj@I)2r7y16?atE-Cir!u4$-Uyqe@R zDwpiefptRVj*FLDiuUc)$|Vd9$}tn=j?>DeIEMoYIRCFHH*xMomGWq%wmuvYRTB_Z z{uo2lA>NM?k97|0G~S1X{c3NVhK5PKQdg4NE4si_AqlDJZj9*=|)${(QndlcD_Z@Mxl(L}egV$ww z^2Ei1tBz*)n_;XJ=tp%ai zJ|K zF6DMk6NmQ%-9A?5tZ*W@hKa$Yo;bM0VG zI!9A&(+89QP>s?&4Cs+$DM2MV29mTn`Y*&Mjw;{BdqM0o>TWck{8vN|{2BqX7?>uQ z3#3PgD&HHh$fQq;8>W*_KXY)cV`8KH=pUVvhU|l%ZJ|Hd8RvnbwTo^ zp|fE(c`rc=f56QDvIA#(w;>KK&N)^1ie$i3 z*b+gIGPn}U3_uToGhQ*UyW1|pj^n-#>jbvnTF`M;TqrgI=-e{ot;y!>}r6h>B-g>wnSIWIScEK3Xw0^zaw&2evyj{_pw={q1=A68g&2O;_&+ulK{o-~UR*?}9p40qxo7 z?_K3%-o=;D-}iSA{>9#G@&tk>-F|DO-~}ow`dcl{#QQy|+l0DW`4_zvv-~bdb@4u< z{!?`yY){H0MlnS97(2tgdSIUvu@Yz&_v6&M^#{ye9eXGvyUL3-*$h zE=e}>H^Aiw>Fg+F(zyfF|MVW77p{{Ey|bi4_QHT(U=CF<9;yuNrnh@Mz6hi$t_^SNOl#O11F)QwJ(*q&SM zwEx0J26E{r;H1$gPsG_0rRoC*qo#J?BtSko-Agz|oZ}uR-iEljh?SibI0tF+mQL>) z0a#VAWD!0?oK#yor1^`4am9=2gjbzYR?pKCWR^O1%4!-7PYA5FKI7=pyB&8om79)u z?-tt&?sj?B;uLv8RJ^-%RS6`Vlgfe!>s$uu_1&O>Z7=`mutt?;L1XaC7f!`y+Pbsa zg-Jy{O#Z&C@0?O)^K3fW3QQ@h-;cjt_&Zl71PUE2GhvrG`d`P`zJDFl{Q|ZS`+%SM zi)Hp-l?M*#`t-H{W&%pT|Ci-ihk@3LH`qwv5$3#iOxOp1tA_Vr;r1%7U&Y@Gyl#7I z`H4e$=#~GRvjsT~s0B(Ky_>%o#7P+V2-vKU&B0%=F3B!WoiFJ!&6R+%s6R;pZXqkg z>860ORa47w(&x1^=Vv{nvsHCZF3+=4K$(jtViO@Q#?b>ssrrjYY@!$Qg4Q+n-5f>H zSdXPVdn73OaWDvEAlbVvcmdPH9vVtQQLcUkPv9%QW?gU^!)jUMwp*Z=eI;mXCXcfc z><_TD$B9Gt971$OkF7UgHHlt*r2$wyIH_botPvd16~#~fjnKKxZ}$Sr`B8j{A!Enu}ylXvGP&x0B`_3tSQ`;eR&;)tJ{4gV<|$N|TmS5L9y(b1XH+2q%VU z_!)eg=Dhkf0UnK6!3)ww)Iw~)RSMO>27A2ElprhwQaWM5Bb%j{`MZRlVD)679t>Vh zL?_68%BMx4WEgLMCoJX1B*R{c{+a{t4A9zQvM5Q|Ur6d*7c1Sp`do^MwePJaoqW6| znxzx^w_s!%C+D@hrbzb!+mJO zP$>eFv{HszZWt_OYK-U&o%jSI|=z%teq$@O>GU=q-6lHu=^rnZJPA!t=+r2nd7K0;fWDx+ze=u}+ zAUtq2a1&SY{e>vVC~YoYjc5T+0;KD z(tj%OVxrL8TlskkU5|`HqbShTtH2d z&qhSF7}U&`to`i@n*6TYnu8OVgRH?bOsmxAT|q;$g#ID>`N;aZ>P5A6t1ehtzq+3L z#L)UTVFpE&JYFlWSKmgS1J8rEqjq?zu9}TwAwFhgyEEETEd3J{?$O{xR%S1GDpo+A zbn}9A@3tS~qgB`%b5MOt>b6Rz!uhuuPg!+}GC$(1NrJrVhK-zHnpih0=n{`g?%8J# zm##4l>cdLvvVs#Y5c*ygOe;$7Dp*reN7t1roRps94o>xwZI%IRyMb$)UF~hsG*9Ji zC9uwWErPYO2l>(+YpU!9d+dN<(r7rl@`^GNdiSPAui#?w&NZ$DC=ANZuV9qAtq z=J-f)kSzb(33v~(tc8&O^!qQt9i@`A|5oplCj`qIsHOTt`>qbPW8>lB;1G%(pk7lv z`-7&g7iR1CKQ29A&fd$Bt@2Z+1nYjxBU7K%ei%<*;x-j-`;GSJ%LDIS8+3H7tEj;5 z<;aB2v6R997>=)BGAecC%|G3G?Ix7wZGT1~z>lbBpBE?S3~Ek3Xg z>q@F~OWsA~qcdLGUbm}8Czh@Rjtc0=XYr`;e9u#N7UFJ_pylSf7vvC^*9CmG50$rK z-9gq|37PQ+VLvP|3p_eRdOruW2-?>)n^lB7UoI~30ri!D>qKYqD(F9H?h^O&Nk8#b zL;5q!I#(P~hqMP2Rc*(~@`p&%K=ZOLK^LHo(hY9fn}2^+xH;KVe)=-~Z53sZxTzK! zq21KsDheMEAmoE9NeTP~5iKe0w6Z#ydX_C{T5R%k-8L>;T;l+?xp1l!dpI~!Xi%P+_qTN3ZRd%M}%(@hH8_9QEUEq;{E97DaN}ul! zPPe5zOLbWgp2Bsz>D|C=7aGC;3yzfS=agkJ$a51dTW+vhHl?(@d~Kc_;_20~M$}i70F_7@7D4*BiAqBb6jD4_us$IwYbUrhkL5;O+B<**>GtK-4x8Jhr`5?Y^xmn1kSX82*~ zpLG1{UmX9#>G??MBFX(B8kbfsu@kZnQ3F<(i?^I;_de8_#<>&cL`Cg%E^|&<3%oTSj#GC_!K!@wBNagzNT_%=alcFp0uup%KJN&2Q4X;{RZE6 zzx*yMpf8sw&-;VY-B?BDD=pBU(%n1ICZs@)DP~i7J=L8YF;b~F`TM(I z$AVE|t@x{+KU2R(L1UTIz-ROip{XjDjc76TZ8}cU={e9J@Xew&r{{BJa|k>b?i~E? zXCVQ1)`GG8?xBzlcR$P@!|&FG^vy!y6Zv`k?nfa5Vn5fdLhnq=<|(T~#%A?uUB9VW z^1P~S#`u!wqb@K4`h;zeRlRm+X9jYggFOqKbQhrYG}c#Qtk3nXs$EQWJxr><9o9*( zPpV$amem9D2-j`O(;&2U1s<35NV-gEzld0%jial7!9qjt(PK`sW|Jj+h(i$Q0WUpUcy+>>YZP9b=9m((EAN5>sNCfxClG8`jtecxV<4piR}E!=2!8Z z#Ed>98#i^G7T-2SV&fqotPp)AIM*bcm)6rcw(Hw1u#P3mt~>kv+)s$?obR=pW%8(# zBLdzq$f=kgz&ge}W_to_ot=}gMpFX61lskX9^$Y+QSOR8hP`vg3jD_T{#j-90Ikx? zXo6fJqLSmMOqnu1L3^*Re?R1dQJ%{@w?nIEksI<`%k@3QZ8XaJ`-!u1qd#h)#V~l* zc@|-{2o5*;?4lT+=@!`BSX=i%SNLI%S$?`)zkf7;bLZfjl|d=rIPA^r7_Hb%`Sj*O zy!lbj)8&@^jku30Q-dq=3oyfUfs!!co#3PsdJ4LCgm+-i@GS>_>8n9wU_U4>xqbQK z)xLUc-)P*b`jv1-S<2g_@%KQTg|s^w61NL<=I6j&P!YCSAT#J}zXT<_Af=`Z7-Z6h z(6xTxDrihd0{^%NUtdq-He{>)xw4+5@HOOpR)`aORbv*LZ0V**LLy?vchBDr8&^@P z<&t@-Jd|GGC_C>fhwJz~k={I%nLJWYF_^nHCz;Au}@*a~opnM97M-uC?-gV&l zNcMr}D%MdK*Kc~g;~N9~s_X0?FOZhrEA<%Up%ibUAj*wfJ>Ct^^s$t2GL^U+J6bVp zs92y5+|cgc2Y9*CDyR3aK{o&Cps9ImXhUGf***2T{d6VB^Umz?N{!@A3Yl3v+9+*! z7NtGM{l5Qs_)_@NW?~WOg&?nqslwmEn)$WB5DA3zt{Zz9BAU5iwGG5o@&4X)Ib9wD zgk&3YCA4H|Bejp(nIW@1$*Aj6t@XF!WSQE!v{8Ld`YkWcMW}VSS|xgJfaaPcRm4_a zYMewpZ;1E2BSkK7B+F?IqYV2v{HM1A(7x^C^>tQIzcG>*#BA@Bb~V*ialM!FUGLS2 z*RLAWcynX!DnWd=F&ny38??;O2ek{Z&4VTYJ+9wi-B4JeZ-m8-#3m{|@q6ei_k7mt z;#vyQ2*s2SV9yA=hJNe`*n@R)IndHl;Jp&+iCgGE0swc;_7u0<+npO68z`biJ+Sj> z^$@L)Hu&?ZH@uMtw5&tk4PAL-Lw;D0Q7T<6l6rD(m6~(Pv0IAKB%BpI*pZCi>pQ#~ z(9Xkbe32w=*ijC=lW~)QZ8D}atDQ>!J9_ilb}#>460}wDGeEkLLEE+Gx^`(p3F<-V zPA&b9NN1CF!Gf=Y^pn_C2+xHhaaq(Etsw$DNpP|x+Azfg@J>11K9(W+^UVOO0{#wUn9tM9S>VT;y z%3{bYLgj$+9(cLmL8nA}5G)=zm&O9-pvn!V^8K9Vfq)b`aT)0m+AXLpW@U-#U}gEb z4z}m|4Xr><6W~d}()qX7PY;9tB&Wc803Jxe8;1g>by&J?v znn@zOLN5ZpEMh%$_loUo&)yAH_Pv-yt*O4xS>+>9a&`QfSG zWt<08BQ`Ea&Z^pQvnl7a;>HOU&7hR-*ks`V6F=_l#0pzxcLr?@MtL3p(AUG_l!@>5 z-eFIj^3egJ^KMAEYVNnO+MU6XOc3{BAG)e48T>AE^;Z>1IXO+`BfBkYw{(uaGEdqJ zOV&~N`w)1|tShsIeQ2IN1GYiQDG`CYq*pHJvX>W5X#4Y{ikxj=U)8@pG-?(55&%jpzH@C1AR znOy-ne3{*SiV4s*_X^dJ3l^1EzwFm7=~|>)+!|ai-dC$zTE0Xm@CR3m<;(9|!V1b4 z2?edeIuUtSzFbTCUBs20z1O>MTvD~p`%bpUyCmm9FY$)zJQaOT*wgJe`?Gtqaelo7 z-fAIb1EfqYrH3x`I15U^qa0Pz29S2!86dVc?53x>z-2%|(Q|(0C0HlZzf<6I<8}q& zs6q?w_I{%6{-}f|#-+u-mn! z*fs6?RALVqT~ANAzBu8!bm*F26>Il4&>&Oq*^{z$hDVmpD*pn?N|HQl@FXH5xXix0{2Xk^cu9=R1eR4VUkhftVfF1$ z5}^N7+D$s=Cp_YhwwI?KzNquLz9e|P%0S~@IWS4S)jq0?O20KSj-o8!Wa?Gc4P9-@ zDQMk0)n_+FQcmfhQP=DhZ3WVX+$#HXp666pMBmuz$3kJX1Mywh@Z4|96 z=(j{gf}pk4_O}bz%2fvi!Xdcfn%UhX`+t9)*-e7=Tl@Frl4oX~dFDAk_W@r#;<1sZ z4HjT@XFT?xp>?n>0e82Sg_OtJ^|FoEIL2l8os@hec|_)7E{$UgC_&Rh?xhP68Kbk# zn9RkaGG~pYvvY^G{^QKRn#9RvAUebi&Vi7Hg_Oa8v@HXRskB4YWt67oLk5%C?tmTH zlr-W3M`MiojAZB?K2=fzl})Xv5mKIyjFxKb;Jzr9oIOq7T1= zE@S}c>`#^7tHype^e2u4aeg4v{=Q{2+SKG-@GFN*>(vWAIy1ubLVg%q=T$t<5A&%q z3!Dn*2GQ;zTQ_RyNSlG%7*RR7y?dN%c^{g`fAV;OArwub&UwmB-iIWS_z3c}TqzGw z#lae(MY-I~i=KERvJtzAn0cIX0ans%H4R5C#gJ$sn~vd#8K;}-ysc(9V=&)X|A_o4 zj6`ReO&Pqy$YAK<(uHILlsT>Yxt{FT#ps4EIoMFvSg`1@xE%Rzy*hg_d=cV(56Huu z=JWTNrFrc9eZV#y%FC)2VTyT|g706M+I-m}Ky%HY?X{4u((Y;9QLn-u@bW+#lk=Q4 zD1$Gk>}uhO&K9Q1fBw1G zI7xS|NROWA>XUW;sVaSQFt7hr59;^0NPWTEPwvM#N8#KW9qJ1u$*qVeHRp1FW^xio z*>!(7aOoi465&vad*pwb&a{RJpG3TTl2;NY{3;rQe!}3`!Ftj8wK5kmlPSvta#BFT zK$NCtgWIOe#CvAEM{Cv;eeYKk8M+M-PV|UUO69A{w&=47=}xO_ztS&E86t=`s)SrE z+i7%t4VaMO)I*;a0!$HLV}RToJpYF#yZu^${Q-|qPxAAS@+Im-ZRyBQNgGE>q(3x{ zMV;T&FnU~2iw{ayS0QnR1hjrT^4CzFig-S{Eoc*dN%gA`2|Ewt9@r7hwSm))i1^W2 z*noQH(7)(^bQVZ%PyQcqZ{|Vk^>G;7$Q3pvuJNiOBPQ;Rh-=2~CYjO&NG^caUQ91c z*oZlJ@VuAm^odI2xzD$z10YR!9AxfSV8fQ}q*@( zlm#3ak?Di(4xoR8`wuI-R7j<2SW+Ui_oT;nRmQrime*8TUCqlsuS9IRDYJT+dMV1VjWzFaDTlfqO)?`y$KT*YXj>vZNrUSimf$oWpbzZ0%@%i;K zQOhwZb090rgXSY7FF6N(8`*?C)*L@FIFIX>07<{ZuVvpOP1c+^MWF=f z5-_&<{Zr|BO~{&KL|(e^aFQv-w!t1UI@+gcv|YG;E~v|NH}iiUZYUSruCy)XHfgx0 zp?ni0%)bykJY+}hy#en}l)EIm{EkO!sq|-BdL1pypb;Zl{7>5n&w_`|5?-L_7yFe{K?dwjo`Ja{`3{1NZ@TC%4IseJ2!aztYF)(Ajd(vp;5o7da40u z4X_6`OM-YSC~vxY4wzbP8G0jV?>xqqPX}%-VQh90r_F%>;+^B(7!uiUbshhC_74R` zDQ}q3cMG_g7UfEqc}Bj$_K>EsMY(|Jtt0sTGhq?5SYELOvteV6k=391Gi|?twhtpR zLasf!^NN4wjrDk=nItWH7~grrJCOa$T?WYbSlHe)`O3zJDLP!M5)M!nHVb88CixFHnlVGVw$TY0sm2)LN$r=${dgZZk0|9O`$Nmu?`jcy>D1#MqnZU4`+b{qP6 zMeaJ2u{e`f?+p7Bz64;t^rW@Cmv0A7;0!q~WhSlS*RKT*<1Eq%{Pbtqk3svQdk$pm zJ&z5skMYJFqtibMr#}~88tTokKkUnsXP{JSPw>vPmxDW6m>+MS%l(Vu=ggUtIHyNS z&pEy4WHWPSxopWSljAby%GS);a(w1Pa!h8a9Gm$d=fLiUzU5aa#rSQ3htXd;>l;JX z%$X=dD(9Xg&z0qJ2mE>H?03z}ZP!6By*!P>ueSrDl!BRwLNGmtU}d47g93GUkM`K@ ze2-ah;*R-lgoPyC%b#GwzS9Y}ZXpYjVq{eV3ezYK`& z7D6TlZ$p#T+h>2Kw+E3GZ$YYlsQC!ZHLU4qt}*|Iec@cnL&_i(7MvzN_s@j*Z1$&} zK(>=~o@OBiEzXn}>326vcuoUzc!a*egYPcSeub&bUFyDbM#S3;S)=zMcOTtz%;@rU zqj+@f%2@cGdk1Xj+cLF-k5K3mCobkJ4c z+}k2@o$2t0g*41-v`>a?rwGw+?(?NUzEc9P>^R7HN_=;~M_7{s$&dEP%PzA(0^{tw zmkl@D9(i--=><$yrvuD=^m|GSFg!O5r2-q3#+Q% zzYTBHGxHmy?`PQ}f8+31F8zL%g|26QKg&SZv%a5&Qvv9>5_=A~WBjw+b3M1*4y(GH zN_!c}6k~n;w!#*%0M_MYEy}?*%bRxK)EST*P$|a0rcH()t6X|JDE}7a{&ov!^vg=0 z_G+gN&(A4)kq46Q#J5*DSzSZfM5i@d<1WLO0evyHtx_Bf$C-_5nOj zAJrMuPSI)wQO0_bJtpzYH<#zQ4?#Eie!vb}zI5aSjXU1I)B5m4dE6jm2-Q`B8l9)g z4_P{G`Pg{}`>uSvDvIJfN73bDcprAp;{=>zHNBE{2*p&RT+({*xuoH&EWf1uz$1gv zx2ks(r^f8aUh{w0ZjRr)J<0{>0k!Ue3~5&Cz?{JGGH_1qu=*40#Fxdlv@3s`5p)`S zI$`M|zGx{F>lUPnZ@O_^6s&fN^*5$WfX}Z3^Sv;b&gYtD6ghxf-R4a0!ER<^lQhrf zF|_8GQ)PKxzI1Zt?0MKh?i!Ch5*@9CN|D_uqAXwq5s?S<-dX7#Hye5eI;Ju3e*XvQ zYpaDP1;0ZW?h(q09~GcsjPY1AR>4YFlXJz$VdO8TIM_Y8_xA-Z`W^ zA7fq)J6j=xsL!*?n}`-dGj&#Z4V-|gD8Rsizb0@a_>3M&Jq8f1_ynv#&nTb54(Vkz z9&7iq8YhxX!)4{U_I%ijx3p0P0lMDGufJ)t(41C-?p;bc5p}#4-;2HzP==a9j&! zFQ|C*kT3l4qAue1L1*VOvNLMWkj-o;GMKwrx$eahH604QJD9@{ zdnXd zL&K;^Qth7f&07ls+pn@(Q+F47x0J{`;^t~4gDc&FNBV;QnOn@e{U2A zfxYasSs@2}u+(-~H_nC;*DP_){L;BFHjUD)(dUnp&069na~&8#K2)}t>{~b~f@$D< zIL$X~7`a8=W#y|5@Z?+LAz`Hm6S3GAy_z(sG(mszGy#8&JHWSyrlG~2Xi@G7TxfxZ z0*l6FLYsF2OQKDJ*V|z6kqfN453xWgx{jt5f2_ZjZT&BZ88!vhIzeR z0iF28b$znNEQGSBV%E~AX)aK7r=4zOKXlE*l~x~@z&OmmqIlGQpNIdaYV&}o z2yQf~@d20xl5*QI3o%>bU~i6`GHo|-uLCMS(dtor~3^Fjl`N4afcTEt+$Z36ck9A7`qQEONc7R7di+%SuhV2;Is=tQgHY zMU*uXZ57Zb|M2^>T|H@u7M{TzLj?k77t{JPc~|WX))Xn>U%_gVLbW@`9Q$0 zH0SaWs;gPuLe?aTr3AHAM0C&~4Ygowb(xK=5<9QBVK0}!X$d`pKCx+t(=3bbe2M(e zLK_Y~gRgU5n&u-O@qJhhJ3=04l#gjn_y+DzL9_EK#AndrrqitV zavE}VUQ=#A#Mcp>H|)a{@}==vpmCl(`iVl72Kr@XF>cp7iUuICE2c050`c8VN6Kd z6=V<6+c~tUze_BI*T5pFbQq-7SCmXd+({dzKi&s>{*sb|Sbr>NzDje(D)h)seg(en zG-u`T!t8+^e??J)XaRP26m80BV;P^6t}1274ngyFfR(O@3?j7&(TzlsMx=Ti(5XBJIp=NodH|6L`^tT` z_T54-@v?FP_HUz|y&_jfBAQ7$Y^y|lNFc6&P=Pqo<8B6z@c zD@Q_d_qhFDZ^I?CtzoAQCA0kj-yoT+X5Bkupa-;q-;J|R_4Nd7G^X2;DeH;g^A}8z zVd`RkfqN!?@8RH~vnEJ7bwVM}@393O<`|=10j^fIRDG!ZJx1q;n31{V>IJ9R(~o%9+4x-yZDAzt95v5*2bLMPZ=+ zY3?3!f2aJq<4Oyab^eiUKR`}P&;76?INJhTti@Vix)`1)+)%eGG$|bH5F4S>-c?&W z?NkhOR=OJtbnySC{rCb-9mVJ|d2^uw`8D*TCYd~}N|%#<<<8LeEm~}=kdn}L8c}&1 zMU-ji1ZtJFRyB%Yseht zGk?4~3f=?6oec=i8)wb;c2ojI^S?}3qCRK^DK7sMP+!P?}sEa2r0#Z0g*a0!6TA&Vd4>nZx+KZGprm8+hG?#rB+OL>eGCLU@PgvN0LVH3;7!8W0lF~iaL zEn1z2R2}LDA)|x8%5f7Q0KNH9K)ZWRWr&JHHNR7gA<}A>KKyX$qnsR{Nuf)b3fx4H zOsoG{FpuvZ!la0khx1SO1InvyrD^o{rM5Tu-`{cn0|8$n_@OEVZJ>GJ(HcbTD03&I z+@|I`kGHV*DHaQ9%U5srAjVBHwB^Yc>rxP#`x$0WhCP{Oya+hm+`3X?t+Jyzv6q)J zVcRa&St))u%SIhoC|qC1fcH))31Nz>qUSl!*=~k?6J!1Hzwo%G`$_b#W^qh>I$~@r zrae#chzG;sOuHz~VOd0Hq|b}e8FpmR66eWM`a%&l5rVBGUoM3;gOQ1i(izG9lourPH0Q$aDNt zxg`YW7w!pV2D!vt4=>1j+|Rk$4XV#FFB$p#9I2WOsb+^Z(3!bH9I8JW4-2u&$}ablN3ZDp!7Gta0DcH+k(PGY?3cEdB_Dx<> zcBwB*j?Iqs_RgN+8v`mzQN9lSnqwG5Yi_@nm(2dj?WCnv6lk8YSKERlS<)x@pgB3M zOb(3awazIU!eeCvFL%IOFQ1prD;tA1@ps=2!IrWIdBZ)7oM)uPIuIrs!ylCIVG~KM zzl7EWLzk6g-cRIr++O7a<}EeA^~pd2Eq@(hY6*%ik$`!kHeH`KeMJ+NZn&%>A9> zZD$@KQ$Xp9_8QMH(R3Q@L}< zmNEQ|*pN{!cVO4_c~y;j|_p z3y~g!I(W1ES$Q@n42h3CN4D=FX4!;V+rxsGOtZpgpf_efZ~w?^_6GwN^v{gUENy@d zMfa54G~#sQ=2I{K?)3Z5oO$;JjN6FupW6LDr)t;JgO8paC61d)^Kt#X;(MU#r~k+& zYy7tDN!SPL)z>2P^ah`&Mm|q(@p-x>IN5Ks=m%$S`;gP&2bJ}~oI+FMcgp=8A0d9k zN5w=vk8pmtIi~R&B{q<~Ee7#-9nOQwqo`-8XLa=C_*v7SZ;(r{>*+i^&ED1&Y4agm z?NhvAUE@APHnYHjiLLDAGuJyUpIz?B3NG0e;VXd=@e`dp`FH-=t)-%1lDq?VEt|ek zzECG$S?+j8eS>v<>E@ue2i{;(zo&LIh!>E9V0u$S#@oE59o~fV|}-lLV+atfs8l#{pz1+>3pDjpH9N|@gK@ppxCw|Z@Iy@6*e88 zD0jB?mS1%_Qt3_uzcaQiPJYQ%#qYer@7xT3>6dvaukCsMBo>z2FY)gdb?eVg^e1}% zwx8(F*6aFXehZjc{IgQuVR=i>OaId`EZtHsoU_>y?N(nMZy)~Dool^1&_mYlT7RPT zCD*l1(1}j;(SQ@DtFoOS($k^Jo&Wbf{D-m^yq_`Vpinih`*iH*_OFhFW1#9MeqKld={qO4F}J8P#FoT@jIm_xReTyaTs{`VP-_s zq0<%sR9Vz{+A46`boTeWH*#%_>(-%DCr_T#viWV~%09Vg^Xck$S)9NII|>rn_>yVj zDDj@Dcil9?b?eP}#RU^@5n(5Em+LVc9WgU6e|pzHbl4`1FXZ)ay*2+fahNz_WZrW8 zU~_ZVUE}c}b5<_w;b+}hAWkli-YX)%${eu(`iAm*${r&#B%J%AlDjA0g*Qfw96$UP z)E4cUDLo{kKYE7uyB?NIo{E?58ecLpZ+QOoud(Z&UH2O6>-d4)H{#|gw~S=`@9+`% z{O^dHZ(-AZG4U6Z?_+GrJ#h9MB~mrqM&mhr>_5Jbh9eI!A4QPxmbf3qYm>(PBLCJA zc{K2!yw9hBeG7P%IdaxenkD`ZJ~3j}sLp@rUHr#k+V8echLC>&Fk_=?@;?x^h$eq| zSQzpVcH3=jY}g}SHl){J+HF$-^<-d&dpXpb&Y|9~811ww~+l-Mtrc<*DC70vz2a97Kr-&r?yY@Y{>aiKTUR7tk z1Iop4R^h#_Pu6KIEbjK?1fERBlj;1OIo+Nd0@kKp8qPn(oNO9@es8zu`@@Fwg^Zow zZ_=K*x;^{fFzx*p5F>#N9qly_y%qS|=)c8ajO~$>#)ivG{7SL4Pr@0v5$9nMEMbdL z&Xfns}2F-L0ijzPtihxK-fgl2hIEVev$5HaG9 zD5+|E!+zx~=6n}46@?zF;xzjyY9J*R(Dd(W9YFP&QRddtoaTRwdC%pX5)+5Jb<*Pe|(RrB=e z^;=H=w&_&eMrvko<@})+0PjC^OZJO+IIFc4*iU=H*?DD50K@88arG6;dfQlCqMYj z=~t>-{lTdSXvb}^*==YtiuuKs>NL?+{jpe6eOmmy zS|?goSrD^MC)O-s>3J?;bzbp7<*s0^>wt2tUC4A{#PKdE2m17&QX0&`*!8e)MqYx-{;&j2Zqo4_1qpI8t^~W@XAt{hd?rw+ z&5!D!%hZcBep{rSIK;|2s0<8R(9SoI0mYylSUN?hv>3jpcVN|iv~3_*W`kcdv%#tO zOXDY*Bb_LgbvtHZI`;nmb_hd|MWM(JzlXblJBfxr37z8%jPu*TFb^AIhmLhk@Ka@_ z%EWJ#OR%sMhJ2^I4Gj;=DfXIkiuf)oG#Ce@XN+Zc$hl2ctY20r8~sa^$6cz)TT@^< zVr-qo*6g6K3{>HN3t1uUihl-&$U@dWWodAboFO}#NE&1GS+U-4g!TIT+tLOD4?H_8|6i=Pa4fCzIXFXQ`=!pY2l{o*_<) z|A#%?I(gN00e*Gprb>k5Y$>3xu4Es^_HfQ z6bin&i0%tX@{1ISS2%(=POoTjdv%DcN*SzqL|#^btVIV>D!JUswwYQp1%7DB>(5$+ z*tjjfbkd#C(B?5~oZRcYRacV6Huaccg+`F+b@eKsv9(pO9x3u4o$fr?!kA_>DK4I0 z_7FuCsSqOycG6pD`bY;j`W4VAj)JFxgXAvIT?ko8$nZ>8wcv!~o$?OJVIL3q`xfo) z#~qbv|SDsrW;*6JvUoRsY4mYxs(B7js$??vvHHJ(iy|}(0b=-M@^?*N=>BvN^ zN(ppPcM;Zq_5;A28@&d!f!Oh3vB~9hy%tWM8p^ywuke z?=ILn?CnchU%V&K*WTvezy979*a`H&+ii*=RFzuO@+;m}o6;U!)k1z*`WK;TIzSNj zb4YZkmCpbhmcZwubu!62Y4v%Os`-j?3;a)oOvKMZY^iLnDX*H}s@w;e1J!6QHz2-5 z?3-HcR^?p#fD@zzp=efd5$}^&>;hAeqFKem10{ZAETUOiPf%17Mm1px-@RsQ;QE?Z z;S2MRMbySgWZ%Qdigl+Nk;lMv{Lw94{Tb7)2k)=-0y(MBJG9b&PPW^dbgVRc5^Ofd zWl!)HWk2Y>Gh6ab&tBroksr$L?VXi9$U8e*@!c&i%ASv0J9D#3yk*%b-iquCzGQiE z_B`)W)LNc>8d|QduYC%BZnRVX7WJ&e`7dOoTkU*_Q&B{5vOQfjx1(l_bIN8t{F|M@ z=o?tO<^NJP;jJpXRm`8>8ti)OBOdRX*Ujf`^bTJCP8r^r zEIS|tyule=qZ5i4ERuD|m8#9wC1oB?&&z58{BdI&Ta~$OL*To&SLxfP!!9v-2X&j} z+P2(uedAsw9Lj6b)z5;>554h=wglun>FQ}NzDhbrt$kH7w8zU>jhw!lqr2px4i1|T zMO=%j5?{~G#|rWAV474EzVgixB5bi1pLt!tv1Rko3Maly} z3f8DCPemn{$Hz&<26nG>yuj&w5l^@{Kj;L<9 ztLt|6WZNoO&rq+M)sa2)=~P!$>N=|V+yMS<2j`y)T{3J+1@sxFrhGBK7KYeGWY#4gZDzyJpeO5 zU}JyGeD6&qX}#;%4c{M&1*OufKE{40D0SvH-uc+pgY9jhAp2!xo~dUKaEhr zL`d&bzxRBzu9hIJ)#aSxY*uE09;t!V#G?h$c?*l=gE=bqUy3X9(cgg%ijJXGSq}Wg zK;LV%Kxgq2&}UOW;5n4*h%W2j2!HiJSnmE_YG)r(j`XSD#{`j|o4Y?bJJ6Ow?N9Nc z)U2e1#gwJM=H`P>UiaNG$g=S7U%5ZY&xak60UNiTly(gDyMJ@Kr%z-uyFmd^bfdv0n~HU)mXUQZ&ga@TtG+%zS%=f*zus|wB^T>PW5J5^tAC?vZsV=l>r5uGaXJeOu@)uF~N8H3x z&{Mi}D%}shHlFYwB8rXzCZc<4TQy*t#mVCc9K9KqREn~%?I8`KpG^>iLOS)$<;a?F zkWMwm=wRv1N-9N9z5Bq~gh45VRVj;FnP5JWg|}N3caUR!*jH$88bYjfCgHJ?s&ZY3 z^&RE3a-Qb^w4D9;ccwT$DbE80+Q{)wbGeCsv#PwrLvIy3SMjH-_|qypwFAG+q6{lW zmf?f#!K!gbk5bKOI}5_MIjz`dnb3y{uw22mVA>>-(`{r2bxkMD8}~!M9&a2*|ESd{ z-gpc+pA9zi9ygb>{*JV~8QrnRrB3Y8s+_?JMrHxJG%W@lVXf(ypLbMR4=TN&Rsnm3 zBDrSBTC^v)S$dKTyA^u!!M}5}>8!r0e-r0sS%jOl9_75M&U)SeuR1}Pjy3!Pvh(OS zQ|TBuGfsceG%!DK8KP++n;5dDWfrGmM`p4N%C{H0JoiQcnayIC=iL}{^tKz#$F?FL zpzi!CGdq8$j%w;A)oHHxzVNC)znVJ-X2^Sp%ZhSqtS-Bs%NhGp;wGd2GtkI2;P}QvtD`8Fg1!v&N;~R3n zuD+*7`u_J0d%sxlm!tT%{~R1sm?+!(H7icoU1#^x?tTC#8$dYE|y(l3-8_hdar`NAq$% z4enShJE#0_koai>BAOmTL?QAUv4rAyr0TG8Iy@0xfbb?M_bXMwx#e%6`ZgK>s%Awnb~~58Z`mg1v_tycU-Y z5y^HH96ffuC57F|eST!usPXH2L%dx#|MZCsW!+ zp$^%=v~imd;zp^Bj|0*Be%O|TTgZ~G3GogEP3E45eab;Gwe%_a5g9>9M{k(%IU%(32hNo$enKJ*;AbFsDpI}L^NX$d^*~#agx27Rt5A!cY#$<*lf}{sDWZdR-1LE~$PBHRM z;b~$F15{)FJ0tgwwy-R#JdW49J#x?2Vrey4mZiScDzNPZ{;wzd6JoR)ITWRMDDxp& zf%tLD-HZ()-YMQ`<$bt`_aT2b?JMSw!)#D&r3Ulf1bDGI?3IG(Z-E`hAhLBKJ9z4+ z(0CrS0arlt)&doOGNC!T^hkYJI)y; zD(keegUW(d=5-j#_VJ>`S3pD@O!05PF)DJ_#Nl+rF^6AgCLb{7|9~*)|L=A+y(7np zt0`w_D)D!sP$#@;5x)kUFT+(B`h9I2sk_l@#!Tq1&2dg}ps(~-gnyY0R)3NpULXv} zvw-x1brtyug_Yv44Kqr1b_-Hhrp`)B^%&tX%IrTNCd#LmV_5UmsyXi=gVJEX-b5a* z^v)^x5kWW6a&zIWg|GG3=bZaGCem64b~h9M*`l=t9}Y+wz34ag+8$VciSe*Jl2Z5Y zu;i#m%bYi16qE@w73WQGPVpd$s>haLotUy(C)+YC6Mu!%h^(Ict|4+)$L~_~M}|YJ zn@)R0-a+Jq15ugWn(HIu|3*Dcz}RbEK{=Z0hN9z{;9%^0gM5t4LxT#~Ju)3uZ$` zHa{g#g=pQwh!do(jogwjguxdtth`Ur@N${&pV%#5Mb6<*pTU0E|6ye(pV8~j;54-E zLR-&9TBkD@AHxtsn@&_%Ssl55n4h@?snd!s9i;O{r!)*5t=5CTq6eSz^G34w1b*Ja z%H#ZdmAf0v%?YL;yGpPdd35->yWBz+HURe# z#OMgdN1ojpdFJn&ja+CDgdFB;L0?X_kiCC`(}I|ah-kzug$Zt9ZZWS~TVDge&@3jw z2TB;K_gQiTpTT94h{_{>GbWzyoKxEA3%^q z*45G(J7;BiO?I~^5k@?ttcE3Bw%^Pg=VF=uY?VZtMOieg43b-(g4~Fk(aBU%<`_RU#FF^ss(!2UZ55!Qkp#lS&a(f z54^EFMwZKrh23jrtIN`Kxt9+_V>adik3zRB{q)b32LGj%>|lS{l{VQgXOxtd^i9lw zHTKb-=F|k+#MG%KxuTm6}BxD1bb`5eM*EA$~6WCgE3t z-&Fj0Dpi!K(B#pfGj(N=*d)334w>w#zIb<`%9g zt}fw`{fM=_UyW;^D9w^2;)$(kpvxeA(=q^M2l^RzxIZsd_3wvqx+EH#DD^>|ENJ$P zZX{H3mmwaoBw+`_o8E!AA>^-XcjrZ}94Xm&&y0H8!MRXYMh7w!^7>Maq>~W?dgw8X z4cQcM=DNlvAcw4_SUA65H$@%EOvPd4neePsea@AGVP#dA=AP)Q8HjOwcACLL^FcJ9 zW>K!4Sn^g?kYAK^T67Ba{&n2fC{in;o1{z<4p;)4+Uc)fS;cwK*li;C6uSNf5(AB! zqpN+8sKL6 znO!*g)HxGdbIvSS#v366iPo3f;u`(n;X66$r-7Nkdvr`DXeO?(BDzw#bGS?JFKA15 z0;0jQ{g*_fTrL+-st zIo@F#IeXE#OJ3V{JUIQ zOz%if8(s1o{N~!m@Jw77UmyI;!%P--d;x>@BVvmmOYt3a_R{>n`kCtn0mixVrvUh!6^xe^ss3CeNsy~Bwt6lnG6?~8|iZc>rOV#<` zg1;^kKg4;YymXWBqqU+n5?8>s$J_9v15w8smI<9&?I-XI-nB!gdBqh5ij}v*Y@h5C zE5s&oz2lmDcuj!|yX3?=><}C6mC||ge4W1!VpItJQzTvAQxMs!4!&2%^1X`KQ~zntMf*jj(e$;5!q!*K*l!jOctX5uhF@rmhjHzPrO@oRbY2xDBjX9|jSOi<#D@xU z+bZnhSO4%Z;h8y79%AW>)xEfH)cYz$lhXNr8DQe~EfVm7EbUVJFh%i%PPi>qyVPWq zx1sE+qFmE2Qc2q8JlofJe&eEATk!zcdOxf?Ck!8VE(SG!i{~}f)^$gq7Pm;)*Fduo8~NUr?w)AtQ$0xd5))h}}YW z<6sRFzD0|Bg>!2&S!xqamH>Vl^~3O;F!GqvU!8vrv=-Fn-@^2l`Txc37U<5tKrf73 zRT^NC5{9(_dA1UC&vf=ioFo;|LkX@SpR2#QqX%}L#mU@XdlF&8npjMkXo;tQhiy|h zJqB0I-_dSHt(amHe>STfc4#iaP5b*(oM6I_UhEsP;iPkXJi&xqg&OCU>#z zTvvl+hh5F8@L1~B4^@ld=2HpDHzjgg;#-cPDE z*(V&&ca^#+OJ{A3u!^8WwVGs^S^M0;jXP$#>joT95c&$zj$y9ts?|~j>Gsg#nBmqL zH%6}qSf^H|uH7+&UvDoscPtan2f03RTP3!xrYc>lmlku|X1s54QY%7Is%zZhI@Ow7 zy_mN;VAT#`P+z=9`DWgQ92D`Xn&#As?nbE*ISCrw0p$ZktO+P*I>_cp@c+HTC@)X7 zG`%h1qyi@1(bVX+qn@L7mnzw63f3QYV5amu3lC`2c*9_a(ZFpWX%`{Cqq7lko%nz- z{Hjf|ov*HT{T3h|P9#YkIY*NRp2`9%GNLVY@TH_@yVNXZ*iqNOsrzmu=EEvhN79;R5x$iV<;QU%;VQ5PVGUv2d32;&X; z@8Agh`Ya65glw3V7u(1`&gARfB6!{3X@0C*7le`L&IEW9eO{UNSxW<=$-FVgEH^9! zyh3azqRdU8(kXh@EJl5?HBmo7zbtU1Hq54SvWHp_(dSC6$dY!93Hq(qFft~-++snj zwHh1Y>&o{*AtS#ne6j$&(?HALBugv%7gO}@q27Lk{~u|1lA@DJz$4VA4sC+}!kT5b zH#{kVTWeTGH7L&^U0ZNXl7gi6QwY%F!WkkvSi*^Gf<#X+&lfG=;N+8tIPn)mlwyqN zh$w#Ofm3hy;NO}a#W6KC1+hmc-#2URCB(UOHLS*wYMq!|RWqaVPK!&ooUTo{2CP_a zOWC_ahq{g#{uUT$qD?z~8Th5*r_m;D4;r1%I6I2n;7HuHz3lABm~Y!A^l+CzMqS@w zZwk2B3W`@PBO1=IZ?AwmsHs)R61wN)b5)jIt-TU;NA0zaB6dXlwz0Jry9oIx6E6T> zxp6n<=sEQJJnnrCT^hlSw_u@K;qS@IueG~tPvY4L)QPEaq#)NyP)6BNAi&}_fSBsw zG-^xG_N5cVb9{|f|B7~EcG$6kYufF#4d<=Q4nFno=$EBNQJzx2q*B#iiHpJY6YA$w zs``xnbt}qTbw8D)Kcl6+DAnNJ{pubnN&9f`Ba}YJ_$2iMDpl{IC%B%jQtqaYuxj?& znB`i8Fd>2;|3o7m@+a&QQ5K(h8*k7mCHv%cZ=zg`a+2>4#oz#m^Yy)6EV_$PviNTG z$Zl176YC>Oe*hJuMwzPd<@W_Ugd z{$pX9xt)lU-u5cB27YqLb1sv+2WZDNk+)-ftBdn^FPP6PCxC`zO?vrOCsB{*!67X3 z-0Jb8Z%?6berXjXCgkPbH%Kk7ZS%FToQJ(kT!Hzr*IKGA&LU|cYJLuU`zY?=SBYO$ zCGBkN{bY~(aR*L|d$Cwi1-vNut%3MFyN6DK8>`Li#^cg@8zR^X{u%9W$>o>}I!l?b zRElYhhjg*8cUGjWdYm}$KZtWy;g1(k62-DQa2x5)`&`U_s9mGaMg`Uq#}qT2x8C>o zy@2AZ0cW)$&qG#3TPs9F_^Ngy;}mKkPda_2X@ShdiL{pdB!3CH#Vq-EauG&0eJ7n} z8_V~M!&N{rAPyVwXkaR!w@l}G(CFer>J!Z(^bF}v87-S-Hs}@?s6ux#Mzx3HU`M_( zN~T;gI`1&FB+doRia8Ql@=g(b6Du5;DUqdDxE80#QHmN=_IgLExQ4#vz_*a`(5Zcm zzI6Qht+4hqr=8b^ePeZ?QM-6Sa}(0%yK6q1c6yyc)`o2^Ng;=?9DWOE7}q zLk@m<_~qkw3w{KPh?gV!wC0L_@EH8P4Zo525$&3e@AfQqNdx4b*kd)d*OWaS6jQLS ziDYxECZ6v+;tJpa;f|Y-R8yTCJ27PdEZ*IM-_%As>zAR|PSf9Mh#vFmX~yU~)Hmu2 z^-GiUp#Sp-C!GuHCs0e!^HASuOyIkL>rTvf zrCn2g*+IEp$@Y|X-yFyj211@f*sWu=IN+Qzo5ymjfMh#XHer!q6J%r?w?39Jfat1o z$XQ{+-+*#8nCCnRcuN@AV;({;8Y`6+zLlg+%d$6ng?i=va7&! z5HcZ@6H_vgpS*V!o!swzL@kDqLyvH_#xF45XTt1gD=QvtB_Iz_TpNovVr6UOZOCp8nt3?^J)vH-MtYF}Zxzt2 zo$rDtht+@)Sw08bEYJ@U$1^L{kaP7Q)gxY#bSy@vi?5UcyajpS7Dm>s-ZP%>i*cR% z!hvfC-xqgaU);g>MKHKf&gXA{wy?Xs?iC%13O;@bR=cq*-$S+qEPY#<9jCbpCjt4z zENstTTZXx8`HnJC8j8QHOp?y5lUEJl-xF7Zs$H5%-%6EcO7rBIwAN!`?J{Tf=~;7T zy)iqDo~4Pi?PX%=?78;Gz!fm@VWQGVLMBTofKGxxp4(u+-xw4EwQwOw`@Fe!#7Jq4 zw7y}@NOeR^`hc)9CM2y*;x=|uv7d%u9mwC^5?&4tjQNw`U%9x2&e%`wb6O{onGo*) z$``V8dPm3Cf%cXGdbqyOR-gx5f{h0q+&XN zR4T7K14`MxR9fL)Dn4d^xZ$zJho#5d50ivIl)8POujk zwM~#`$rFQ}YL;8vqB|QB55boQ2_eSe;51^cj1!XFwnE(mn`8qwNVHip=0-d3DrAEj_?qZ^MBS^; zzNgM$@2M{E3Odl{Gnjz*7A{uhe0?FoLmjL1+~qk7iszbgF;qGqvRUL`a}?vV{#9t(OsV|PASf9Mm)%3i&k=dIVBJI>Mit@9Oy(7PZ_>T=7W*4%mriO+2 zkS_wiqQq)TH^2f0qme){XncooRN(Rm5!?nMq5(&*1GLj2Cy-6NhS(8j-LbV7?uI$^7Rj?T+FYBNQeb7g3tUwe0=ESSrG1U&D&{=1 z%Ja8_x)i?JuTE;v>H#zTs9w!ZCgRjAv^AZYlk3ctwU$Ss=+Y zARk8W@MCTd{kFqv z=3d`z?pI!$_AbFENNX|M#Q)GZ`RK(nz@rZBjNM7n@;c{>h@;z!IgmXMHcgNq9D$Ah zojad!pILVeSsBDC`!m;+6G5qJziOy+&%37lJ=h@aaJKd}{a7Xgtb0xQGT2bAFVPy|+Tzao03{U@6&Ix{@@)~^l@})Zlus!bw@-R{Ge-iC$-R1dBy>LR@4?#MF zxm+A z*TE;&RHgRe92-0CZwV{?14dm~Ne&pt(}>m-uw%WOs07x^S-Cb2Z(1S2(;=qb;g*K9 z7`zGD8>dHUbpa!4^t`pbu;ln0^o59ZC4P?bg2f?fTs<+KG zYgzwB?8}_$`PGPz*P_XYy&lq6^o0~yu=nzc6_EE;s1##a6z3AC-Hb?sxF7PGMOrZ!pQn!;}g2|^A%kyJ^Px||WA^qg5#nL>wf_`{Nl6;9@ zSyJK;rLUK;t1p6Dv7~@sIo6%;f5dYZZ92f|w16IBcwA2Zl%>H};S)d9t0 zz^q9d(g$=XCpx6H(uQj0VB;>OCQ)`sX@dhe23NLf_+CjHssJA89`5u24(j%Nun)au=s<9J+uu8}taBb$@VQ&eS9#{4MSN$_de1n<=ca;sU^FFw z%91LoK!28kk7OCol%+eVx19bou{}-??=3jp4&`Y?R*Yl8)AX&w0dTQ3qGu-lMeHJ+ z?Cx`H;d5w~r=941!X2~&0q+;{5r}L$bb-;ip}fZ8(hM0CH|C|Fb6#%8 zbr+qT&*#P2o&X$!SOegxbcnhw&2yyP#CMPmG6h5_ZA(9)(YcQVq8w}fb+Rw|R^kb& zJ13AC>5YFU$kpxNa3_d~QBIS_v9o0UzHuKE6Bti}Bss zZG1QL@r}gznEwmN&ZqHjzpdU7>0jf{>`4Fe(7(zL>Fe42>sS^3^+EjW>HO=^dj0I| zYCMiMyTlL3QZN4X-{9+g_}3Sx;Ntl@gGP^h-Hfl>n@G0l!1}{pvJ#Xe)|iP)PDR%w z%7YV+Lvye3G-Ab_k7rd728qf$C?7^t-T_};NLJ`hGWJ?eiq5g8y~zxjN#4%?MqYyY zWEsB42zcV=@Px27U1`uoX~~*f0lCHH7RGIt(5DCCX$-$j95X&fW`B}Xxupvr!;ZOJ zEG~$FT}1Cgt-J)QZQl>Y62BLF=mIa*6y*BO)2!EmItIl)*#0`@(OGO+}9l^9I=rdES7-72vQXtI{@fX`5}Et zT3{)372WK6kJCxRkN$<%swv1pY!V^%d38KIftz>WFZyISu3bNcyHwKKla3QdQM$o` zEbAJlVdHlMxzCAMneG$hp`K7}4Nm+uNOT7ADAdk#GGQW;hgwn=A9{=L4C>>8V}$1n zkfsr?gl+$__tXg(y9*=@;R5;D_X1;V?EDGFcD$xK_}%er6V1ph(*F)VN`1_A6Pv8+jSd5ms)!i*6cX3Zp0Ymia)}?hkQh*7s}v3ae$VDeZ$j{_pfdGF$9ogyW;RFqGJ&sy@sO)?9rj_SBz7ln_cfHHa@S5raYH%v zdGJ>a8z7shv80%HU^Unu&dbcaqv6^7LbjvfX*Ntavb=zvjKz}%Jdybm`RRXOJL#dJ z*pbY>;yBp~Ja%M=t8^aGB$kwW4-Mw!OkinSp(Bm<#-wAJE@arP8o(*9qLg&VDjl_r z1t~`cqQszGCLKYHyi2vRp(%~fBO)p!%81(yeXR&W%um#;>~L zhnbPPDLb=*OT7hjw8Q_ z)JsD>fz^8^M6UbbdaT6(yZIh%MYva6JLytb*TZ2MUqCgg0sk;2?Hderbxib(#+V&x zqj3MW2|a2{u&eF}+!AT;;&t5YaNZAOnybQkxpVohkYhAxCknUZxV=>CaEZ zuL6Df-+Kc+A(te2+>&DHoLy67c8$louL7X>tF(5sPK4XX;K%X3XYX9iR*W(b_Hw2< z$9U3fi4KiZNkczSHOg7Al4w_+(zLCxo7Qyo;`+Qoj5=b~qC0MJifbTCTJLD0eGHlW ziWopW*u3OvbF%@s$Z_e2xTe4Y{wz8+qMAD3_gT4H2VJL89$!KE-Pxe=bDJS~QD9A| zVLchN1Yx36pqAx1hE}&plg>={40mhr#tQl2Sq^!Oq5Ks8p**);x>>SwJ5S=Nh_VfX zvZcR{R8CWi(nD;|LC&km3v0Lz!@%5}CfFY)m<}uGlJA)GtwW)IVDd=X0y6s%T z1Zn_Ml7=~edvkuer!-INKvR4R{d33URgi6N#A+Q^^R}~$Ug;!RTmwl(B4(-M*(co7 zaSAp-S`lA=715X^*pFOA+(b#D)3Fp1i=s=t*i~f(q!Z3-u`DW^$U`*IRamEK9uwsE zVbBqp48It1`?E@XFdtSZeZp+dmwe6&VZmv`Pf_B+=}tW)P6_anrtukJmrIn@_hGWT zWjR@)A+8gtSNlVz8tQ#i|WN%sLAqBmM) zQ@R8x#CR6fD4bRH!`FfO^kqjT=Wyw5IxWPzH!QO|kMh0Ru<&co>)q!1EQd1T0P~wc z;|StaB@pP6l+kLD4xDidA%V-IO)7jmJk>ZU<9JS>@Pnim15XJ!y&q?MKb>Rnlyr(& z=3dBQr=E~je#|xEg72jJt`i@khV%%_+78Px;;J=1OLvq!>z)LSP{88s+SMbtBHASb z6vsxyaDBHpamMqI5bi3Vy<5lkZXI?r-AO!3P$#EtdW8C+H_Ud!0sbcT_(oPDYt)VY zsJOwA%65or<%MT<(!KWr4$udVqtu^XUi82gm#xE_1vVzfrCXdQh{_O!^WO^3PDq-u z(Gf$mhK(pxajiyQ5UobiRTr18&S3gFeZ9lhbpkZ&q;UfLnU6>tdN_r1pjBkEOf{qp zL|@Pzc?7(>37L;I-ag+`8PT-Z?ZRQ29T9Ra3pk`Md%BUn`Oqf*hFJMc2G&J-`YSev2btbuFpt1d2F!^y8)8@#{8Sz zAL4>{98zuDu>y6Z*@mYL&d~fIi`ep!O{v}s{urK}Ug&V45nXQa{QWco=SI4xGfz5F z&n!FhWcEr(XCOyEvup_8fnTXlLE@9`#9z@4?QfS3l<*DnymOjsSYhkZp_G#5A!p^4 z#y_&mWbE5iND~r&G_JLrQ~zy8bW90+OkF+h85DSbSdI*hLHJdo2m0Vgd}9&h_xbqk znq*~BKF0Pw=|0>|7W`}D|K@`-gtwT4OasM1u^n0Cp@n3VB5e@w(>~f{A%7i>V>ZB& zCUrOXVa|`Uov9HlI4FVzlOs5=|1sjoSWRzSYf=wbiMW%v)FTN}k0e~d{;d7$7AtRy z>|uyQ7H6V|pvg?fqj-u|^$X}-_q8Av1^Pp{G)eo`UNW@RVe4goojY=ZszNn)gYvYXfASQ@@zkP#_$~>6Tp^k_&Aq zhC`P1t~H;}L;UgGU(9pOYX&Vy+>L9EL7p`4i+RcYUC@6s@dsds@Z^o~rd&t5FVXh@ zvG?Y2QI&oF_%#c|fCvMUj!JMqP&Ajpt&%(=wO^lW z|6JF(mO_>gRv22?vJiW23tJQh7h=so;YZ#_al2jh^bw}VmTy2f+3x~)|v{9WtLOPa_~ii z#VTr4!f+Y4*}-p*=gsTLtupN?#pfcMgZwP@`H2yEktKD}R^;*SXBA2fg(2%HorvZW z=L66dYmOR_V*y3_LNx~7(w0To4;hOQJz}E9B4mTU$b@ej!S7)e>xO!q%ZasRMppfm z5}zYpy(MHrky*dtQ|yC_0%e%r24!Qe>p7d&iV=p>SV5E=sotKSay5m?Km%9L8*vRB+%?j+I#@&%mEoiIq0Ck@9nlOa1KyF!N zDhn%WiS#>hKGcNO7)7B-LpAQ72?fWf?TS6|1I9pYFv>Bq^i+&;Xncdd93vbKaWE}0 z55d_cpW;E(t4=O2dj=+1aI(M_SBY7`dySvbwPKG+r@^gi8t-H{=YpJoJsqRAefplJHOs zQU*EN;JN<>eLLuP1{^a+`z@+W;J1zV*CqzwA9D@pGlE&};2>}XH_mQF$n@Q?Q1P!& zS&!(3uDWiK5IHlWNHF}^+{V8!zjK1x63p)WG9>`B)J@+yh=00DyM0khaIfi7lriNi zq&HVkJ_w^nAgkDon+FK0WE6D_L35%+uQ%Df>a|48i} zZwPBC=VnJ*w1tzhgO+w#y0qO3TQzanxbfWMS%LKc#N%JZnad34B{ly7$=!L*6OX;; z$~RhL;|i2O{|Xe^6ZSr40W2tg;C<4H6dtz0)3FY-aOj8VKN0im2J}F+o*(P9hy(RW zrd`yJ`THR1lZeA@nbtYafiDQUs!1wh9{8H4CvMrH)ibn4l6I|eX}@>^uquXDPk-te za3i3YZovq{z|KG4tL+Kuc7n% zpP#2wZs#bN*8w*ca!+2uY8udt+c1Cf#MN_Y`t@gUM*!P>57M2v`+Hg9^=it46P|z6 zBw`QMdC$}v!PJHqSaGh&>)`c+WYr%W8|3q+zAoT3T8(?Uf$TqkUG*h@&Y!2R;;#gR zbIQs*aw}oYEZyKh@;9${RuCib-3Jt&8#_NIZNXe0#ii?wrnu4?0&2smJ$f&F0d!v3 zI@_F{D^81AYHTwEBPM-hx|GL9-+^^A9Mh+ophCGmQ4*!h36z=A^rldN>y$uXL%mUS2Q0I>Y z$SsS>?H;T>@~&XJX(yCwQ>vrg;wVeEoZT>f>Z~afW-#{jbex96sdvS5Qzvq`$!Hc` z?l?m^7Y(PUJwAPAC#7s%9=51N8*4x)58%ANFq}3*^5MAa?gi}MBKf`bw6Z+_@~fUO zlp4*60Mue|WjKQ~Jk5ZVs=2O>)2}DlpVxO>G_Yqc2D0alF^m-Gl+BQ1()r>tI{+By49y@t3h$9jE3@#qGm%dQSD_hNSVZt(uf#k7X`;Y5mcG z8&#@!xHTfAAQpP;W5}L{Ea<4dNQ2W9SO-n4euDw2yZgF%C*2U*R!(X=82J&LrlUUF zq(S&NJ+jt(QLo8prcbf>!&61X|iKE!3t%Nq@x`qo>d8ekcHGG$GD*5#k4m(0#O?Z69%t=#}dtkYz zr)T9NQz^HVJzj>5w2$MGr!z{S1N#p2#iV+_o;!olo~?^bMy_%c+H<8z|_eIov~TV&L_7CgIj$pW1i3u(eT#?iluZ z#G0p~oO8AaKOJ|@;iH*`v#9%HX$P*1JG1f5q1uk!x@o5{BX?H~>lmwqV)u5mpC}Eu zY-F9Y3vhbj%gUWv+A0n1EDpmLRF#6i-fV0|sK%Pv2(?5ws)Q=BNUU2_b^$2+i)mh> zJgp+_r#Tv~kf%H9`1Y)mS(dZe#lXgx`BXmo_)>f)FsgcL%nn_j7v;>}F8q8XVN#;J z1$jifS+Z`#$^p1>mwKR|Y8~V%h}O;VYzyrTRpKg@?oA7oRb8TA)lF1Fu%vZHDr~vV z^?78_!SB~0&gL@9Q*u`C$3tXwj93EIM~?^iR?fPiy81YuMst2@E;({6rH&lcPh%;!~@!9d{k~P@$Fo?E&emzPsY0!(~9DkjM95--;~bm`8KsmS()Z8kCq;j8K+&7k_9)IAKhm*tNP} zwgxry$=FXl!8KBvs+tXz4m=u-j97IjxDzJh%R#9F{@h@WX{4{m{wSIme$*R^Ibo7F zc*fP^{&|$QOOMlSM5^Ay4bE(hhD&lN)M{n5PH~tI#ljZEMlF*GlUtS%U(nK5>iNb} zPvwzHd=Iaw50#kTj!>C5CPq}pO`%(`v?lOovF|uceV!L;zCSg&7<@+7{+pm3T3hE|#JaR*iGTKpe4mVrUz8zA*q{DmFoI5XU>5(%ycd$M%` zcn;FL=JlKZ;o+}0->-fC7?~H>HJMw`ry*vGZ^xfdO4FLUHaKk}5jVRRgF9DCAy$}F zg>59=i=HdqOITmcrENwFndvp|t3J;<&^@LhrgDcV`6J=-k#pH5%Q@_@c==qYNy1C1 ziMy9e@>i^n z%iYx(+_l@&yZ-uF#^~Z;@(c7TYXIBe9Co7ZlINKlv{DTt)ELU41K3X*jNbA%W z75V%WaaS7LOMO<8W}KqU4xSjCqjeZ32y?Vg+r16$Q*B`?c(CLhvwlI6CF;RyddDlEuHH+n`*{RBIth1hK ztQ55_`NI=|eKC2!Q1G|-I@!^gHURV_$c|<9L0t7i$a(#GhP&9XIxnBTvzwLM30So= z&ABXnP*}ACdk1@DsQZzO)qTN_xE)98JMK00qFcRji>gZ=93zvB z$7`Zw8XudgF&F9ETNYf^B3)W)w9vjUS{X_=sGjlU)sgDH8g&KiHO!%4o=D*`X}=1k zodxA*S?P>YGuDT81W;7-pc^$nbJI)~e2mS|;rsGPnm z=-&2Aim+bXj`iZ&#`WT+UGmwlv7_;~Y7It^p0jp@M`3ExT0-4YaT8t@k{%3M#n>R| z@o*oAJ%3nnK9yFSo2B4f4bI3=$KS8Q?dy11oh}~hNijRTBokjzmt;gO-KrlFE|sdT zV#6i4fE}`L#TiT{IU7CT7Y$=daV8YQDyvZrgrmn-&eOwD3XWkVgZwL2;{~M$WBxha zLG#_I1vJl~FTjm}y#j{l5zhdq>1(TXSCmH=zXpC6;Vr~lkX3>65!4f~!m#VODD9oJ z(9!_xSyJnycR@OCP<+qEu|6&MwUE-l zMz^(#dxPWPN;%A+yRpDlQ{DZ}KTT}PdYO46O-_IJc$L1Q&Qk5{vVvMElZe5if zLo}NupS3JaETy*fny0Im$$iqMW;>Ss;ptjy#kWh`8DED#54Egq%mnHCNB`C+HZ8-m_9ye5A{*v-Y z4+<{U2SXj4PWdzVO8*hY49X9j+f+w0L0UzA4^HBs{Ghy{Jfe1K!2Pu6x)$G7=uD&- ze1}bxlGDLUIcV?SJ;l1OL6L@W{gwUJ4zyT23Ie$UmqRzA0FPK3j4gi=OTS79VCXrY*gKyEA$ z(*lOz)CP>-8gR1=&2>efH>+JtWwk*OjL{zKO9nNasGQI}-M!NWq|GKiBrriH`BXR0 zAHt}AyRFrC8r;%BXYYak2q3P46GVbwdau$PpNesN zGL2~#%2_=shxjW_;iEYp;@@H$a01kE;`MMpX@gEC-HV=~bxX1PZaZdm=3t&i zy(PuH7;62bi-7@{t?}LOYxs`tbFRDyfOv%l9>`CH58qn7-OIw{51YM8OB z<~V%|Gt#+{MNZtWVUjIc{=yv-yJ@MX)KuYQ1=$fz-+J1iEe;UhfgNg{E*>>@ZF3ZJ z`ib{cX*d^7QKHk4u&P0Wl^pALdVWz(^v5YgY|#ay=F9e37mbFFvaxIY2@`h75Z^Va z-E8n()N3%DxEF|;&I%)x{`uBW@rAxBE-kQFS9B3K%+oC(#e*(jtxF z69E4CcTWs<-Tvy?QLDe)n`KQZ5YA)O1-=nrT%KfUQKog~4%T7ZcjIgd{55SeV0{uR zGwsr+|KPFLY10pSzQW3mYsee(0qXDZtra&MK85`b=o4Y*k~a|NYy99zy7Z=-qQi3u8XQq*Jc$MOmk_?Ji+9T#qk78u2Wj^E`Iul~%4cfm+H%?!}Ifo%Q1M_R_-+W*A z^90F%Kw7CMRMEV_nVACI^Q@9kLYo^mYD{Gw=n5JDn+;@9X zEaqCtbW2T)+yb-GSi9p%hTp_joAAZ)vggbCENW*P=SE3yZoQUMxy3CPTj+mj6O37F zoch-OY0Q-#J31n5*o6x-$lhd}+kOG*{O`^Zo`{Ld+n+Sdd}FnR;5%~hvb-_)cP%Mi zg0EB6vDxW)r#$a^)o)4+d&Yt~V*MvZ2dtw70% z!Gl_$^!T4G*{#rS|A4-i`d`dn%M874B5KFcIteGekmgJT^Nh`^mID**4gG8as;yly*te7lV^~ zN7f{5<{S^1c%o$ts}k~{f@OX7R-5^#X2zZ{a$cE8pPg` zcFGfZ9rsq_JJLzdtU503nCIm>viUkjO8qfzC3$?qUAQsoh3UhtE|^C4F3;fW6JiO6*9^pM%&{1Z>Z_T% z!mHt0mtb7LMHIFwjNGyt=OPmKla&;?WhX}ex!{E&-XZxVFONH;vn-M8HI7~0OjCjM zou@+sT5Zq#>z(1FgXNYb!v9v+>8`R4kVVyW7&5kJc#JW|<>_)gQ0@ply<*xPvX(W> zZM&X&jT_%CLrf~Z9Lsj&9w>cUJZ8;IpgDcU*0Yfqx%RsbPTk!Fvl%U*t9d6JH2$mJ z0HbjFY^^Dgm$ z)O684E_G1afTXTu;a0sQ=vlY5!UzIk!M~Zx?!4okwqClEc!_}3o9G*F8UuhP z+-;!cT(~o$JyP-k);43MceDw0#MB1rQIiNLtHV$GHvoIihRGv4}Xc;$l~WrR)x$X-n8`A#1w^ z9n;3OR!l!=FqhFevN(xau0Z|V5agQ?E24$*NvV>RjfJ&)Wl?HapT8Baqs3o4x5sHim^ zg5xGAcJB4rv20sg@>64;%gFNv&qdUSlgQ&cN-VohU>#9N;uPF_ACefUw27@qMBbIs zs@2r>F^SLNuKSkQ`xcEhkDcNYpRVeOufc0iy?lz!%^i02R1($V8kDjP*N=PldiPRk zirwoxg!>UIl@&~1A|&Y))wVC8`+#z?bU^iP#q2YfVP!-&tYYDILY{N#Gv{v4poR&t zpCSK-pRf#SYdql)a7cS|T3nrfo!st-TwEjEJGOU^m*bV7XA9 zDm&#(uydoH?5u|!y%%SCHLOtRUk*PbPOVK(vF`T#)WDUlPLGD{E0hDqEryx?)be|y z@7Z)YR{L^s0P4lwngGP*hx+55K3)kag&lKP`bmtEDer(NwG7b9%nRh6X3@L zj6;ukTGXR0%fk2^-)0|$?uW95dk8HS#@XnhcYE%*F+L-!AGKAzZ;V4KsjbzB8$G#^ zu>GpcxMzTNh3@+yTMeDrK;=a`JyCxQ@y|fq1}k<3!K^?Y>x*4a@KgG-(Wr$nsD)D$ z3R~6hK`m_0dSb68VK3|xk=qOPG8FZ4oZ`pjI=-xT zqn(6mqBRaSf?$JgIo{!s>rgj2+$5aa8g;fM>TEwn|6rZ9j40LM#KWFkJD3~ffUf#u z0dXT0^DpX(QIqN9*<+rk>Lw(%IniH^bhL><(kxpfl8#hM_H0+EXC40n;DPnlJ}=Yd`SgP5pp4YQ$gq0acIs0i|yk zVzZAUt+<34ab4+8Z9g8!NXy{FVfWuZNX#6Rio3E&Js6j6XV@8f8Mx}t(rg(+iI&ui zkv^N?9zh?@?1>M>OaA*?C$i^nx0-aD+N@@Jy}QQYhGWn%e%6dRTyFR7-QkwzJTSIY z#(6gybXdUbvM;ophHZnUeg1M{G3xax0BEFMCcXrX;_BS$MzO z%B_0EbiZOs@(Z4XM$@mh1}LVxVH#9T@(Z5Uji$8T*PxjHQ!yv`1&^V*dC)zWH=vn+ z^m|M9ds<<~HO*nroHy-$XpQlvYJR~}QmdX4r+!}`-s)?tapAy82{(XGUcg;Sk6`q5 z((^6G{u-ubdS<{vx?mQdi`=jzud3ySNqYg??=DBA8*z7tNnO8d$-f~ zyYr*po*(`Ce!NxRul8f3Jy*HrbDg%L(h&Gnz?Wa>_l30lHtfLu(BQq_wD>y6xaWwu z?T_t`9c>qV@?SA0?u3uc1 zwr)T}%E0=X{`cJIcin4EJa@kH#k;y(_^o@7-@E;Ksq5+ZgkL(HJ<~Dnr=L5Vip6(g zM^^D;n>LQ0_}1G`y!rTq%{lM?03XXQ93QR#9p{^`09}(R;?TTz{{i7uE~6L>?5y@d*k&-AKLKB z!|NX$Q?w*KW9hvwEE{tF@)g5gx^L)8w#{n>BN4bFHbls_J(B+)kfGYR6y<3kFs@MgzE=z1!)NQ=F%y)I_v{ z|7G_R;ARirs|fs@jod|W5SxceEif6kb5kp|~Z>KIpy6Xu05CM}F+{Jle& zw5|w^WReC1FpvO8csaa0UI{O#!B;%Is)gId;dc7q7AtTPWh!H1D&|eL05dCA4Cw^4 zSA2isPT(<|=o+ya8419q)QGyDUXSn=6`Vqkp5rD-n%xr%8gUIIo{RBN9Hnky3Cngfiicy8Wgps8Z$ z(_?`l75!!o0~#yt87Bhu73(@!fvjTm2i<_)^3lI_0J_UR{=OaXT=`~u1W+#jVN5Xa zNcjR;3#=-iu+t+TC(6gJxBzsOYwtP<++J=d_zqZ7921eQhbwQT}Mne4riSU^oxt`3}cU0408%_&w0c554I?!T!_wqU*kGBx7-8OIXQlP_jEpY)b*H$#;8K7i4-*GB%3DgsS zg|?-(hk!-4S*z_pr%iAS25zw(-ZT(cV!JfFFK|2j>kf3;9KUn~?!n99t+LHIZw4NL zc?3|lO&bsbJZHP}Ap_8DTi{|qukE8f*Lct`y!FZ@pk7En^%Kx2Y*_yzFhrRAX%)~U z?8w*yj1-pITtKss`oeZ#l+eCMDUcIFyS)pH7e1Z2379A(7+wQ*73Q2@2ed%F64+aK zA?F34RTvVo2$(Fa{8a){-sJ&Pg_mBQ0!$aaDSjL{RJd9<7H9_@nZQhe`c>2~ggXd0 zR`~dj0YHav?0R3|1kh&zW(ysTbq3}LX&-k0<_cH7yAwE5_>waN^MnPi2w=WoC};_k zgop)3;C$HE0T&7>ed<#fTOdS?j_(dq|<5Oi%=g2E*G9l`2kocJR7+mxJnoh z{1tGGaQ}E0a2@C<0~W#G4}lv%$3K9t3gb;%fUgTJOeBdVoRn2w+idTCxIUc!G|9MevI@T z3*0Vj95foZL)iM-FyN=c4|y5D&jjyC5$F;&=MDf?2tV$>8~BA#G^Ho7QWzcD4Y&t% zB?9*fQzJS6_kpfx;C{rfEwBpdcn9!1;e5w%;6b=+2|Ofx{-+UmMA#l306Z#uFjxaT zE<7~h#z4kSB44ipWg&azufU&BUd{kd3$K151J59SM}g;rQ_ma(UJ%;+xF2{)Ks^Nh zCKRmw9OyJA?d3&3#sm3sm#00@QoilARzR-&^$O~DOyvU})dN}iPt`TlzPs-F)dgg(eII;G`nwN5L;VnX%WpQ5I_0jHUnMnPad-`o=f9so z{gK4)n6?P$13B9wV>-}c%Xn=dkhje) z?E|#i-XB2ylf!nde*!Sq_Q}ROfs(CeN^9T}+wbecfQ2?8ItW-~JAX|JblQdutU=qd z#TJwBJFvudZvAQCcH7=HM}aQebD`BhYB%=)t86F7?*<;RU9o%ulx;I7{1bT2cFprP z&~2M}#tHP={_L^=$b?qqtATo9=H{1xMxkBxVql2SUz`s#36K3Y2N)^v-%kaag?-&8 z0;7aeHDiIC@I_K4FkXn;e=jgm_;ara>?&k-NCsMj!{7A=_C~p;{>&;kmv#as3+rNI zfxPe(`hc^`fR|!vUpnh%_>u6g!vy?Ta9wHv z+%AkS4g~HHqVjdXPlbt|dY;~tjbL)Y!aB}rp;7`Jm$EbfjExa=7CEywK4@-gPgs@ki2VM|rek}lA zLVKGJ{7vY0Xco{dm^)4dUJ>5^M>g=P5S%?8cuiO_axBmb`bPt6kpFgItx%YBFR)%% zdyx8HCKft*phhfMdk;`6eo;#Ouug1sB?+h(AKlRn7$6?Ji~3`O=>c28xMuIiOK= zJsbrL66cJeemPj&@N^`wh1l;S6EH+XKLTtix}OgMhKi53H2}lJ@UOH$ljv;Mfc_+0 zeDRnU7$J_?dj;4^y!Qh2*OB7k-t4vZ3K#_tB+DK2pB07i?iNgo4a#NQs;3gkrn=nsIg;_xTm1;&Z( zUw;eOL5#Xc{d&9@I_wQ#g7{q3E5MH8@oehfJBfFh*8&s8$tPC=JB#agQa|5Coc8_; zz`GFtCBUxYdk3h$?3ma5zDuv0+Yp0 zs(Ii5qz~~21H~Or_5-GfmB;%4c`-kW_yn7H?0R>g0Q&C&iekz1L}04eA}s+pNPM+d z957AH=pF+cEWVK(1xy!Tf0X!#46*E`*1#c1r&hpwMU{^jDxO{t3iW;BlB+F%_lrN| z1p$YNCAvVMUF^M44;(Ijf1egOLR@ZOz>(tnFA#r`DHbMqfTP5BFJA$U7Uj==13n-Q zed_{njOc!w_>Bj}y`TRCd`L{`a}xNln3G3*$5^rIheNXNpBw;=Lpj<9 zbcmn-xd)gfp84QQ;CL}%Rt4}e@s&}#ffK}T;-|pJ#UBTh0Vj&PMtlr>Li}_l@h92h z;Y}sLNn%U+AHd1txX$kZpA`4a+XBo%{(@g&Pl>IvHUX!I-=A~>r;1`ZaE6%Gb1iTt%FQa^ER>Hz;B3^-<-n)KXWo1fm?tK!Uk03md|v{5 z2I;W~_$=z_LSVkAIXNHroS0xJ0L~RxjhzdeC#Iiz1}KU3k3T(-Ns{>Cg&9y6AU?TJ z7l=2;J_YrBF}n3+sOQ7K2~aN(mz88ey+9nX{ZXhFio=gS4D~|MUONWr=fy?V(NI5+ z^ce~DBC+!~cBmJL>tgSRda>Al)xA(J7Efw3pk9JZRhFyKGP|6+aoD z0`)R+Pv8Kkm!ZAr5A_S;gNv+CzaVZL)EDX(#n_nMP`@Z1j_3*XOX35UdO-aW@}nEn z%f*^s?}B={SbC~6)GNf-fA0kK3bCS1N2m+MeQ&-D zYNDWCB^n2`hkCWRVSQVuSBrODYXkKfl!w+(uMvm+GZN~x;;9y`pk6D!J3k!ib>j5v zVa@neXL)V04t!@(d2k0W__xCHXRn?IE-63z_Hm$8KA?LQFt^+>=L?{td`Ny7&|dyy z7vekl@*Q*D1X{|Ue)Lr!S3dN>YM`mS!{;vmS^0*fg+SRgE#VoU%a!+84$$c;;v7K9 z)g~nq$h*v;89?S*I)5PP?{2-SH>p{4ue(T{vTVkhdL4+yS)P4E;)h z4%@xuTY$N?!#kWn$(A0o9=OEz+PRg$LR(V!3&0}V$Ez0towkXG@_}1yKPOBBme@jD zP6TeZy}ICGpv(42!Ehk)gT#kc*%o_<4?SZ0BC9V@w!LKS4m@Ww&+Z6x+fGEr0KK*^ z!^}V?T*?Xu>V;1YEr3P=H`N0}gwa##!GD>A&u9Gsj1=D0o(GzRxX^zAqlDL1{s82J z@WuOp@xq34p92$xZ%TFoy9!SprTG(!Q0RCc*jspg;G00J@Zl@30+WS?*mXc&SaNj* zFjbfxwhWjq^qIO4I8>O;%>~+p?@!JEW(s_($-ptfflnO3vBIFQ9soLosN`Y53BqgP zgMryXgqQ-%5pH~QH!xR--(msI6yEv1GcZqhYe)xRzTga^`4vg%+p-OCzF-&;4qPbo z{GkPKk?_uH18|8@zDxsLCVV&bI@0(>;flo#TrRB5JPRxos(v^LTqP_kIRsoI{7c>s zTqj%{{}r%E*xSN9{Yq4i_|SRwq{G8y;<#@~H_mBMm^1-M5z zG`b6Lukhlrc;G%^*6JAGe&NGs+X1VDO{?wzekT+kB0lsW#_cq3b4ZwclK9Xg!ot^y z4?QY`wP@gpA8d#vKJ=vU*gWDxWz267ANrF}qB{jVE&MZq_|P-LeG9(_o)hl4^IPBr z&{YY%B*a{G0e{2%!%m=E81TwA;1yxp-6g=Q;5**~UK6HYe-r2xrnN5y)(8_Pz6z`r z=Kc6GuwH08V>J-`VA2YpMvRE0c^)nJoW(#L`o9H0z4**m&jABOwsJPmAnqw5{xeYQ zaf0|yBlxQEz#wtFX)G{UOsyFOY=QQj_|FjVGedwa#kbF;0z<)frU1jlqAC4>CUNle zKEQDBGZtWk_{){MfUU$AaykJc(Y|&7-XXs6Z8Wg87+cZ~*hXxztu@drw)v6fh1!Z@ zR2ZC{J<#933ABg{h8F{q#AC~7KB*`8%k{usqGjkhU~jSO z!BxOM;1gB=`-;~RUj*JQ=3gOx(<=5m^gOU1(uerX{^G->^MLn=5B)g@m@MA;&`jU} zvFDj7z=2}O>Pf&9(fY&$Adh}`9MA^-=^>y1zKHlt5&Xk&U@G{2;xh*!e~Hgb6SF?2 z`KQ6+%Y`YxbaD2ydw?0BkLICNVEkYNjuD4N z8-NdrJ*Mb@4}t$6e)3_AOKQ;{j|E-CPd*}ESWEomqvD}2Y2Ip_c*mXRfevxm^3%X9 z@$Pmse>Glg=Q;*_OzbTk22Kzs-}gQ6aq)_c_{fRkI`JFe6DXfw0kg$dH`098B=PHC zh<}`n@1IRh{p%Osp7szh;PglJ0%g{I8EFhO?=~Y zjF&b7XNcWm-vG`8KT7=KEV1k3#4pYk#}}^yJ`MhDH82n5dL?jjal~IO6N{hd1@$t~xzqyn z3*sB^fv*Dp^~Sedpng$o5uXV4i=yC2fchozgO9;Sf&UuO349dzuWK*g3H5S}cZh#l zA-?|)Gt?_oz6t!-0Z%Ka3q|==;+Iy6oyUS-0{=CweM_iUiI=YiL%mAO-EV|?wb-e` z0QG9|tylC=uMt=(+*Ke{Fl~`T*j;R#f~sz&~GjyYD`?(`Op3 zP9K1EkRhf>Ge_+a1nIE=NDO!b+3nokPM;Y}t?9j;`Tvx@pHw23R&tX1{}=xsNdXfH z^mar}PI`JHRgsa2`FQMh=-?6=-kP3E_84d9LUN6f^vM&#%yF6Ny-B8eLo#%|MpBtf zM%dywRnBp+lW$5)RBYf6+O>H7O88~6zz&Ig6@32|3rX~P@|ELw$gQc0u#&z-^yQ$&*ug2$cqRI&@Rh-K1ZeYR|RvskJ1}=Mt@n9H-Dm_J{gtzLc7p4+n~$ z`OVTN88J*xPbV7KrPOqLZhGozlIL;|@$pK!UCPPH%=EdvG+{y}2vz){bbwIOBriTb z-s%h2uO9_}K!0jpda6u*_8!V3ohOVTd2OLWgyI&ok?_kAc{RdkQCL%xk;SBR@na@{ zHm_<#DXP*LqVJ8QRqasr<@3B^KZ?sI3Y2uC7?T}6!u9#1q??K5QsfmoCYQHQHqT(-N3w)ejYEAEnm1HB+s!l(UY8N)u-l> zF0TG1I-?Xh+XtsZl{!nQOUbM1U!n}~RnL9t7EAg*zkYn8*<@0D%1`&FKXL+jffs2> zQbkZuBq2jibsaxO#lQT|EqJq_VAuMBg1M^E+=gQf4WFNFXz-~KnR;IQ zz1J32#p?CKQKDfp!Hc#hS%n~eu5bV2LV*g=N&tC?Ai7t6m@>3!@OQ}!uNn*NYC$p~L*Mxl$S#y1&~EC;?TFDcCC{K^VfzQM4l zGT$GAipmhP#ZkG4%uzjZa;&qDBfn-VN@R^gk@){$R}p5VqM*{5Llj|dis8iMhGbuA zE3S|_{;>SMfRJVmSo75IS!r^iH4uHi{04oMm4^;dj;R*S);#zH;me==O4WL$&rhfg z$p(YLpS>Yb$vOM#L2|U}z8;xT+sxeRfVvXGR~+i$UX8PAKc9@6nUj1j+=t}(2v>8W ziG07>pFRqCNHv4sJ_F@G;z`RvW)x%99R7zOcB(I=1&xy@Pab#q=rd7*)DuCf{aTcO zd@Av^sycaM1!Cx`@KsRe%^|~y6LY+(dHuxk*?HNH@e_UN!R#r~zuc|2| zB{*MrRQME;teQtFrJZ=q7r}Yeo3{_o;IH6^_)04jroh zEyqV+We#d%J`!D3Q(7u%;ER8K z?^%xoKGYQNOlXRaYM$R%1pM^*tMu{N6PwD1;vOZy@7`pw)KZr8je?0P zl;|}}4<+=*4g^z$N&)cYKb)ZLu{O^qqK+DY5Py~0NA0PvK7}Hxxs*Uk>7*7|sm%1R z2r?r(=3G@h`?!it|4I$_dx!p$>NBcyh(Spaa2L(#N7=h6Kj9d=UYeB;*l(^zYjcy@ zigvZRImk#xYEp2?L=yRTQ+YwQHCK~=&DCrox)h3@FTc&`8Jerfesgstg`l=D6daM$ zTusel{X_@y-rruq(!SY!=N>sSh3sSgD`(%ndPn3L`ZU3O$Y0>rAbpMu$zz5b+p_+PiO` z_ltce5hMbF2yG7&GBulzPzj*~Xr4cm-&Vy~$sWaArAVcR?B7H`%2%`c1y!ZL!BxUb z&dC|ryf-3tpm7{VHZW`hOW^XyPjN(js7sNlfAv)TRVj*UB~^#xXcY%S%cq{W|Mh{Y z6}2`H6VvEH-<%^keH&Ha(sQ7rs>4%nen!1}^K;_qn;#`*{`%*=Ny}?)RQFZIH6Qw^ zsJ}^ltNm++M*DtyepINgzs3BT!PhomwpSI6YK1QN-z@edZKTgfcZ}cMr&jrJzb0c1 zK7BvL_$59ojrRTS{pJeBm>cc;=)2n=9|iBWq%;KuS&HRmbDZaXlX(O4+~U5`zGAPT z$-ZLG(_~+v=T`H+eQ))@F}}WV8*U1(Z{J3G{qehrzGm_D>8IS{zR^FG9&=-OirV~_ z{Ax@;Wf0Wt&rhFU%YBOoyG8iy-9#>%ef-FgBga+#oYC0o$Ud}3XxK@BH$!D4K`Ii& z{*zEuuz)tLseghl8czsc|Dy~cz&$t|E}w(h$JJQ+lylLdDUFs-?Q5R>{5UBqDY)NM z^JuWM1F1(<+b7bTiy_!tpKE-GGC=*uTz_y;76&!&4oj5JhQEES^t(W1QGY%S-|)g; zCVcF3Vbo za+1~f9HFG~X9XE*Da_|ANkuIKTgIZXVc2ln zN4440A3_X5;9LxkM$$++rh~%}<-uSCPmD{o*-M2K#S(=Rf{h$zppKD4^|47Q2wfGv zITIMb3OT?%Ff2%FD}_r*Qmm9E&6EAkR0n;04q1wX&d2v8-{ikWY94~G*;Xgsi5QwN z?92MGB!tlPgd<5*akmO75>x4g-)e;anp&z&s|ukkyqTZmUvqVm)D%L$zjHvOw31pX zVfqu;q*`R%efWO>GfT!}_SwKUXqDO)jGk~LCp{_1M0$7!J(t~0{yo(sC0SRO$1(9Q z&$VU_M10ld%rdGI=g);k}%nWZ=2aala!? zd59#rSqQ@@4pi{a0Q{}6xMCy&dF>Pb@+-n~GtqtrD8f72-0xDBL7h|EefQldTC%()p?hmHU=bFVumXpI*)oSCfNmOoler z0}JaV^>$empPOQ3ab0hgtW%oYlB|_9^WQj_ezOC;Yk(Z;tNdycK>v-MDlE^s*@20l zb_+pCuAZ)_W+ZVpJNWl1-}J++7Ms_B=5l=4rdbswr~Ns5E4q@Trfvvdys>zIPeN5u zY6^2G&tq?nK^GO39WSMw%KtxUB|_E{Pn$Vz>q z8YfxMUZmh9S!2y(%^f^|1tYoRIeH$$(}C;5^>O;2NT(S^ke;R>Ch5^=g`x>2q4pAg zjZgD93~D5a{Vhq<3^*EO#Xse5B()kA8P%C{a27OIAxg`Qjs+>q<8ko05-NV97==lk zT%|ct8ed4Q{2n3k_v~wM^$F75>BOSxf^P7$#YD&1g!I za+P164*C*IV;UsbR9!vc>qw%a7!KGERFW#p%3{1M#mlUDEZ2I|4?56?DeN#9<*|97 z%uQTMMxaWQVgNG|jq?9o0#}oKJ}F-K{u({_&wYi>VG;N5S@q_o*!kPc|5Clny|p~49yk7{An%k6Ld)bUSg3A_4vdg#jlcfBHnY*`Et0TY zayQS-^3-h4^*3$En_T8lj8bGugg$?hPL%o*3sn64&(o=|>HwSpi&991`$mHQa|vAC z?WYOU%1q-TLQs&^Uh2P;;#PkdZ|2i~uPx~3Pw{3x{rAdve-p(AqM1*PwY_;dQKeHW zW3z;8vM-8StXhlKVgLorL@(8YP-_%~6^~hU3db5ZyoiElc(~A9JQi3BwW=Mn-w$w${d0PKYDeZ0slrk<`^#~ZAb^EKyc#_uNi0x$%oklBCooy%@VNYmsffe=6hlsB;C%aMCEi+4)+| zMy;DA$TM97>U0AtJ>HlF=oA>bXypY<2HSuCI?&tZDfR{;Kgk`r4{UHL{+Z!#m>Vs> z3_h+cJW)iLln)zT*nkmiDgr&WPH~Ao5oR$GiZ;?Q8FbKu#7&_G)`OL4dXtfq1M$*) zPz;tqgf-N|e{eJ8Km7HJ3@nIg63LMIU()r<|2NPd>M*mW0P+0X#RAVFmGF|B^b~<| zt3!IIxq#Fx@FHIMpez~x1Ca*Nw|&W+?2&zP7lyc#KjdH2TsSzgJJg{5{$E#%`~nr= znw57T*tldJURWQ9H${RO5)~{pe3zJpd{4m}C}Yhln0dVUcn6~COMzJo-Z0qf1^X#* zM{Y;84%A63Y%xp^$jVD{(j$?~z^wege3g<23StodFi@aS3JUzf)<&}cDgBki0)K}o zUXqiZBJ%N1w((L+qWN8Yb-zoBJ;mJuxWgN^03jg0^u{2?=}kfDr8gOQMe7ZzcF+q3 zTJ<0QS^gfZQO7Rc+M%}(CR}kM6#mwbHza4*URUCl!V*t6Q zcb*KYrN-d=Tp?0d1|urFm;t6y6dw}*7jnVRO(HZaUYbI$1T`oJI*s&yg@V81LP13{ z5m+Fxu+Nd#6Y-rCWr4*1WI6D2uZXi8jWIFWj~LWruyu++Ir!ghk^YXuR0F^1KNl() zx#LoG|0mO+?@j#zP2fl2r6NIs68(ScRRX}@-DbZ`!COiAzmN;oo7)3_0#K?$+*J4f zo2~P|YnA)m%%R+x2KgWZ?cV=ptK9$QzL5%muhc>2Yv=s!9@;YK-TG3W*ZjTJ+^<&K z&L+Ree-aH1C0q3vi(w-zr^n2PQ8Hl)F_4*EGFSRx5I4sa#QM3>F1t*;|24TvFK~P( znPXnAhua}-b!~RW7bX^Vkz(1_p9)Ol3d8Md?W62{@cv*=wGS~3w>!8G-)3Bjn`6x% zp7Bg#AMR@}|HQ>{H{jzF?p$e$v`OY9&e_BL;WZqo$T$?;a+ zZm)BXvOi}Z<$lhd$!GFw-7lIxdM_LwusX@HY^r-BT!T)&BRhv$GZM?K`zf>g;wgaEK;+iBf4v zac!^C@bj?A^byX+k1ZT!f8C2E>Tlyk5k~6Z;>*J&z?l{RK$8&efr#VW&9`23&P)lVwQ8-Udmj6s&EaP;copGo5QI(Gs$Ku+NH9^@sigh?@Omo!WgB!M4dA8F6AFw?&Gh(bNr z;3f=4>V&gMDK6K=;cg_PPC9aBI5(V|>>T1urSx&~jsqL@VEQAN+)@y^8xuF z-s#eCCP-1a2RGk9?hj`j80931=($ zaqc8`SdK(k!F*4tnnk+ImcyS0u!YiKcZigU|1a=TE(}I09`>S^Nc4>2@8cFBRZ$w0 z6yEy-)rAN)(w)g=B29<$(|D5<&bPLFyhV>MB~3OT=i%oGn$_`Iu=V|$U#EHsI z9N*QleFgb|(UGB{Fz}wkD?asHK#3A2; znZSUGy8wo^nU}c(2N|Ct`|CjlgA2a1MD4(V%Wyp|_a3|a9fiUCW<6OV_GTrsxkef%{O>Wl=XTj@TN zbVH_=oL=-UZWB`5&cEUMaI=X@9&63apfnP33uh+O5fl69E3@=8(z6ccZQOZiSB5G7 zO#0+KwM~2%?csa;yRIGlyJ!)qO)RTm4v%yPTIvM85C04PDcwq|cviNT%1&pl4tbG) zd`pLab9jLZF_ry{5`Rk%r1n2MDmAG6o#dq~Loq*qz9F5X9%9E~PKuT5xHp}{9d&HD zJKr?CD&J(c=W{!^ptL%vzeEjlBuOLLTD0-uCX;(-r4czm?XMPbk3*Y9uTjc%e7YAm zvA7GFlRMycN~@gTIX4$BDV#4AuupHGO?GjTT8rsFm<5|6OsCwt{=qYj4|5lw9SKLw zVp%z}apTZ>eO64ZA(ewT=ysI^p0^Y+1JkhGKd5zEGKEW=!^NebhO6yC`2`L0$Sc`D z-4)ViegpTi>w>hBEpioE$~_u33^jT_KTJkVLfU<4A7sz454TjjN$HuuH^?3MS(c3q zB}?kSI=Zaf=Lb?;v^<4kYC!J$>lMx;*a=Gc0o-7B273qPJ)S#a(()PHQf|*T3N1tr z+)(RJy#{ZQxIJ~gTEZwT;2jB+6~?~#*2t$yR7*7McNwj_6z@pnsFv)zr1X67OYKeQ zgk|`LzGVLvt#pNd*}X=3Rib~7d!eLv2BNjx?;&4<&_=3#@Nn6IWTYPMKn0nol;LJG z7kX6qOi%Sb^d9c`!p()BxHlKZ7be&{S~5*9yY;5(-(lkNg1R{FZufZSMrXXUGq=$> zf&acFpG)QQr9rHoV}z!B&d#rqlGwqI8KpAjCiK#2h1ESkI_uWL#<0ciLnlmJgz`Mhjdrebk~|I%&+P^uGS4lbhf8G{=-iu!};`~&VP zlil<{Rj$cK;nb~>#z=MUB<>-)m6@+Y9kxiF`AW;yEjEUJMPABfupX{NelI^n%8*9z z@s^K}I(pDRyqO-cAs#W6qnz7)6s4$P`Z6BYiw*rn)6OnET< z?UP{!#H-pa-Uq~0zvx!zU~!J|c#!({AiYDF9)`s~)5uiI(c>SXs&4)N#it=7w+^^< zDQm)*#&4)#@fi!FR=w9bgB6p^M*pf9gHdPF$YiDXhGG$a8k7ypch*M(oBOh<7-o{r z<$u%}VpUHgk?T!c@JBIeqJ!e=0#y#^VkErj9i~VOOv|v|4*ubRj9L|P_}3l>GgP1^ zT1gAlM#)w!T+XZKwe$5T%ld|TJ!j<1oPpO!T0X>LF_qxtH*8X5t?FyEk*Ov=rM_y3 zX-T-zRA_RbNq@0}zGT122~}b3!d42;-PW6AtTsjzMmQq5Nc))OuyI_^&*iZ@b#CU8 zQO3-4<*{elOoGrLfHY%8M3n&c4wCbvbd5-NN};XP8L*bEty>d2Bc%4YpcC&4T#pZ-WL0$7Rdy*n6^|G zwe5OuTS-iI6Q8_6d1Ybc{RRQ8kEr;nRafO|tReaTzBAbeTdnr-@4ff`@0`h(lVs-1 zIp6u--^t9VXHJrib95U}l9sQRW#CjER5;}-cUNJd&QS;s^RjQ;ff6eHn3F`?^0|lAcAj!6LyxOGS?EfBMMc)k=l6w;aqi~Isj}1W&}p(R;oUE0{j%tO{%zbsC2H@*-`;cHt7|x zlvg}1NmV(}LU&#mv8g8E*r2Ef{Eh;rRIM4#+lpt+qGKLm$SB1^PmSKkq#C6a&oQR@ z&pzR9{z>z-&7S5V&BFj+Xm$#&7Pr5?Sr%8k0D7G;0y-n-9|1n7^y)Mc^Ae=|9C7L_lUna^U;FYPm9(CkbCLl~DQ4v*9FJ~gg3d}LkzbeY*brtxt zIHD7fQVwv#=|yHTiC+A;awp!FvQ{5_5R{gQe&90TQqGaxv((!oP@XIIh{9QgH-##c zqEMBez%DE_%fb33dGLrEeP=6=l6IGZLvwjm3XI6(HU~Aw3e|??2q7fPE8ij9J4K`T za!%32AR|g8oL7aFu#@Jhfu+Hv)1_GzSDXx}f#Bu&>p{&;_|ti#s_LtfGPaB5fO~r3 zl=}*ln+fJ`mYeIFFTUcr#S2#5hmorydLXHa|LQ`kUd4vyB@y=PQuHq*$*UejKSW=i z`eE=xxIn!KLt;@6O>EVpX0fU*xAg3SQ*0EQX8dr&ftKmwba95%ocLiO*o3=WZ5P!# zxx2m!SgnZ`f|4+-Fkkl9Ps&pi2iB3i>cx_*1~Hxi2_?zAH-sY;;>uOsl3E>b%&T8I zNiypK=F5?jEB2odWh#|fQC{^HpD|%*ArDDZ1DUVL2T(IgaH*`WdfVtRAm01;2zM``!MgmO=~YR4~^I(wa^t z%k`jcnaO2^?%SniQ2CvNW6(-aT5J*4>@eY$a=rqr=6YY=C6CU^6upq0s;plUT0BY- z)*La!LcXS~AV>jetVDJ~z2wFPb%_O;yyj1&m3nB>piI!l#9|f#gqO8(K0e7QgrQl? z(5zNzuv`urcdAXw;tEArdmrXDUlW}lZH_kYXilM^_GP@P23HNPw$`w)L`D^2HUUGO-O& zp}Z?GG2u$#sFW);bz4gd#a_8h=eqkOVs71Jy?`qrlSnRtD#dkOOc(TmF0=@RLE`+V zKdMI6Ac{OKI49Z&t-WqHI7);Bl1Vx!?$3}!?&T|z5$g_M{-8ZnHJnicSHoJH?z(zL z>#b%swzdBLfV(Wa?oCdUu!xFM&C&_#cu3wE6~E4p?6s8Eaj9*{Cs1ZZk8RT{ci6i3 zs25dYm3Rs^!A0WvxhwqB14|T8yi}!CwN$Z(+o4}{QP1mA3#hZjC}#<8Lh73RLcJ&< z>LJd%xGaOnKx=jD@Ya#74XuYzt8T4H4SW4cw~XkAAvtUOg+i5B4f}Q;aN-Ygc^mZK zY7rjZ!$5zK8=V7AL4C5H$X?JHPGkK>ReOcd*}*WNV57(+a|M#ND9||&6!JvGY5qk0P>o&)jsD9|pf~4K}qlNfRaZ$fJzg#?&yVi}M6omIl8= z->Z-81+TKXuo?yziY;P`y``?@9F#yyG%vQ0f_UT@cn%aaBifp(kIqk}S|_&D7bXhz z?y)B)3J^2mBYz|+9G#aT#YvdT;E_D%lR7!;z7#TfeUi%$2FU@7+bELk$a2}?hCRp- zaVl{(-gPM|wJA%38E9_3dO^(sX}-kP-wPZE#4E*+9TCo{e$iikv5Ap=*i+U&1e*ut zw6paZ;^hS>)W$MkeZshmq{8g+ze|2c!0-x&izA`a%;NghU~l2Pf{c-12&#O*IqjUu ze$@K)BtNRUtK~ek9vBs92pkH)a#W?I zRp702h4tGomY^>O=*I{!BZl7rDZqq~-5wHcDCW6awfJqa$dwpmO#Q(VU=(dFh*WVRozV3UK`d( z;s|a9O_AP{sxEf6G)CVGn1g0{Wbj0E3S{AiZ46jI&-*aOKUJ$Ws-1tkVHXo`&ilEq z9TYAr1V9D;lt1xx*9;d@fEGXPmVL)NA=iYfAU+)!oriUy)~mALSKzZuGmWzGK0b4~CE|Cb@k?>^ zosbXG4Cx^Bp~0IJu~dLFrs`@4XNYJ~#=PTfKd1%-z3~7O1Yv%Q|Mc>kc_;iW3@V8U z8xP|uBy-p)SfsF%b*1H*g4D|G(@?N&w7BsJfl~$`IL|DWO2AximblHpHbMgt)%5wR zW?cx`g5$L=KS?4<-Iz1WP0;!044zZN#k zrj_s~0%zx)lAIuoJ38+YN9SDPXL8TVjZoXRQJZ!$@Z9KvOE3zKDAim7)n&HnN$$O~ zYF2<3PrTY79x`lDRxNxUc;EDt1RJ?ps1}O(YI(T(%tC{F$UU?$OrUaA-YIO#aT=Q| zw@!k@fj{qdx=(R?|19>bxzWrDn_;n;WeblMl9$CXt(!wwUs%HW=6ieWATGnu4u2;E zmE_*$o!q~bSgYdzSy4uD;GN4{*ixH!LtdeEKu*zyY_17nuDSjQP2BugkLB3nw<(fc zMihyADa<&NvCYRZ78&C;=bNSIFf7AV#KYu=QE`6}_~4O2SQ8~-+tW?FlVt(f!Ztr= z!mWj2Z$Ov9QekerzV*Bu<_fkVh+Eh7&988pfIJO?U zy3<+X65K*P*Dsyz2F;ssjb2^=PY5VtR1D6MJMT3Kg*~w1*k|+HUvT>j&mlMwa*W~| zo%b_cjh=_mnpAV}r5yNGl>_IIno@(4i5ogMa{UOt3m1Cit=~U2F}-e<4O4?COXp^T zx`E|5ShXo$!K6zOLc%%3|lcz()Z7oT|6Zghe3=RY7O)S-hMxoHJaSTiuc* z-xTr}GgcM+^tAE*pni2>39Q1ZW$<2?4HvhpvaBgMGH^m` z^fP@6q(fDq$~`O}Mx+2Xec+1jd2X`k>ryX_X^JyM#R;b}nq&df;y(MNTew(oV_vq9C(g%W#1zN_sq7vsSCOYh zQQC?vg-dhe#Su9{yd@Wcl~L}lb)T2dGUQfeXJ(8tpRfT_Gfez(eyT|2$GNGngf1)Gq$0j5PnB-E{j$Mk>(&>El95G$4N8#KrXANzmYfY3n+?}IZ@nNfCj5^0G_gwTt73{ARdOCHf*Kobz{V?d-@;I0Il%_@$

zRKidxGOtp$6$RYN*bdUj{R)qu;dp+ABv+`y zj{OYSS723<2ha^Wl`Q!xX_!P_vS1a39j{Ub(`cpt`M4%jvRa`F$N(b-OV{HY$;F-x zlt0KUx!VF&HxtBcCWhYC3I_0d37j1nJVKA{-P(8|s| z=mpxNm@!d-J5XPL;cxG>!o4TDCKglU`#Yr|4_9Lv&@Ngdt!P9wjF^TD zA|NE{Y*z;&MpVEPPS#jDns5iaD-^lhwH$7#IA8ROmlojeiSYIVC{z>u0fva;t_|F# zQzbng^-w&{?1l^)iwN~tVUq9@NbOx4aVf;LDcXaYK9M{`*vI8^g=I%9j8x{3bGzq)!0~raY z3POt?r9KLA9gu?ca=n5mNi+gGX!lMCKW>#`ZpDj)3z`ruP+K9}sz77lcDDNx-4 z+*R&V_d{d4L4`7G%P3{l5X48GaQEZj2LFZ7v}MTioFt3GkF3a*$ls~;lPPwwhb(C* z0Z#oy^FohbfU9$vyN7cnr@a!+jhVNq<%$p{+CSsX!D zuo?_}K0i-wMfSwVH*h*^#bwZ6tf1ifxbHf~ReCr(BkVyOMx1bShVqr9zo5l`N|OO+y1&@X$}5_O8YRd?xjyc_h2eurRbi*{Q`*t>z+@C%oonC73+ z(kL{wO!iN?c+Q=Zp`p~4FtqyK!&r$SV>Lu!ig|{BwLwvTt3T`4uh)YM)CEZGvc1m{ z?UQ%tP@N%Xa8}^<$%C7K4SXX*!Z8)A6mb<*XtK>(On2uc)zsWPW7@36GZDupD|lZA z9RaO~u`~)4*}{7bN;Ac`s2}@M7|GIkcM>))lRlT{7zO;1G^NHwI+pFbm-78KUEt$1 zQ7l_9w+ORKHZC}O-%6TW85w|pnj`Fk;=sXv=C5nc2B@d|`gs-xrSJ@&Oc6@rTwG%5xQt zlkh3IdKH%{Dpu`)Z%dIxf1m#m7*B2?;dFl-{M74L^w=-RUb5*e!P{G_E4#722Q8HP zp<}gMuh&}oj_pS#z>v4J){3Mvq9-VQJ>7qRGR*-{RL}fg(lW_EW&HFS`i5qI{~@MB zKnaxv5qUaQZxkE5VI``_JR+-4ItnZJ`t_4~S`+m9$4}!Pt{-#A_8(ko-Y7Q* z5a$Ua87}1eYklmLN@fE8CXDM4vy5Yb*pi`N&HUha(ul3VEYmNqktz1^ZZ?32l4s=Mc zxv*B+?Vj&yY4j)jH36}{2G)(MzNucHY-&010Jr#bIr@HHj>=K@Vz_)i8!M8p<`Uh| z*#}lJ2Cg(m1s*|#^;St)yg>M6K#}lrU=wTtw-JwE=$DBFTY?LM=2kP2Ev>vc@F?cl zUrBT?0w1guT!H8g{EMCy5eN2?=UMHhQcUo7VRTKSAwfYcXyd7p{D8Do)L^z1t2X$$ zjmflbgUW%YjckHbI%nw(YI@nHK2@Ljgj64@kB*k)kW(MS4!mXJaR?psgTKt9 zd^jTbncR3v;P~(6kw^n$hhmr^)ydvx1FG7Dzio&&XBH$m!X9&IqGYbm-<=+q4+XrE-o+dwG0#8t<6hC_3#ROi%hHJ zb{0IymnZWcHwq$9pIzz>vENyQ!&`f7U$TDtRy|M+lCxfy4(~HdjWzP9^Rf%nSrbRM zn4{HESK+y+8>K$#P07;X1CZai4g$v#Y<=#gg1^MfdH?o zUJM{KMjQDDM-oi9nbwT?#}=@916Cc`cSez}47Q9mW7Vc~NlwA^GqEiHri{#;Tm?B$ zU01^l8auLu@$1u7OV=*FgZ?EssLDrn_iv*c8XmGhu9imRq!OJTd7@uWiG;vakRxg< z$qvXAi5+>BA|5xv#}BeEZfH(4C%(8Ls9s%|lbs$kYl5GtN8Ti!Bc1|BErkcBoqzHG z@;H!YXa(I+kG$hT%mmyH{?7Y7&2B_CWbrfk=fq2p;j!TL*df?-v>L7@|GS}CtkjMw z!2=!i&LLA=XD@&-I4(bd2Ktx`k($K_{;cVO%!kqxN~E@wyAa(0x5L4Q!(W~h9Y{3g$>9bJd3id9&ZcgkF4u7Q{CEgU2*2pw1jo#+&fK5S?(-n-NL$v_R% z)2+m%6t$u#F2zLpy?Cti=r#dCNRQx4xZVCl@r2+;jY`Xy7LNdDRXn5bHCt%gu=ych0!8wWTN9jNnI$3N|_xXF9xj&|4{o z!|lr~Cje4zOtq_D`tB88>j1jdSXP~ay z;oVJ$1S5T=eSQ?Y8U-%(_L9DBWQrbq|4aI~vsV$>C!C_i_l89DJ|Z*!g# zi&#}i1>BqCScbOMTf&(AWAD=HlXApas`UoFxwVb|4iSUZK1Mml;{=9I8C&mhPx41} zV>KFji>smy`1@Sq>h4x5=cL9ayj?Of3Z!p0}Z6MUygS9iB^8DaG3qjO1HpCn2S7n;mJb=U8>Ot48m z?50%|JvvbqKbqFp@eCg1I{55Q6*a=>oXT?W-^|Dd8nXSPDd@l!NgP}k4l&h*)gQ&e z;6OMa1_lSlB4YDX5zA1-6SX=JRfVWCc+Y;cf<>k-GDujD`)j7ihz7{KD+CALnBcZb+(v-d_#UG;F{+4ldL1# zdwYzuCRx~5NnfaF7XC8_0}#=_KCfVV2jo+?53|RMU}&=*+MxICk0VOg+f(w5ZJ`Ea z_h3&!ve8Q49nZqD%9!SY#Itg5iqj{K*g>Z9mS=F+oIF`A zWqGDQ3(v~K^J-50Q*fbg!`1e^gX4Ps-@v?uersx=cdDftY272FLxFc$#{XC;8)%ej z$(#{nyA%?S9OvV3i?ZPx6x}j{@L`CS%4#GfCW{O99yAGaTLRI5G$sEd0Z~U`N`7uI z5Dc^iZl6*;wc zzY!YGCN;<=)mSC}aDucLS&e^QX#TLu1Xw2<#n2Qz)`}#NwlQY&(GzqVg8E#&SP<`} zl6x?^1(AS)z5rWc{sOjUw+wHDc+!*?+0P3Q6Y7-w^ycZ!XEi_D+}Lcg?WK4j7G#a4 zcp+lhqYLWoxmLB6wboWYTisM4u>Gr9&PVo-jDN>KCRrsrMK%P!+E$z-nAu9cwiy3x zzjDF#O*=l1bz9W|SKzrTT}{U7Qmp!Y$r$B8Uk;xKo6IJxAzAwPWmcRXciLPT@i$ahBx3yS@jcL+lUjy67OVn1S2MqLJK_)+zg>dOz&`_z$B z@4WoL)L=krllDK2r;FyMiZkFR%>ukE2Wutp4P^%YdD|4d#M*>AA1vPl%aYaMRwuo? zEsQC-2@gVM>~UtgOEaCJc%n3Ubaff2>3eD{b*|%iuTlLz7dhMdjnYKBD?GtSw zyGh5tE}#+E1U%Z6u}sFoLb$C`S*uLfQ+Ve(nJKDU>M~Ykj&0V&s$1;W*_fz=Sf<-z z(dp?y6BzyvHVV(0eh#Dsf1uV{F{EfKw@x#SxuNrd8)lBV;ruZ-c*fi?Xv_`ee6JdF zgLljgZ*u5$Pg8J5uqSQGBAeGTuiAv6O8CctnK>8gzU|DrNcY;*arRJyGND0sj8|`H z*xc>4Fz-U_HgBQI!;dm3AxLK9WK<4003XX3x?6a-Lu3Tr8=Udf_tvb-eHavjkRTYwAbL7BQwQWlAxMC-?7C3ryayrqm~5jvS(Rwf0ce@sP7E6SnUd zeOBID*Cvd#izDsQNF{uiqIk1R!Ja9bnVoluA}^X?u{&@FJdAF`b^uhc0;9~Aw=lc8 zhsE(tSh8CkIjh}nwM)3oZE2sttXB$UZ9C_Cgb{$DrP&}Q+zbp^_fbj zA*75f=Bh*BPEqiy;t%K8uM5q+E(B=5Znk|J?X`=ptF_J_jFmSGcl|)e7|T=^vw+54 zRxDMJCdB+>g`C+gTk7VRev>hQ({6(JV-@zyT>Bga54{0JfzxD076N0s&0Z|n_Uy6p zUD&gSp>t6Y;%7eoNb1Pj@T`hCifxZF#2T`hGhh-t*2>n+`g8C$%IHX2?2hO2_N{hf zcO1^y?`oBl3=46ZTtNJ2Wg*+_iN1Gpd#+P#J$vO#-KdLx8I8aj#oyRm6^_le+JEt_3=!T5>^os-uF_j@3#5&uX;v-S)#T*2;)ta$dbfM7>%ZpuOw_RhO4~V(r zb%K5Mxwcu#NLB9DEqhlAR@@$tVLEIkn;0(CnpxF$=3K0X?aFA`ZbeXBLEKoEDzf3l z83m6upuMZCt!tjWOIEhA5LQym!~E|(2%@Tr);YTDwTqP6g>vlzwYIgb_U^o+4f4Ei zcif$;{Z*)T5$)bZv%QOFI~ULXcH4EADDxMn7c(7pHVFt->Cko>oye><**bYb#ifev62<0H>~d(79J*KvohxOg*)xj` zb{nMI${6inJv%5YWW$s3bjJ{8gIYOq95$wDt8Q8-o9<8?@7qlaCDTHI1e^tPDp|+X z`QEqNEcWuqvf3rfeD7te^e$7R%k=*2@S@olMaP?3>tMIT_&vH6cUZuULHk5bv0Jpu zcrYrlio(oF#!}2$=r6aZ{2Amz)j-eD!wBeAm@?oE?6oG{5z+0=#R^uOc^8Mhi>G-P zFZM1Tg8K5sxD%|+yV&N8(!mkElKP^fM(Uv;A>0G8HDsp|WB(L@f5QVs=2K_e&bDT^_o)ZK$|- z9J}?qY}+-(E>lrQcMd#?hiT(h)K)Nz*;WC)z!fR<#i(%ZVmy+CDbvEa#r#W~%H?N> z+jj;Gm&`p;m2oE}+H9uHg>WaK%2w3|Wdbg#y{pafOzxt)+OS`R{qEddOImAVdhHUu z_UFuT3#+|FuN{(=@cdMmY&z@0Kj_tpia9nYciRoNVqu6a6ppHpVZd*lV#o8GKI_YU za+&?yW%g;l+_cg3H$WU_v+6dhN@s!CL!-)d@zFg7p3HL3Y}+#yTgD>p0Ts~9D;X;s z1Sw-H%izlOOu4)t$#B{kPxJywht<;{a+O&_%&IV}3~HxeAO(&6I_7(u!D=k+q!d~# zbzPQhSD4M7z{bnus*u=R^LWCI@`jGpcXc8B zA{%YRld|lV%Dm--QprL;7S+*K9e#@icZ+5r3scNYUjAC|=t|~isl!}pmFgUG6BwH< zv#vR&Eg9=pX6w|Iu8ewo4$Dq7W$cidE3(M+;a1N>thOP=X|>iHYR62gyr0f?-?`*_#DoS>oNYevAwLG3brHh_s!M2%G8dswHR zSg000o0_pZb!8~SO}^z(EHp0Dm?_-K6s$W!2W7?P%UKmgSf;RLipkeK6E?h}j8v3r zEGWYF6#l|6^7Cf5*-qR4V@R=xU$J4G1Ch495(J69i40aMAE^PAAs7)29D9b#3rG#c zMxuh@sn8eV4>{caLL;#k0kGLCyWGlncc>29hh^|bAY+Hx{D2(?&>jMFNvtx<8({70 z=zTte55^_#2e2FeK7<3QwBPx83+=tK6#d z2n;7$qRDx2om@pfsJ#5#2o%t1T{qWDa$-ZfLt zMDz@77}|>*;$C8pGBaW`I=}Cq zq??hh35|PEk@wW8ZIyZm6U{c_KiJH9EA#D9ym#kF2fITJ?o7ia`gn`pV9k2%^S#g7 zy^)MJ(&pWq_b$oiy%HfQqElwn${4SHZHSx zrf$Q2NyfG$(A4jVWtc!8L%`D zxrk*&F8)T_JRoz7l;4Ka;8WbVorIIbH?i~orO;sbxTB7ERkZa zEYhl!b>g+WRT*+uYiP)CTSMi)XbaW;G#aW}C}t2>%s3Yg(i<0+>5)YiW?EFnOpEcn z!NvBhsZE({Y7O~JOEYzd--#wju(ffLV?vn(qtpf=MzRrnPsC$0k(`Gwixm>UhlHV# zz~L_p4-s4}H-J$)8}GA$gDvzz%q3EXR~xfn?C_z0HawTe^dwMKsVfzh0;FF~&*E&I zb0}N49+Lqi;3E(LT`gAPYQzn=m>u!i)^WvR7Dq5VG>>80bl8!=a=#ZQg6Y%a!=D#BV2JvQEwhrz7%?7g0!o7Jv(=$xxJ{raFTM8Q6(t;n(7SHJmC3Y#vCf4$ zo4E*a-o@~9q9RaboL9M&u_3LD)#4m4exqY>tR)g5yo6zSUmSvyq;s6>XqV7xu~^H> z%F8W+FsRHTSS)3|n^CvX;;%BRC|b(IvcY0GidZI!HnFTsum}MBct9L(IfFh7!gtoe zWmfAT%OLzNh~?#yO&B!DS}qI{g!10aYDIOhbOxTAdd6UzO(?ew9)c?WbVlVFgUbgA zgUZVXl@CT4GC@;sK;!E4$!9#}*t#OPPK4QeMn%d!F)rguihudrH!-v%jALbZV zQ*%c78AGejs2+-P#?YaI2UicS!x=+|;8RsCx?wA~4XygBrHGW_2LpskO~tYg2CQJo zA>Z|3U>>9np84=0U;@ih4g}zT>vlFh7X@hhAb>IPXU%*NK!y<8hk|+Z>xY5~^eYEc z`QNyG^1r{+CJ0X?RsLG=-`ep{{kLBIpL=l&{9Z8D-wAl16|{p&7>!}V>FGb1b*TAb z)&bD%1ITd@MlD|g3yb+;(Nrwp`2X!7jB#LC7!epYlAK^D#%+f4n ziT*P*RXPp>Ptdcla2QUY?)FS(-(l1mjzBo3)S81@<4yXg$uL^$2QU`!%3lo_ZR5}_ zG{&h9El?+m8FaFkB?9es02oZ_LyeO!M_Yl28vsoDmjNz8L+KANC}5kel-PhW=uJe-8k<&c}<0tv{0c$m=6({M?TV zaDzo3kOhEF`-V~d7JNmW00@W!TINLK>0e7p`4?b3J#0t@tT5eO_6 zeZ_1M2+ZLUq@zm!&G!kPh4g{c84&o70X@kXx6H3$T#a8BSN&hPUBP=z6NK&mBLLPUlZ|f%e}+--$Egl{?57tn>6}SH+DN;w zFBoVmKzf4O4NwT9)(g-Uxt;{LL<8&h2`OHKBJe@WGHB*aI9i>wSRxuO$Gf+!uZ*1MjeZ1|W=miKC5c zs=ppkH!(WyV)r@FTr2xX=Y$P_;gDtl$S}|d2VC!PK#c%nf7TL5R<5Mv|3Y&*wOMKj zbXRJr&#CY0n1jp(-cqSKkPjy6uLK-n#o||e?_ne#4&Fqc9NixYDzjlA@GpY0%tQ?8 zqk%=QgWx6buk9azfwQsx6jSq|0QAX_G5RQA0nM?$3@CTRJ_azdNLd{Guk9azf&T#+ zn!kG#q;jE<{;}Zi?$!U02L6A_CH)UUIq$}RAj|)~kEN{F>8USpL;w62Sv6S)z<_9E zPgN27x1sSJH}FbU9zKTYI09%ohZFub@IIZ!!ShsG*aHOW z5C`ZgF7z+(@o~^AtxB21-e?|YUJl5G)QLng95_%j*qCYtFNaa%Y}~`keH?5dHYV^P z$;Q4Pz~7wHKN$2KcUlcC(_ni*Up{g`QnKV{WP2T;EYTu&fHF8A^bV>dS_bG#R630C z04LraFAAeS{Zu*&w&@4^IXKHfz8Al~52vCA5GKAF0DwdA_dgi0-mR4LoFW4NG|NT`)Pb5ID}1PN(P4m62p6ddk~2Mk0!S1c`M3aGBgB0$AbXyA2{A_V zlRF)hmH^;~tTB6h3VQ(mj)T6_`e##d9B&yHNAEwZ2mO8krf6#ZZV;hXIM_;T0T3p{ zo(}pj&TB?G)`8>r^yuik5oV{!%MrEe2I$GoVmu!}TNygM1o|kS*U%#8ff4`_WI)Y5 z0OXLtMS1`_l3{(oM<4q@_zisQ1HJiNp41(X+2uLjzVz;Z952uI4oLL!l&=HfAtT${ zSMwp7rn7{oa+V(*x{GFgL z2mNP>=qzG_e`f#DVDcXfI*SD#qNxBn0We@6KtDeg^A0!;-186M<*<>{M)3Fa#5O*j zHZu-<1aX3SIRIN3Mi!|MU^+~KsMp9UWxPu|7{Bmi2oTd}`kHaz;{Yp~U-&ezkov}f zsU)KRrlC_W2!$U3c*=Z0-rVYF!+hW-<57Kg2zOc41vF~#(KBXDuUCO5`Y}~uP5Nd!pX*g>Cg26U-2{=D%&d zzE$-x4)&ov5OW{EHTt^2Ykjh207cVBoezP7zSDg8p&y5Y$3z;s}DfT$C%)Mj1~Pc z=KEtE!lw(shoOHUaL^AltbxlZ2Ck|2u!R-i5<^x%?)~jLm0wGrLTqy z_bh%Xt$_LPWiWj@69$zJ!4CsCs8#|Is{PFXBCBt?Okb`4!Wjs(h2&3cErAbMLX++N z4l)nxX#Q+P4PRSx+OnGdYisyoivA01bXsZyA;|%#h45|wVjdEteV|9K61wq24+vB3 z&j8HEFez9Ld{p~T&?}9u?5&YL3DYIQQ1tjP0Qg8j3;+(GE!PJsu_OohJPmO28URSU zXZk=N@%7bCLjut8XJf_qKWK1{Vveys(6{{LLu*`P^_{_M16mFnNIebZgs1_X?CU+R zaT}&@l)N?o5hcU$G=w<_e|*F6@!_0Gr>CZLzu5U3~AH!f!gvwq- zbCjPp4Ie}oecuh3NB(iZRDUR4{4}Xmp^y{ky;86UsrcXu==i%PXYnn&I}k zQTW?EZWoJH($1q5(|N_->Z=mdK?*1`T5ORvPA3{>x^YtBK0hb zr(R~M)GMq#^#}Gy>W}RH)NAbC)LU#>>TUL5>Rq-a_8wc6`V;Q9n`aNFOr}_Bs41B` z)6|jrgejf!n>MBbrcJ5OnI1@e)3iLb&vZ}ffa$)}A=5*tBc_$9qo&oVmQ|EJ}?_TO0UZ~v|3f%e~79&Eqc@=*Iy%d+;EWqJEO zmKE&@%gXkoWmS8-Wp#UpWlej^vbH^KS=YYY(%HVkvZZ~cWo!E?OIQ19%cJdUEZf@G zTDG^Zv+QVp*s`sC?b|I!+jm%wwePeXZ#M}Y9g-01s1o8G)xtd;Lxn^~jgagZCbV}97g8M~ zgmi~pxVNKLxUXZRaDT^{!UG+3!h;=W2@iFQ5|(v1gykKwu%g2$tn6?Jt2#ytt2^An znhuY!wquO2uH$Us;f{LYk&dy#`i^si4IQ5lHg=pVZ0h)=u({(?LZ;(9p|e8~4t98j zLmdsm;f`^_k&f}gV;$!UM>{SMj(1!rJl-)uc%tJX;rAV%7M|?*jPO*)#lq7apB0|z zm?&gBe8RIGs_JWmkO_R1cX0yOc7q~m@53S z<1*p3j%mW{9iJ24=+K1jj?0BNJEjZA@LaJkr-#ayq-x}QW5Z;BYPfuV%q~9|tCb&$ z)yd0ZXUWTB9(ht~jQl`Mkzb89$R}ds88mFGC18UyKcMUYaU*22#VF zuf?3stI{FooAH^>x8k#$Z^y53o{Z0S{#X23=R5K1obSfJ=FG*fcfJ?@y7N!*Z#dtN zf76+d&vC}$H#+0-?>O&?f7h9af6tkWf8W_2|ADh3{zGRfKG&I!|Hyf7yw&-BY>6`; zyWRPx*d5MOv0pi-q<-z3nrd@imb%M1EhV~k#VTFfV^ywgv0<*yrAE5;#LjXZkBxFY z9do#}l>zjdkseo#WaO`-JOI>{G78vGJ~K?0nZVu?t*V zV;8!1$3E*i77MtJ#-_O*i_LHaQz6&mv6-$TvDvOCW7oQ#ie2ZLp8A?=M(SIxCt}}r z{XX_f*X^mhTnA%G*WTD>*XL8!qYuPF?#JUZ-A}}4xqlzO#{Fb`w)?60weF|m*SVjG zf6bkZU+;c4{&n|r@$b1Gjep<0E&c=d_V^FoJK}TQJL5lc?~32#-W~t3dry3xdvE+^ z_rCai_x^a;eITy855^mZWAUH3kH#0dkHv3sACE`f%i}+FuZaK5 zy)yoD_p10}_v-jB+-u^uy4S{UbFYiHx*v`&aX%8j-Mv13hkHZ(PWQ(6FWsBszjAMm z|Jt32x4Apxce%I3|HHjC{-5ryIP)aZCQmYL_JB=29cjUnN)Pg+(^k*D=`zoKY0-0k zy4>?Xda&og^ckLq(l*bs^bpVTbcJU{y3(^UEqPX@t30dI)t)u!p`Nwr8qd1)Fwev3 z;hsm*BRuQVcF%@%t!HC;q-Rt5OwZ3mU+l@I zKkIomJ<;=A+UI#bt$I$R8$B;V3FY&yT_IqAVPx8Eyp6vNU`cluU>44{t=_#Jq z(o;RJr!Vuokq&yAQ`0?Hq-J=&kovsmi>YSMm8mN{SEat-`BLhOo_|YS>G^W%D$iF^ zU-Eo4^>3c5Q(yLkQeW}ROnuceD|NN!npDU$J2lgDZEBY1y3{qEucc;tu1{U-`FiR) z&o@$E^L#UPz2}D1*FFE9`iAFQsc(9|ow~s@C-v{18&lu%d?)p7&v#REJl{**==px? zJDwk;zU%p6D&m=&THyInYN6+*REy`wsh@b}r51T^PTk^}pNe|))K5K;)XzK%Qa|@B zOfB}bq<-P~N$OV5qSS4kTT*v;qNzJQKTZA8^Rv`a&pWZ0=f7erJh|9P&%3b=o}Z^S zdKRa)c}~W*d)|)i_H@VgdEScc_q-W<&hv}Z^PXE%Cp@>MUhuT0290?mW*zf-tbELp zlse|QSkstiV@!#~OiDavR_=*elvHexl8#xGYtv=QuhOEjDpsznjty4U#LiIG#%#*E z*bwF6ScURPtWsGYlax)dDrIx5TDc=NR4K%2lohdI%F5VqWkYO)vN3j+a%XCk^2?M{ zQPVD^F+EyoO1qUy(jLX19-~Z3pRG(z*DIH%$0~tzqY_IrDe=T5$~_6cl1NNal8MPm zd*V{1BN0$ii784tF;%%YahY;oVw!S);&aLa2~Bx0ak=tPBB(4&OjnjCW+*EXpI25U znw3?FE0ooVFDPpgUsTp6u2j|~u2LROd`WpE@o&od#Fv!~iLWRd6JJ#}C9YOBCvbD( z#7w0#F-zH!xJKEUn5}dru2mjQT&HYHd`;P&xL(zyCBCifPs~vcByLm=CcdK_N_<*CGc<>^FNc_yJN*+fKnHnBi?F0oK~KGC9_Nc=>3A+bn#F>#CX zQX;CnocO8oO5$hA9}+)TUQH}k{+RfM@>=3n<@LmE${UGRr8}`ic{6dl@>b#wN^Ugh58 zead~w`<45X4=4{LA5sjptUR22M0q5+URj^qplnEPR5m6zDVvg;mCebFl1X+doyjfAmgH7tYqCq}NoLv+sTv4$>e`2|CM}4c_*1yLg`b=HR*yf zJ3YwzXv*r{mMZgZPl?_gsdDem)L`$f)EVC0DVujsYKV7ls=~W3Rq5TIlDr2}Ro;WC zYVV=cQ19VXjrT}unD?>NaPQI72=B3!-FrM$>wP>m()&c}Oz-bgb>1gaXL+AWjq*O7 za(JIf$=+3ufk@;;Xu?R`Gw_MS+2yf382cwbDN?R_a#?|nHn*856IZg?T?Y7^)bwrRE=&Jr z+_dy>$9*pSyK!1NHtzCt*SKJM-?-`NgX3nT4~_eL`mu4%X{N0|WYS`5%$gdpXwPgD zw8qFFttn#FE{T+BZ|xPeosX4kr*;h1_U}AH+p^!L#g7ls)~~40UOil?`6H5+I9{c_ zy|P-H6d9_ej@4*~whz-fjt|!|yGCe}BX+HOd#(2V@{!u=LuYD7R@G_utvO5EynB?E zKJL&ijmTOc;?$-@T-v>BMr%_eZf#?yN85jJjCNV%Y%RI7UVGs9SZ!M59POQTpU^fP zJXd@2`A=#Gj($q}T;x1WizwQ&YrWd#kp}I-RpYc^WW4rx=lR<7$OYPl;}>c(A``Ti z_go?P_hsp^&z0|4i+r{j;>IBiCr5$ZTz96#iCnMEj(lCq9RG%P zZRDHUb&(siuSNb{yFT(Q?dy?mYu|{>(cao}qjqS^ceHOtzN@{m<9pf-k?(8&9{GXx zt;i3xZ%5{8b0R;|Zj9WdeJAo`?YohA+V>(iYu}H|*Y4jQ)_xGtwI4N-v_%`j` z&8?aqS)y$_a=VsXe}~q2{7&tKeZSNm-1I9g68W{ZAkwC#j^Cv%jQoeT{osFU=>xyf zS|Y#IeiHeewkUG9w(YHvQiN?RORt(|;) zjrNPkTJ6@zI_}&+ZdYxHJFhNekE=eUDXt-;rnxbsysRnYPI+@kMWZ_;Da8{~THO+|*X0e_=V}ev z?`jKa@wA8ZxqTrgi~S)7T!D~F?v9XyuCpPx6FNgK<#vTM)CEHhxw=CRyUvANbe|77 z;<^x0T-OtF+1(pboPRMS)O9H&%yl^=+|?IyqxMS3QPN)6a{3!UApK3?iu)}f&Gj~r z?s^9ZEqxb=sd^8HN_Zd0aQzRs=KcW4bbSbvmwp7?aDNOm=Y0a)bbktDxjqB3U7rK7 zRbK$N++PAYuCIVx*VjOv>l+|C?pq)y^*bQn^*s>o`2i?!{Ro_o`3Wd={R{+ie*ubI zzXH9bzX8Rr-+{vNKY$X~pFmOhU%*k%-$1GBAE3-N1Soe61u9&_fJ)bJ;9TMepvpB8 zsCJD4q7p{~HLfv0t!pe$=NbppyT$_zt_eV+Ya)t=wyWEQyD%mMe@JaF4R2?+H}2F?~t0X(j$ zK#OY{kW@b%=y%Tm+B`D>uWJ@?$2}WpbTHffK0*fZMKvKu+Bu;EwAsFz7l0G9!TA#z?>) zcN{1wJ^}P(p9D^OqJW{oDd3FfG%!qv1};>c0WPJ*0K2w#Yz_bkxd1HW0f>+fcoGVL zi%Eq*f~N>Tg<=2`N&s9a1qh)G2+b}BNTC9tgi3%Gs(^M+HBePt1Ki801yVe903*}` ztk3{(LLz+|BXNc4DtDMBld>}dnSW7~m1y$?wB_<^ZH04S{K z0Hz6Nfh12SFkR>ZW(Ywb*3%8l6wU#0p7X$o+zUXwrw5oN^a8Vmi@>#vOF(ZplVYC%UBa_qw&yue5S|A`;RP@?@kLM)UIMRWy$s62E1)903aY|uU`fU6 z;MKG@z?!-@K}~oI%=f$v>cTsqA-oHo%X|+sh4;az`2T^H@BwHGAA*kX5m@N?80^XV z1l%lq3Kn@j1Jga9gT8_W88fPtkR9E=tS@Qgr$F#-j~3N(15nE~Sj77VZCz<7ZN6NE`% zqA(du5~hI3!c;ItmSVFjJTVW(jk_Y+)XlBg_XYJPW{F zVIi0&ECTa|#bAN31S}MmfSQMd|BtXvJ232VS|VJ%o8tOF}O z>%mH416U<&1dBcYg2&=Ff%mdqV6`BCHG&A%3KCc+$Y5fM0@e#E*dS=&V2%zp3I^CD zm|(MDfo{PD2Vxx1BWwm+ge{;~*b24^+rTzqJJ>Gl0DZzv&@b!)1Hx{wL)ZhJ750Li z!alG|*bfGU17Nps5IiRw0?!MF!3)9>utx|5dxbFYq7V+=NH_{!5{`jYo(S-=5D8X$ zj)P$dC%_udNw80d0t){_nWj zqs2mSj93JY6^p@fVhK22ECnZsW#B}y91IaFKtQYnL9q&i#A@(LbqxrMwICwafv8vy zVqyb`i;W;5Hi31XW{?!!ASHT0T5JIebG;xVwt}qK26AFM$csL3lIRB~ive(o*a1!z z&w|s$PH?)|1z?I6lE&6f6D>#fkqww~~fH;qIYOS;H_WUK|dc zY#0GG)r^EX<3~ZwjiaFiaST*aJr?Rn9S0?f#z6T?ln} z7D46WVkjeL2^5#Q6si!HLGIM$PGL(SqA$SrP#JmNMeCVxBBBJO~^;!Y@#zY7X$*$w$h_CT%TUMQhv zAJiu9hX%6_Kqm?hLha%q$R{3#{NfR)B{dWZh+$B8OE}aa9)(Uc9D|OwL_lZ7NT^dh z4t0qqprCjX>K3D*JDyX}sif1;IWZbKFP?#Vl4GD-v9ZvgCl2b0kB4q#B|sO%MCe9# z5)@mP40YzDKs{nA)GMYz7sYfaJ}Cpb=gEZbda|HPVm5SH%z@Iga-lvk54s}eLs!KD z$X`?lT@#C-jOJn}w50^<7fYek+%o98SPorHtboqtRzf$#D(I$I4PDQufd<4{s4<}q zx+T^_x5WnNj@SqdicQd6u^GB2x}hPG2O281K*J<2)Rx-{4VT)Wy9Mpg2+0SHl>AUi zMgWRS?tn%~XQ9zjCv-Wv3mPK@p|MgoG)_7PjhD_t6Qm2!M5zbr_4Gm^(nTn%=n@1- zm!Z?yeNcJ&6$q5BLXdO~DogB#VCgzk>b(Iq*W82%+=gz%-+^wX4?<<$ zyU>}mdk`x92X!{w2PY-o4_`}s0B&+W2-lQ61Y^>}FfKg;Hzhv`*AzbnH@hE)3F!&= zO!kv7DLn;K($jFd_Zisjeio*s=U_&99AU`~1&=A~EQte#iln%vjm z>$$JPR~z1d8&lqd6B6EnCrNL^*W=%TCrj_bQ>6FctkU=4snY-8Y0?Mqbm>F5rtl+p zhV(H!Q~Cs+C4CBe3O|GINoIQ>03B6@jG~)^gTRZ z`T=fn{|GOTeu5WDKf^^$zrbPTzrtrqeuLvme}^j){(vj8|AZGwf5H8!f5VHVe_*eB z2;Ax(3U?z)Pf&@KR|Myi6JmFPFx^E2OdTN@*N?vwA$dN}2$-xhKLg z#Ub!&34qr~AY79Q!Qq)OyjDWsbrK4i+ch+p!kmkVQWpm;FjCrsr z&4(>%0c=YPVMkg7$EGZXH%m+4Ez(l>Qpz%TtF#>6Car+CODo|W(kghTv>M(et$}w- zYvDc8I(V zV4)6&Nd_D)neb7`f{#fy93eSyq_i16E^UFk+*{!j(l+>{v>gt*cfe87PWY6x3qCFF zhNGoD@EK_@93$<6W2OCYMD77NPC5w3lpKP4V-CX+sYl@Yj8OPWRT!M<4TtM!adS8xL4|jFG||F#`E8`O;T>eO{4O#^eh-Pyd>^^||I9a5{s2j@ z{ty`_e}s&eKSpZYpCA+DPmzi8XGn%lBB1;g0?A(^weD{aSpF74TK*Mbe3ta;oMd3*`mKB6%T_;9i78=PyP=>z5$mRZEe@@-ieLV>yygvI42iTZt@@S0NX( zRwGF@YmlY#S|rf24p}CzN0!SQkQMSqWTpHs(pkI-StYxW)v|y@#*4@rSwgNR$;e=Z zg51tgk+rghtdn)*W{!cZmrW$K)B`xQsPaDKO4@!zlMf)ed=M#dA3_ZIFmk%#2x7{ih$V+1f$DIi z)O{4O!I5H4_0x8ZqiENgmkS+2lWUG7{*(OIL0wW~8;ujdaF(kiME0bY=ySi@DuMynGHx@|{N#eHW1Q zrXHjwvlsC+UPMY_E+OGbmyy!!KIC}C6(rtw6-h3;hSb&fBMI_#q}qK0NvgYv6s8Rz zS>?Botcu%6qI?HQ_6;I^iFc6%-#sKr{tro(??Y4M`_b$551^^?gJ?tiL+H(vhtV|o z5j4&BD4H%mhE}INj-JeT0==I2B$^>Vg`TQ>8oiVM40Nhko;diu5 z{sS$p`V;L-`wK0X|3(8<|DYA}5Hz!PC|W5GL#yQBXpV0LS}l)6YvfUAf5K?ARvv?v z#g9enaOBYkIbVj@+8zNPexniDQKHK6?GR(L)+!)Xqj&Y>XT=p z)xKG%U!IM&HqAi;@?5k-o`;^5=cAqS0<=qBhz8|FXt%r=Jtr?gOMOex7T+>7scJcT zUS5F~r>#V*e5=qB-)gkIa1DAvUW@j~>(HLk^=N1$7sy=oMK*ugW@lO*YVe*+e56EwnPtMz6~bT9LIG&8**o=A>*z zZ^+xw&Zh0?O?d}e?AwWErS3u_vv;Ed@*eb-ycZqJ-G`R@_M;WP1L$q}AX?))gx--4 zql5Ah^sXF=-jl=7Axb#v^&LgKe8Mi$t4z$I;T}6X;prNwm`!h4yrvLL=)= zqjkP$beM7mJ&_%Q4p(APZ$lh9LWxI9vJ=n-Um`kENkT^{$>?Y$1+Az~MaL*<=vXBk zZS!TIu~$atocR+(uL4?x53@LDZLa7wz@kL#HeMp}F4suo=qzSZD16*i7X? zY?ks6Hd}cZo1;8}^_M@2WhOj^%~c-9B4VDv<|$8N^OdKt1lW z!*u0$%uxQoOyy7Pp6@TrQvSv~mH%Laz9E>c48?ByhGC8}9IMG5ffY25#5OCVu!_>r z*cN3BwpAI64fw`kp)upJZOQ~}yD|~mp@d*N6#(0%fY@ChgzZ*fY>$FqdleMhr(oC} zAC86j32eVYVh0ooJE+juA%(#XD=c>0&tXRt9t%|_VPVQ-EL@p_l_XEajw;izW6E?a zv}gvFR5}xj%bA5;_szy4lsQqpZbZlyz8we?8V&u>p%!He#{mttW_z-+LRKk zT`9#f{AHL=DaZUu1y<^>#LE0tSU{=9I+PmhtWt|*`RlNg{(9_aX#m>u^uIWl~;9Oy~$|23?{ z-;Z5Wu45Jc8(6<`6HE6GVAqvf*bU`2c2l{74Jd=yE#)rOP<{_<^#6z5R_?=_{P*K^ z{s-_o%7gfz@(_Mkc^JQ^Jc18VAH|2NkKr}`$MLF+C-7nFllXA;DZJMIG(JLo2G2`* z7B6%^hmTaB$499z;G@+S@iFR4_*nI2e4P3UK3;tlpP;^mU#NK z^$VO*zrQ=hPqZ-sYchUi}$QFaHIfr2dLe zR)51={J-N<)Iab$Re$1B)xYp*>fiWu^&i}mHUyuc4#j7x!|++^aD28p0-vLf#OJD` z@OkQJe7-scU!ab~7pmj%Me2Bbu{r?{_$T6R{t*0h9e^)UL42tS;mcGQU#=qf3KhjW z{20Dc#qm`tfqVTV?(tK&&rjp4RR&+9vbf*R;cHbMU#CvO*Q=B94eAtpqdFCD_fNw& zsnhXJ{|wxv&cp?E7A~r@@tZ|+@Kf%&cu&JTJm{Z~mzFKSC3PV#tBY_&U5u;h61>a5 z6xY;cxUMe84Rr->sw?r_lvTK;uEuS34eqFG@y+TwyxYGXKj+_oZ&5emTh)K@ZR#d` zyXwMsr~^_PCQ)Qg&$RSJ$JPD#3H1PeQay-A zsfX}W>S6q}dIXPFL-8|e7#^dB!8B=c}oBftrRF zs_A%ai;}`vI z+^2eQzuJQL7klx7@>V>cw&9oj?YKMLhbOuH_|>`qe%arF7gnCdJJe3RC8-NPs|N8- zwHxnJ&*4G!Jl?Hdz|W~Y_!WOIeqOzZ$245RFQ}LC9<>jT%(;TsCS1jP)ob`gwI7eH zx{mkxZ{U~IoA_mQ0Pj<8;aB~)@ru+t_!V^!zpCEFZ>QeFGb;bXulesIuBrDE{pth6 zb@f4_q39u^-~TXiLw$sZYj~8nsXj(Tlsrz{@IOIZ_diJts812M)TfEt>NCV0^;u$2 zeU7-RK2O|JUm%8PFA_twmxy87%fxW)6=H<;Dlt-fjToi9PK?&xAjW8K5@WTuh@1Ym ziE-LH#CYvpBDeBAVuJQQF;V*;5u$xS94q^f0JM(?Q2UsGv`+|F`;=&D_>5@weolD2 zUl54)CE@mdMRccrO|*KyA=9xfrwt*Jn}!m+HjMClhZB>u5yWI|Br!!BMNHL3 z6SuO)5Yx1=#B^;Ok)AxBn4wJ|YP=JP=!y^`E*l^c(?MdO86xVlVPd9+5VJItn5|*N z91SPtY6NjUnVIqyPZskVr?S-6;3rY#|s zYfFh0+A`vTcR8_ATS2VSRubpEtB9QJ)x>IT4Y5XBORUw_5kc>IqRYF1Sf_0y)@%O~ z8?;TtM$JWR(gY$kK_pJ)NJLnkOmuh^qSLDqE=?l@O(#UnASBHsDr+p_qSq#5%^?(R zGofl*2u<5c=-M`-EoVD%)w_c*w4H>h?IJ8~H(_gg2uIsXY}WP>TeST|N74aet9Fps zrX3=-Yln#)+7aTKHL;Y3u!QKHv-jM%9~5VhHnM4$IKu}eEa)Ot@6yR|4H zn0SiVqn##tywOBg_8DTY7DMdQVu}4)9C67TPaMz^h%4Si;-Hp99MY1B!&(Y)%bQ9Z z(b9-eEu9F{GKg?3lQ^nn5y!M_B0|d{BDGxNxRytRrsfmjF$Kg4t&ljW6%kQdF>y*O zAx>+hM6^~$oYBgOD|r<}j8;j+YE?vWd^K^|TSLTYwM4vDM+|uDi3F{Is4HqD`n^p= zqSj0#X>Q`W*F)U&wh%YGULsj*B~r9D;-0siNY#AA)p|dX78fAWv<@O&J4<9}oy1*l z7m=w2i7c&~$kxsgIof$5SGz#uX+1=~)=Ly<7m1^-mxw~`GI7V-M-*vSh+^$3QKDTV zO0|CCw)Z+wrrjXQwVOnRHb4w|ZxQ~&+r+K(J4B^6NK|QeiSX8YM78!GQKQ{Q9&5dy ztkoVM^D7=C>$Hc+dhKDdL3@O(O?s5fX?u)p)E+0Bv?s`B?MX7U^(oS=JxzwSK0|u6 zXUP`rInt{=PbL<>K(=Zxl5N^cWV`k4Hr~_n(4w8Tlk*(!03F-(5 z=_q-x93x>JClQ?>QJo}nD<~4vX%g2NlF(U_)H#yUdGb!lB$C!AlZ-xvWc8^er%xk! zeL6WwpFy5%ok>pCXOUC%+2mAx4mnMqOHSA4k(VmwlTob;$Qk-Va;CnBoTV=&XX{JI zIr>s^uD*<%r!Obx>nq3w`bu)4zKUF=uO=7kYse+~T5_qrj$Ed%CztCR$QAlVvfleI zxl-Rmo@sTFr&xo7|*3 zq)XpS3i=jO)VGq7zKtv^-A<+!>>y=*C#mSWNLAlWYWf~h*Y}c{#rw$U*8QZRA0SQr zAZh7`$QuoZ$zaV9($+&sM-L-6>*3@U{V2IrKSplTBgpM~B)LOBPDT}+ARCiTk~{S% za+iLJ+^wG`_vq2&Ui}QYPmdw@>#^hkJ&ru6$CHQj1oE(+NFLFX$WT3*4AWD{a6Oeg zs;801^mH;p&mbGTnPjA%MIP6)$rE}Gc~Z|MTVnIbC_SG%r5BK=^+K}ITSP|d#pD^i zgpAQk$ymLNjMK}>c)fy5&@0JAy^2iItI1@&hD_0G$tG_dnX1>5X?g>ht~ZidX-#B? z-b`ldZZb>vklA_*nWKBjT)mad)7!{=y`3!3ePp5TCyVp|S*&-ECHh&iRPQ8nO1j80 zJxG@8-DHJ+j;z$rlU4c!vRdyUv&(wP(vpj0jed!YZ@x^{>V4#`(ko=0ewD1(uaU*s z{bYlFoov)^kOOHq$tHb(Y}Rj)8FjZww|_sCZLKeA1~k80QNr+oSY zR9eS_lwW^{ib!~v3h0ke9r~kGO6+6QS^aUUQ-6Z$(x0S)`cqW5{xp@4@(guOf0in! zevUe?KTloIU!Z#Q7pY$TC92!=G8Iw%3e{2hDs@qRjk=`2PF?i8LHU#3q%P}kQK@xr zQ+@h7)D`_*Dn0c*>Z<-ebxr>t)vtd*UDrRPQae7Pk~==8Zs?y-*AhOZZt9;=y%nER zQ59cMSChY_2K29}IQQ37Pwh8UdfKc3D0 zb-z-b*}qXW8NXA3q(7*8`kz!``(M-$<8NxH@eei37(xvA1JaB74xg7Vak zq(&N}s8PmfDp)jzswx;uT}mEDjW)(pt;rLpF~&q{tPw&DW&@PJ8KlM;5Ouu>rp6lx zHNilsj982+X~(J9OoD2zAgQu;ikfK9RB1ayg%~Ua7#sx}JOvq(DA<@x^(IcC5MwIU zRyvJBjp-C-%%JjOW>UB@iz1BK6lu(%C}S=~8}lf}m`}0B0*W&hQoONqRXV>NX?V-0n;d@VJ@SVzq?)>E^L4OD*GMryY4 zFEz*5M9no^)U7Uo>Mjwf+g%cMw^F9&844BKtWsGi8g(vDr{)_5Ra;_G3k-`|XxP-9 zE{9rVY^D|)Tc{<*R%)rSjVeppPL*fupq3dsspZBl>Td0BDm1u^;Ba`19hgV zkvd>BQ3s7?>O{~@#RNUnA)|$gsPj^XjaKSpW*c=n*iIcWd{n66r^1W?6>fA;M~$=8 znP4Y%%;=(ObAnWa(M?4f=ctOh^VD(U0(HXZp-vjTRAk0QD$2M-oiZ*{r;R=;+PFfU zF|JZE#x*L|=%?b0>r}jPgGw-NQi;X@m1NwaVuQD-WaAEXqi&E&G44{S#yu*{_>U@Y zzK>2f?x*inK0s#}57ON9a?*N9pX$$LQ$b<8*xR2|CkwlFl-oqT_;3 z)7i!|bdK>XoohTt=NZq_Nx>KBeB(trCHN9uV7yEh8n4hr#;bI(@fv-(;B~shc!MrA z-lWTnx9F0Bx9M`@9lFAJm%fno9(}p=eY(>4A6;d9Kqm)3q^pgO=)Ry0ny2IEV*(fEpPGQOspjc;hT@h$B!zN63Ae@`a_f1q28AL+#4Pqf$g znGP%Yg>E%|rQ3|(=yv0G+GqSh`;9;8%-~;i!1$Z)F#e&>8bj#R;842L7)Ey)!|9+g zg6=j((&vm(bYanG`n)lQzF>@{uT+ks(}Uyb9%BOCYfPjs8X@#01E4P(Al+v`^c4f9 zuNnw_%|PjX1EVv7IDOq9=o6`V#7HK)_V%o+4>b0$5)oJFSvXVW9iIrJ!VE}fh+j~;E#r^lEJ=&|NPdYrk4 z9&awDCzwmhrbN@GOf#lJv!+UOrbhFoPERroda`NKQ%sAVYTEQP z)1jxEo9P+m7J8<+m7Zm8qciij)3ePT^c-_1J=fet&og(^^UXc<0&_3D(A-BCnQ?S+FrJRBPM~Eok?!wFq7^flR?QT; zESO4bW*V)V>9k>H(59J5TV@tr7|f<^GlzD}T)I6Yk3LbFPj5C0=q+X;z11wDx0%KC zcC&=uVV2T~8D;cNvz*>#R?zj;mGo}2ir!;Z(|gStdY@TK?>Fn{l3+c3z-*vPgN^h- zvx%+>Hq(bpH(e9-(1*7$RDe!4supc@lA=ws$tx+2&~ zN0?o7q#2~EgWdFT^BjG`JWqQIF3=~<9=a&lOGlX(=~Lz<`m}kOjyC(~Gv*b#GI*7a zF|X0FW;D8+3wslTI`T=p^$NoowEwQ_MSbsyRrfnRn@Q^B$dH{zqq;_c2-K z{Yz6fN3{BWPIjFjNkm237DTS9p*ks0v(#9T6eW-gn*FipW< znLhJ3=8E|{bJhHVxn};!^qYS%*Ui6~8|FXEO>+p-9309Fn8TP`=5Xe=IfA)kj${VS zQOsR)G;_}!!wj*;GDEF#%rI*_Gu)cMjIbs$Bdri-lm#%OEs&{ihM2Y>%#5)Rrag!< z&Dj`J(||K$ErMxkCYfLY#au3@nU)~Ks+nWLYItUxHHoRtpUjN6rZ5w%sf;f; zjmgTG&g7-eV7$SZOl0jWW}-El39;rdVQF)j>b!XjV9jTu+zS}cTF5}wA_le=Gd*QX zm`hzt8N^z~v<8fD%GgvM$@m(@=s!?HhOJy$AYmB>0XX0WEW|CzxRpl0Qq0(k1TMjeD z+RR)?+rmt>wldSKZOn9QJCoS8gPCFNWD>e|F*B{*OiS|~#*@022{!FxjwkJB`YI1F z<#h*{h}c6+V%cG4mUV#!ydP*g;-l}3YSk=r%tA@$TuVpq_bxd?xJrmZ@ zz__eNMzER~(Q0NS%gxA^hf%B+Mzy?*X0ngL$y2k9b`k6h}b!M-1gV|@@WcFJFOn1U9rXlGzlUII+iK!iAG7|4H2dsO{LF+%p zQ+6MF$hx2HNPd7lY(2;xu^wVOOCM%Ktw-3X%tzTU>oGRmdYsLwdV=k1ev&?!LF zwx;w=_O$gD>j}QihQ+_bMqBT)XRP zn`QmXW?R3oIo7Z2sj}bL!MfjBU;H2Jg|0u@K*3*ZXx86sT-879)q){xQ`S)Sc+oKS zY}{}**BZg*StHr{tWj*fHJUB3#;}9MW7(dHacpnqc($!-0$XTJWQ(j2HmwX`bBjQ> zw+mu3YGAh5Lf8@uWlJrLO>M;4GK*l#Et0LUDE49(%~o0rTV=6qwZ*YD7SHyVO=4@U z$!t#L6t*yLDqCkwV=s42XX~vQY(d^kwy$dz+hEOR8?8BPlQoxZw&t;JYd-6-7O*YW zLUy2Q5nEZgnDtsq*v!(UY^$}5ZL^lM?bZs`XRT!Y)+#n&t!6u{HLRy@Eqgq$jy-Fw zXFIJ8Y?rl>4O;)Qz4e>eZp+19C>Pi(MIw97lGyW>%wDh*w#QQ0UQ1(71$6eJWw4hl zlf7(NY-GS@PXrvc&)Uphv9_=$16$cMfo<$nYdd?*+QD9o+sXD@yV$6}Znh<54|_VW zmyHhWV`BpQ*|fw1Y;52ld)+$3-mng{H?1S=fECK#vclN-KscKcILh9(jiq?lB8w4KI|vD4YHb_P4n&SVn;S?qW_o4u8t!%nbs+0;NDJJHT( zL+k=JJy6I3b`cBO#Vll(u&`aqB6b;z+U0Ckpn}EhN*1@PSi-JmNxO!n>{^z#>)4Dy zJ{Ppzoo2VO)9rS4hV5f#+J1JH9bmJo zJJ{LwS$2-y$z}$+*z7=%t<39Y=i2Ako}}~aJo^GWP~XGOw|m(I_C>a`_!7I&zRWJN z``E7JE9_$XD!atK#xAw{*=6>1cDa3nU18s3SK0&YD*G0@+P=-MvG1_=vIg0;_FZrQPP8BAB>M?Ywx8q_ z`zcPfpXN0C8SZ@1vz%@}#~JqXoN2$nS@w&ZZNJ2|C%nu#_A6Xo?W^2o`!#Nh{W`bR zeuLX)zsZ#Z-r}~~Z*x2BcetX!yWCFuJ#Lr%KDXQcAGgQ;fZJ<-$Q1@Y;`Z4ebNPW! zxV*rp+yN9^yoQ2To>%>IE3w}0fy z13z&`?Vq`0_Agw7{VNw~|Hd7+f9Fove{d)5Ke;ITFRmi+H&+(;hdX5t;ZEB_xoCSB zcg7yh#n>abSbHQFXOH6I?a|!r%VW3%dn}h|kK^hC85iY|&4?e$!n zy@6}DH*!AvU(RoD;sUmd>#zl`DIjuZZHeo&WvAOngjc| zTlRkLwtaxRV;|()fkWJ&eVDszAK~uVq1+HBj2r5NbHkjY+;Ha@H^PbFMmmw)DCamg z+Bw0EaZYk$ohWXcbBY`9oaQDt(cDDm3>V_WaDWrbfleF;Iq@9qByfn6$e~UWhdIey zOCW{Aom7r+(m2vd=O`zGqn%8Sak4np$>umGhvS`GZjzJ7O?L9RDNX@5)hXn>fg*02 zQ_M|wO1K$LDL2z8<7PSK+-#?Uo8we+p;cAfT&J3w=hSfXomy^zQ^zfI>bXTu1Gm^| zvM6;^NP8 zYn@JRozuk~O$~C_n!CBu;&WVk)_E>E^#Zrv>EW8IdbthGMQ)>WiMtecnXC5pahseg zTw2CeuD0$PS5n^3RmNQBT+R(naBgy!s|PsIxy4D&ZBBOXaEdd?sm@*QtmhtgG4nr8 zbME7H=YGB}_5r@8>_I*w?jhcA9_Ayga> zH#^VpTbyV40snJ+S>yBk9sdjbR_8^2oAVNX+y643Tlflpr{Yz9yYm_!oBKL{%l`&{ zw&_j&Ox#<1LDSp3H}M^Qhx0DK(|M2I<-E`DcK*ljaX#SpIv?`;oR9eZ&d2;f!Y6!a z)2I9a=QIAG^ErRW`GP;}e90eizT(eRf6ZTx`Gya5zU9N5@AyIg_k6hX1Ao-{kw51A z#78(k^O4Rkd}!cTK0N+6{#|IQ_fKSv@?uv z%OB21J0tk8z)1d9@+kg{Gn$Wa#_+MuSU%1f$HzP4`2=SIU!6XYPjo`~BnRM=9gt6P zAU@TB`7{UN(;bu#4`6(H0nTSQ1fS`Ue3nD;*$&O;I1GO@!1B2c$LBdbe=IPG&vz#C z1jme0@g*Uy>Bb z-)cV2pLb617o3xPj}yiBI;Z%H&T0NwWi)@uIm2IeV)#BMmcQb}@mHOA-rbSFUvm=q zrj8_juq>HR%ueA`>r?s0jx@gCN$0OS8T<_=lfUU?@y#9C{D70g-*R&K+fLs9F?0@$ zaV?A%y|!)JHfr0BWG2Z>P^E3^``+)^Ypoq{`%rGcokMv6 zcMs(U+&fedFia>67%mhAj1YdnxUZ@Y4AT$J2WH$y(6q*7i31)Ra6VwB&=D|8=nR-Gcmn1K-hjD6SHL`>J7B)h6R<$=1+;eh0~QLs0d1Xq0gHtG zfW^WjAaZLjfnsZv^1N%>Y8U z6%d+!JAf4K1W>}=09v>gklXfOKv2_tKzQc;KzZ{6K!44Hz^#IZfbjf>0Y-QPV1-8k zPIwH+YkM5vg(rZ<=qG{5_NRa)!qdP~;Td3=@GOvC@*J>Scpivue*st_ya+@jzXYrl zUIy;gyaKEeUIl`ZUIY44UI$hSZvbnAH-U4pZvktCw}ExSJHUG3U7#iYJs`jSePDy| z0kBc{5ZEMq1Z);Q1{!id0ct8g1&*hF25b>N2L`*o0Iqa>32YU<0=5ZX16RAg0k#X@ z0^aiPfE~j3z_p?ufStmRz%Jn@V7Kryut)d>*em=B>=S+i_6xrQXX5_=G7J9%4hVk% z*Sr1(4hsJOhlGCtK^O)^^$!O`VFVxvBLP_$1t`L3Ko!OSnlKj7g>ir(j0a3%0$>Rf z0b7^^IKpJW6{Y}(g{i<1VH(igH61uA%mDn!GlA&%S->%2HjtJx2k>>x1$w&X0sgM} zz;R&#a6(uJoD>!Tfx=>-ye0q$5&$4r0D%wz0(v`OprQ%^LIo6vEXRN_0SCIO2_Re` zfl~qnl*G_LUo-=p7Fgg)GzSdi^FV~K1c(%t0=f0efT-H#z!_l$(9*FIh!R!-(ZXsV zMpy&1cB}^u4&3YhC*Z?HQZUjoBHv#d&W*|ZMACM?)0dAIW1%~Rk0c{=Ifh1uE zkdUzxxEr?%NEUVj?Hzl7mXy7~`Hp=+OzM81IOhP+(Qyz+5e@;Vf&iomBG6wY0qKGa zq?ao|hM)qOf(CSU=s=cW0J-rdP?&E4o(>zx791c)Z~u z2~j|`5DnA_F+i;l3)Bg5K)nzT^mHTu4MHN26Q2Y$3dul|kOG_)Qh{?q8sO_l2kKKZ zfMy{RXc4l2Rv{Z`6LNrdAs5K2$^*`K<^xU91%S7v5I8Rs0Ubgy(9u}}bPA<_M<@e| z)5?Leq6)w(R05vPD&Ss!HE_4T1~}7R3v>x}K(|m2^au?=XJ;dj(a;3kDL)GY=bi(6 zLNnkOT7X`m70C6p0ewO{&@Y?^Y8pC#p3Y8SK=1$;1TWz0>;f(d-M}TG2Pmxd0ha|o za7E|^`aAo8{>*-0P#6FPIxhfSofm1;6mq3;I?oJxFg&Ka;xqDcZIva^^|*nzw5T61^icf=AJD&ls)jbOic0LD=5}yZ0 zi!Xo?`7eTF#FxNZ^)G`t`LBRkF|UGS#n-@b;_KkW&NsmE;+x==&bPob*>8hsrSE_f z#CO4o;(Orn`1iq^ogaXc#1FyA;z!^V@nbML?Gx~F=ciy@)n{OG-RI!7&M&}*;y2)Q@msLA@H=pZ_&qpN`~jRL{s_(%e*))-KZBP#e*x!;zk>6`-@y6e z@8AOQ4{)LQC)m>X7kGT&Z*Y7-h*LpQoCY>zP6sJ*2Ixtd3DV*$kP&Bt z$4lpctT-3s#Caeu&If}B7Jw%Q7J^H}Mc`6#F?eDi09+;l;BpZJSBMa}QiQ>VR0Iqe zK*6h37`RHr!PO!G1`d#5TM7jZCD7n;4+F*|u;Aq~4h%`=!8PI%@I>WO@Oa@eaILr; zTqmvoYcf}Y>%~>z25~ibIbjXBQCth&>Rboj?pzPv?c4y~>D&m`=WPN{cs7HZ#Q%ZW zwOhc=;#P2rxDDJYZU;j=JHWico!~Zc7r0&A4ek*4fIG##U|{7waF@6r+$|me!#oGU z#FRte9#H`IiXymAl)(L>42F6X@PMd-=TbHBps0fb0}E=8gNk?pRK=5ET52Gui9w()27|eEA)q0Kg17R*KvN6{E%6i> zI&d1iQxyRQc_KkuJOf_KjRGAp8jSG7fM=p(L060eV?6QTVKD(bA|`@I#UwB%Eg3u} zrhv!ARPeMX4a|&B2TzC@;7KtP3>34#ATb*Z7IVN5F&7LK^T04MAM_U%fKi@8FkCDG zPl?6gX|V(h&nN{imY0DMVmTNoR)A;3N-#>S0;9!ha4@w7j1gRrNKYG>EVhGT73aa$)DAF3>;zLq511x;!E~_; z%n-Z5zW5%nE5irY#Q4GT*j_MG>;sdd`@vJ50kAse0(d(9BG{gM3G^jg2D8K~V7532 z_Ela56Ft|!9Pv6>mO2FHiZ{SK@g`VUbPFu0x(()wcfbPiE?6ku1B=A}z+&+}D9Lj_ zbRqTus6>1aDit4s%EX7Ea`6!;Y~WF-LVOImRr@&Pt$hNj6rY5u#HXNY@o6Z0;29{{ z^DNX^^BhzoJ`dH3FFS>j_z4u}`4l>l^%>MDehzuW zFCee@C6wa%3hENShPuUXpdRsC$R~aW`Ni*{UhxO0Py7+;7k`2V#Gj!H;xEue@mJ`Q z_#1Rt{2jU?{s9e&e?nKqzo2X4-_UjOA81JY7fPxd2Hg;cLpQ|{&@FK!bXyz+-4RDa zcf~Q#J#j2FOd1Cj#f^uCOB0|}&qQd1GzrR2oeYhXra(i*Q=w7PG-$Lm9qKBc0gaJn zLSv;_&^T!}l%6*S8ZXU-CP?$3iPC&%lC%JtEG>klNQ^BHth5#4q-_u{ZHJafJD{b~PH3653tBGihE_;>pq0{IXqB`NS}pB|E=C`K)<_4T zwbCJIs7`>^Ng}jflAsNe3~iJYXp^Ku86FMVEa}h|$$+*>CbUhmpzV?k?T{R3r{qGr zq{C3ez!7M-bQIbn9fS5t$Dw`F3247`5;`CSLI6b?Y6d_eYkx~_OMyiI+4Ael`S+!7Y-?<0g90t zp;)O2ij&Sl@zOacL28B)r4}ejYK4-eHYi1Ehf<~UP@2>MrAwVqhU9@VB`=gEbwSxu zHx!%S1La6QC|B}Bc~UQwFZDqMQa@BE4M0WG1*llM2$e{epi=2FR3=@4%B4Z5Lb?i7 zO4pzq&vmFu8iJ~&8&HjO6RMSNL3Pq?s9w4QHAr`%M(G~ZB>e})wA=@umF|bnNe{ry z(t~h|^bp)CJq))=kHAp_kHYQJV{mWM2tVW`T}lB z{}LXMzJky6ehpuczJW7xzJ)JJ-@%up@8QeR5AYS~M>sp~CwM6CXLwNh1->f%3Wucr z249nYhp$V2z(dlX@D1rN_@?wX+}-~V+|~atoS8TbzF9gP?u;G*-;zecJ^iEL+tO(G zjx+|oD~*MVipRme{_(KCe*%0@ng}5Q{iFqGNW-rEoR}1)f^m{&%-@YOW=gq zrEq@HGI+YY9G)SsfIFjB!ZYPn@GN;Xd_8duJX>B1&ym-`xAND+bL9>2Jb5ELn6L?+ zFK>ox>i-8<#cqMq(ze12M1g}ERhW=9IH6pJ6A}zKIn#uj>n)g+Z8#*! zfgAH(n34~}w0s0+XHj)a%XXW$ib6ueT7hC`xb;8k)gyjqTf*U0g3Lwo|fR!)T1 z$w}~fIT;SkOMy4Ysc>yu8k|y{4*O#>;Ei%7d?hyv-Xv$ko8=sMC@~k_BIm(Z8}i|k z@dfaum_j%%uL$<%6~hr(C2(C^DZEuKgMCrua9(}|d_KDp-X>SU^~u%ncDV*_$*6^! z%In~YsCsyZ+yGaWH^L2VO>kAlSvaHd99-Yl3|G~+z^zfO@J_i6-X*ugoq6Zs-Es%K zNA84A=6K*sXOxhcDOl!u#Ytc)#2ahh`1Hxg{6i#OB1sL8A$NKoN8+NMKuq~b z#FC#vZ24)#k)J`jGoM9V`8njU{5*2C>;>eA{33ExehE1yzlh+Az|{@NVxnBa!URdxm^Dpa$5c#iI9Il?)LtO zM9M!QXXKxeDESv8TK*M@k$*#C<=>HWZGRxa<$oe^@?S{2{5R5H{tuEM|BEEb!;mC- zIFc-nK)NeNA}wvBkQ8||5?ww93C08Azr)6UmZiA=&b5Bq3%Fk|WPWa^-nQo;)APmlq%f@F{Dh!k#dW5(FYPA3-k4N0CeNF{C!zL5Ad5 zBq}Ek>1>NfZpaD9O*s+CYDhvt;**hEatd-aCKb6Yry;(!bmWelfm~_JMDEI2$UQk5 z8K&eQ!+2)TOl$^DMCgo#mM=h5@d{0ii}mtka0>m($QFfTx_dE ze7RLfM_Dy8Ua3L4Vrr2IN*yv$sYfO$4M;{!BQjZOLZ&EZk*Uf#WSY{9OjlZv8A>ZM zQ)xpkw6!C%l=DbmTL)5K(TU7fJV;2K7n!4UA#;^(WS-K4%vXHK0>zJ<%IrllGWw8( zNq+CTJ>#iZNavf=F8$uA}2GZMh6G4?* z2&UXdaODm{D0h*}ta}Kl{D<_n-G>gw+>iQ`9za8K9z-eSA(U1gMzhl&K^f&ylvN%> zIpuMbSDrwZC{Lo-+MYshv^|Y3Rh~hYDbJ#(VxB_-(L`khnxw2mla*Cyin1C_Ro0+s z%3AbZ?mF~%-g@+S`vx>!*@$K+o6t;UGn%FR56xD#pgGD`G*{V%mSt~8^OPOvo&S#z zT+G;o<}16=n1VfMfwC7ZRQ91o%6_z1Ie?ZZ2hmdH5L%`PXt^Sy6^exB$I9sSA_c8f zRJ2Ob(3Dagz1L=-)ryJMC>9#nZlkq|gVrf7TCW^N8e^AgY=B@sQ*o`jxkPey%83L4a&iu#o_G&Ut2?Nu_+J|z?F zSF+IH_H1-O$wAw)a?uM)9(qy9M{|n{&`U}odRZw#uPDXnpi+WfRZ7uoN*Q`xDM!!7 zRG{63mFSRCg@&|Oqc@Zqw56~Xy{Xipx0HJHw$gy!Q5wdeCvI4;`=i(FtlV zI#KOIC#n7DWOV?YqFz9!su$5|>Lql#dKsOeUO{K7gXk>vDmq)ehR#v1qjS|Ebe?(x zov+?R7pS+;h3ai|k$MMRtlmWf)O#qP{)d9Z2H;K8BI%hsuA^#!b@?nP{w`VzKW zeHmM!zJje(U&U6buVL9muVbs#H?TG8o7h_QEo`0oHnv`U2iu^&i)~cj!#1h!W1H0v zur2C`*jDu;Y@7NqcDnr&Y`gj?wnP04+o^tz?NYzMcB@}vmomP>_NZTDd)05Si1u%> zkcRKDed_nve)R|JfchhLQ2hx@?EM)_==%k$FZmTar2dB8Y5E<@OZo#7)IYJHnmP*8)zMf<@)*oe$6}^B4hyLokCk7YfLZE9 z%vL91Rq>NCN1cMX>QwA%?lkPMIvp#@n1LNpXJSXyS=cdkHkQ~o2TPBdiyc?zVJFo2 zSXuf4?BxHWaWUD8ut0S&)({~{SsELL5O z#i?ts!Nj##yt)ocP}gIL>IN)H-H0Wto3IphGnT6U4@*{L=H)}V%A3H9Mvqk0NUA2^LQsS#LZLL_!pJ%c5e zMqxQs(bzdP25VMhu@*HBYgOa1HZ=ijR}-=GY7*9=CS&P|DOjhPih0yDETKOg3oFUM zylN)arDkE>YBpAvpM&+Nxma?49+uRfkLBhRV2S;Om`^Rj{Aw}QtCnDWYAJTNstil% zFUR`T3M{q166#6I-?y7y*J+&W;tRBEFS6#r8dM{$hy_c|*-pg2g$`x#wHi!+^u3{s!YuHHbIu>0r zgk8(LfsN8`VxzTN*sb#0*cj~&HdecfjnnR7T~!^?Rk8b z_5wazdl7G}c?rK-@iLy-`wBisdljFny@t=zUdPjV-@xZXaHW^3*tL92(Rdc@m(5%@77TK zLIsBJ(Qv#imB9CEB%T>d;rlci->)(F0gc5EY8-w@h*o8Ef#W-nF=*t;1DqJzm(b0oSyRxUOx&4Q(@?mHj{5)VAQ3wiUOv zZFpmzfdCM!J2}HXeu76X?U2X<7e^>JU+_A!!-*(rP=st&A}ry7mw5q<8{49@H5&` zJW4x;M{CFN80`cetDVH-v_L#w3&In$U_4O^!E1X%@%F1>c#;;5Cu^th6zw#gszu;w zS|py5cLq<_qVNnY8qd^X@GLDB&(`Abu;_R^M@ztSwM0BmOTzQDWW2pA1uxK2@j@*P zFVfQSVl4x&@6E(Zv@E<-%f`#J9K2l1#VfQtyi&`@tF!{VS}VkBv?9D#E5_@z61-k3 z#T&FTyiqI1o3sl2tX7Gi)2i@htr~C9YVcOA7H`w)@OG^pKd&|59aC-7QC^y6>lnN!@IP0yjweu_h=osPwT|}ng{RIym+71h4*XScvEi=KA`#V z3z{E4+uMs@)cWvCT0eeS8^Et<7w|#tB7Rl7gs0YB#;<8t@LPq0cw)^}{7%v}{JM4> zAJT^KoZcJw4eci05_1c`solnJX?O5DId}2f+CBV6-G6v@*?q)?#`}po+5^O0?Lp$6 z_7E{lf0!7qKSGSqA0aXNfWTb3|R= z^Tb&F1!A23A~9ZniAXGcnP}^Kg_xkfN|a>1MoiRSCno7{5R>&ciQDCG5mWTHi8Hb9 z5L5MciE{<-5!3YdiRtpIVy6BPF-!lLn5}<8-0Az2n4^D2WaNEL%+A7U(|`3-zCf+Jc`6Z^AFcBK=olvHlwo zp#M$)`X9ut)ISMO|BHb1zlrlz{}8bLFM;U8i0Ia(oQ2PG^brI!C0X@Wcjv2@w&!lxRs`Mr_oV z6Y0Gxh+N-FVw1j#DDbT&HtTDMQr}u)i@uK7s;?)u=^Kdc`bMJ6w~5%HZzhUM|3`F1 zZ6S8*TZvO?+lXEIc4D`_gGf%^N$k;g5qtIBM7D1au}|Mi43+OA_UrqJ65j#hfPRoT zs2?H@=>j3>B5}P!B1By#BwZn7T_qG8=ULs5HBeL~=VjyjR$k8tlx%x#SC-V|f?z>FfY`8+?>4U_L z?5o7(m}^A7ew`@LhloP`22rHnB#QN0M2UWzDAn%}W%^yB-FJ^D*Z(83OYS4j`tBzy z^asdF{Xw!ye~7HsA0`9qA0cb>N6Fsk$H>(B$H@xc6J(X|Nir(oDYDl0G+C=ZL$>;! zC6ltABkT0%$)S=L$a?)nGPLw1vO#~DY}8*NTMAw!uVuYPHtDaEXZ1J8bNZWPv;G#@ zqQ6c0eeaO1`nzPC{vO$`zfYd5`hYyIe@J%dACaB<$D~L9g!Jm4l3n^|WVik~dByhy z+1v0X*`t3&`t+|!zy1x`tA9)O>EDt4`uF63{sVd5_aoWi`-!}u|4d%ge<3gFzmhkr ze-rSZ>zhgr>C?!t^6BKs;u+)( zeI}WdI*V*hpH24q=8!k_x#TT<9(h}zPu|fNkazWkM44xcoEFs4k zOUd!ZGID~koSbN^ASW3s$!oq<YlCg&S_$OXn;a-p%0Tx9Gg z7aIr20OKGD7>7vE5Xh@Ok^KMRjf4%EL=1%-@~I?hXe4InByJew$z+ox42vWUo1_ef zqz#v3jKd^r93eU5D9Ibg$R);ca;b5GtSLT8E;9nj!U!fSazn`T6`^EzRv5X` z2q#w=r^waDX>yGbK@OHil534KWNTRz8DAAmt}|lD^+qh&Q4&XPFyhHUUjn(&NF+BI zN#tfDncQNekXwyZa+{GxZa31&9YzMZ)5s)u8Chh1S~j`c$RTg~a>+eL9=X@ZC-)fz zPXF~ zCz~1@NZn{84Wo%XopzQqjdSG1{ASWJT1eYyB^{%Ubd7fMuyLNuE9)SS7@g!%!$Su9 zz2q^Yi#%?0lP8QG@}%J-0}VeJWb~53Mjshs^pl~+02yXnAR~$|lHtZB@`V2~*_m~P zJY@`$r;V#*gmI0`&Ad)V8bjn6;|3XJ+$8V$Zjp`2x5;SZ4td*mmy9v)k+H^qWSnsy z6>r>61^OSL5{w6_MB^bU$#|HmsCk4+HXfx?jK`={<8dm@c!Ekdo}^CtpQ191r>U5R zXQ=qbXQ@o%IV!~eJe6g@eWmHyi48jy+_^ky-$@JA5ay>hg7BU5p~@EF;!)JLRA}|QZ>eBRITwj zRcCxb)f-<@4aQegqwzJ>Q2q_oWPD4VHNK-x*L+W%Gk&0&jUTBN<0mS{|1;HU{6e)E zzf$eSZ`66?cPh;P2i0NxNp%{3Q6A%ODm?BV%4_^frN#}Tx{Tpew=se`qxy~U)POO8x?oJCE*g`lOU7jCvN46aVoaq5jcL?XV>)%sm_c1P zW>Q1OEGo2WHg&_8L)|pyQbGQC)GcE^b=z1#-HTmF-7ywXca6o=X@3Ca$pWZ*21teb zA!?WjQ^QS!O7^4F2os}5nmCo@C#X>-NsTrsYK%!!V@-yN^t04BlcUC)Jax;rgqmP3 zr6!uos8IiMYLdBvnryD5rkJa!spe{Gnz@ELow=5Z_OGK-{OhUd<_2npxseLW*+k7W zH&e6B|53BeEz}wRR%(v9jml5jPR%uUP!ax})I4(+)l$2giu3QG;{AK6MF0Os2+aQ% zkrbq>t5(Stt1)2&4nJQI~rBV5Qoq|n+LQIp2@>>*Y+7xCw zRI1;lE=L`vaPtU7m`5qnJVsIGaf&uiP>gw!V$DE`GlMAJ45pTtAyk?_lnSa3qn4WC z)H3rFmEk{4EjJ^mOn)S`!aPH*G^40hW;B)UkD*qZvD6wfj=G#3Ppvf*sC8x{l~9yK ztv8dY4Q2|p(M+Y%{b|%DGo9LOW>8zqOlqr{MQt;)sT_X}wcX66c9?n8PBWj{WfoAo z%|dFASw!tMi>ZBP36<+FrS_X;RII<8I$%~%3I0mzpjkylr&d#k%o<8CYbnvJqq6+< zlw>wgve`%}W)r2FXDQ7*N9krWHI&vu8D=YGnr)P2wo`fj^HhPqgR;#|$}v5ZYkH}} zW*2qD?52*IJ=8JNM;$l))CsefI%)P%fo4AyWDZaz{tHyFd65b+FHxc9Wh%_PLRI(& zsc`cub;`U(oi?vi5#|sTY2KjDm^Y~?^A;6t-lk&AJ5;QBmuil=N5z@{QAPgy=y>yf zI>CH^PBb5+lgx+cWb3s7Ay1;yqE;L`Fi_DklV)GTc#C(-5^}j}!`Cq3?%{S;W^G&+ke2cCy z-=-_gcjzkfT{^q|J-XU_pFWxQ0bOH$NY|Pl(RJp>biMfr-C%x7H=3W(P5#g6Ci4rr zBjro_toapv&itBgHou`;%x~#p|95n&`8|EI_6NGn{E==qf1=NuKht&oU+50=SGv>u zjrN$o(_Zrry372N?l%9Td(6M-M*lx_mH%JbXAYzN=5V^#96|S)Bk6u~6kX{bO%Ir3 z=nLjpI=gTjebF3GUot1qm(7Xv6>}0jXilcDnp5a&=2ZH+IgPIIPp5~>8T1WvCVkVK zMc*=K)3?nz^c{09eb<~vpY_kDi((hh_soTKt$z_c%vwwjw*u%97C?`*Kzft~(U&S= zdbEYmV=R;&YhiS`AE(Dz1U=p&=?NA^Pqb)ylEu)IEtZ~Qar9J+r>9v<=;_u{dWN-( z9*SK~&$L$1v#gc$Y-<%g$68I#wbsz{thMxfYaQL-Ur#TvHqZ;Ljr2MHCVG*znOgVuH$vUboBl{;zJ+C?MQZW^`r(3rKC#;tucVeO|$>i|tz2Wi?m zMA!QTnz2N>#V^s#ewk)1h2|`k<}Hn0V(Ii!%b?r*CcVtE=;fA8udp0?rRCDAti$wb z>j=HZI!dp#j?vZr5Wzpy~zruH(Md}7AutAYK76Q{&0Gmb&78H zpQcN4Bk1i`B)!8rL+`Yr=v`Jcz1xbR_gJy?UMr5?XT{U|tpxgjl}I17lITNLGA&ps zv}mQ$l9fiwRywU%8MJC;(wdb;>sB^xSUI$5<YUwbmjt;l#=~Gq%ecEcIBdjJm z(mG3@vCh#^Rx=%Kwa_tED;;aK(Q#Hg9dDhd6RZw8(dwj=EDxP*dFd3Zi%zw==`^c{ zPPcq?hUKR-tzJ6I>Z7x*emch*pmVJYbe?sQ&bKbn1=eM{(7HkwS%Y-3b(Jo$uF<8| zb-K(NqRXutbcJ=3uC#8^Rn~2~+PXv6Sa<1K>mFTa{YTeZ_c0CD{Y<0v0MleW$egtv zV$N9)GtJf`OpEm>(`r4&v{{cc?bZ{_dFx50!+MJ8w4P=>)-#OPdY0+3o@2VL=b0Ys z1;%H+$oQ?7m|p8;rq6nX>9<~G2CUbZ3)bt*Me7ablJzEY*?Nn)V!h1_TJJDdt#_Gg z)_Y81;rmQQ+y_iT>W55L)kn<9{*RgK)+fx6^(m8>{~2?``kc9GeZkzazGQA&Uom&A zubI2nH_ScjTV|O39W&hio*7~Pz}&9=kr`?K#Ei0kW=7k;Fk|drnZW+vn6dWnOi=$H zOmo4X%sBfmX1x73Gr|6cxsdrUGtnN#OtObFlkE}A6ni8S+&_w$YL8~7*<+ZH{;^DW z)i`FlJ)TJ_oWRVmCo(hbNsKRPGBeAb!pyd(GIQ){%v^gqGtZvE%(rJU3+!3ULVGr| z$ezP2w&yYd_B;l#=QE-G3mDK|$UycY2DTS7h#kP7Ho#yu$lx}_5H`#tHz3U2dXy=R z!?Ly|1UBsNWi^3IRZfBD0^Gvec!9>@0GAXu)NwvL9n%%{u+uclt-NR(s zJ|@fdGud`86WG_sWT*5qIradPYhPgU?2AlF*(E05zRVQZSC~S3kO}I$$`skxn2^5f zOtC%0l-M_zQu`(o+INd7vu`uy_8q3ezRLvn-D4{4|ClQKKDOGvpRKVUU~BCM**g0n zw%&f24eNV^J=OOp8{YRA+h9M=Hrh|HP4<)QS^FvWoc%O=y6+jb*?yL-EP0NNZ+f1+ zocjXXV!y}+<-Ww;D0rET=zE1N$$OP;wO?Z+`(9_y^u57G^}Wf~C%(nD*>AJ$_B-r( z`(5@{;(Kg|{XQGr_W|2k_#xYAf5gW2eaw37PuReePuXkLpRv(VpR+N2U$Aj~U$S2N zE4Iu2n(el~VZ-CUWs7pYV||6+vpx0?Y<%C3tk3?5jV%3{ZTI}b`t4uYUi&vTtM+%c z&;En$xBp}Z?7!Fx_TOyt*?-uJ_P^{Udl-AXd^j7?FoGQ{9LZj`N3mDz(d?i-hCP3F zEbB=f$6mF^vneSP*iO$x_L@D3y>3rthwLfr4SOnk)1Jnjs+`W=vS+Zj?V0Qydlq}% zGn*|ep2Oa?=d#Hu^Voa#e0G?#fF15EWaFwAu^pbpY;REjdnOrRBho>(DHdXzD`0kn zgRmnVl+7x`*ijD7j&=xkj6+Q@ea>UaF(zWouzC<*)n#L zvz(1hTft6tR~v=XJHy$?&U7}hw+lA2=Mw+N z&T_V}vz@JMd*L>=q-HzYP_cuZ+0V{*4zN9* zgX{w55WCP3SWkh-c6lUrkt4H<9fge@P}y#e#s)Y#3pfS~IwlJ_78_e^v#{f^-T5wy zIEPu(Il^MjQ8qsL7>hf{+0@(EiDOwOp5>ebmUj}_B~B7sm6*(y z*QT&bom94>A&srAPiM1}GuXKLOtz^yi(Teqv&)?vc7>D6u5|L)^7&B-R`upC-U3b9nN|7x~GF}&F^GGV?6Ag z0x!GM>0;04b+fyi9(K3mV^1{t**#7#+mY4B-t_dddz}GxpL2n|<+;e-^;}}Z$}Y2m zo-6ErXOPXPy~-YNuCck%*V(v%A@;K827ASGlRfC%VsChEvnf?~*xZ7<>|otJ_MYcI z_KUR={(0-&hwn@yub|=y~sJvOPuSx%pG=K;f^@3a&eWfaYvokxlr#LT%`9+ zt}Ev)?wIp7cief0i%WQyJK?;?opj#k0-X=IAm>9a*!hSHaX#j*q<_MNI-hbUyq|Gl z&gWdX^9AQm`H~Cwe#M<~zUEFl-*BhB-*OSocU+|NJ$EnTzoL z!bLg1a?#FjT#WNOcij627wi1VT}b_lYc2nqJ5l%#SDgPZ7v~J);+^5#Q1%Ee!5PT~ zdPi}I&S);Sa13`keJq!rK8_3Wj^~n`30z_0M6NSt5|`{u=1zI1aJgwyxij8rT#7TD z>r0)%MR{j(q4~48Xzy$;)tSSkIdi#mXC9Z~%;!Ay3%HY+3%N{Z5trg!%w;(NT%s4? zvK^31^+H^Z19Q0!!liprF3-WZd&IYd5*~q1N zH*s~&X0G1(AJ^b);ToN-T$8hn%Pil{opp9_=bW9~&AeS)v$LCParSVxEBA8U#rwEc zXFu2G9N;o*4|46!A+EYo;LbZD*WpN9tXJkb9feEss$8;HzG`ZV{zS% z&Gk4AS5fA2KIbr3mvw}T_a5bW0ahIHUE+Qp? zyX+)#SDYlSE+v^8bW*shPAYfJN#m|N>D-W$!QF5&xm<4+HxQrA-E?xeTTU)_+sWg~ z8}qp=Zvl6=vXIO47IAl+V(zX}!rgO9xt8oQuB5D-8|GGU!`(`5gj>apbgQ|Zk{WK5 zTg#1h>$ov)JvY{E;2QH9xp8h2SNH#itwr8*+<3Q{o8Y!^6Wvy>(A&mkd)v85?s+cH z+rdS|cXE?m4>!g2a%XG1xT$V8SK#g8rnx?Dy6fj=xV_v=w~xD7)6aS02Dn-71uic2 zA~)N;#LaOpa~F!QaC6;3E+g(LH_yGs&3CVJ3)~^DKlKK;(7nl(SKs0mxwpB2vO8S- zz+G;!dyfln|KkAnJ|1-M=OOn29(Et(5%(b;bsy%t3LoJy_fZ~qAL9x4ah`Oa;6v-4 z--Y;4L-yBCco5ui(lrx&3Dzl!!LK=iU*~?!r&WBzuXn%Yo0GodH@M&P8{HrH2Jesj zCif@4B=cu}v-=Cb#r>7v>i))8)c($IbN}G`bN}SGyMOUJ+`svq?mzr4_g{XuJB;7s z4(Io}BlvypNWLh46yM|>&F^=|@CV$n{6Tjdf5;ur3+@D7bSLtXJBgRw$$Vb<6u#0s zl~>$pyy{NpHFpNDyEFMZ?<~IFJDWG$IsCnpxxDGl2xe7d`n4^H33*LrvJ8SWlF)7{G# zCGF$0-2HsEdw|bz5AwP0AwJI)_#Usw$JI%EzAN(uuEH0(DqrMke6g$ZC9c7jx+dT3 zwfHjE=F44&uW()dV)kLa(mldgxkq`w_ZVO89_MS^6MRq2Nxs$%zTK$v3-a_}0=WzQv8^&v|3`YHuvx>c;V1-gv&v zP2gLK5_yj|iEnq4`SWfH-;vv{wY&EJX5;eFm*zRS(y zyWM=g$1ULhkD;^hi!y7&@b0(W-QC^YD&48H0V)bOZ+9#Rc6afHt<&8_iNZ8Nx?M3+-J!V9 ze@HP}-KkK!4l6>{M-+#9jw(7@yA;Vk1N8}Clps5Cl%w>rxaJJ zPb;ogpHZ}RpH&?1Kc_g=->bM;+ow3we_nB|x?j;!JD{ldUr-#X9aLPe9#UK}TvQla zhZQ%fFDY(T2NbuegNobLBZ@oKql&xLA;kn?OfgZote7N(6%oR?qTO;u5h+|%L0U%X)5J(dq z0@8(tf!@YPfDGYLAX9h@xYGYPFj;s4m?At0WC>3J*}~I6j_?eyzxG)mS9lJ{6P^e1 zg%^N;|3%<*=S#py|I0vu@CqZ{TL= zED#ca%l(PKLLmuIwI>6MgcM-0kP0jj(txEx`aP^=2C!Vn1Xc)>ftA7(V3m*stQN9? zmWCW)jgSkh74m>}LOx(c0toC7AYi8e1GoASV3&Xb;eHI* zE#SZ&fdKXjByh8z0`>_saHpRE_6saUXXwWK?WLy?ZD8{ z9YB+?6F4C30-A;0z(HXT&?4*wb`0zTT7~^Uo1g^R1r^XCsDVR*2Iv&Dz+piL91--u zQNaLo2}Yn>Fah;?GteVgfMbFc*fn4Sjth3+gx~;n4mg36f(tk$xPjAx2RI{mfwO`S zI4AglUG5s7SEvPc57YsDLOpO^XaM?!Mqof_0xk##fI*=d*gkL&7!q25i$W_fEVKca zgmxexbO1r&5HKQi0(bil1LKAxz^HH(2nk)ln9vPe7J7iNa10n1jssVO6TnsBBydeQ z1zZ-z`lXAz)j&Cuz#Qz*fY=v+!D?Mw}pP-jxYe+6)pf1#6e)9I0Q@*F9H$b zFc2wT0;0qK5G@9Q7;yyHJ1`0;2SPxsI0nRtmw|XO3?zu-K%#gBND{9C$>KF2MZ6BA ziZ_5X@g|Ti-U2ej+d!sx2be701*VAq0a@aGV77Qam?QoV%oQI1^TY?ieDNW$KztaS zDn0^E6CVYqi;sab#K*xx@d>ag`$ctZq<>HrMh4>XXU;G-Z6u$wh#Bad` z;&C{zud#j{t7M^e*?7xzk@5pKfsmZpWrI-FL1T^ zH@HUp2V5&o0N05V!S&)KaDx~DZWJTIO=1+dS&Rm^h%w++F&5k=#(~vhJSd0>peQDS z=Nw6(BqoEhm;&ktQo-$F8n{DD2X~4Y;4U!}+$~N9_lQ%#y^}N0c*Ix^dIJ?;gE${-6f40du?jpOE&ywW7lO^=BJiNN z7;F)jfV$eHpw+w#Y!#P-ZQ=^BU0ezFbglwB#MR&-aShlht_97eb>LxfJ!m|z0d)B` zg8slJ@QAn>JSuJhTe`P`UE(&dTdW3s0RgNDh+vN>fyYD{JT7hrPl!9flj2VBl(-8# zE$#--hFXiGHvyPy^aq zYQZ{x9eB639t?;LU{GuXN5m#@R6GD4u4x8C;z960pamQgTfxg>8yFVb!EvzzydoX~ zuZo@EHSsWbT|5Hb5RZa4#V+uc*bUwmd%!#5G4O)(IC#W=0=z4p1TS}=0w+kP!HLot zaFTQuZ0$S;Mo7J2q|^sSN$0_6sUP(E2EZ8U0%)=gf?dr+U{l~C*ykDsW2H-AYij_! z;|YQX4vc_t(kQsUBLv1vV_<@G8BCPIV3ITrCQDbq6zM9MDqRCFwp|C)q#NL+hMQoz zbPLRoZiAW99q^*~@}-BN0_hQGs`Mx{ zO?nJ!?tC1wJD-52OHV>Gq^F=l>1n7)dIp*)JqtAlo`Ysd&qK4N7odZI7olS5CCKl3 z8EOf<0?m-zDGpjI#Y0B|3D7zz5o&WKLF=Vt zXuzEUZIDu-jZzx4NlJ${OBv7>DHGZ%O@_8fQ=n=o3lgMkNR)CQNy>#}DG%B%Op&U*xEp}95(w!e2+~V1bU1)O?Ew@rNEl?4aL6PPkXa(3qX7!CNHo+H zU?8i+LNWIkvO3iV4iXh5<<7bFMNA8o39Pe76KNhnG_1x3rJp&0oL6f2*F;^cGC z$v`g@FZV$S@_8sx?uU}(0ciB-1t?h_giZ&BpcMHclqwHHY4Rl~T@FAQauCXtN1(=& zqtIkI1Wl30pe*?^lr4v$9C;kdm9Ic~@>M8bz6KS@*P*HM4d_hZCNxdH1x=T4Lo?(% zP@#MmDw6+$X3F=$v*i2X+4BG3V)+4hj{G1zSAGaCkspTDhDYF1`BAt`ehi)`KMpJ8 zCtyH+5(ed`U`T!%hUI5qM1B@V<>z2bejdi<7hpnu5hmrAU`l=&rsY>)Mt&7$<=0?N zejVoJH{f#lO}IjS3qBio8=fz}16RuL!d3En@B;aLc%l3Oyh#2KUMznEFOffnm&%{q z!^3|Hp9_2jFPA@u_w;-LuaLil{S9BiE9I}@Rq{9RYWZ8(ed#+`tN$KeBmV%em4AfS z$v?s4-k)K+{TEnw_*b}F{~LV6@;kg<{sT50`xD+E{{^dC{)RWo|G=luPk=Yc6XDJB zBzTJ)0dJKf;caphTrEe#f*b>@8)M-M`Z!pW<6%iofMq!mZfr<`9hZ{f?Q#mdLr#Tv z%4zT}IUROh%7AyvneZNYGQ3xw0=q6{!TaQFc)y$j`#W=CrJM)vY{-XIashmKcq*)x zr@_Yh>99tg0bA+|;dXx!td(cNI(ZhXmuJJ_;bOR^ehzGq=fb1yC9qL0g-vo9Y?kN2 z7Fhv@h5>kd7=*1d1lwd7zTJ$#b{T~oG6wH#!eOUOz%H4D-7*CqYo+14?F{UZS=cLc zuutaUE5rZ7SBJ}Cbw>p}=${Y!ap`2(FhG!wvEhxKUmT`>f00 z>%+_8CV2&XV|XQeKwbsk99|7K%WL3+@>=-T@H)6fUJtj*8{js1Bit@;f;;5R@F95% z+$nE`56j!&BXTu-R2JYaS%kY~2_74k;U0NAd`#W}AD4H+C*)o5NqIMXO5OvXmiNME zHlq3htBDu=aokzSOIQ&&xX4ZqvhoUIW}O8{q-j1YeNNaIn_`56V{9 z++%}BdhPINuLEv9;)I7}7kp86!^5%%z9f6$fb4^VvL7CiYv8foT6oM?2Zws=;lq{& zcvNnLLvj;5CLe%phGzJ(d=L)HE%3P93SW`i;Bap{e7Uy+zA7JrZ#z5TYw}@uy!Qxv zT|Nrmkh|cUayNWS?tyKNWAJVHINa$y0pF2N!gu9U@C4;)c%t$Qe7pWEJV|*DKJDy< z8$Eq+gz`KbsqBZNlml?I@&X*A9E4+)L-3W}i}1DHVK`2C3656=V81m8*K~})`wou6 zS9?S7^{z4a_L0l*_1-XiyLTME(R&3>P+o--mDk{#z1QJk{|z`vc@w_ddkfy)cN=c< z-+_~rci|M}e{ibuJ|sAaM~akhAZ>MTBDKc1kiC6xBYXPZL1rr7MP@1ALw5DOkL>UJ0GX}) z5GhuEgsA#HM&>9#LFOtyMM{*PAA*IT%k)DokkTT`B$UNnD zh_>&0M4|iv0hB)?qt2fYQ28?gDStuEUHlc%^!dH3Di(=XaY%xSM=X8+B8jSUBuQ0)B&+5lDXK~&RaJ%DJ+uHxQ!PZ& zRf~{=wTqDq)e>av$WkOzwG6q^wj7zPT7gVatwhcZu0pa@tC4Kg8l-n{Es~>Jhvcf( zBYCO~NWN+#Qsdo(6sR^MQ&n4#X{xQrbk#OwxV9RZp%Rcnm53CnB&2^(MrNwEBePUH zkn@8(k=d$UNU>@+GDo!snXB51l&JP0rKkwL1k1(nRgjF>noT>@oRR@s3U^8-Q@F3!BZb8abtw@Ec4e9S{ zN9LJ+kEbsAZrI)j7<&mt>T=a7rty~rw6AF^6?9$BO6N7kwakl^42WSwddxjZ<8tXEw` z#s-Ix4XR7XMpXdWqzWSE^drb-)hMz>6+*VE#*l5Q%gB|%FjB1=M+DUsL{wcxB-J%U zR$WIXsBa(>)i;qz>RU*J`Zf}&zJo-m?;_Fa|Bx87!CR#K@-)FqDkt<&`{0eXlU>WG+F&5nxcLRO;taQrm3GnuMR$oUTt{}O;(pneCP zs(u%prhX5du6`e_>G=Siq5cppRDXot9Q+u)G585ur2Z7WHTW4iQ~f!5ZSV_pmikNd z?%-GGZ1vaZoxyL=V)eJ^?ZNNRIqL7xx#}O#u9_dw<4r%IcN%_1>l%JROVq!jrRv|% zGWGB1JoO)_Lj5NiZ2AiY)PJL(`X3ZhPe5VyM0DrSBot9cpr|?$#ne$Ku8u|tbqq?X zV^K;ShtleJlu;+3tU3|p)JZ6>PDabsDQJZ{6`ik6Lo3zkXq7qxU7*fH? z6J4pEg|1T1Mpvtg(KYHh=vwt$be*~cU9T=hH>k_djp}*m{vidrNe!Tz)gU_HfY2>! z7~QHy&~0iItyW{GpvKX=odmjXh(tv-g-U7~mDLP7LBpaGH5@ug!=uWff6)j{IjR|| zK(#~j(MU}ty0@kZjnXVYqwk5tV>F9U-Oyq*R5E&{WNOG)=PsP1kHhGc=pfOwDF=vStf9MY9#n(riPsHPxtU zNI-KmB5D|t&|Hm-=4rO0`I;SQfo3N3xzdq6w!E4RO3Z4jSs~&ew5JEproc2r8IRYt*J*DO#{km8c|Nugz}mLXt|~t zt2jjqu2 zper@U&{dk_=xWUgbdBaDx>j=v?Qon%*J;k6>d;wqz2+RM3H72IG<~SP@jN=L??-(H z2GEU~3+UOlL3ER52;Ho?h;GpgqgyqX&~2IkTCEA9f@TD5Yac}o!y#1EjG>a|GAe7r z=mhOJY8<|TPSjpSeT~=9X7hD)lJ*7~p}mPlYHy)Y+S_Qf_6{1Oy^F?b|3gi~_hE6` z`>}ZK|F8t@16ZQ=L2R(=AuLJzFqW)+1WVCAilu5F!_u^mW9ix_ung^!Sf=(V?8fP* zvB}zJF!S)U*c9z^m}U5REKBU8gZ9@j{n^*CE6s0U z`Pw(JQ0rS*f%a`|s`ef1X7jt)H0^uXbnW}t4DAP4q4qfRb^@jwnTRR0lQ2LV zfq~jc4AMqn`%Tdptc}4CZ7gOSiNjEBJcel#FvCb9Ht0#haBVWCA4$P%?Wq`{O~XiS zI!0+TFj||5bu>)I80{2{)n;LwHXGx$IoNnjF4lfB4>OJAW8p&uSh;p8R-v7S&DT!H zDz!7PDs3UQKwE?@)Xu~fX=hSSMX^gJ3|ptgvGrO4+n^<}TP_N-jL_IdErV^+ve;%V zhi%dF*jDYo*r~yCY@4NaAhLYuJ0n$1|8 zZVMK)Z^hcZ+pu_DHI|?gurnbMOVml2p+Uw@hqhy5ojb53-A?RWXcyM1-;E7>_F&1n zy;zEFAC{`ykEQ99Sh`Myojt6^&W1EthE9v=%sOnyrpGRX4A?-(i0y1NVZ9+U))%s1 zb!ID;sk32|b$0B0$bpS?Ik71^7nY@SV<%fZ*kP|1GrE0Pw$6{`=xVTBT`e{gs>23D z^;mzX0o!hD#PW1a*pBW4nEgmIX7e7z)CXFyd|fM6plid1L+#i-2t77UcL%?a0 z4rA9kk6?wmqgZQq7k1Lwja>}&U`4uPn9F(`o2fg2&C;F3%x$Nz*}BtMvF;4Er|~Q{ zM|TdJtLw!|bbZ+Nn)BGDP(L;j8o)|*7qDPx5DSHdut4Y{R;C-qysk^wXefZq(*-ew zZUh5#qZp_QVV2f0>~iQb2I;~WtQ*I=Ojj^OcNIf**Dy?X9m91uu%m{X7@@m`k-FPh zICKZ2baydY_a8PMx(~k^x*zW~{|{$$58z{=2XR*S5PmK6FwW^7!Fk=Ic)9K|yh8Ul zelzq0K414Fem(RQUa5N;uhKn(FVH=UUkN>jFVsDcFVek$FV?+?FVVe(-wC~pFV($* z-w3^m-wwTo-wnNvFVnq&Zy$RTU#@!#U!i*&U#WWsuW5f5-!=9gzDoB#zH{sYe6{XF z{A$fd_^r^#`00b6;A?cB;%jxE;bZ2{@iD^}xS{n+e4Xwqe9zd|_Qr^a6$Js zt{VFX-#0b^-#s=F7j=_xNf&`D$0BiA7llvIN8=OqG592XEFPhc!z1KVMr!s2Cm4)4+P_;LNe_&j|%uFzNDfPOw6JX(o^`YOEMvH*wl z3-P0#MfgG2Vtj9C2@dO*;)s43e#X8WNA)XkOurJ}7g~km`qen0UxV+{uf<9II(&a< zJx=L2;Iw`tKGL=cXY`wKR=)*ThPL9IejCo~tMPKZfLG{6e7;`7EA=v7rQeP((C@$( z>UZLc^t*6XXg9uCzXxBU--|ER@57hr_v6d;N_>T0g|F1B@l|>azFM!vcQxwpHF`b1 zR&T%ux{Y}Mm5G@G`!uE{x|I#&JXU6+F*y70)+Z z!wU@8@pBzF@X_E+e5&CVKFx3&Z*RDRPdD7fPg(!NXBh4y3Jv!Y+YkPaC^9@i%rrbm z1cMI|vkVUtvki|Bq2Qy$Snx5zUH3RqYOWdbt1LcoSs3B>RkF&=!KxEy?gKn-sanBgq~H@r;{hIfby zUGEZS>)s}R2hCC78rgc78-sct_6Q4#(lpK0q?KG_26&BBE#>* zwbnm~#fCqLlbwGNOALP#OAY@J%M25UhMtMU)vigzazg}hI~Yl!zOd~@~HnPMNBS-8W;R)xle~FzV<;0$m z3L?umpU5^=5;?{y;$qzb;<9NWk!xH;DW}?`*g_vX9O3XEGBTDX- zl1hyNQDzj0c}9uYKOz&#k?n-SxPwrg*+~G#T?A;{O_&<@5Rh>%(b%+)fQ|c!E8R+> z*>dkg!>A^VEgAwf-h12_bp&qI6RHsdK^Tn$X*3b4HZwsPErfc+O3+3d!5HlXYjhBt z(Mj+|7oqQR6Xiw^p&9WK6-FOXf7MUSH`Wl9##*AvSVt@{))Nbj4a6d2BeB@nL@Y5L zAeI`NiDkxv#ByT`vBKC&tTeU}O()xlRmKitweb+K#@I=$H6A9`8IKU_jYo+M#x7!` zv76Xr>>+lVj}e=V$B8Y*6U0{INkUzBinuU#n%HJMLsT2j5`ys@AsTxL$=FBO51uEE z9PTG%;{c)TzCcVc4HB0}hlq)$i^MVSFfqw=iKz1gi128TXtjC9J_~M4ah5VGG_M;!QV+1k)`d(R7^EVyq~;O`#)0O`~aD3dXP*pJw&FO9wyUFkC5r6N68G+W27VaIGJgBf}Cu6lDyjZ z6lwB3O-?aALuQ$tC9_S>k?!F0(iMD-%rm`C z_I18N=9}ImeZjX#fADRx!1NATAAFabYI^UUq~d*Yy6FS*K=4CyhUp`+G59gr9{hwH z>iU!{G<`-k2R|o^Oka>QO<$5t!LLYf@N06G=^Jvk>09z*!*^t{>3edH=?8MI=|{4$ z@h7sx^fOs%`h~pM{406*=x=0A@OQE{_y<`R{F7`5{zaCV{w8nu{~_m@CXn0B6G??> z5($_hNYE5XLZ&Ek$PrD#rWo>2FqTA2aU^PrCoxk3iJKD1&R`Nrn3BnZ!4#4-rIH=N zG?FrDHOf$*Frdi|?(`<67shC`5nnNx(%_UcuO31^(Qu1<58EHH+ zk8BAlNZSE`TxkNyRVIjBZGy=)CWKsTLdkU|j9hQR$qgog9CefAMiWJDGSTE_6GLt> zv1F)$Be$A(a+~R2vf5Nm3Z@EDG|eX^Qza>zs>liE1>{8YLUNLM5!oGFOh%ZOkfWBR zWTbf+8D(BhT54C28vRQ0V#_Kr+Ps>KF|Q%DhP7m@c^!E)xSotNZy@8%8_5LoCh}6- zX0p$+g-kSWCA)&#$RojOvL`5zNoJ8uz86m3w8&(Nc{_P5xPweJ?<9{0cadr4-Q=m@ z9x~m$muxlcBQwnV$xO47oNQK+Q_N~I%d8=@%~~?YtRr*Hdh%+6fgEug$rC{n>25WX z!$u34XSS00W*b>xwv$uM4)SEsNlr7n$mwP`Im7HB3(a2gQoWBXGW*Gy<{GlWTuaU} z*O9Z$^<=TRfxMz`BGt^C-E*93q#R$H-;o%VcjbOfEN%ljnn1$Q9#%7lQ9lsg`%CG|PKby5)T;!}0-@ zY59;E2!2FOwtP%Yv3x>hSw5w*EuT?2md~kN%NJCh5m3-zo3GKd9lrpVXNDFKVvk zZ)&jlAF9MMfw~l!NR2d3qDn0hRGB4`nrDf+SD1~a0)ZF`u*6cq#yBb%h^IhH!o46p zk%BEr6k{6h)>+D_YsV|7Tb}vUdP^m>!BR!JY8Oz~ z0}H8*mPOPi%VKJ?WeK&#vXr_JSVnENET^_vR#4TJm6TvvMeVe&rbNpcO0uk_WXn2g zf^|JL(Yk?}WZg(bST|9T*3DFubqf`3-AdgIY@=eV)l{ripyI3|6>pWO1glIXTDMb4 z)*V!`btjc#-9@EZcT;KBJyg1NFLf)hkIJy_r!uWdYO+;DO|hz}EUSjfwrZ&ytB%UG z>Zv@dfy%cUsRFBsx*af6Q>_+in$=28x7w%~Ry$Q_bx^@0PD*>sMP2f{sUoX~I^E=@ zTAe;>rqxfKKU70`T59h>66+{uTRk<~+CUXs8>vov6E(+rfSPMnRGio~8)v8H%)?rTTi#QIxfpqOE-tV?9q@8||l#mt(9a8m6kO6dNDz(UZ zjaqEIPIY;1P)n>gsioFiRO8{>)H3TG>YVE?wcPq2wZeKIy}jdpdZqP$^zG3H=v$)? z(yOcw(W|Ww(>F#Rq1RX+rPo>?qt{sOAK(wnT$ z(VMN$(_5@B&|9r9(sxH+qPJOJrmL;5&}a0o(t`ChTC~1SH+R25OV&4O+4>ee!S*(N zXY?IPDZJ*FFwomC;+h=r~?Q=Tb_640_ z`;tzyeMKkPzNV9H-_R+xZ|PLqcXXQVdph0r1AU@my6P;=MnVxL>h29bRm7Zez zjou#mozAlTL3=HK(kI-1(YIZH)7iFv=mGl#I>$DV&b3XV^K21xzAch2utm{RZP9dX zeGEO#7E4dJ#nCft@pPdrfiAKo(lc#I_h6dI^lV!SU2IFG=h)KdouPDkt}TNuv1QVw zw#jsvZ3;clmPKD`$)**y92&6Y(x5GmhHUvXY%8D<+f*90O`|c}bQ-tKpb1+cP1=fR z$~KdxZL?^`Hk)Q`#WZJ|L-V$|bh)jBuCSHT^KE5xrEMNvWmC`#YyiE`2GV;%5WUC- z(~E5gy~Kvn`#LdtsST%nUVY&^Zv_AkBPTu$4^ zDri^Re0r6wl0Mp0MQgei(5r0=X~)ut;F4Yn0@N7G7r zqiq$v$+nu_Y+FO`I=q(d=w3%}v8|`K+BVRxv5j=6XA`YAZ>BxoE%Y|qR=V1@jTUUx z^eMAIceabPXp`u(KAHB6ZKoyM4qCSDq$k*S(G%^v>6^Yiw0mqXJ;}b0_KoeQBkW2# z(ypST>}uLOrlI{~S~}XUqhsuPI@WHW{kr-9jhYt#p#zMkm|tbc)?U zr`nx#n%zaG+ud}A-9u;Ez4TEF!=q!6Joo%n9bL{nWuDyZIvp3TD_9nW( zet@28Z>Fc&57N`^E%c6>R(giLjV`pe(?#|UdZzslJr)a=_ng;D>Xs7oq?eLzXYrA@B$lgc8_Ve@( zUq6l52WVZ}1==z;NTc>48na)dar-b$*e}tfJwQ|TAbr*|Leut9y2Toz8T%N`+Aq_b zJxufVak|`og|4t)rRUqP(Utb=bd~)EJ=T4bt_$Cy7uavp3+;F4`tV(Pk^Miq&3+%V z*nU5=#Qr~Ksr><_G5jFY6n=~AwY;dhv=_IH`X;rEzr_V<};`v;6*|ByKv{)jme{+PLC`-Bng zpE5qfXN+Y3oM{h#!5j>K$(*o!#mM%rnM2`kmOG?VIxVOqnnOqwH(Ibexr(j5uRh$oRb6;5I@9LY?kBZb*zOJzd7 zH0Ex1I%90hU?w{Jf-8OTx2Ty|G5uwy=hI4T*`QN>`61-t#qf^ROn-O{Q|?&HR5;c#^BwCMjd25W*R_$UbZlbIw`^vr z99x(Lj;+i>$2Mk>qnZhZ1?FN{WEMLlW{E>)mO8dGryM(&k?>AtnPV5T+_9Tk;n>3r zg!eKR!uy!v@P4MZR>=gyDrPjSW`@EV=8jv-taRv@RSrF~+F@Y&JB-X4hlyG1Ff*aB zg<0pYGV2{SW`o1d42B)dMu(HxDRf?Cik#P&v4-o+Oy><|mh&bv+j)yA zcHU-gh3_zPoOhX<;s2Pq&imLB=lyJ{^M7oa^8t3A^FdbOe24{{53`{25%!q*Q5JGO z#=_3WS;YASdpG@i=7{` zOPn9EOPwFHJI6m^n_Zu>%bcIF%blOIJI23YS2(|9S3199S2@3CS3AF9*Eqjr*E+vr z*Ezpu*E@e;H#mP}H#&b}H#vW1H#>h}w>W=gca8tXZgu|7Zgc*@Ry+S>1?OL^==__N zod2+1;{DQto(l}&V|u}Q9UHrbWIrnoZMRM%uS%{7HhcV)2|u532bmBUVU<+4*; zd2E&|pUrj^usN=&Y_4k>o9CL&=DTLF1+GGNs;h{d=9l&g}ZT~#dOTEMcdg)HY< z#PY7iY`JR*d(yU)t#B=4=ew4(m97L5a;$);o#?J%yT@zUN$xr}!d=fsx*OP&TyNT@?Kfsxwv$5_DHqL#Bjdypl3GTyeqWcJ&{53~91OKgEVz)p1s*=g<(cDj3%H8+IV8SXK*(0!RLa);TO?s0aO`wBbTeU&YC zUt{OEud^4&Z?JRSH`x;RE!NU;n=N(UVawci?=6D=$12?Sae(`N4s`#IgWL~ru=_y{ zaX-YN?uR+d{RoGf}`9|aL$&iyRMyPxCA-OqCs z?iaZE?iaaA_e)%r`(y{`)zK8`yFnj z`(5r>%X{1^_xs$nmJhhq?hm;&?vJ>&?vJ^3?oYUJ&!^ma_h;M&_vhS3_ZM78&zIaL z_gCCz_t)GO_cz>0|F_&$_jlYj_xD`2`v*>N|Hz5%pE$|=Gbg)$;U;)~B;A2c?!7Mo~c~1XBs!hGo733nZcEK3b|5G5m)A! z$<6c3;uN0Q9N;PDK+hZw^33I6PYH*3N;%Y1#$ld$9PUwYR}KLj;Q=|)196lG=4cPX zF&>m-Js8J%aE|v7-0(Qbm3t_z!b5ZOJq%arVYw;~$1U*i+(OU4+#*jox7bs`E%D6f zmU=3=Wu7W-xn}{l!n2TD=~=|B@+{_7dzNr(JWIK?o@LxR&vI_PX9c&xvy$8BS;cMg ztiFfSTf=SftmU?P)^XcB>$z&r22Sv7Bq=FIVLCaWlPsZkD%(o9(UTioJE*9B(~0*W19AcpJG=ZxdJMJ;2TL zHggK^K@RY?aG4V>}}@|ZwH5Z4{?~clf%7-Il_B{BfUpC%G<@!-foWZ_HeBC z7{_^!bG-KiSMEK@Rd`Qv^S!6JO79u2%6pbu;62AJ^!9R#ynWna?|E*Cx1U?;9pILE zFL2AfgWL-55Vz8Mkz3^*=2m+zacjH*Zml=St@Dm>>%F7g25*Sl=pExWc`tLDyd9_LehPw=U}C;2qrQ+&GbX+FdE z44>(HmY?i*^&-A^^&+@&;&-T5~7yCZo=lDM4=lVY4OMD;mrM^%2GT*2CJl|)$ z!uL53_`cvl-q!Ld~y78Up&9Um%y*|CGx9$N&ISGGQY-`!mstE^6PwQ{CZzHzrmNm zZ}esIn|zb`&Auu87GD;>)tAk0^X2f>zFc1LF(e3HM6PxjB_Q~U}()erD# zevnW1LwtrG<}>{WKiQA+Q~Vg8<;VGKKf&ktNj}$4@p*ol&-XKYfuH54`Z<1@pXaCh z|K(@+%lSfo1z+T!&tK}Pye9>!;%E66+>-+=Sc+|h1$NU?3+`o}0{F`{vznQ1}TX@>Pm1q3h z_>u8yp7jen=NEb2FYz}n$h_aXoxgcu2On_ma)nFIjc%YlF^7s6op|fnLD(wR3%sbuP-QC@wppuG3gMfsfA|fK9obDi`)9xUo zLvDBXx#wbwg2jbvJM;P@_J?QhXRTFsaNJ#XZqQS9qfaQ?Y4MgF8W+pPrM|KoBV%RS z;p1gph7)Cn$4{0W89!BadE|82S@W4PZ1il|xb9q;SwCK;A39&wK7OHW@6bfqb@OCd z$N0rEeDqS;4fEx)&haZ{UE^2Fq(`U9j*k1wy2q!>{?*Ks9W(~YPROp6^^RXJlXToD zo9en*MvUGn>l?pa)<1ry%OnKsx#eFf#rqaBTcBVBgT=06F>uFgpGuAQ^uO=ox<+F!wwINXMTAsL|&D+4%E- zeEbDqVDLp?totQEDSa6@(eVnP7=IP$w!a1_$6p7I^}PY8$KM20<8J{Md*24=(RTpN z_`AT3&i4TA`1^ov`~yHg{vlu({|GRSe+-z$KLO0+p8|Vqp8)~g=YVDW3&1-5C14x> z3b2oV4QMpq0FLo*0q6L4fNT7Fz&-v0;2HlB&LxtM4~}9sM2X zQ2zmNqkjVY=wCqj=-)ua=s!T^Xb?~}8Vqb1odq15o()uwh5)0}p@3w14p1{X7pNVb z2h@#*0rjKdK*MMR&^Q_iG>t|9&7;vk%jkTdb#wtR)*l1hFf0VxMi&8FM;8O<-AjOu zfu%r@Bo-Kx#sR&T7r5fe10p3Wfhfr;AX>5-kU8^#`I0rj0!aZd ze0eQ!Ra*$eNY(*Emy3XflJ&qMNinckvH@5kDFH?V~N`Y9(CLm6-8HksZ0i%}z zAVC5Gi4q7nb{PheBnXf!L4gzr2Bb>xdvS0ANRyC2x`YBUBsAc+F!zFCEHI?vfJ_Mw zjLOP^EJ+2BEvW=@Bvrr)$rd12QVpE!s{!&PwZKYA9k5DL53H6n0Qr(eU|iA!tdTSW z1(Fs(InxRpH@5+*nXSND$u_`i+71*-b^z-nJAnc9E}%%V8(1&d1E^>A0>zSjzy`^F zphR*2*eE#&lu8Z(n3|A}9=L2Z0F@FWaB{{3R7uRh7KsI@mRNxri4CZg*n#sV2XJb} z3DikkK)u8b=v5w|K_UQ+5--ps5rJlj4``8$0j-kbfW7+!aOUVq;LOY^piOcb*eW># z1WC^Vr)SOqXJ^KNVCi{amh=K}Ze{|QEu92Hq!)ou=_O!}^fE9$a|M_yy$W;=OaaH* z{lGlwG;n@q1_+Y|fN<$GAVPW_h?L#{qNF#0Xz49rzVtS5sP_(V$$A%9ApIAJk^ToP zl->s(u-*@vM*jycl0E8Dt#P`l|BJZPdy3V z=y?jV|^5?(=>GReFIFEz6nlDy#=O7-v(2q?|{ps?}C$4?}2I3_rZ%(AAsr755WxSN8qKYkHO1R zpMY1UJ_V{W@#)~CXEC8l<^=aO#rEsiZJ?%qJ9xmk1B{XF1ZR48 zf!f~P;6m9RaFJ{;xLCFi93R>bj`SV?m6Hd-C9*@HYVt7H-+lx%9cu@d$~r*BWG8sn z)&<7Oj)LmRZZJ;P1IEjGLCs_zm>}y16J-OSv3C$mk_~~<$zf1FIRakO90Og>QPAL! zfSqP3XquFPeMUKGo>YLzG9|dTTLq@b)L^Pi11^(k!8Dl;Oqc1wt_}leoiu{G^d>Mv zW(JqbEMTV03TDY{V7AN-=Exl23YimhDqNs#(hcUyJfLM#0FNuYpm9`z&~R>KvFa8wa(M=Rw`%1yDaZ0U9PJLFeQ} zaP-_I&@*`%TqC;zo28=%{K6D*Y7 z0(;wUgX?5>K;PtDP?Y}*7Rmkt*URpMie>jh8)W~34muxzN@Nd08)XkcrLu>i6GtC` zHpw1^Hp?D^u1Oz<`iGu?%4APMpzJ9~n0y-YPCf&jus;h;D4&Du^5>!BlP^Gf6fZ&n z&r1*_dl~BJd=gUxN_Y>yTpj4G5LJ31PCgAYAq~bZYV)h>*Ptk+Sz7O7=cP z%RYb@*@qA-`v~G>A49zC6R2GFDO4f*462lU4pqs%fVRlKgicR>1y#$whH7NrKnMH2 zg=%HrK^DXJ(Ami!pgP%)P`&IYs6qBKbaL_+s8RMS)Ft^1YLfj9HOu~hT4aAht+KzM zHre0McI7|NR#^}fBoBsy<+Gq!^4ZXAc?c9D4~0VIbD(McTxgDb9&~Op44NwshuTLY zpgwCPG(H&x&67t%Ve1nTeG2zgAU&{_E==*r|~=;~w{B}7P?j8nvgJ6GBPXC0auNzmQc$j(hB`YLC{NBpE9D%tO3p*8<>kKwE%3GjardDW!ybUUm zZ-q9>w?U=y?a(Iq4(R6OPH3}y7gQ$S4Q;=;2Lk1LA-`fD1j+Y9w2r|$PYoN z{4j*ck3hJ*9U|l%5Gn73D0vs8&>V$mc{jw!dmvWc3vu#3h?n<6pB zgBs*|==P)mYLpwHCbVH zaUNQzxBx9uOh9(mB(zv@5jrq)37YA;3@uSyftD(+La~Y|C{E#r;uX`7#5n^=odGC8 zaScjTT!)erH=tz2O(;ci3rbbohAuenK-!VJ&@#op(4Lw9pftsO@Lucv@ZOpK!TV+& zfYTKZ!uw|)f^{Pg!^drpz!{21;pK|Q;7rBiaF*f;I9u@~d_waSd{Xl?oTGT=UNqua zSUUY2oU3>qKBs*F&QrVy`}HruD-|!ps}!%ms}--p`HI)zHHz2a0>v9}=zqq?`? zwTidl^Tu~zuk&5FQ1KpoXy$$R@XQDBk(m$Sb&8MRBE`q>dc`MjvEoy>bLKO6gW_{| zc;E}TYvxP%bo*Cu`^?vHiQ*f$W9D0U`|x+Lqw{-sqv8j+XXZz^cjhPfT+h#Nd*?5( z$@D9Hbmlks;L+dVQpF!|_spO0CdFUyX2sud-^@R7nIZ@V6~Qp1m<7X%*)XCAf%|7d zVN@{(#uRhmJ%)KOt_Xt%X2M}Y5dja*M8c#Z3Z@j%Fs+ym56vuq8AS}tDi*?=ViC+M z7Q^L=C2)meDO{fxg z9d1-)z)gzfaI+#4Zc${xt%_{8O_2j1n^^&GRpi1!$~-t&xe}hGTm{cou7<~E^5G%L z8up!V8rg z?9}k^fLIRqh!yZ6WhFc)R>9lvMT8eCtKlWe8hEL)7LHZc!9!v_tPmUEVX+a8Q#Qfz z%4Ybuu?61cY=sk)ZLmq)3MVSJ!3J?VoTS_VCo6ZtR&f`6Zg@9*K)MG`QSOEN#C@<% z+z%VY1MrA=5VrOnf)(wDVU>6U9x=DW60rl`JJ<=QD!bsJ-lMQy?1q;qd*C!>FRT>% z;A3Jx>{SiG>B>PkLpcO5R}RC+EF1_=39J>RaJEtg=P2c{SyaF)lu9^P zse%s~)v#35z=_?6>acw(GKs{JK%Go z6JDis!Q(PFEQ%g@wNildm0nnKOoTn6@1AUF48GNV9Pa5q0iP95!Zz^~T%bG+%f&OW zQ#=dLsL#PCj*Y`>mFM9?T-!^(eQMEM_#D(^!u z<^71%^*`i@>;a^w_d&#>dI;Gkdl)$-K7zQ#N0CYKF~lxDj^N5C5JLGR;uD`jNafSW zu90UDm-s9~DW5}5h|eRm@&$xZzKEO_Uqa4^FC(n-737BaD#9sWLwM!u$Vu@HWV`Q8 zWL$g;DObLYR4Cs;DwXddRm%5}Ez0+iYUKw=jq*dJR{0T9r~DYHSAK#_4tKOlF+ACb%APsmm4&&c`C zUyxSiuZTxlW~*i+0Wky# zQH3I*syWDxk-5l>I1ibl3PXII;mBN71Ts$*iG-=5kZ@Hr5}}%pOp6PUYeO-}d2t~k zA6$e)sum;Dqf3w|)lwu{6^qPQ#UTq+@kop+0kIDyA{WFYWI{|v7OGN^DKQnfCN4v6 zifPEv?sR04Dg*JTmm}kYnaICl7IIh2zK4|OAlrN^kR85UWS1`wnX;}#cKTK!yM3#X zJ-&QopLGqgSXF>5QLROmstS=<)jA|jRfNQ=)*}h3Vnj2r0oms(K@wFPkt9_q(&O8N zblh7%AN7?X$tnOzQGrOR3PP5tU?fe2An7U;$xvZPyAMZWdq*%2R*`V5ml&E$i8&!Ld zQq^9h-?tCx^6f_s`3@la~r9o(w7IBQ|5Jsg(ZjBfaR%Jvul?l-fm=RuOLCRHDq(Wsw zDphtw>vJGgDkq}wxsWX?H*(D9L8?^(Qls)BwJH(Ob@~vQZw#qZ9Y=J&6UffalZeB2 z3aM9}MjBLSkVe&6WW;w4X;O_N&8qWAi|PVmR!$&h-z3tix`?!?E+Jc0mysa#6(m@F z6|wuKkW&&rqU@bUW~pb8+3EliqP~WNs;?t+)He{L?6caSjkT}1Bt z7YSGYheW9FLnGDqqr<-cp;77wP=oJ5)S`a~jaEO5YJ88N^VN@{3)GLHG3v+Bh3Y3z zsqaZtEqe+bQa+6yHa>&ueb1tc)X$-6-}C5V^$X|{^^53I^-E~1`eigu{R$edeifDY zUPBYqucL|TH_#;Yo2b(F7Ai{LMw8X=pegEi(Ny(&=rZ;DXqx&1G+q56y3h6zy5IIO zYV&=9&X_($Z>T>*Gt{4>%hg|?nd&dmEcI7tw)$%{NBs@DLj5h8tNso>=ldSbQ~!Xj zRR4&sQvZamR{xCVtADvCv-=fQ`F=wS)W4%^)qkLc>OavFzQ52j(!bGl>VME8br8B< z9gG&MXQ3O^v(XZD2)a=nik7P9peKEE(M{@k=w@{oTBZ(1L3IQQsUuNX9fcz5XcSe? zM=|vR6j#TfF5g0wP%lDB^YM(fr2XoGqU+Ndr-%}3XwP3l5a@U26e)kWy-W9!k=zGAdRy#YP$D?wY; z8&RLH6m3&)Lbs|nqd}T7G*|myOo zN1%oha1D>1^_8O$nhG>hQ;9}ts?cc77IeO*8eO2NL1Q$v=t4~$ z8t~Pli!=?WM%IWf)-<6@G|lKKT?@KY(~8Dw+R!-7Ry1C-4fXrBqY0WFXrg8(nxxr< zCTn)1DVjZKs%9^`OtTM7)9gpnH3!fP%|Udz<`9~xIgDm$j-V&q?P#{91I^KNq84Qr zx5?Y#)NLv zn9&KJ1@-H!XsO1AUh>(|O&SNfS>r?v9WJy?<3>S^2Zb~O3TwP5q7l)1gN62tj-i<5 zI663V0-f@mL~+e2l+c_;ulvrRq~;7?GxBM?UUFI-&0ta_Gv6!`wSMLeHM$*DELHnCwoLm4c3%D^c3k@vmZtq0OV@sbWoW;} zmTSMmGPU1hS=t}4Z0(O&j`k;Ph4yDGSNjV#qWTrP<@*i0NlhLPHIjM8Rcw01eRcPtZQv{@Ld&Bi!w z4z_1(1;%T0v2tx5R-s*qRccpZRod0q7HvLOtzCoFXbZ4f?ON>6SRq!YU5DxIMOeLd zJ=UNt#u~L7uqJH@)-|>f+do!{9Uj|+HETCxE!r~7GYVj>S`cf~LfBRzc6LmS(JbtOZ-5YsHr8+OSyNRxD1p z4U5-p#}afquteQX?8w+IEJ?Q;OV;hdQgnN<_OX3fs%}3vY(9W3(;dXpbce8X-C^wL z*b(fKwjJvq>%cN}o!D|+7nZ3zie>4#v20xrmZR&%`o{XO6}o<`cWeO5)eT~Kx*=?( zZWvpo8^KoVj$!$_QEZJ)f(?#Iu>ze8TdR{}g*pYcPN&3*bSiAUPK_1oG}zf;Ew(|Y z!%B2|Y@^PAmFkSxCY=d$cbc&YnFZUdvtngB8#XXz$3UF}8&EhgNaw;}of|`R9t_n9 z7^d@LxK6}|#(Wr|8^cK5ag5TPz-Zk`jM1IKSlwxi)1ARQ`m-3XJBO9)#<2?Bd8|@* z0o&g@fmP`yu`RlbShemFR-?O&)#|Qbb-Jrqy>1F?(D|`O-89yuo57lO0jx!L4Qth1 z$J%r^u&uhASdjh}7OcOGoweV=X6f%@v-SUCA^QKY;j#PhQ2qV*9R2_Bx%vn2dHM(O zF#SXLv9X8oaQ!2Ag#J-HQvVnprGFfc)<1#I*FT9b&_9L8=%2Yu?E>7T_H>z~87 z%b&-W=wHB>>R-fT^)KOZ`j>IZ*eiIv{#86d{~DgCe;rTKzkw&~-^5e&Z{ex>xAA5A zcknd*yLh_(Jv>AIKE7Q40iLP<5YN(oglFqN#&h(a;3H$7;w$u@;iF@pgwzE=MOUa0>OU#I^GFVg>vuh;*A7wdn;2OPiQ z8}z^9CHg<`jru=v>DXU*ss3+#ll~ukvpxtf(+A_AeijbtXXCIw1V{9tII5q6WBR!` zuAhe!`Y@c-hvSq!0;lznIHQlk5BsC>?Su32PU!-?T@iz;qziFYzX<2_i}54=B{;8N zikItS@d|w$Ua61AtMm!@1#=?4MW2LM>yz;seG2ZgrQ)^vWq6%F4X@Xy7F6Lk&gv9K(8iuAvy8XV`#;8A|Z+fsJ^VzZCEGZ^DoIH{)k?W%z&zz&rgQ zepCzLCM%3zlp=Vz0mUN>7#?ZB@hAgK;~9oM_@I9;-s9hgAM@|Why4fe z<%WZJzyA=PX*i5$8IIs8e>*Psci>8YC!THS!gCBqajm}_m->6~QGYMK!qA838v5}( z!vL=E58^8gL-;Dgy|{s41kX1d!`B!_@!L)bUSN>oYYj5I&>+Vpeg(eHpu}&gRQPd? z8ZRn{bWajGO%y-08RC8w@tQ#9+r=gARP7!HJg| zT=*t~8+Z6UxM&dY%?2+%=@juYgAWG{W4P6S9Jl*V;E>@Y4jWG4h~YGj8qVPUzOy)H zIEUkgahx!m$4SElT<4#_DZ?aA8!qCE;Sz52U&e1rui&iVD(-Vk;d;LxH~6Pv*~02JZ3S#D{FR@Cw6iywY$7uQJ@lw;2A#Cwl(Fs}1)NQ`-B98pHpH zGrbQGF8_l>t>Gb}&hRi%Z+L`o`yV9)|6_#D|2X0GKS4AYo+KI#PZ6U3X`;#S4AE?O zmS{0NN3n2fIy`<$;4LB`jK)BZPzVB?#FSN0Y$ z%lI~N!v792+xRXKVtkJ{GWtGo(fv z|4J+}{zfb|{!T10{y`k~|4A%0{zb$Z|0d4({~;#)K}4J}n20ydA`*U)nV+66x7)kj3QAC=?0%Hbo&A*(u;m;&)`Ll?%#%!X{m_w{Ht{{qxxx{*79#L#uNo+8#B1(*_iD`d6 zvC+7OnDQ48rN*_yCSxJ7*|?6lJy1lH8P^lHyNe0XxPgF-B?N5TNFc^i;);J0aoxX} zxa2P*F8cujHG%|Ygb3US6O(>~*gcIBgb^clOydM;BnZk#65FRKf;Q3wV`PXKKTEJi zju6y5!5Pa5-dI7D8!L$lV--Woc9 zy|I~SFt!kl##W-q*hbvACmC%vZX;TZ+lf}=4x-Jtlh|t9MFg346TzlE#4OWZ;;w%m zG267C2r(TX_Dmln_Dvrmc1|BALQO}AJN|ZJj;Vu~Yw9HCnYxGr(?^LgQ#Y}Hx`zli z^%4=LJ|fc8Pehpp2%mJ2h&Bxo^G(CV;pq`#f$10#V;UverzONflayFwk`aqda$<=| zK`b>XiEYy=BG#lP;!GMM-lQcurgg-@X+4o(G7yO-Bavh>5y>Vqkz%qCN2aaBzkVBW zXxdJsnjFM3laoj@xrlU=o5(PEh~*}M$TWG0&S{azGWm#X(-@IsI!>%Gogj`*pCock zr-(e$z2KVZ46({|me@Oej#zCPC-P0_i8ZDRM1g67=$f7+)|xI7g{DiyI@4vMd-@7d zWV%YMH%$@6CO@&kG)0hF6`ac3S-A7`k`$^pNKawy#K;HB`NRp<9NXqmuNt+%a8PlUAYkG|2OplZO(@&7R z=}EHO^b}cPdYY^>JwsNRo+Y=Ko+GPG&yzK#7s%e}7s*=FOXL~#%Vf{=D`cJNRkGgn z8rfiaooqC{K@Lp6Nj90@BAZQblP#uq$X3(4WSi+da&Y>6a`fm2V*ZmHp8ktmYW|yyHUC4#nS;pv zmS8g8Jc~>)&n6SiA>_fCP*Q20LnfK$lF82L? z=aU)c1>|yb44G+ONM@NAk=f?Oq|vm5%rP$|SD0f-=WraEYmO&nmIN}-oJg)TCy}en z$>eHt3Yl+CCD)jjkp<>7^3*^&dEsORDYY&qrBj(?e`glC)|^cinsdlY9V+qlus3s8}8}oO3X#%M)P{I)Lcy3og2ta z<`QzVc_Ue7E+s+pCK57lCKXd<lWXzQ$Ypx;(^;<~JTut)k8nWD6OP(>; zkrn28veMi@R+$^gE#@Y&+T2W@Ftm_0=2o)S+(y=!x03bdZDfOaJE@-9K{lFqlGC1D zWRrO}*=*iJwwU*lt>%4Xn|VLE)qH>)>^MjUSq_nhO^3-~%Mo&xrJbB@=^%IZb&?^L zE;7_|l$>MfCg)mu$a$7tQaja0hFSW_aLWK0VHqSNEkmSkYM6|&jF8cmW8{3xD7nBQ zA!VIX(jt+OF%~(w(4rvQT}o0jr6Lzu)Z}7|hSX1K$t4yYxzwU3V=V?U&SE5uQzkOr zVkQ$T7BbOdC9ipGWRk^Bp0qm19d;*~Y;ln(7B?xI@sRy$flRe{$z>LiOtbjNbjui- zVL499XHJmIEhouL%PG<@b(%Cyogq&jJ4>3U&XHM`aWdO-p0rP0Aag7en-ooS{|poQ%_KkTdfBlxONiim<#y zk(QS!%JK?DTVACY%WIT->UGLG^#&zOy-Bf_wDA&~cRHfwu zs><>qwZ-xgby58>Rc-l%sMWmATEiEVZ|X~`-traIVELMAw0uJ~S-z!) z&wfWWTfV1SEI&}KmLDl`>L;qr@-sCy^$WGt@+%c&{f!E?{!Y!Z{z1*Q{z-*c|Dr;z ze^Ya;|4?(SLDW2JFm-%t78PclO@&)SsI#U}D#AL4inPw9qO9|%XlocX-x^LWutrcZ z)<|lhHHunfjiwe`=Tl3p3#g^m7%JAfkczV|qT;QKsRZj1D$%->O0vdM$<{b3#Trkg zS`(;c)#ggkVrvn# z!MdI*u@+MstsAIPYYDZy*MnP79x^4t1*a}hmtuTdH5$g67 zN}*Pa!mK#e*+)>gm81wOMUhsTqO1%>TUm;+aujRjDb89>@zx5e+*(OhSgWW?>lUiY zT1{=S)=<^fTB^ocN7Y*EsXA)|Rc~#i8mvuJqqUi8vbIpo)>f*;+D5fnw^D7^ZPZrl zb}GoWg9^6oq-NQ6QL}BksSw*9D%7@@nq%8X&9&{P=GhKVVYY)*xa|-XVLMDk+Ky0B zwstDo)XH7)Dl}Cwba&6#o7j_INKlhy=lT_tN2a7~S`~GELQRd1YN)`7mbx&Zqb4Tw z)Z~PLT4pm+7bi^Ar3o{2dBQ?nnXpo-VH=fZvs39d2bE!SQnv#xYPro#W!gMcmQA4U z2E0_ZO{D$}_^2G)7eTQVYL)FQwe8wDYS+w|`A9uzy3x*uSM0+P|Y0*}tb3+kc>!*ngy#+JB;B?LX6T_Fw3D`>%9@{Wm(% z{yUvy|AS7p|4FCV|Dsdvf73g!{X;La2hnNvU^?ACi_WmmrkC48=uCSkon@axXWQq} zIre$2>xc zbdh~2z1|*67u)0L4fc4t#GXKJv?tP~_9S|fJ(=EYPoc}~sWfO`Mnm>A8n&m?h&_Ww z?aOJ*o=M~OESj)q)1*CzrtB+d+MY`@_B@)kucSHqDw?;irpxX5bcKBlU1=|%tL$s( zE%rjX+P;piu@}*`_Vsj~y_l}IZ=f6OC3L4_Bi(2(rJL-V=w|z7y2V~bx7q=^%?{FA z?GPR0fazcdLeFxb^lS%4hd6LL)Ird593(y0LDB!(Xj;@W^gIVkhdDSp+`-ckj&eHE zQ9(yJD(PrP6+Pdvg_dip=>?7&I>u2;FLcz=iyZazVn+kL#L-AEbu`hjj%GT}(L%>N zTImEw8=dIbN+&tC(aDbObc$mKo$A<0FLUgo(;U0$bjKb#!?BlM?$}3XI`-39jstYI z;~<^mI7F{-9Hw&}N9a69JH67;L9cRj(yJX^biU&#y~fc^7dU$8wT@o8(9uV)bM(_i zjsbeTV~{R(4AC1L!*q#bguW+4pi3R2^d^Ud-t3UlWeyn)I_`aRawurnp`;Oqibfr3 z8gpo9+@YljhmIy4dYW<=Xxd?<8Hb5x9cG$ySZLm1rOO>Qy24?nD;*BH%HgE9I9znK z!%f#XJanx?pz9o7y51qu4GtgO=oq7$9LMQq#|gT{aguIzoTA$tr|GSZGjx#iEFJ7T zN6&JO)3crD=@91yI@CEq&v8!DbDbCIdCp68nDa6n?z}=rIIq%?&M7*|>8GQe)AW4j z486b^pktiZ=!MSf^djdCda?5+y~KHoUh2F}$2#xOan8GRyz^f=!TBGZ=)8|fa^BA* zJO9U|I3HkAoewh0oDVT+&WD+F=OfJM*+-cS=VQ!r=i^MK^9d%)`6QF=e2U3&KFzFf zKEvcXpJno#&oL{V&oir>FEFc}FEaVgmzXuqmze_RE6iHwt4yKuHD;ajb*9Mq2D9Gz zCR6Nui`n3On<;U=!)$cE%al6bV>UV8XEr-OV9J~yGNAJ#26BGP?7H>|13N!u5a(wM z>inF+oL?}w^Gk+se#MZ^uNlhu4MRJ>WfdIn{jAS#*TscgdYXy_;%4ITKdCYRxN@kyO6_e>&&1AXq znQYe@CdXC4tZ=Pma$SW?o@*Vm(pAK)a;;}pyNa27*9K;dtAr_VZDiKEN|{2}CT5*$ zGgIU$W7fL>rq~5C8(a`m;)0otE`%v{q0A;1#%y-sOqq*dKo`kCE{cI&G=sPp26eFv z=HeLK#WRGfoFQEm4CSh1Xjc`(xVA8?tD50lH4N{nWy)Q3OogkSsdP0kRjx*6i>ryL zb~Q6Kt`?@&)ymYl+L(IRR%Vy5jZqG5XZH2%V21j3GA8vdX4lYeX1B11*(2;_oceu? zOue7kD;!|%Di1OZu0u?>dW7k*v@@!q4yMu7$#f2PF=qykGW&#XX1~zGs4czB z0iln%WbS9K^b9aw=^)eO8e&YkVdhfr2yjFvoRT=88kd92WGoDt&=$_xR?W4H`6V6m>xl3OkG~)ic@5I1s~HsIK~|AKF;(BCzyWWBy+j{6m!IK znmKPh!wd*#8Cl;sX2LYiTIQS!d6SU{x0r6lZAQ{_hmi_*8GY}+jPcli zj7+$Xl?(T?hjjmA6~Y7T_3j5*rSK3dl|0N2x*lOw!lP`T{xP=A^*B3WeS+J z>%*V1+hm`!Zs7~oBYer;m3_tb>c3_M;TzT~e9MlEe#g3$-?O6d1M3rhWRI$TV#kD^ z+2g`5th)bKHpu-O8|?m_o#p<6o$daU4RQa)hPwY|=eYl2=emQ~dG28L(%>vM%srb8 zcZaYM?oc+;J%{b@nakdona4)C!`PcM;cT=!f}QVGRDO?9WT z%iPP@Ge~i`hc=26iS;!tU?b$oe}= z*>&zsY>|62yWU;K7P|p*TD zX!crwVIeomcFH&wcJnOaE@x491&g^WS=?R467DT5>8@sP25MN!UCYw$I+k(Qvo`__ zEbDG$Id>DwyPMf^cMDtLZe=UoZETf$E4#(LjjeWXXKUO$*jo2aw$8nat#|Kc8{B)? zM)zK}$-R$lcJF6f+y~fJ_d&MJeTd!aKFkJrj_U%(UF4Cni#;-S ziAT;Z^(fd_kCKh^sMvUqnoaO%*hG((P4ej2WRIRr@fg@tkC9#GF|lbLGn?+Quo)gJ zyWC@AGd*@T%j00PJx(^q<6>8M+-$DL!{&JecBRM5uJVZNYLAc2_l&V?JjdAr&k1&| z=OkO`ImNE?oMwwWXV~?gvuv^F9J|3Y&X#!2vl~4Z*iz2~yU8=jZuVSc%RHA@&~urE zJXcuQbCpFrQ!MK7vzTX^#XU1D;R&#$=Ne0SuCuh~2FrMEvaIJ8%Xx0Iyyp&E?zziW zc>ZN8J^!&)p8L2hp8L6K&;Pg@&jVbo=RvN{^AK0>d6;YPJi;}49_5-mk8#bO$GH~I z6I`q3Nv_TF6t~s$G#4a1!vzb^aTL z$0vfhG07~hPdb}BZV%zKu2Am8#2oJA#9Z#o#60fQL>PB^BAgr3L~vbwk(|6IiaR?I z%}r?Ma|X=<&Tuq_TOcgtVuVGU=hR~Elwt{YZel6dJsQg`6ymr(S3Ea9k-!~vC31Jv zNu14{%o*G%+?YL;TO=&wZram0xh9=EY|G$meapEMU76fsA&Wbu$>y%j2j*U7uOa#S8gdg0O}=?keCCg|%FgP{>WqtmE4Iia5JtJ!k4G=B_F? zaLGammm+NBQiW1(nXrjV6E<_{LK&AK0Nio`75t_M;LJLd!8FVc7Y4`PH_JINp2``kuwA?aS`6j zT%`93*DJlsMR}*VXs@4}@15pu=x4YE-T-%V=o%N}z0Mf}H#k$^CT9uU;?DNm=B$A` z+(PeN&Jp;RTjc$ZTkO4$U*f%=U+VoIAM1U9kMlmr$9o^*hXW7u3EoHeMDL?~lJ_y* z9(bG|v^~Kmd!OVlc0I+Xc%SA|z0dGF_0RIlywCAz-skyr?+bi}_eI_rc!^)`eVNbn zzQSjDU*)sCukktF*ZCFRH~3udn|z-4E#4J)n?E`74(|@U%dhml$FK6f&mY%+z%3p{Lf{)-41CKMdB5XN z1-|Fkdw<}Iy+86Byg%_L0zdO5-e35Q-e37r?{EC^!0)^-@CU!i`zOEI`xk#Q@Hb!P z{f7s=LHt-Cm_HMk#h(q#<{@tge_9{P!`?YO;+@MMJ3Ei>>ki{j2g3RDfe3zwK9Wbh zQ9S02=5g%E;_v0|`8IDpe=)FzzYr+k@1^B-Yq*o=+4T_$0BBPZpc_6tS822U_@4v6Y_=wDHTtt$doejZYW1^BLj}ez~}l z&lGp@S>kR!TinCvhtbn#n6H(xD!_!?2*Yeg?#CyIQ%=;Is2F}_he&NqoC z_-64W-y)vkTgCq~bQWw?C0rDq`KG(OyStn2?(S|71gud)M1j*CV0U*b26iWSyYt*U z=LXJv^Dp-E?zPsd85zB!9T~f$8wru=M?z(WkuaHYBwS`1iIAB`B4w75D4BI6T4o!G zk=aLLWx`0D%rO!#bB-j)TqB7x_ehe=Gm|vl> z_6SfRdlaaYJqA?C9tWyrPXINtCxKeoQ$U^UX`o*A4A3BZ7HE_`2Q?#bm??W5=#;$ybjjWXx@B(xvt(}rvt{o9b7b!Vb7k)V z^JMP>^JO0Z3uGSxJ+hC0UfIV$pX?K$U-l`mQ1%%xAp0CxB>Mswlzj;-mVE^*k$nve z$-V)GW#0lLvhM&u_B{Z~egGiZj{q$D2|#2&1E}m50F(U+;IiKULiRgA%KiW-*`EL{ z`wL)XApk221vpt4z{|pcQCS2qCW{0@C!}o(3e!(}5&;29PYz1XAQ#K&m_&NR#IP>GE74L!Jj@%JYFN zc>$0uF9dSrML@2+7|4^C0QvG#pg>**6w1qiB6$T+EUyGg*0p(n-}E1Xh?SKz^MDR+<^$=p`07u$KcW(ZV6OZ);6Hf+*mL-4}WodFn@8-X)A6ELAO0~dE%fKw-}z=+%iOz*Se87pVeqi~50D#GZ04|>f2>D%L_sxF*QvNSM$?pNrp1&77fA)Xi znKSo+SI^xKp3^-5p4B}F>W@DJ((;EvM*ax6^zx(N?#qvX=XH;Rto#Y^lI}^6lRpLS zIsY{1xbX~lQTHq;+xZ;G%by1ioqquwmA?pH*1ZJo+x0RyCVvGCQM?MSIsY1{-TOKi zs(1rDapq0%^7gmD+h^Yft=HZGujt+d&AZ;ffEy2*ros1>Hwrq~c>RO7RI8 zt@sp-QG5o*Dn19}6kmYXbzg%2?Dz`2q5B$)S9}8|D82;~72knLitoW>#Sh?B-H+fk z-A`bO;%88Hxfa8j2F-qNLk zw{_{@k)0V}u_6;JQDlLoifr)2l^pPnE*C6Q_ z*PFpsMGM%bXa#2|+Q4?j46sAd4k~pWp!4QTaHgUY>{N7tU5ak7TQLiqrI-!QR?GqC zDCUAH-8^uv;&1TI*7;!Y@&a(4q6bv#dO@wO51g;)2Nx(7f<1}>uvf7N)aVAmKE-0N zU$F$#>4w0CieYd-F#;}90N|hk1Q#nH@YWR=T%th0vpZ36NP&S00}c)=2+%u8f+GqF z^i9$rpkP38k_ABp2TGGX2q{KESTP17ilty+av6B>(sFR(_zDnJtOPN|D$u@VHHa(L zfP`W#NGjHWTQ02!Da8iRKe-X46`Q~_S2u&}_H6-|O>G686Wc&Wu^pVA+yMqBcY;%= zcY${&cY~~A54dz{FDSpc5Bz6xKR9{x0LUp0g1q7oxN_<+II1`Tjwz0Uo~z?vi1HX1 zsyq&^o;m@pm^ulDDJQ@+Q>VaiVF7_&zz9 ztWXz9n4V*;Fc)|n5%Sxc}f?UuXKY2N)NbyyB91}ieQma0*jSCaMeyfSfUJorOF^! zrkn=Lm3P4dyZ!;UPW=m3DDQzPmG?qb%Kt&$UH3uN%KM>hQx8Bj$_JrZ8K_)EL$j5yK&Q993e8cz2F+Ez4$V`(0nJyw3GJAA3tFIj8|qQM1NAE3g|<(< z2ko4CAL>(n0QDF9hbZMA5Uu41-3M;n3cx2xv?h35BSlpnX%(P^c;f3RA^G7q7-a0Z%;Sok)O= z-AshECz7CPPcn4ZlL7@jsZh8o4LW%!9g0w8K#{6UC`y$DMXRzQ;ZhD1qsoP1Re8|W z-T6?QssM^t6+-8)6+!FH6+;QC5-3qs3N7=NK})^m(3*V}&_A9^=*HP9C`nZfC97(n z6jd#>!dnMjIZ_X$sv02k_C_d8)da0O-wdtvwm{3httS*p3vD(^gKwfAqxaeO|Mty%!(sCuAWRWFpM z>VxuC{m=&QLa0DB03Fz|2r5(!LbjWWp(53PD1XNgwB9=mZSsyl#VP5LPbE8DiW$vQBbvthAtmtptYx1s7A#>wJIK}Q;kCPsxhcR zwG?VpErYgrmqS~3R)gEY$YA-ZbwGZ0k-4D%E z9f0Pm4nhl5hoBzSVW?Mi1nN^Ah5A+F&_dNQXh3xw`Y%8O4XRE;i&YcQ>20T=C92cV zwX0{K^JmUNL#lI-aO6C6>&69W%ax1J;iH$JVbx{GaqtQ>qPhwJs%sFax(-3A8xX9z z2_dRm5URQjVX8?8S4}~L>JGGSj|?JJa)?qXAX=q_7?lcQRceS+X&_#ug+^66XiTMt zLevH*RBeR9)FvogZH6M$7AR6}g`(6pC|YfYV$=c@t9C$fY9|!0c0mbhHc`OsM~WN%fyFrTz=1)gdsW4ux5D7|f}|VO|{pkE$c#F?AFiqKSq> zH8F6QCKe9Y#K94ocsNp%07q#O;b=_~9HU8wV>KyooF)~H*QCJ-nshi(lL04bGT~%R z7M!BVhEp{;aGE9;PS@nY8Jc`JQ&RwEX$s+NO%a@UH8pUVrWP*O)WH>+dbm>409R=m;c872T%&1*Yc(x!ou(D8*R;V6 zni+7TrXBVj=zyCvGvQ`UC)}dxf?GA+aGPcpJVP@ZZr99#J2Z3QnVNZUr{-_COEVwt z)+~T$X?oz4)cO7Q*v21MmXPBDhC02={6h!+n}1aKB~YQ|tnvlON^%V0*c9A-5uU{13V<~6I}QO#<2OtS_K(XNF$8?Rq#|y8({S zZiFMXo8Sp?GaRMe0!M4N!ZF%yaIAJa9H-p@$7^@O3EEw7qINf&q}>B2Yxlw_+I?`U zc0Zh^JpiX`55gJRLvW_{Fr1}50%vQF!a3S;I9GcN&eI-;^R*}70_{n-P&)w^X-~nY z#M5xG_6%I2Jqwp=&%tHd^KiNL0$icJ2v=$^!ByJJaJBXdT%)}T*J`i9b=vE2z4iv& zpuGt0S{=M@FJ}X9@M(w z#aa)%MC*lzv?4sLmEaMr4+gY;7}N$}NE?J3%kZ9erNQ~||Bv$u45~q6siPyb|Bq3wYT_`eB7lw4|!jUdr1k$aGL}uxt zklDIuWR5NdnX8LM=IP>)`MP*yfi3~*(Iq0ix+J7emyGo5QjmqZRAfMxhAh&hBZImO zWU($2S)$8AhIHA;ur3D~(d8n5E)M~9`3R&dKww=Vg6N76R9B2(x)KD}l_G?$3?X&p z2&Jn)Xk8`3=&BG_SB-GG8id!?BBQ!G09f{F*AhG(HNSwYCiPv`_3Hoj%Q9lbw($7Yc^>dIE{ahqfKMzUM|Ba;U z=OY>V1xTj82g%a+BH8*rBuC$m!$_%q z1S!)4$T<;2%JmRZp@)%5J%Uu}QKVXrAvJm&snrumot{MM^%T;er;$cIgEZ+`q*>1) zEqWel)sG@=`Y~jNekszfUxsw(mm@RvE09k8N~BA_3hCCbMrP^PAhY#rkvaNx$Xxw; zWS)KlGGD(DS)kv9^yoJuz4|RkpMERSuiu9JSB^pk^gED6`klz2eiyP>zZ+Si--8V4 z_aejkeaMJ@KLY3vAfWyr0_hJSu>LTD=#L<%{wRX!#}QnA3?cN#5mJ8wq4XyaT0em> z`cnw2KaFtuGss!-EW+#0A*1^9$e8{D5@NWBgc>d(VTQ{{xZw&CVYrG!8m=KxhU-YQ z;Ra%oZXz*;TS%wxAO!|1QfROtMFu-kY!HwVg99lwIFT}g3n@3a zkqUzcsWf6!v`o~_z)!xAEA`tW0W?0f-;6r zQP%Jo${9XKdBYdzsNqX=%Ba~&!x)KX z8l%uGV>Fs=j6rjZv1qO_4$U*hqxr@Jw7{5%78;Y#B4aXIY)nB*jHzg;F%2y6jn!zUu?Foj)}r0UI&_w?9=#woptFsQ=p17cI@j2Y&NH^4 z^Np?O0%IH6W1NBZ8r#u6V+Y!AoQW`bobl5l# z9Wnlm0>=3$Xk36o#vT+l_M(Wf4@Hgr=yCf(^n`r?J!xNrTCNYGD|RhLPuZ8C6ZRqW zw0#&oV;@0RP5|gxJBXgMLnvm1(Ji|XRNRT8=j|AJ(T=0Ikw7olNt7^B=*c}addbe9 zm+dTi#m=EqyLfcd_EGfejWP7(@uld_t;^6GdzPbD?JLl0_Lb=2Ypc-f6RXkSp*863 z3v1Esd)J{i?Ca6%_6_JQ`$qJpeG|I!#AfuieG58i-->RU*oIEox1*aUcA$6cJJHqK zcA+x+Zd7jHgDUKMQKfw!sUAqZgDwxrK>=tyHU`4%qY-r$^9bGO6 z=nBDsjvsWQhp)I$|28+eQt+Uw1TVT;5K-S130))j(7QMM=vpCwo;w*tdE+#?PPmJ% z7ydza9Q_yFAl!omF5Zjz&i)VEB;1E>6z<0Y+aJJudmqF$3lCvigoiQprAM%>!lT$W z;W13V`*G~>r6;iM!jsqz;VEpV@HFN;^$eyw_bj$ccn;ewJdf=WUcmMWFJk+ImoVk^ zm$CiAE0}G^tJu0@uVDv-*RfIK8`weNP3(~H7Is*88yhpegWbLGE_OtC4^xi6kL}s< z0k-SrhnV-^M_7pIV{GE$C)hFJQ|zel88$9_jvW`iz*g`25}Q8o6{bG)HFoaUH`oc` zTkNFp9TsZ(9-9z;z%B|uVyA?ku+zfN*css$Y<%KZ%qjeao!|94c2@WU3p4$RofH1T z&I=*f$z7q?p<`j#1tA;@H$`BVgh=eN5QSY4qA}O?7%ajRi(M7sFzI+a7HLYrt_g{l z?|2e+T}Z}m2q~C$PbwyDNyBam>DVnH1G_C`Vo|0nY*NU^ri2{qj*yGVggh+Tl#j`U z0&M4@LQEwTVG5xbQwk+mjHwh;3uTx_D96qpt-!QGC8iUqFuhQX8H5_lDAZymp$;<( z^_WFyz^pXSc0hwOEh(3 zNv2s?vS~J!Vw!`cn&x6@rg>Pp>2GYs_W4+bX#tjL>cO&1y;!!X56dz2W4We1HLCVOC+8W;K>&)?nFYEtX@}VYy~KmS;9#`DP<_;+P3Lp)q4ePg}5) z8Y@;{wqe(|+Oabi1Z?{b2j)8E#3nQ@?9xRyc1q*Hvc+-Jb)j+_8@*y z^AKKSei*-`c?3Uu`BD6`<}v(==5hS0<_Y|o=1Kg<<)`rLny2yLwrBADN1nxRXr9B1 z&ClcOkGz22)Vzq_(!7M<*1U|Dm|wvsHLv1Rn%D4B^XvHTJ#XOZ$v5#b^IQ1UU2o&% z=67)I#BUz_32!m~jJKM9!Q0Hg;xo*@ z;l`W4ot7`INA;0w*A_?}&5_`Yl9_<*?r zzq`E>Uu3Sr2hG*EZL$VGeXSP1ez6YMoT$ean;UTZWFx-B+=LIAoAF_D3qE3Q#Q}30 zE=Se95c_waq~Q!F#nB{=J_~f zUVzi)9-J}v;;gw3=gj@M;p#$s>G%N7n-}5E$w7S7yci!dFTr(Zhwu=~Fz)*AogHcc zaQ#^j|K|#Xhgo1e+=Ac{78LjF!SF~6jz?Jt+&xL+o3~K-u8TAtZDH^j3yWX8&f&2Z z9*?t(;_;R-Ji)RQPqZwrRaXSsqO6R+a+mTP!} z`~>+{BwKxA11mZM?-YiMLv&@HWdGe1=7aw_D_Rhed(Uv?%ctq6+V{sPQg~ z2Jg0L@mUrfKHH+l=U5E*T#FGmUp3*YMKiwkvIU=KvEuVBHhh7_j`vsue68rfdo519 z&*H-SEpB{`=)o6Sy!e1c#5G4H{N@oKzR2Romu(H;gO(t^*fNbTvE0RnEdSuP3;*K7 zmU{@}rF)6>;{S*d%Y6i3xt|a(K0tt$2Z?p!Lxkh{!^8&h5n}JLM+wOC7y(-zClJdM zglGSg#3u16Vx#ypfm)s+Fw3(9Zh4N7AAg=8EH4nGV=6YI{tLGYG0i31nkB1SE56JwTlh!E?$M5y&WBFy?e5pMl}h_HT0L|Q*0qO2bi z(bi9h80)9RX7Mv3*7`XSXZ?cMB7RB4TfZU_tX~sb#czm2>$k+N@$ZNv>-R*m^#>xw z`XiBQ{fS7k{!Cok@(bZV@hg#T{f)@5{!V0C{~)rge-hiozldyW2$5qAC33A{M4mOA z$hSri1=dKS&>BS)S)++!YYb6hjU`I0aYUIlo+!5_5Ea%$qSBf~R9TaWYHJEnV@)M$ zt!adEBAr+zW)OAOOrqYJMeI40O*B|@h(>EJvF%VE(PYghbUO=(W@{nQVl5&jb{7+^ z))M0I;Zowtu`)t`tej}GRuD6+mBhJQRYbeBn&`0B5Hqc{gs`WM=(N@oUDgJo+uBIX zvNjR3tg+Dgo`wh{BKGYJ2|c4Fn_4q}0ICUI#?C(&c=B6_XeM4xpQ(Qlni zEVRxcwn%e{0qZbcS~+6O$`c{BQ6khfMqE6!lnApeBf@RViQUo)BEq(kh_tODqHL>) zXxkbh#*v=4@wzEW)?Ho~UJ5SWuE)cc0i$tC65>aov zOf=Z85RJC0M3e0r(QLa;wAgMCt+ty)o9z}c!*-i!w@nfqwkcw!?GDjtlM!7uInixX z5VLGbVzy01%(1D7xi$?k&!#2j+jPVNo1R#4!9bipWh8oRCSv_QGqJ~LA@&-r#6F{q z7(ZkudTj#HXLAt!HYc&r<{}1cZo+fLLoBj+iHp}n;?`-27_|9_#Wp{FDHZhwx9us=^m+Fu}}>@Skh_Ls;Q z`^#jk{S`9K{wf)7e~nDAzfLCF-yoChZ<5LOx5yOx+hnT!9Wu@SE}3qBkIb;YPiERb zAhYZrlG*l;$Q=8}WUl=aGSB`gnQ#A$EUFG| zZvT#~uzych+J7Lc>_3v#_MgZa`_E*p{TH&%{wrB;|BY<0|4ugA{~(*}f0E7izsMGQ z2-#{6CEM&_@j4wJ(iqhk0WQ>QOp0`?*jv=@_*y@Z7Ar6gi6BT;)fiPzhNSJaBxA25S$jRn z*&9gS-bjwxo5(SHGZ`YZkfA~=878!m;ld0uLTD!=g${E2m6_zqU7e(PqKlk%c9Zst zv&ijdXOosob4bB3m;6s*L!RCHH+g&4eDbby0jb^6L!LX^Oa9~RBUfDOCpV5SB&|mW z$m1s$ky{T9l1p9xRo4zIA)|yLa+zzGT<#hnqXmFm;R4BHS0HldNtlcg5OU%?O0INa zWUPRbTdxx2iNhqRK1Y#p0!^-RG306&OJ2Xsk@j6YxyCh0u62!(ik(Zzb*^RPde?F? zURXg+Z(B)jaIGRYx>l2`Ppu&ngtcU%u#QX;)|1J?1~Nt1NTv##$TVRynJ#Q0GlZ>V zrm&6761J1s!VWS=*h%IJyU09YH<>T&Aq#}PWTCK+EE4vU#liuyL^w#63Wvxt;V@Y) z93d-&qhzHpPF4xW$ZFv@StFbvYlV|!oiIVx3#Z5i;WXJOoFSWpvt+Yyj%*RmldZx9 z(y;p?*(O{fX9$Z{;eLt}9-w&PL26WZh#C_fra~N# zP@#@TsW8W5RJh}DD#GyubxC@XigY|hMLC|P&To5$igr9p#W52$>{hg5;%BdXBxF;(RFgerD?N|iW1qe>m0Q)P}XsB*`b)Me=_s>1O#Rq6PK zs&afwRXe_;Y8>BFwT>UCI>(Pxz2hgU!SOTI==g0<1v!c+*ilR&juHxWlv0?ZjKUq|)P8jZMK~&{We2J#(oszvP}fig)wR?i zbscqBT~8fRH&92_jnv-VO;qqoGqvJi3w7a4E46ZK8#Qru21PmAsd04&HN9&lb^KH( zbxhqw(T;A4am=Dl9h^Uk9B_?r@U&8PmGo~Ldf@1b}{FE#4uqfV;( zsmY5ADcRluYC^q;T6$!V8gneBPN|nr;d+sq+9;<~&H1 zI}cG6&cjrt^9WVtJW5qN$Eh0UF{;*ioT_u4pz56`sRri+)#yA$H91dH&CWAai}Nhi z>O4oaInPrwoENBe=S8Z+d5N0oyi9dEuTWjit5mo18a2y#oto{uLCtaAq~T%wodYv+=&nc(+oeFB9Q%MatRn#JZ>Z z#XEh}sMAl4IRjLPD@cX9rl~O3T`Ju54;A71mx^@VLr1yprK4T{qhnn6(Xp=k={VN| zbiC_9I>Gf2o#=X)PI5g$C%Yb{Q(TYHsjkQAG}jY!y6Z_g!}S!M>3W*Zay>(5yPlqWZ2^%7m^dYLYAy+RkeUZqQ1uhFHh*Xc6X8+5trO}fJM7G3Fj zo33)bLsz@rrE6U8(Y3Dk={na3biM0Cy214k-RSz5ZgPD>H@iNiTU?*ft*+1MHrE&Q z4A+-*yXz~u!}T>i)AbGA>H3!La(zd4yS}GqxqhH$yMCnSxPGGNx_+kTxqhMNyMCn? zxPGI1T))%3u0QBL*PnF1>o0ntD})|!h0=>$Vf3IYoL=mTpqIEJ=^3DY) zo#3vf6Wuj*lDn2pcGuAHTLqX_dZ z-$UESd+Bs{AARUxKW)@6r1j$i^y+GCk0=^ml8+yK4u zFi2bU5G|a9X{#QgZF-c>c4Kso8>j7hg5G$Nqy;@i=elWn^=XE7=vmsS=V+Inr}yec zX}5li_UM<=>hWc?SHGMV^($!Ojg_>dUq$D+SJOWI8hT>yS~}mojxKPorwiR1=py$< zy4bymE^%+BOWj-O{nA!?pR|oGb8n~1-8<+C_fERfy^B61?WPY%d+4S6_R>}Eee_{z zKV9uUKp&9~(lzcwbgla^UFSYRk4s1CqtZBiTslVAyN}Zi?i2Je=_K9go}ioDr|4$) zX}ZOIhHiDArB6ub=#$cUy3Kuop5eYox4SRV9q!BYgmi_T>Ap%E&t9WD-Ph?Z_YJz+ zeUqN$zC|nc+@@!{C+RuvDSEE^4n5B;qvyNj^a8hnz9uQ@9=D3VE~)8Ww}$R>Yw3Qs zj$Y{2(>EjoJ>WLdi`*u9&~2s{yDjuB$x1JA+vrKjP7k>S`ljTdhuuzk#Or9&G4JO_5 zCX?ZLi&02#Gnt-um@Ln`Ot$AeMk&3|WOB~NHNSgDV8}a#W8K3cxHwtfob<7GUufvro)rW?7NV{%=Dx(7o;?%)0570c`}&Q z$1|C3PZl%Flg-TbA}Fbh0|Opm9C>Gc#deV!7g-&4vg^pr6J zo^oc9r-B*uR5FV_Rm>7kH8bR?VTL`m%!sFs0X+2#=xJaePa^|+ni#~>%%GkY2J^Hs zxTlRFJTn;5)6P(y4u|POXErnDnZtzqr-u#o&SS#7e>36U z`Amd&0Tb!%VWPafOtiO;iShO`vEGGDoOghU_by@*yn{@lcQKRXUBV=LhnN)aFq7&X zVbZ(+lkNqX3@^lFdSNEZi!j+Vy_=Xe?`CF(cMH?*-O6-$w=pxl+nG-94yMbylj-*EVrF@FGqb&Wm^t3P z%v|q2W}bIHGv9lFS>Qd$^mq?3z23u2pZ5sU?>)*a^o}zF-eb%n?{Q|(dxBZ)J;^Nb zPB25>Q_QgUG&ABo!vNm14Cp<_K;H8V?7hGs-ir+Cy~JSN%gle!nIXJa8Pa==p}f}_ z+Ixdxyf+!vdyC<`w;A3$$&7lZm@)4iCPb7mp`x4#6BSIjsAM8U6%#3{nJ7`iM2lJ` zM$|E}qMnHp4NSafWD-OZlPH>*B+g@p-mOe1Yv2Uu0*AFR`=5m)SYuE9_kHRd$~E8arQnon0Wl!S;x6 zvc2M4Y@hfx+b_PuE)?Ho2gLW-MdJJHp!fm1Sp1M(B7VdUi667W;wS8g_$dpBpRu6$ zISYwju(0?gi-=#bsQ5LDiQlle_$^C_-?60lJxhr{u(bFi%ZNX*toSp_iNCPC_$xaq z{>F}pzq29IA8e@fCmSaH#fD2EY=jibMoM99loZZJOA&006v@U)QEZ$P&BjYHY=RWa zCQ5N^k`&J-O9^a>l*pz^No<;w%%)2zY=)G|W=d&nmXywBOBrmAl*#5wS!|w^&E`uv zY=M-^7D{<+k(AFCO9gC+RLGV}MQoW=%$7?fY=uCRg%+8Qn*mkLv?U35onbHilQ)*|sqz<-Q zn#sb#9p>f z>SOz*e)h7ski8-fuvf)J>@{(aT_`PP2c-XIQp6#4ku=P%-#WtH6ajWn0@+(4#NHNR zc2Y#x#S+R+i5PoF#Mvbh!463zJ1kM`h(xn8kzwT`%bvN&v4F(03UQQGies!wT*|7& zWvoVA&T7RKtmDW^Rwu4v_2O#QAg*DJ;#$@uu46%IJ!=*>u#mKowTPQotGJnkr7f&Y z+{)U;ZLA<}XC2~>|4!eXtV`U*y2ahBN8H1%IkcBWqQ0ag+ZvOe(;i%N%C zOgh5i(ovR>##vH2#s*FuXZ_*{HXxp4gW?1`EuLa2=`>4AXV|;qS@s|C9J^FH&n}ZL zu*;>3>V_c2zajw?)1Xt&KlB@SU#Wnbz<{Ev^a815vxn|#UT#N5{uGRMf z*XDbXo8fzjYxlj(b@*Q4X8K;`I(@HkUB1`3Zr>Z+EZ>{lY~Nel9N*jAT;Ds~Jm0(A zeBXQA0^j>wkM9Gn*Y_dU=lh83_kGMQ^nJn&_&((p`99+YeV=oSeP3`(d|z@yzOT4p z-`CuT?;8&AeanHq?>NZ!JqP=K;1J)B9P0at!+bw;xbGK^@cqh>zTY^?_d7@X{@@tj zpB(G^i{pGD9PbO|Mtx!2m@k|Q@kel>{zxv&AH{|Hqqzuw3>WE-<)Zv?T(m!)i}5FL zvHnCZ&Y#4^`;)l@e+rlAPvw&QXCfe|{CQlq zKcCC-7jU`$LN3o=#O3>oxdML)SLiS0iu`3)v@mFxA{z|UQU&WRCtGNn)4Oi)} z<*NL3T(!TRtMNB*wf;t~&fmn<`>Z{?c&ZCtZ|2G`BDj*v(}G_Hdbjy`=1zzMD_aFQzzOmG!}Q(R@>G*=Zk!&L{)ay5Z-Ty5Yy zR~NXz)dwze4S`EsW8gB^6u81Q2d;80fooiA;5ye9xWUZ`+~nE=x44eLZEj{@lIsji zab1BsTz5dm%?il5*#QMNC!pl!22|XXk8@D82=Y|3THym(qBLOD|1Y8^#aC85aR5&=`<&c2Lp#h1*0zM88 z_&FjF;K)FbqXN?$9k|OefqytQ@Gr*&?&0~sz5Hn4fBabBK0YLPKOY)=fDa2k$cG0X z;v<3&^O3DT<8ywe;|u=46j@k-}F7Q~6VlG`=dB&Q}LB_?loQf7+47*9Nos zGmaeopp?tk1@ri`j(q-{qkuo}DCFydMf?RvG2aj@;Twacd{eNDZw{987abM+&3%=8 zOR$Q+HF6Zgs3Z4nBvqx zb-YK?^VQP^-YpsVnrRd7lFYnUvhcOjR=#f9_J4-%g3W2H4FmA%x9;xlzN{y|H; zEvzh+bgoG&p#Om`KN+K zl}`s^{+VEL<+DNg?B@b0|9r4`?+byPe=$(-y&S0dR{|~nYM|#|3l{8sJuvcb z1k(<_8JPLE0xSP^VCUZnocz0in}09x^6v*X)_)NA`45BJw?7K9`HzGC`A>oY`A>s^ z`Oktu`OkyF`7eSY`7eW^`LBXu`LBaJx4#L7=f4fg^4|q_Z+{;I`5%H2`5%Mog=#^K z!cRfX!p}ji!Y@JX!mq)-+rI^M3cm+cxBm$07XA#@O#3USSNJ=~-~J~k-2OMHU#K25 zDAWiV7HS5K3blg9h1x;!cAcO}p>7Z=)CePF(giAD z3W*?7NCr&{bkMAj3Yr(vL5l(tv@B$TR)wZP>q4`jO`&`qn=ooY_bP9SDItM)qU4mYPu0iiYx1djGx`NHD%n6PaDiOlgPD~=aB`U#%&L@v*_CoIr&0;# zR;t0gN-daQsRy~WMzEmL43vTus0BOF3QnLG+`uS!fm!eatB?)sLjS-i3<%u9z`!dE z3jD(0plaEWVBEZ+!P!g0f^1=U(7#X?3@8M_`FSIPBl|`M0}G>qL4{l}xG*{xQWz5q zEqr}a%$e7~we@q?;{#gD2Q6+fPx6N%8ZlQ1OeZaPj+MyyA!A_3~=Po8>X^)DxhNL3b@#%0xfo}z>3`}@M8B0qS&K?EcUFRioGfl#oiUkVxJ1S z*ta58>{pR4vK35`tH>1jil#-OqIprQXi=0ZS{CJsRz;=a!P3awL#0ud#p4z_jqYs?uk-G?#a^l+*73qxu;7LbI+6}<(@4~&OKL}l6$^1HTObk zTJFWt^xR9O8M&8BGjp$$X60Tj&Cb16nv;9IG&lD~XL1|g;!_xBHN2L|Hk4r0apOjYRJ}s@zeO6kN`@FO^_eE)4?#t5p z+*hRyxvxtbbKjIU<-RR#&V5(flKZ~2HTOelTkglw_FT2nj@(bBow=V&yK=vjcISRA z?aBRC+MD~mv@iEZX@Bm|(t+GxrGvS@ONVm*ln&?qEgi{KFCER*C>_hyEFI6)DxJvH zE}hKPDV@sIEuGHQE1k*JFP+UbD4okSES=9aDqYAmE?vwuDP78iN|$rt(v=)gx|)lW zuI0ee^<1=cBNr>(%*9K$a!{!<2bXT=kkXwTTDqIVN>w?$bT3Dg@;S0p$Wf&UBafEO zjXYL5Kk|49syI<9=1!L2ic_W0xd-l_eh*B1zdHL+s0RB;s3!Yps22ObP;K_PP#yNg zP+j)5P(Aj&P<{6OPy_aZP(${kP$Tx!P-FIsP!smsP>B656lQ-20c^EUg#9@LvcHC+ z>|dc6TRjwKYlI-SW(a0$hY+@I2xS|FFg6mx*?5Rx;SkAUA&SLA2{siY`0K* zwtJ`p+auJG?HTIC_6l`odxyHPeL`K?|3cl^exdFx8|uMwp`I)s>ctA7-mDnv!^)w) ztQP9WIw6)F5aQT@A)Xx^64+rOksThA*s_q!=0XZPKBTf!LK-_Yq_fjP20Jrkva>@L zJ11nbb3+b0FXXZdLms;*^uiWFHDoVjm7qW*-SpVIK`oW&anR#y%FF&ORQV!9Eq9$vz#P#l9Gx&At?# z!@eAz%f1qx$G#e#&%PaAz`he+$bJxB#C{ZB%zhqT!hR86%6=VQ#(ooC&VCzS!Tu0l z$yN)mVt)>=W`7N@VSf*=W&aGXWB&=SXa5avV5^5WvNgh+*qY(ZZ0+zCwoZ5}TQ9tg ztsmabHVE%v8-{nXjl#Rw#^K#87~aFi!h2aLypN^B``J|Z0NXTtkZm45#I_6{W?O}i zux-Le*|y3WmXPfVYTp8)(Br?t?+f$3EyD7@J-ea-(vfRE7<|z+w7q59d>Z|E;}S##SRPK ze>jHo?EOoU9T_gNqr%m>(cv20gm6u6Qn(g3HC&sU7Oulh57*^pgzIrL!}Yn@;Rf8C za6@ixxDhum+?bmmZo(}Hhq#5|Ft;cSaErqcZfO|gmW89-@^Fk>9gcHr!VtGM40G$k z2)7}OavQ@Kw<(Ns+rtF6BTRBT!xXnGoZxnclia>A%^e7*xTE1TcRb8+C&L-;RJbX3 zCftm>5N^(047cE}hFfyi!>zcR;nv)(a2u{N+?Kl?ZpYmXx99GKJ8=1MN3Ia=#FfIG zxd(tQ+=D<@?jfKX_b||%dj#mgJqq;X{s;8p9s_!Fj{|+UCxE`(lR!W2DS+jk1vu_` zfahKS1nwn3H`%KZ)u0JHGq*^O<)vP8_02WfYDrCU<}s)DCZgiW4T7aIIam$!2!T{E&@#8Kwu&l1txJZ zU@`{*Q#cry$|1ls4h5!jI52}Fftefy%;FNjY%U4R;b>qkmjdQ-X<$Cb01LRLz(TGW zu!w68EaqAOOSqQ6Qmz%SjB5id=h^}*xOTuwu061d>j13gIs$9BPQY5OGq8^90<7n{ z0~@#=z(%eou!-vpZ07m^TR0Zj%5lIpjt91L0Uyj%ZY*e1*O0~ z&I0yxHgJG*fPkk~`1^~yofxroF5O9(k44mSI0H?X3z!`2B zaF!bmoa4%X^IQO2;6?x!xskvnZWM5t8x36H%7Lrgc;Fg00l3ah0&Z}Vft%bE;1)L( zsN|*rx49X>9d0IYmzxDtakGJY+#Dd!%>@eFJfO%e1gi6kfExT_peDZrsKqY@YV*s0 zI{b2=F24e($FBtH^Q(Xc{A!>fzXoW;uLTwqTwdLYDa0K)u60N^(P5q>iO@>_u@ zzYU1-+krU01AzFQ0L=<%>W!z65mVABgneAB^PhMLpqSQ=0AxH;XjQG zs|SBs3} ze~MJ_KS##%zeFbRzeXnVzeOhTzegtXe?+G6e@3SAe?_M8e@CYC|3qf+H6t_mdXZUt z!^mvDabyl3ip=H1k$F52na_if1$;EJkcT6ScqFozMNH;t_2n?=^~Eh6jrmXQs7yU0eqV`LNGGqRcQ8`;AD7um}5k!`#X z+0ILm9lRXb$=@%}=k>^L-iqwu?Z{ru1ei_{eMM`{TNBejLYkvhVWNL}H0q@HjhQeQX~X&{`A zG!)K68VP43jfHcOCc^nhNVpgY3zs8+a4ixMu17%OW+W=yj>LpwBrZGxLc*gUEIa`s z!c!nBJPl&Pb097}4-&#lASt{IQo<`>LUm%L8uLO6zYJTgt}m7 zp&r;ps1J4(8i3t|Mqqa#1ojZZU{3)AdkImnw-5*W2r$@JK)`+i3bFzQasm$W0tpI2 z0u+TLCXh8?Z2nJX#nBZ8!0>=q9SRuIJc)x&63;-t!1Hmc6AaJTM7@Q^y z0jCSYz!}15aHcQ@oF$ZlvxTwX9APpzSC|6M6Q+Xmg_+<2VHUVhm<=ux=75WZx!@9E z9=KGP4=xiHfXju2;0j?8xKdaOt`e4ktA*v@8et{4R#*kD6IO%kg|*-YVLiA}*a&VC zHi4Uk&EOVc3%FI-25u8}fZK(g;0|FIxKr2z?h^KayM_JW9^nAES2zgn6Appgg=^pi;W~IxxB*@gZi1JETi_L;61*zh2CoTs!0W<2@P?2FZwdwQmhfP-Qg|qO zTX;BnM|dQ9S9mO1B|H(mCp;O=3r|H0!qd^B@NBfY_(HUX_+qrC_)@f%_;R$i_u5y$CJKt* zMWf>P(U|x{G%o%ag~V!6So|r9h(AYB@s}tj{u;%_-=c*0SCkb0j#6UvXhN(RO^UUn zv{*Nq5*tO+V&f3LAlg)nMVpC8w7G~zTZnkHrAS6wiJ53?v3azO*fQEyY#nVU zwu!bEJ4QQ*U85bv9??!>uV`nnceIPxC)!o)8|^0ci*^^;Xb+K(_7vr4FHwp17PV*} z(TesJ?Px#IiL#;_S+!389?ut$l_eUp-2cuKOL(!??;pjB+SaiC0JUT->6P+pEjLs6PqO-+f zbdFex&J`bs%@ZGr%@-eyEf61zEfk-MEfQajEf!yoEfL>{EfwF4Efe34Ef+tGtq?zs ztrS0rtrEYCtrowJtr4rm){4Kx)``Ey){B3{Hi&=6Hj4koHiyu}aa6-4^}W9dTgnt~e-GB@T<- z9|Xtp;{Ab_I3iXQN5-m4qhd9rF|nG`FG%Bi>DVGu~Z#JKjTjC*D(fH{MHnFWy`FAl^s%B;Hs0G~Q48JkCmA z#5w7!I4^w@7o;EKqV!W-l75cM(l2pE`Yo!cwp1tX zNcG~bR6p)XjpDx4IG&Z7#QRI3_y8#!A1FoQgCsCMSc=AnNU``(362kwkoa&3jh9JS zJdp7C2#Ji3l&JV9DG|>}$@pj~6(1v|*GhI4e?{r=J;`GOZd4PSb>$bJdh&}%L#Vyn2Db&?}cXBmXL$Wf@P9EZBe5Y%19 zpdK;~^^{4dmrOyunoZJ-R8ZXoT!SBV`X7C1;_W+#eb(4}iwV1EF$x5HwaE z42_eAKo#;(XuLcOnjjB{Cdy^dBsqX4%OjvE@GfV>?#DDQv{$-AJ#@^0ve zycaqu?}LuX2chHg3Fw4;3OXsDhEB<6pwseM=!|?0IxC-t&dC>{^Y-hk^XZ^8|f zx8R1#J8&cAUAVFGKHNn401hc1!eQlO7*IZeBg&^RsC))Tm9OBK@&g=KeuN?ACm2?K zh7si#7*&3SG37THSN?(tm6Gy2Cw`9&k^kC)`Wv1NT43@+h)Pc^uiTJb~;{o<#O4Pb2%3XOaEN zbI1YZdE}t-B63K12|291j2uy3MUE=3A;*;0k>kpn$O+{wugG2HH>67W9l59cf#j7xk%ICUQdIs%s;mDXHPnBRnrd~VmRbX; zt=2^9sI`!~Y8|AWS{JFW)C9C>8=V$4^={Xsxs0`Rgm7QhV)T&q_1iq{ZtcS zRSV%%8{t(45mXlu)hr^Z{SjFmfGFxfL{$eNnmQEG)nSOC4o6IN1Y)Tp5nCOFIBE`Y z)zOHjjzN629LcIU5+`oq+`E zOk{*Q3mK`-MnJntUx)hn9E=MM+E09U* zN@TLS8kwT5L8hu}k!k8WWV*T@nW1h#W~v*JS?VTawz?Uaqi#Xws#}qH>ULzlx&v9D z?nD-hLa z>Ir1MdJ5T~o<=sRXOK`<>GJJp-WF7+0&TfL3! zQSTso)hcA4dJoyJ=8*$x0lDviB8Suxa#(!;J)%B{9#tPkkExHM$JPI#C)CH$lj;-b zDfLP8wE7f!MtvGRt3HdKQ=doAt1qAz)ECi<>PzS)^)>Xe`Z{_=eG9#+zJp#<-$k#h z@1r-=573+Hhv+T!BeYWe6uqr}j^0tfM(?WMqgCpU=smR>npb~D3+gXuQT-FGuKkVH z(EdSdYX73OwCZSWtrl8GtAp0n>Z0|uhG>1QG1@?Df;Q9uw2=m)jkPG+L_^V#hNEGP zKmmUnxm-J0>!kJD6X|a39U6sYHd(TYl|kd zc4$&-kJ4HPG^KS!(^?ml(Ym1-ttZ-4>xDMcdZW#?zGw^WKeVOR4{fE1XlqSH+h{u4 zRx{9cnuWI4Y_x;spdB?Ay>DTn_bp7ci#7=DstrNAX+zQO+Ay?-HXQA#1!ymA1ln60 ziT2S(p?$S-w4XK>WwnVYr%gh6Z7M2g(@;^HflAs;RMuvpiZ&ZnwK=G!%|&%>K5A$S zQBzxlTG|rS)|R4+1GKg1Ky4j5NZW`G);6I-w9V*H zZ3{X~+l3C-cB5t5J~Yq{pd+-y=t%7dI!Zf==CotzXze&UMmvd?Yp2n%+8K15b`Gu3 z&ZFbC3+M#x5<2mItay@k1)Z#2MW<-j(5c#WbeeVpovz(PXK1(3nOY?}OS_HE*6yHl zv?_G2mPhAl1$4evL>FieU<D;^wp4o-Tc$mSE!UpMR%kC`E47!g zRoW}qYVB2QjrJP0R(k_mr@e`-*WSW5XzySfwRf>i+6UNX?L%yf_A$0q`xM)zeTHq< zKF4-wUt&A8udrR(*Vu0D8*GpEEw)$t4%?@FkL}m0VF$FIv4h&L*dgsV?6CGbc0~IF zJF5MO9n=2Cj%)v5C$xXDlUfbzlvWcvt<}QLXtlAkS{>}1Ru4O`)yFPqjj)SaW9*XF z1iP$-uq#>^yQ%@$H7$Z&*Ffxs7R7FAG3=HGVU-$;-PRE7j)r1)H5{wb2<)ClVtI|i z3R(gyYDuiRPGdFnG*(k*uv&TstF1T1>gdg}x_S$&p56+pueZh;=xwludRwfK-VST5 zx5t|39k7tz5ew^`FhK8)Mf4sRsQ1F6dT%VI_rcEp28dIi=;pMdq%Cu05dNf@h7#yEWn#_LltL7#?+`bkBbMUxb>Vg z8?0}^hUi~Pw0c@0h2+Qe*vC;YwY>a*!E7wnA zWA#(mIQ*uiv`bBJ_ehHg&KTbbczk*HCuVPd6>)15?1~y&4iOtY&VKeng zY?gi-o2}o$=ID2^xq1~gPrrxF*Ynr{y?`y$i`XK)ge}$|z?bL`;!E|1@MZeL_;URb ze1-lfzEb}mzDj=#U#&lmuhE~x*XmE<>-4Ab_4+gT2K`xlqy8MeNq-*StiOP7(O<;3 z>M!Bj^q2AN`YZSj{dIh&{sz8Fe-q!WzlHD7-^Taq@8J9Nck%uDd-wtUef*&Q0e(pT z5I?McgdfpA#*gZs;K%e&@#Feu_zC@U{G|Q`eoFrmKdpa-pV7a@&+6ac=k#y!^ZIxA z1^s*cqW%MZNw0=q)_=yY=)d4s_22Mo`tSI4{SW+x{wID@{|mpR|BYAb|KPXvfAKqd z4g9WN6R*;1;rH~~cwVoA7xcP#QLl&Jw-50eMgzR2(Gag?G{S2ejqy506TGew!s{7f zyuJbA4GaixXi#_~BZ)UQXuOHh3=bL2@vzYf2aGm&#Au6yMms!ebi`vuXFP6n#UY~` z4jbKZ#OQ&eMlT#QdgHj!7blGWaMIv#%8>Acq2Wox#A(CAQ-*`54Hst&56>7`ys0q& zZ)OB|b7L&t!Wf6QG%D~`#zefeF$r&DOvc+9Q}A}iG`zhr9q(Yw!8;oB@lM79ytAzZpI3{yRjDUVXVV@8td_1#s<8%u?g>EY{vTtf;+(My=Z)RC zVC=y~V=pcl`*7LVk1NIjTs02jnsF4@jpMjsoWM=vG;SGZaN9VCJH~n3H7?+uaS`{8 zOL*3}g7-JB;RB58_(0oS$LySs%sBu5~VHEJ;MiDPF9v}kaA!3B_Ffr12 zlo(|^M&yjgiP6SW#2DjgqTG0f7;8LBj5D4mDvTG2@y1KU1miVgqVWbX$#{#HY`jZM zG2SDl8t)U+j1P$E#z({q<5Oa$@i{Te_=1>id`ZkPz9Qxt-w^YRZ;AQFcfvC%+?O$J76HgIB#K@eLFlGtV>i0wv-*kLflPNNyI%VBXP*+L>x9c6Gx0L#8IOwam?sO95=cXCyZXiNuxJ$%IHI!Hu@50 zjDEyfgD1`z0&(6Di3^5ATr_0jlA#ip4UM>B=)_gSBCZ)WaozBU8-`EZH2M>_jNwG3 zQAXT00^*J_g1BppB&v+j#64pSkvGbTf-#mT8smuS=6IrpIhm+wP9bWUQ;FKj?jk62H<2*+5J__{L7V%DlzD(i zn+FNTJVa#7!$ec_2+_4lzF=hnk<0!^|(q z;pSIlnfWytnBS2j%t&HCglvjI8VY(ma4L*!gD zOwKa_a=sZM7nmTq(2SCc%ow@YjFU@Dh+JyI_r|jdy|LFKI9RzFL~7bk344fBafRbdBWt$ zlcqqPGDY&VDUoMPnLKMM#F|f{)&df<7LvHNh$O7VBxx-nDQhX2u$GZY zYdJ|FS1tc_$#Yctu(+CsLrwvuhEZDd<( zJK4_KLAJMck{zsFWJhZ^*~!{NcDDACU95d%S8G4n%{oYSw~mlKtfOR4>jc@$I!X4n z&Xawti)3Hx64}qXO0w21lCvsF-nv5y)?HGxsz}MYN6J>7RIC!IS`Sc~^$4X~k5Pv8 z1Z7%JQkL};Wn0fsj`b|%S}#(b^%CV<)G+IFYPj_URc3uj1=d&82nEz*`k5MQ{X&hi zey1v|KdAB6Khy;4UuvRNotk9Tpe9?js3}%mYN}O_nr79frdtiD8CFATrqzg=Wi_E@ zTOn$W6{hA|05#8wQ1dO2T3|(~g%(6DvS4blg-}Z@lv-+G)G~{pmRlsX!b(sptt7R| zN>i&XhFW7~sI^v8YMs@LT5mO{HdrmFjaEx)lhumaY_+DgSZ%1SR$FSD)sEV3wWoGi z9jKjF7iyQ)joNMXp!QgOsl66U?Xx&)zr|ArERi~BDbyiLr4CyLb;L5Mqn1S-v+m;( z)*$MHHIzDO4W~|7BdOEYDC&%rqt05RsdLsi>bzA!U9iSe7p)1@C2Jye*_upUv8GU0 zt*O*CYZ`UknoixYW>Pn;`P40I0aa-&q;6Y_s5{mY>aMkvsDjv%gO8_O}Va{yrhvKPDu* zT0*veN+|Zv3Dy23q1nGCbo;l2VgH#h?Y|S2{ZGQS|4le{jf890On7#!gm2eQWbHbM z{&wBO0J~mdpj|&P$Zn7rY&T2{u^T0Z+Km&#>?Vofb|_J1hZBJvNsO>#iIFy%7-eIL zoQ)?&+eBiFO(n|hL}IL+OpLSBi3&TD7;iUAOt70LCfcnMlkB#M$#%QM6uV<$s@*v; z&F+$zZg)-0u)8N_+C3Aq>^_OvcHhJt`@h6on@`NMrNn&OOf0ai#6sInEVA9iV%twF zv9pP#_JG7Pdq`rrJv6bx9-dffmnBx&L1MK%BC*CEl~`-%66@^IiS_oF#0I-OvC$rz z*ko5EHro>tTkMI6t@f0}HhXGfyFD$j!=9elY0pUPvS%iC+p`mU?74~izFT6SJwLJE zUXVCoFHRh^mn06^OB09fWr-v9^2AYl&3!0mZQ{7SK5@d{kT_{?PMorLBu?8q6KCvQ ziL>_p#5wyw;=Fw@alt;ExM&|qT(XZRF54#(SL{=XtM=){HT!Jhx_vHj!@iifXCvXS#%va$1FvWfFiGUR-m3_D*Z0q2`! z#Q8P}I^QRw&JW3$^J6mZR7*n6Pf6JMC5bq{CQ;|NBLfa;mc>InCLcobGH-&Tw`lXF5BRvz*<@ z+0LHi9A{s0u5%!H-!)6lca9|&ILDI}a zUHXXg0e#f@kUr*oLLYZNr%yOv&?lWQ=~K?v^l9fC`i%1}eb)JoKIeQ-pLc$sFE~Ha z7oBSKCFdvlvhy>2#rcK4>ikMybAF?*JHOL6oImKB&Y$!x=P$a_`J2A&{6pVys?&F! z8g!LYlfLKFqVrB|y5Q8Ii%wm-x?7K~;WnUax{c^sZWFq;8>Z{H0A1Gw>3VLIuJ6X^ z1};Q5bYZ%Yi_nc-ly2f;bjZc&uuIT@OVJTGL4$6Rj=D4*bJKL(WoXFF(6HN-M%)%O z>b9gYw-t@Mt!ct-Lz8Y>nsVFG3AY2CbUV_t+lfxOo$0jOm1f-TbjIyLH+6f`&D>se zbGJ9$!tF!1bo%hGLKj&A4jbbD8zJGdg<(Us^b?9EMOZRp?x{vGAeck?aKX(Alx&vv>9Ypi)U|Mj8(4sq(mfT^q z?3U4r8_=pdg4W!TwC;|g4L3)d?r7R_$I!N0PCM>++I1(;o;!*5-N|&;okI6_r_ux5 zY4kvMIz7mpK@WCk(nH)?^iX#;J9OuAdYrqOu5j1T)k8#2KOqx(Y;1*a<9{y z-5c~4_a?p7t)#cPx9RQf9eRg*m)_}C(YxGx^lmp#?{N$CUbjf^b00|UcOOh0a34w? zbRSL~avw<@b{|b0aUV+^b)QHbb6-jwcVAAOaNkIsbl*;$a^FdvcHd2%aozP8lUMbY;lfpbUg?n6z@c0zzi7CpHQVCB^B|RlYdwMG68L6~q zrWnskWjs68)N@kJylkquH#pV88f%jLb@gVXx_L8G-M!hV9^RZ(Pj7Cjmp4Dv+gqIK<1J0~^_Hdj zc`H(^w;{!OTT;BYEhTunQlfV#C3%NavUfD4c*jzzcQU1U=To|OA!T@1Q>J%4WqG$! zws$Axcz08-SC#U-dnw<0Af5FdPWSg7Ne}QIO%L?`mmcIjnI7ytl^)_fogV5vlOE5<+m=~3Qm>74g^dbIaOdW`pWy4?FTJ=XgyJX1zx@MLa%;$k=HQ2*o&l>cwl;|7fmnoV(H}`lwRS%>6IRm zUge?b)gG2!k?H%6ReFQRq&Iq*^d_%qdb8I&y~S&p-s-hVZ}VEGw|ni< zJG}PkonFWEF0WI1x7Rtn$Lo^b>vd1>^LnKBd%e>KyguoJUf=W~@4xh6k4+!(`1Dav zNFVdW^l?v0pYZhbNzY85^4#=&7$|+lyAPvy_ptzPVEVi_IDNqzlD_B-O<(ecr7wHK z(^tH*^i?lNU-L$$uY04@H@x!nO>aW_mNz9`=}k-D_NJ%rc(c-Xz1it1Z(jPIw;-MO z7NrZ`l628qny&6IOV{w1r)&Bv(zX0m>DvC9bRB8Ad@bTdDn zZtfS;E&PX>mi{A5EB}8?YyUB(jsG~))_;O&=Re7`_n%=p_|GyO{TG-{{)hfe~szpzs_{`-(Y(9Z!$gocbH!OdrWWtL#B`a5!2WInCa(#!m$2l4CjB&@ctK! z;D5!4{Sr%rGBdhWinw%#SjGA7@7R5Hr$; znNdE<ZCpJ2*;k{RnKm~noRsqkrLyq{tw_-SUM&oGnx3^Unp%1rT_GgJMR z%rw6hGu>~^%<$VXGyQhVEWbT7+wZ{4@jEhe{Z7n0zcVx6@4_tbyD|&?ZpdzHN}p#|`4Y3*SC}=v%B=M@W}UAy>wSaS;G4`w-(oiT zHnZ7xm@U4~Z1uCuHh&;a}m_8?O;dx)u(J;Kz^9%brek1=(# zCzyKKQ%wEr8Kyz@EYmQ1j%k!V&os_nV47qvGNJ4xCY-&@0NE={Bzu(sv)7nt_Bs>G z-eBU{n+%k_#lYE02Fc!L(Ci%s%id-1Y!yRf?=fUH&rsO{lgJjCWVXc6*#|SJ>_eG! z_TdbZeI%2~KALHo{a>b8_OVR!?Bkgh*(WnCvrlDOWuMNp&OVcAlYKVRHv3$rUH17* z`|Jyu4%wG79kVZII%QwUbk4q->5_dd(>41>rd#&SO!w?tnI74PCEGSLHQO#TE!!b8J=-ZWBiki2 zGut&YE89IYJKG~OC)+bKH`^;SFWWmaKiem>Alo;yF#BI-QMO-ZahA<2$#R*cSw6EY zD`b{u#mtJVlv$ZoGOMy`W_4D}tjU_0wOK2(E^BAjXT8jZY&Nqo+ds1@J0P<;J1Day zJ0!C;J3RA$hVFvBZL^I6aNA_e%v+PiV^G>Ld@D0ELs|=MvE=f~%#9fB+Of=1%FN8n z%*+h?{43t;x!!Zmy`$Xp?<}|dyUHW}-Q_d=d&(>Pd&?dFzVf7he|g$}pgik8Snl}` zl~?)?m(TJaDWB~>T0X~rtbDHjc=?phkb`stPI}0CzU4)OouENJ)H{nyT zyHEu75Q@Q`!slQwp#USf~LaLQN1Aeg!e% zH!vXl4hDrkKwS6}B!s^~Quqg?gjygi)Bzcx9>@yyK~87@@S2nv;YSQt-!%TYjB9r2^=bP28Rhnu94YhwM+v>a(LxzGM(6{M75v~h z0RqPh2slAN!HEI}P7(s(WFZJn5h!q~K!ei+2AnQ%;0&Q3ST6Jj1z{j43WGpN7!1n7 zzn~%v1yx}fs0kxLT^I!#!f4PG#)6hG4zz{wU|5&{MubV=Okpw@6{dhOVJcW5Ob6q_ z4A2qE!Gs`yNkIlvf&!)m70d`4m=$y|CzzlsSfD4^V5JZSX9*E-wlEW%BSgWuLJXWI zRDkn^1h_y*f(wNdxJXEYi-iohM96_l1s7Z7AZ!H>3fsU#!glbmume0I>;#VryTD_@Zt%FU2RtF{ z1y2h5z*EA0@U(CcJR=+h&kD!DbHZ`(yl?`%Ae;m*3a7wJ!fEiba0a|0oCB{4=fP{j zMew?C3A`a(25$;iz+1vq@V0Obyd&HI?+SOod%|7tzHlFWAUp&g3Xi}?!V~bZP!)P2 zRD+%h1yC)q5UMRc1Jx0qh3bmWLG{F!q59&hPy_KbsG;}<)JS|2YAn75H4)#1nu_m3 z&BPC&=HiD?3-M#9rT8h-N~{jG7K@-ZVlmWK{2Xd0mO$-AAJjqo66z>^4RsQKfI5o+ z)J3cTbrowu-Nav@?&7ad5Aipsr}#V6OZ*e+E&c_SiT{K8i2p!+#oCZxtOtQ&eFzd8 zLa^8bLd2#JDmI5Ou?-Xu+d)CGJ%o!LAwui~kz!|v61zZj{(F}ZyF;v42618^h!^`p zArXZ7i4fFZ#GnCU02(Ob&>)e528%2-MC75NVn1k@*dH1$4uD381EG=PU}%&$6dElK zhsKB_pt0g8Xq-428ZVB8CWzyqiQ+_Pk~j&PEKY`|h*O}c;xuTQI31cU&VXi!V3OG*{dU%@g-Q^Tk8Z0`VBMP&@%G5>G*k#naFd@hr4dJO?ck&qK?_i_i-3 z60}mh0<99SLaW7_&>Ha$v{t+etrPD->&5%f2Jr#3QG5t(5+6aE#mCSV@hP-btO{=v ztHImF0(gg52=5f1g?EXsz`MoQ;XUG;@Lut4c%S$VykC4DJ|KPo9~3`?4~ZYahsBTK zBjTs$Z!k0w=z9N>wSH+*;YvRxFb@3PYhWH13Q~VRYCH@2778}BM#HR3Fu{nHCYzf~N z+rSUR4)8;uGg z4mXkrxUodSO(Y6#D$#H=iGiC-9Na?c2e*{^!>yzNaBFEG+(sG%x0MFN?W7@ad+A@e zgESQGC=G`@Nh9IT(ipglG#2hEjf1;M@H{5r!lgh9w0?Bo#&_4aOuL4oC(ZluQ_xESQjNn3TdWCC!9sDGD=E3}&SS z%t=X@mr`&@O2hr6EZkr6-~m!4JW!eq50d7>gQa=!5NSR`?SchqH!MnfVM*Et%hCZ@kq*JCbQsp8Bd{(Vg$?N#Y)U6!OF9YL(rGv> zoq;3LS$L*&4vtFa;h1y*u8=Omap@B5NSEP+bOlaI*Wi?N6HZIF;EZ$|&PsRToOBO% zrTefaJ%THxC-5xkDLh;H51u1cLFP);ka0M-v^d7QSdLLOQeSoZ&K14Q1A0Zp1kC9E% zC&*^$Q)G)&glv_Hk!{lF$acwx?2x`dc1m9&yQHs>-O|^{9_brouk=>%%Hy`R zk#kaAHHAikrEs$GMOXRlH z3b`Y-M(#>&kb6>F{Rbp^PGp*R!3GyanqPzu}ByU3|%R7)M z@=j!`ybGBo??I-^dyyIPKBQdUj|lPsM3fIAl6)AEiLR61Lf6Z0 zqZ{OR(2erD=qC9CbhG>+x<&p7-70^KZj(Pjx67ZRJLKx*oPW}r$FaLvHkZYkA<=W^axej_+u8Urg>!VlY2Iw`p5qe#2jNXu& zpf}~F=q+{R;n7Y?2<@!&L%S#g(5}irw3{**?XC<# zdno^+J(Xc-FJ(B|TN#0tDWlLn%4oE&G6wZ4V^L5UheFDD6jmmnh%ymHl}RY3OhE(6 zbTp{UKyjrUB@_WA6%nNr8Ko5kWfT=<6%FMS9px1R4JjttPqEPcN*EoWM9_iCOmvVE zMF%S}bcj-c4prjlFvUTKD@k;Ol0io*S#*?=Lq{tvI!5u(u}UR6PML*{S7xIVlsV`` zWiC2NnTJkR=A%=T1?W^|Av#T2gico$qcfBxXt}Z!6_jPDs4Pb%Wd$lLD^W#Rg{sPG zR8!WVy0R8Ely#`7tVb_>CT0n}9vqMmXHtyB)9vy>y~Y~?6AM>&ShRgRF=yK&Exql@nQFrFR=T{SJ(sPYwV%&4faU+7JICG zhdoig$DS%bV71gAvDzwt)lo~ax@t|Vp86A3U;PfcyX z^&hO6S_^Bg*2Y?>b+DFdJ*<^lA8V~P!rG`!u(oPbtex5%Yp=GzI;btNj%q8cliC{V zthT|rsBN*XYCEi(+8*n!cEEb59kHHjC#;v+1?#PL#mdxfSRb`J)>rL;`PH5nsP@7j zwKoQ8bsR1mY2C<-uW4KCSgi2zhN@0{rW3~RuMWlrs6()U>c7|^btpDi9fb{1$6`a(iP$i8GB#YDf{jq8Vk6aQ*eJCe8?6f1 z7*)c?sxmfCRj~1@j!jSvY@%vnlT-_vtlHQVHG)l5XJXUTC^lVT=9cS78ZtHI`J@VkvbUmR8qe8Fd4eRX1Webu;FwTQN`Fj#a8VuvzMUY_@t3 zo1-4a=Bh`qdFoMYzIqH>pdQB-swc5U>M3lodKz1zp23!?XR&4KIc&Ll9$TSaz*ef4 zu~q67Y_)n7Tccjb)~YwKb?QxQy?Ptlpx(tcs`s!>>V0gp`ViZqKEk%DkFjm)Q*68X zAGSlS64;F$VJ;JEr};DlN|a8ms|a7y(BPOIMr&Zyr7&Z^%B&Z(t=^J>k&1@)J}MfKOf zCH42fW%ZB174^@+RrRmHHT8di>*_y&8*1IaO|@R&mRdh>TWu7$qc#oPRhtFwsm%lT z)fRyVYRkYwwRPZ;+9vQ=Z5w!^b_hIGI|XWKoddPCE`d5)S)i`gCs0rG2kL8Jpn(Pj z8fsXekroIv)`Ed18Xjn>5rJkJ6=<$8fxN*GXsLw)t+alD*4ltT8*N~qtu`poPWv~| zUK<+dpp6W4)W!rlY5AgwmJji3lLB3}$$@U#v_N-ldZ33U1bS*>pqC~EdTVl^Oj84W zG(FH)GXj3i41k&)fV4;e)|>#Mr30vz3t*ZX2xzkdL2XU|*X9NYZC-%X76vG7d4Sed z1Q=~)fYnw7IBji!*VY9>+WJ60ZBwAXwk0q?+Zq_CZ3_(2b_51%I|D9IVhj55~2Uprd^eOlV&PliJt8 zl=fXPt$iQNXg>zC8W7BBKLuUwm!PNp8m!cQ3(nI12+r323C_`K1?OsYg7dU`!TDO_ z-~z2#aG};JxJYXsTnF3~y$muj7Y%e1b+8x9MWcgTH72-Cv$-%Rl5nj5^TdBJPitl)KR zcJPKaH+WN<7rdn{2;SBf2JdK#f_JsW!F$@0;C*dr@PW1>_)uFJe59=kKGxO;pJ*F` zPqmG~TKbk?ZGCI7j=n8eSKl72r|%5b*LMXQ=(~dr^*zBx`o3Ue{a~<(ekj;fKOAhP z9}70uPX=4)r-Ci@Gr?B+xnOJke6WpvA=p;G7;L9s3AWd-1v}{1gB|so!A|<^U}ybK zu#0{-*j2wD?4~~qcGsT-d+1MtJ@x;Bz4R)0Z@nsBrdPxJ=mmIRy%6{7&*Gr|91iKv z2Klz{VhDGzk}oY`#7P0fRp-1IHiA#)B2}4qko38dNI!FU*Np{ zB_7hh!u#pp;QjUQ@B#V{_&^=N2kE8wV7(?jME@Bds{euy(|^T>>%Ze8^gr>D`d|1c z{cn7<{y%(-{trG@uZ54(YvbefI`{;=K0Z-zfKSpJ;*<48_!PY{K2>jmPt%*?)AeTf z480{@uD8Mky)`cCZE#6%kIQ;TT+ut@s@?_H^lrGWcgGFA2X5-Ua7*uv+j?&1xMdw4_RKHkW9 zh&MJK;Z2OkcvIsE-pqK4H#h#nTNqV{mPS>gl~F*nHVTP0#xq1)<2j<8@jTJqc#-H} zyhL;~UM4yjuMnM$SBWmh>qJ-M4WgUzCeht^m*`=+m_(D;hLjqeD;_<>5F%~-OJt0pMAjHa zFI4ROX;OPn><5$BBc#Cc;Q zalzO`Tr@Tlmy9jMWn(LG#n?t%HMSGij9tWaV>fZb*hAbj_7b;@eZ*~JKXJ!6K-@JB z68DTl#C_v1@xVAjJT#6GkBpPVW8)O@#5henHO>&V%(Fyo^BhsfJWu4e=81adMWViW ziD+P6CK{Soh(_jhqOo~{Xky+ZnwqzWX69|8xp{|ZVcsQLn)irS=6#~I`G9C+J|x*CB|4h_5uMB`WM{J~*~P3zb~OvgZe}6b-F$}ZVLnUtG@m1Tna`8G z%@@cr^F^|c`4ZXJe3|r{uaKbmDhZjdk+AtXiI{JasQDI&nQxN;^Bpp1zDwffdn94L zPm<;bBxQa~(&i^5V}44q=4T{lRwsG0hzyy~H$W0p=IvK=Vs-kogrk*!-Ft zVtzvoHNPc?nctDa&F{$(<`3jZ^G9-&36P`BQgV!0gB)wtB*&RQk>kx@$O-1J!TPsYs-q+@m@6J{qe zX?7-4W*0JTb|o`rH!^E>Cv#>`(lvXLp4pqMG|R|YW*>64*_WJS`pLN_NX|1Ma=r<^Xb)Igng!4kp)_!^pMfaB`hF zf?RKoBsZ9&$&Kb1a+5ih+-y!Dx0n;jt>z?hn>mHtZcZh4nA6Ce<_vO|DUrKPncQQl z=&AsFkb07KCJV@5E4wJR5 zBV--xC|TD!PS&$dkoB#TWCQCI+0Z&eHnJ{~jjgL>6YDzJ)Ve`7vu={jty^RZ>o(ca zxSR@=I$PDKE>;26)heXASv^h|^%B+FdYLM-UZMI}uTp)j*C@aB1_fGgQjqmF1zYb?i1iVLS|3xG z^$8WQKBa=zXB2K#rwFTvBCTSIvOcG1tAt`KAH`ZGZ)o>bK8Ma8V% zRE1SW#jQS+WBI9sg-}TgrBW6~rL6#!v4T|ABB-22Qm#c&p2bp?7Dvspcxtv4qUKor zskzobYMwQSnr{uE7FhpM3$3BlB5N46*cwhPu|`l!tx?o6Yc#do8bhtH#!@S-anven z0=3$jNUgCZQERQq)H-V_wceUWZLp?O8?71CCQG0;TOzf^lBlhgN^P?=YP+RVJ1m3R zX_?e6D@^USBGevhCbid!Qv0kJwco0s4p?#Opp~EwSxM@!m7bT`n zCoGRTX;o6Etl89QYc6%hnn#_r=2Pdah17X#5p}^@OkK2=P?xNw)MaZKb;VjvUA0zF z*Q}M)b!#?>4z`x@23zD{+tZ&01=n^b4} z7S+YRO?9>JP~GgiRCoIx)x*9|^|T*Sz3fL+Z~HM-Wh2zfN=Z8#Hgf zNr&vW=zjLwbbtFDdVu{dJE1{+u3bm(b&EA3fgwf}UW1Nl&!DrYG6o(v$7)=_&RP^i=ytdYWB>o^IEq zXV^c{<@O)6VE;vn_Wx+fu0_jsZCbJG(5hXR*6ez;Zr7&`y8&(5jcLnnLfdvzI&8O~ zBX&!ArrnB;+O6rB-IlJf+tG2mJ?+>X>4e>hPTF1Ql--R^+db%v-HXoJedwIsmv(JG z?b$G0X`}Qk8>4620eX%dr03csJVtWwoUK1!}I|=LLane(ueFQeb|oC zN9+pvs2!(|*$#c&PS7XpBz@9O(WmSzecJZuGj=6?)}BS5v**y~?S=FOdl7xnUQA!I zm(Z8(rSuhh8GY4WPG7Uv(AVv?^bLC*ebe4R-?BH-x9v^z9eXo<*WO0ovv<(*s|c^F77sgBoNxh< z2tNZP!*5qlg?s#$4!>JH6aJ!lHvE3|T=;|PZusNsUig#hmEpI6S>bnp+2QAbIpG(8 zx#1UqdEu9U`Qev=1>skKh2d9$Md82>CE@pgrQz3sW#Kn~1 z!{NTgN5cN%qv21BkA;6OJ|6z5_(ZtQ7bnBDzBme7WC6V%yr4gZISwt*Z9+65`MC6i{5v62RL@ikz(Mr}t z*pjsou4G+=FIgW6m28OgE7=(7U$QAOpk#AoV9A!qppvbT!6n-wLrS(s{w>)N8CtS4 zGOT1*WO&K$$cU0Xk&z{PBcn?8MMjtGkBlif5b0HNFw(o^P^7HnaHLPkkx1W?qY;0} zu?SdlJOY)Rh`=Q$BS^`aNc9?LBSkgNMT%>jk9=O^LZqa|#fY!QrN|dGE=RtsaV7Fq zjjNHbYut$RD!LizU34o_R&+bkr|3?kZ_(X|zvx~BEV>_oiXKGZqK6Tr=ureMdK|%u z!ZWMpRgG$SRihxUI-JR?8qefajc4lWw|Rik=d)hNoV8pU~4ZBuf96$_!vqMd<-(JsKEXjfoyv>UJ_+8tOL z?Ex%{_5_wkdjTt=y@8d{GGJA-53oAg7g!VZ18buour3M#>!UERA&LMSqbRT`iUFIW z0bols2yBhwz_us>Y>$$_jwl7}jMBiaCZJP5>@PCjwWZlYpzy$-uSf6ySPvDsUq@4Y(Pd4%~{)0K%~_5Q#;A znX#EbG!_M7u^3Phs{rD$IN-z_AQ4Ld$ygFd#Zo{zmIgAh43Ldwfm|#HxG@*-VjfT# zs|04nW&yKfvw=CWIl$c5Twq>o9xy*PA6O7u04$6x1Qx{>0gGdcfhDmez|z=KU|DP# zuspULSP@$Rtcf8Ut7EHyHL*3o+SpoPU2Gk&KDHj%5ZeH3jBNxq#Wn$(W1E33 zu`R&X*j8X$Y#XpWwjJ0J+X3v1?F4qkb^*I%yMaBiJ;2`BUSMBrAFw~RA2<*@033`R z1P;Xx0f%FUfg`aaz|q)I;8^S!a6EP#I1xJmoQ$0WPQ^|Er(>sqGqE$k+1Od&T>6-Ab{)78y8+yc-2`sMZUMJrw}Csc zJHXx8T_9XBtsqh{y{;Og4q?Zf;klx1#>In1@kJLg83DRf)y2B!ODut zf>jl>3RYLlE?84Br(kWx+=6u#^9t5i%rDqbv7lgM#lnJ36^jZsS1c~rQn939YsJ!n zZ57K3wpT1K*io^fU}wduf?XA>3wBqmDcDo7wqS3?x`KTb>kIZ*Y$!OMSC3BQ)uWSn z?dViqJ35`$jn3qCqqBMK=v-bqI-ggLF65P?i+SbfQeHW_n%9u7rvT()f3U%i`Y`E|33ExFY^z;f^>^xHDc_xGP?x zaCf|B;hy+Ug?r;a7w(I#s4lm z9{*qAiTFQ-C*!pWPsM8&o{rZkJQJ^5cs5?I@Larp;rV!j!VB?+g%{(E3NOVQ7haAx zDZCPIT6i_ytngaAdExbVi^3c6mW8#Pjn!&9o2u1u4pgh_yj8uP^G@~pj<0$H=jZAT zoo9*~IWH77cEqA4j#Sjtk&Bu+N>Ov?o#GbGXT>d@&x>0*ZHikvU~wAx&(zD`a%UuUPiuZz>c*VXCh>*jRwb$2@ZdN^HtJ)N$;UQRb(Z>PJj z%<19lyPH!LRl=&d1j}LbG`VhzOLmkkEIgl^lz`me^_;3gH5f0`foq&&W zf4)Mw}B>W;$D|MxEnTV$NGtE1U~e z;?74^9p`+Ng!66Hq;sW8%Gq8u?Od*sahg}nI=8CioSju&=Vlep!Kzj|539^_c2}M4 zJg73q*;{q4v%l&*=U~zwCG*E`RbZg5^G-RQhny2*K|bhGnv=@#de(yh*`rQ4j>O1C?&m+o-hDBbD2S-Q)4 zt8};XcIh7HozlI|yQTY__e%FW@0T8MJ}5otd{}zO`Ka`;^Kt1B=abT-&ZnivoX<*+ zJJm~1I7Ou=o#N6{&gZ44os!Zsj<58r^F`@7=gZRb&R3-uoUco3C5nLBiDIBm;&Y&G zq6Day@B#G`UjPjfUjhviUjdC0UjvO3Gix+SOs?59F{Ng+gkH0G!l>CIVb*M!2-j?t zSY5MqVr$Jdi5)fDCU(|rm)KLYeFAveA#pMs!)wAJw^=w35JsX)<&qn3dv(b6=Y)oD~8=F_p#KdzzG*QJDOH}n$B&zx1 zi2|RKDD))~&-jvwXML%}bG~%qd0!^+f-jqR(U(iS6@2$%Qrvqwr@e=9pA#lyS_z<_k4>J@B5Y{KJYC~eCS)2_{g_B@v(13 z;uGJ>#HYShiO+ni6V-id5=FkXiDKWn#OJ>Ci4xz2gwMAz@r7?w;!EG=#8$C?gZf5lPLA=P1Nx1OVsr3PyFONkoehmF!77; zP~unL;lyvgBZ=RAM-zYejwSx|9Z&q_JCXR?cQWxm->JkuzSD_XzB7s1zO#uszH^DX zzVnHCz6*)^zKe+lzDtRQzRQV5zAK5wzN?8QzH5o5zFNt{bnWC3x=!*KT{n4>u9rMT z*H50N8zj%r4U=c-M#*z@VCe3t2ue2(due4go)e1Ykle2M9je3|K*e1++je2wXze4Xi$e1qwk ze3R*we4FW=e4i;xe!%oee#rDqe#ZEd)fq7PIRhn27&!R_gCxIX(BxMPmi(RxB!6Ur zNr1tVH5ejUlOdBoGgR^yhED#$Fv&j|Hu)FBCI4plWGyC?tj+XG)?xZ5>oNn9^_YRl z`plqY17>itAu}Y|h#8t}%nVC5VTLE0G9!}Bn32gA%&25bW^}SOGbY)V8Jld!j7zp> z#wR;46Ox^niOJ5)q+}Ona6KEM-YK0a zOBqa`l*#l>*^ECGX28@;21-R4I2B`%R0V^k;tZB@m_RDY1XF1SPh}V)ji7Gdi`08I#(}j7{xh#-;W%<5LHj38_QO#MEJCQtAjZ zIdzPgk~+amO`T+>rA{%^Q>U33sk2OZ>O3Q)E;3^35+kK9Gji%Gqol4eYU(K0?9ZZl@;4r8V6GIr`7Q!9O+shxhn)JZ>N>ZTtt_0o@-`spW3gY;9TVfsI&QMwA- zI9-)(lCH)!O&7Aw($BHY)6cUl(l4VB({Hlv(r>Zt({HmK z((kYx)9{*o3ew`&DbI7=IqdP zp6^TNDYJB*bxOBpN2c4bd47W(oo>hGXV2NO>HIu!x;r~Q-HV-&?#)h2m$8%5eb~wA zzU-8=pPiZp*=cErot}o-8EJ$qPou1m##k{OV5Kz9%4vdC(iE$vX;w=!te$3BBh9g9 zx*uz$`?Gd>09z|Fkgc5=#Ma3SX6t7DW$R^zv-LA0*#?m%gl7PRb~d;I#bTJ$p~!QjL5djNNoFz%y!5qY{!hscFJgM z=ZwL2$yjXHjLmk-gxT(y2-_nwlkJ&_vb{1fws)q2Ez2a?KA9BTH}Drs_OO#Od)djEee9IXes*f+06Q&nke!}6 z#LmbZVaqeeSRr$Q6*Fg8DRYjMGv`?)bAeSe7g;THiPbZgStE0WH8a;)D|3UjGdI~< z*;{Pw>>ajF_C8xT`+%*NeaP0&K4KeWAF~a!PuND;r)=YF6|PCPD%Uhyjcb-I;F@Qj z;aX&$F<~nEJ;ksns z<+^6yf#SC;*p>ys_v`ewi2{Mj!#F#8P$Wq;t{ z>`xq${e?rbzjIjjFD{V%n+sy*G$ZTDX%GTrPYy*zTHssiBV~)!<;rMKG zE|hJ>^~<*A`e)m41F~(of!X%lplk;O*64&>zQAWq2+=G5#EPRkDE^z1Os$PVYs>`2baj^ga>7_L@sELS@> zj;oU!&(+OMZ$SveL<`!|Ca?7~Rx#e7!+zPI1ZY|d>w~6bX z+syUIZRL9AwsF03+qvGk9b8#%7uP4ZkL#N|!1;3rIWTvagK|eWICqRga>qF|cY?!m zXShJ_0vF6(=J4DVj>ui*$lNuK%H8DX+%1mD-Qn2WU5?A$K%YDgD&wa(u$bH9`=YHUY z+>gANE9IqJ4PMUu!YjF7c{TStujT&W_1vGlk^7rBbG3OZSBJNA_4rzDeZIEafUn~= zKvD=Do;So%mL6 zXTG)Dg>U0_<=eX5`F3tkzP;Ov@8I_4JGy0jC$}%(+4b{XT#)bTLVPzD=DX)>4n16y z@975kUT%=@?c#iyOY(hOitp>vyx(Pb&}DhZ<#^cTdBhFzsN0{%+yQ*R9mEISe|g*; z$`kG|o^(g>lsk&2-ElnQj^|l-BG0*#c;21Dhuo=rKX*Fc-!10{xB@@WmH0uf%nx=| zeu%5_LtUL8<{JEP*W^dI7C+Lp`B83|AMHl?G44!$tQ+IUxfT3)H_lIR9e$#l;3v6B zezKe5r?_c;s+-}bxjBBi>+&<)S$w%WhZo$ryy(v3C3ikAy9;>5UC68MB3^SB^SZl) zH{7MX=`QCjcLi^|tN5_nqKJvu>JxLfwySVoXdic%w{zTSe8O$UC*8kB zrQEBbv^!*Y#+}qJ>z2|vR~B7&lH|Ex1uETfU1zxuTh4Z0=rhNaz`5@HZu8uSL+87V z;011W=t8#|xX9hgFLocaUgCD}FLl$@GWW*6%iWP3%SD zm)pJLZud87k6ZTdUiUY8pF5b}?{0$*xI_4ZZiBvuT(ae1*Ei{id${bV``&3-{egtsb}~6Cb)q zhd*+U4t?xC)Aot`=D4S>zfCP~HDB9X$Jg;T@O8aSd_8Y7U*FrsH}LlG4ZQ<=Bkv&J z*gMQO@s99Ky`y|H?>OJwJHfZ`PVz0iQ+zA$G~e1g%eV2)@ol~Hd^_&~-`=~(cknLp z9lgtZC+`a1*}Kkn@ow>5y*qq2?=IinyT|wN9`ZfCM|>~u3E$iMk1zA8g!*{ZLVdl0 zkl%YI1bWYgAn(Nx?7bX9yjMf0_gV<^UJnJlH$p-0%@FRr6(YR1L!|dki1OYI(cXI@ z#(O`+dLM;2@8b~feG&?JpN9H*MWO!Q=b-^!Nob(w3k~wV3=Q_a2@UbS4Gs0a3k~yr z2o3ju&%60v9g3W8%%orC#Jkf zdfI!I&Ugfr^``a9d6m6fuXS6`d#`P!H+IS_Z}ZUE-Y1jhc;WK7-Yc!^|Kc-Mw6^}d6ad0!1&?tR^Tg?DerO7DAam3Jqw+5;!A@$OGq z>-{x#o%g4;-rJ3B@IIKf(R+K~CT~#B&0f6U7H{v!t=`|Gwt0K7?cM=whqo8o=~eBq z%Nx^UxA%bC<6RNUKz?EO3Sh}Ts->Sd&3-hwH| zy?6gT;e9vhq*uG_l(($qX>WhqGhUCjXFX@iIWIBgyqB7C!D~MCqW2tp$wPZy_T*t# zJb3I?Z?AsMo6!5Z_idXS-Z%VBFVORrH_?CF+ezH<&f|BzrCslNjr!jAxYiFmxAjAB zHT1~)pv7ZvL;oky`IJyg50N2pF^&rsdUUZHxGeM9vtp-_W-?W|!X8fsJ- z3^lIALrp4)P}52>)U1*UHLs*YEh?E%%StxXs*($}uH-{)Dnp^RmHk5PDhGtxR}Kty zs2mjPSUD`zsd9LzbLEIom&(zhu9ag#-73e1x>t@1^{5;l>RCA<)T?qzsCVVmP}%<( zx(mlR3bYO2I0qblI2>}w0f!tPa(Lal@uZPPHrjY&JH9hJ(I#nI&pi-GMx+Coqoc4dhc(0tM96Kp{0PP(<|w zim91_5^8p!l$sM5Pt6OIQ40d))Z#z|wKPykEeljp%L4&wWdNY407x+bh~fe;#Rm{d z2%wZ0z$htzQ%ZoKv_Ob50wiSyswpc_L)n2^$_dm_ZlIp>0u59+Fo9YXXrxvLny58_ zW@>FgYUP08hRs6*sjYH8Ly>Xd&z#kMb? zjubAWl42H7cJyNE#jGWi)xMN!hnG>`L@cM?NnJtx7+OiaPEgbYf~Gz$W~eoVELGmi zQE{0(l@cRRcVa~UPe4YB+g->WDc= z#lwfF`4NYyrl=#-$fBdvfRtlY(Zu7_mdq2>>X?(%f5=nRkK}3Uc!#$KdOHeRAU|7Gf0?iC7Zx=KBgb&ZlTuT#V8ZcvRqH>o$8Zc!fuZ&O#= z?@;r7cd3^;?@@EQ?^A!zc|g5h-j6;J=ue*t44}^h2GSP;gXl|v!Sv<85c*1BD19w3 zjJ_TiPTvfSpl=68(su%*=(~Z@^u2(OejJFPp8z81CxIyXDIl7D8i=9)2E@|O0&(FWVnSKjMq2B?<(*Fcf=?{Q3`a>X{{s_pRKL-5tzky8p z3m}XB63C{%26E_cfL!{&Kpy=aFpmB|AfNsLD4>4?3hCd0BKl9DnC=gh&;x){dLS^K z9t4!pLx6I67*IhE2P)|iKova_2+*SefQ|q_Itqa37yzbY0fZg{pmZXD(MbSKCj$hX z0)*&PfTYuaYC0XLp)-J5+7HyxnLs_A1vJpvzyvx6Xryz2COQvjepo@BNS6RDbScnE zj|bZ5GGG#24os#ifOfhP=%A~BP8tBZXb|Y8A)tqbfnFK~rqCELl@0>aXdLLH31B)M z0%p)8Fq8fzVHW*f%53_7sdMOH$6PuXIgg%!&!H#UUXDRuPBZC-LW>^OY12frLl@S&bX%53UjoDQhJ;mgV*YCS zCI1?FSnOJQjBg$N9JHQ3oxXvtF4;)$Y1~8y{hR53wr-&td$-cZz-{#7vD@iul{@H1 zGk4N&#q6Tf3wP58TlUcJr0u0kd-u`5;``~~^aFH##6kL(ltXk@^I_Tz9--%EAEnjO zWAxyt<1`g@f-a~%Nk2XI6g?yPG_Cs2(1mSh>59s8^xr3*r$2x$(2r(Zq(S%+9rj(O zZ(&#Hn!r{1W#2XWJaL_VFZu?3C+a3WKK~ZIAm%n*H}MYrM8{ovW9L2EEWS@?bv~ez z#`R;Wf&NSlFo3BA1~T=)AZ7wEm}vxtFfG7PrWF{*Oag{8?Z6180~pD40;8B7U^Fug z@G*Tr1TzDOWM%_GF z;efFW52P}}Ly%Si(is`ZU=+a5s6Zy816hm#WHT0!!`MJB;{bV#2aIFFKt8hyC}7qB zh0J=Oh}i%XGaG>tW;0OAYyrkITY)lW2T;!J1S*(aKqa#WsABd40cIZnF#7?JIRHS+ zK>%hB0SI##K$#-|#vBE3<`_UQ$AJ)Y0w9@_Ks9q3sA0|kwai(djyVt1GZ%mc<{~hG zxdb#amw_hcD$vYa2PQH%fEMN!(8}Bf+L*h*B<3D4nYj_R38En&atBx=ta+En&bc{I^JkCVro?yl#pJZ+&pJLVmr#eAB2o2f0h!yNV9WqxYD$28X8XKK`UMv_GNG| z`wBRO{RcRdeGMGOz77s&-vCFjZ-OJ)x4=>C+u&&S9niS@V+0Vfw_6snX{Sr)J{{xO?zXDU)ufa6-8!(;y z7R+G(3;Nmbz)bf4z%2F$Fq{1m%wc~5bJ_oadF;>NIQDlipZyaoU_D)H9RwD$ zgTWGZC|Jsl0LQZ`$wq)xY$O<9qd#cu*0bZm2DS{Gz?OrJYz5fFR)WoJ z6*!Rv!4?((8@*?O>tZ2)`OMsNz-1Wsj} z!D;M7u#as8r?YL~40aMYll>rl7W+Fsn|1wj*q?oK*|?Z_?5)=MtdO~Y_3(x4iR?w} z*M*DOArVX13+YSQ!$r&31C7hspVL;bYin1sF=-V0VJ6KcMKNp!$+DSw9Q#N#&t_%{ z?68R<`%0w5PDzp30I0C{l2!KGXpQ|9(pe?lU}IWMc4w8v@@Y2PmFBS3RW4gN(PK+W z!z^62iX9HGW)}t4uveqjvXfiau^*3F&-x-Zu-A$=vS(U0v7@p#v+uxLSf^|&JEv$H zdoZ}2J)E?IW&JzZj?`W3w+Xx1Q1u@6Kk#1mz0`f|`)T{xS6UCS{|FvrXLKK8Lz#!! zaPbkg8#u~}rN>wx>NuO+b%I@-aFYF@@)SET;xzle$}?RI+g`Z+c|@jPo3U10Ts zi);gMiMA2%87{}4(Wz;%EFxlV8p*98vdy1^k_4>**Y0uJM*g2TCK;0Ue{ z9LY@wM{zU2(cDbX$ISvGxY=MNHwTR3=7Q1OJTQh^0LF3)!8mRa7|$&R6SyVd7;Y(; z$SnhtxaD9nw*pMzR)S+W3QXk~FpXoubdCcvI3DzK0+`7uU>2u?*_;LDa1NNuxnLd_ z2FG!$z$b@tmkfm4cu*T0(S>&D91z1*wN6z(->D)%}xje8U7)rJTxRt$&dONM zEr?#hJ(stV>x!Vbf^?dbqZsa=MJ$&R#c`c}p6kjMxQtGb8`30kZ?wwXu1bZw->Pz% z0gc;IpmP(-4DMW+$=z+VxF5#Y92ju8QOz!wlIwB(I>KBpzKWZdx|;j2cnvoxaV>Wd zTF0Fatml61*ub#`8@Z*~o46N(o4KdPY~iA!wsP-xZsTqzZ|4?{*}?rgb|+UhaTk}9 zy_*Ym@8OQc@8zbo@8cd+?dSTp9^mRS4{~1YA@1$O!`v^4N4O~oM>%TZG46-llU)DkQ{1KW)7)!g&TtQE&vK_y&T)hL&T~%01#VjRMNVwI#C?)X$p3i9z^ zLlOKpP$d5?6vh7+isrwAV)*Z&SpEknj{gyg=l=&K@V`J~_&=aTz8{pt_lJ`C0ZQaxP#QlJO6P|`8T@d_&yRpI`H@f-KMKm`M?*Qh56a~upgcYj8plUN`Fspi zz{f&`d>mB7$3HAYj)6+}M5vTcg2wa7P#K>BmGfhv3O*I8>FNCW3BB+KhhHCi|sE!{G)$?Ug178kJ z;47g<9)_BD1Zw6{Xd;h6Eqn-Sf&3VZoU=j z;U`1A5Anq*d=E60?}euEQ=mS+51P);gl6!wpqc!)&9nH;F|+xk;2b^zp3A=!F^`Y% z&F3HKT)=NHT*z-KU&NoTSzSSI97*+O>+$h+EAc=w8Fm#nLy+& z+|2*nyoFy9+R7)jZR0tVK~=(OC?K4H0O2eI3g;k5xB$VzB?u8NL#S{C!i1|3E?k2M;W`u&Za}1P z6RH+&K{di%s8+ZK)d>%vdf^ecL3k9NAUp;)3QxjK!qafG@C-ar_&eMpJP)@DFTicW zOYkJ&6?n4nD%>u-4tEG|z@5UIaF_5l+%3Ed_XzL7y~6wO6yZa7s_+p!P52kwCwvA^ z7e0q)2w%Z7h2o-F!lI(tLJK%YSXn<;cq46|@MYzEq1V4asA*X!T#Q&G>}y*r%+FpT zd_yc1qKIX})YRodB(XxMXkIClL{ma-11*efW`ySxS)nG96L$G{;oVL___0hBKtdAU zZJ2F1#Hygw|M7sEW6Q7vgQ&*9n_**9(6^8-!{2Mxm;Clkk4VX2Aou2>$G?LT2+ep+0K6@OJbL zVOIN2;eWwh!W4YBKw*1?u9UsPH^uve^xXZzZuo%ESand?)q6;2Ar1@e!6U+UdsTR}^P14!d0jZyena@ecT;#G_Li_4yDj{jcSktbd{=l4zb9PFxi9pl zJ`luUKk*y5zxXXYK>Q9KD1HwQ5`TaPi$B6c#Gl}y;?M9f@mF}b_&Yp8{1YB2_Jc=> z{o&E#0N5uEgd@a3aHKc{juMB#(c%a=MjQ>tiat0_jDh3DI5C%~}S2qR(>jEWOsOl*O1u?;4~NpMJ<43lCfTrGCPHDV83EB3;5;uN@E?1LM` z>F@+`2HYslhMUAWaI-iUo+vJZTg2sXtGEJg6DfGo!_Z{1$inR+2X}}(+$oB1mnc2t z#$>ohRN!7wg{O!bJXO@;X`%u5i55IvwBZ?|1J4w#gjwRB_-wH&Z;p6;>|F8J?0Mq! z==ow%`U0_c`a*F^#3FIY#KmG^)Dm%V@>22Dv}NMyvCGBO!WH6W|4Q-0W=b3%MT-mD z8Sz0hD^4%u#DgJT+*u}wvl2wHI#&|EYL>Zp3iFe}Hi{Z`<;@8m|#eEf< z#K`E);^E{i;$xXx#m5@9iSfSe;wJwN@r(4G;+?!*VtLeVu{(K>I3sGW_;Br5oC)t2 zYkLlek->xF#q>kssM5pYH_b=H;ZaA$VCpgPoz~-GX~hZAX*elK)6yFrr z=iL&Y?6@tSZ@nYlkH0HU&AlhyuD>saTONq3V*5!h++SJ+50F;F1En?aAZaZ;SXvJc zkv70XrH$|~X%jqL+5(S|w!tH%?eHjR2RvHZ3Hzj7aD=oMj+FMnQPKf8S~>{FNQdB9 z=?EMr9fjkiV{n3W5*{O+f)l0FaFTQuPL|HWDbjg(taK4hl`cID*sj3o(p5M^x(55D z>u{!Y1J06e!P(MnI7hkz=Sp|sJn23>PWlVZmmWb1q(_lL=`o~8dK@X1o6B@1}T@GMJlA{kxJ!2hwM63oL1Wt1Y34j`RlZ zN;hLXX+dyj%J+evh=dZ?Ckya-US6wqH6_c0kHYKPcUc zJtQsg9hSbxKO$w+AC;ohk4dF1$0aBBgtV*lqy*NUlK$*FEqzgRMruhuE4`U^PMU?C zmm13-TxDXHR?bYskIsi69f zbQr%YRn*;+HkI9%)*uh0_~L%@K%~Ds2pJ#`Mh415kU{cLWUxF886poyhRP$5Ve&|1 zxI79OA^VV#as)C;jzmVwQHW2DMk3@GBvOt=qU1OvT8>9z= zhE&NxBp~AmAQK2EhY(065m>H95V;0HkwS7M+kWW5|SGcQf@-3^Ba`I?NV~ic z>5vyAo$?Z-OJ0g}%gd1-c?HrdGsqN~MW)IeGEL@@K3PDf%Mvm}mXVqAXKAx!U+rx9 zKXG&9IsUowB;P!FQQ>^~C;tL@WoV(iGj@^ei&-rHQNBdpT)b5NwQ`yKO7wF1^_Ug% z{>GK^rg4-!A&r(Fc^C;_C}QP^1Wx{_fR~q-3vx`JDDP^K+3BkMahxWf zsnlhElOex0-jrt-S@OJOTZU5|Ihu6kQ5l}>^o8X+z$!VRZngXwvPQ0}S}R|QS|{H~ zUoVduzd;_Dvr!(Ex=9|LzFB^uX^UK1x>f!pbDP}IvRziwcF6wpo$|KYUGjnW-LhG* zM{ZBwE9YkHlZVIbmk*^MkaKbl%6~Q=lJA3u<+me_$frw>%0ml}$#mm!`AXvnc^7t4 z&LU6AFXo(dGd<?x*NTf5kusC>AnM zv5`TFgA7(YWQejF8LF&BhAA76;mSs2gt7@4scc3@DO-@y%2vduY(pZHT}Y&|2Z>Vl zBGJlzBt|)a#43l8IOPZuuN*}Zlw-&kB~z+RQ`chE3ct7%Ij#Y@&;O`youH;Z=ns!+vo)49kfw- z7j07BLz|U{tK3w%tu)^S|%jX$9vQ74s!_$j3{bXoxt&nQm>&nlmh z=M*FFymBu0g0d30s04sZ%2EGiB_s2Sg2Pvp^AXpS{OIe-#;6-gBzaTWJMNZJG3mB) zz4?yv-{!lD*>F$!y5qjG6n>!G@by!FLi?-#LkFloqXX4n&_U|2=wS6Xbcp&pI#m4w z9j5+?4p;l3Bh>!rNOb@@N*#!fRtKRzbub#C4nZT;p=gvk42@QYqcQ3TG*%sn#;K#w zcy%9?qbX_(I#!KEQ`I;$O^rv>)dVy{9fSJSL^M-PLbKFl zG+RwUbJVeDu9}MGscGmqH66`YGtdInj~1$#Xpx$Q7OUB4iJF6!s=4TRH4iOQ$D!qF zK3bs`pp|MNTBR1D0ks4L)KU~w$D@#1hQew&il`MRs#c(n4xui|KfN}vrvHmf!0M70)eQR~oFwH|F#8_-GW1az|6 zh_iR$I{?wGHi6C!tf+$>>zI9i66jpnYm5I$iBTXQZM=j}@tG-k`Ppv7Qug))8px#Mcs9uj;r0z>xtUi^pL>*GJR81>frq)(2 zR~xHWsCjuS)%Zk8r5b7VgBV5~-^Qw=J2`cD4X?g3PEa2OMfKD1l6nJ|)j2*zUDK+n zLyI)Ex>r}9PBK&_-c+B=veZlMwt6<;sB09&gD zqt~g4+3VHHwhd~qWur>AY*Nq0Y*ss=E$aEqt?Jy&ZE9`RcJ&sxLrtjPss7lxOZ~#X zTU{KzM-7Gcso`(*pj}{$Pw_-=sqYX#ZO^L_USNzA-)io#7 zxuKKlsLE67`;n*BwZ1dz+{&}+*~W9~h?Mi{gRvLXk?=)zPWB~rbK7Ngjqi&3Nzqj` zt>K#b8G2p)wBv^A`fjTKZn~xJZMm(McimA(=G;{Y@SeK4<-U5Z^nnT#_0xLL{#q|O zK%0UN)TW|?v}x#Itq&cdO-F}nGtgn$Omw(53mu`&Mn`IM&{5i4bhI`f^=S*x2yG!6 zsVzdIw8dz&wgipQmZGuRax_j`fyQeq(FBb`$7nQ~s4-}g#-hm@ho)#eI#v_VR82(F zGzm@DWHdulP`{?4nVN=XX*!y%8EB4XqPd!d=4m!MPIJ(F%|#0|4=vQfXpy!GE!I|} zCE6OaR9lOV*VdtB+IqBH+kjSR8_`N_6I!KhMg!Uw6wtP!ptcQ#wCyOY?LZN2CyHvj zP)ys6;@TdR(DtGsZ68W%`_XFc09vCRL~FG}Xq|Q#t=EpA4cbw3f_4mT)Q+P~+6lB- zJBd!zPN6N@X|z>4gSKgB(Mj4lbh36HZPzZK9oj{-Q@ezAX_wJ%?F!nXT}6AfYv>g1 zIyzOmflkwIqJ7#ebh>sMouS=9XKKHv%+jdn+1e0tj^>Y=tGz(Z(~<-8wW^#2nlN>t zw#2tcTa&(6(~u<^jV#qRV#~A+-*PRdafMcrvr?SxON!kHO){H1cTVASa-H@i8$<(zf$k1kBrq)?*Y3I9aZLrVLfKpc*>+`he zwy?G^W|bC|y;?h&y+*r7tks?jt@jqQ8NS)!)QY^|!Dz{cS8=e+SFZ-^Kj;dswFaPb^D+AIsK1 zz;g5tv0VKlEKmOzHctN-%hx}_3iMC0Lj5zWNdGrhtbdM`=wD!^`j^;v{XbZl{uNfP ze~ne>-(Z#cw^)__Uo4=1hXMNkVW9p!2I)Uwu>K>4=s#ho{yz-Uf5veA7mUzxHPeGt~555^|wL$F4D7}lf@$C~vK*hGCK)}oKXTJ_Ob zo9@FV=@HmuJrZlzqp%J=8tc?!ur56o>(=A29z7oG)f2EO`WS4go`_A;ldwKL8Jn)B zU^Dcw*i3y*#4P&eQR@`FdyU0zD&Up}stJk^V^9V*PaH5;QTlJ`fZTeTS+jR)qp+~0g z)MJx(>GLyp>ofd&^rJC*^-TXhJ)FE>U!HqFKOcKgpAH?;PlOKZfwm+1AuAKdjBa8bUd=3 zk&5*<(y#$WIyTVAzy>{>Y#eN4Vnd89Y^afq4Ks4E;YKbt!pOr$8so50Mm{#$D8PJ1 zAr@g2VUb2L7G;!R(MBm2V~odQjWR6GD97TB3M|2>#Kss^SfUZYk_-S#Hb5-JfUvO! zjHMa~mS&(>x`AOCMiBEGIF@M;Se8Lz*+w;%W7J@|MlF_S)M4X{dMw{)zzU2BSfSB~ z6&X!fvC)i`7!$ElqXippv|?pO8&+;i!YUq)&Q%)iSe4O%1&mG%FuE|%=*A$U2ZN1X z3^Ar+s4)%0j6MuEmSKd!U?D@sNJGJ@jU8BxaSW?9&S7=NZLHpSHrQai6r5oEGuUYS z6l^kn4mKOV1}7T71zU{YgRRCN!8YU1;3T78aI(=q*lr9Ab{Io~oyO2$moY5ZZ43|g z7$btc#>n6lV^naeF*-QS@CEyfh~RW1Iyl3K3C=X?duAD*Wz06n;yFfE!d&C2oO#BO z%=yNp_yxu}|3YJ&f03~@b+Pe}&Lsw!u+&)XUuM+BEjK=_TVaeKRvNQgC?hA1Hdd01 zk)6vL@y(pEznVAllLX_%JkdDemy8RrY`om57^P9FF||Z9zHQQt`ey{yHG7OTz+U4Ubf58I)P7@9 z!U4m|I%qWFhYT1wY@8`PVqDHUYNU=kX7EwRjqaEe#)7<)22pm(*wA;{xD1~$Zk3%i zWbmBvYRP%ysfr7RFZZIcuI-XBXX<6+H}HzlKwdRs$!o@ovDb|^@@^Qv`)(QyF}IAB z(YK91fICKQ%w6O2=zB(e~AIp2bjshfo4i@kU2Iu*h~!$G1G%X z&CK91Gb=dU%npt)bAlty+~6p)AUN7A4EoHXV1!u`j5JGwQD%8C+N=!5m{q}8GZ2h3 zfndA|1rtm-IL1VRi6$CMGK0Zn6Az}Cq2O4P45pgZ!8Efbm~PevGt9c6->eU2nhn7$ zvoV-$HV1RemSC>g8q71>g5%6d!Tg5GYmjy9%We_*%AYn4W zkjVx~lM7axe6Yrpg0-d`tTVM>y=ep+Oe;9Sw1bVN6KpcQV6zzxPBd2qTg=tLR&#Bz z&0HUxWNr*jHa7*^&CS6Mb4#$(+#2jMcLcl5oxvV+cd*yo6P#l14Nf)p1*e(&gMH?K z;B@myaE5s_IMX~*Im=uN%{C_?bIiGgb4{*uo;f9YzDZUrFi*!WG*3q?GGp<@CPgkW z540>bOFNdCt5cVo@20OXrx&d>-%O><CxeO7_)lrg3 zs`Ce?|pkrxpl93VCp_|ZP9*nZ`1*^fAc}}z1TzM2LEA`DnDXgCXbpo zI**yv(~p~W`w8>Mh?8b-@RYeO>a&i zOdaZH9SioiP6h{9r-B2mGr>XD+2CO7TyThWJ~-667#wC@2@bce1xHxdgCngQ!BN)D z;Arbs&}ZEaMp$=(k=FfSl=UDOZT%IDu^z)?t*7xg>u-3x^$eb1J&TXAUceKr7x5(P zWjxt>6;H9=#>ZOk;HlPoc$)Q3Jl%R9&#*qk{no$mOzUGj%lZ<}w*G_XSYP3}*4KER z^$kAG`WDZ(zQYTw@9{$GXS~Sz1uwRK!%M6`@KUQEKHln&msx}Ga%(VNVGYGAtzmeT zH5?CEJ{+(jaL|gxAu9@ptr#4!;&9Z8$1y7b$E`%1u#)kRm4cJjSiIUw#cQlIyw*y` z>#PjC-tyxORwh2d%EBA1Y`n?J!JDmIe4>?yw^#*ut5t}%Sw;9Hs~DebmEi4GDc)g~ z;hk1F-epzb-Bu;uV^!h3Rsf%30r*r4#HU#h-e_)4j}UOs(iSn5u_pJiRujNk-*xfU#b&`8&@5WPKFLZgk*#V_vEtHHYe=VNeeKt+ieAHd zE!MR5w_Dci2-|YA9V$PCmimF{@eN(vFYD`;W)s?Tcjuo%7{=(K1NCyF;)l`&ha@xHCrjLdCTcI9?!rhkW3+_Ka9G-8*v*|*!8SGdRGu)UVl zxX*g8dcP&r9k3FD2d!UQ4_W`}IBYG1k61H%k6O3tk6FK0AGh8qI$_oJp0xI1r>y$K z)0W(K#+p)o)_N2;XN79dTZO$BtWfVo>z(*Z)*G>xt+fePtWw`qYhK?qD?aABwW{TY z^$c;-niRNYP3pOAU8ucd9WK6Wy;^h6x|eg`@@G7-zAWiyV|ag?zz5hNe4t%}53=j= z!S)1vh~112wI|}k>=t~u-HMN}+whV0Bz%d(&o@$5jG@~RG zUW;ei8y^nhZo;$e&3KNz1<$p&;(7Kqe4M=<&$oBs1@=L_&_0A0*+=kV`zT&wpTJA) z3;1~ZI$mbq#LMm5c!hlzue2ZFRrX(az_-XEew={pCkWVnl0fXI3Do`@f!WUy zxczs6uwNrW_8SCgzeQBr?+`WiyF{)19#Ln%Pt@BV5DoT+#02{zqS5{r(PV#2G~1sL z6YWol7W*@z)&4ipW`9mhvcDiE+g}px_E$uQ{WZ~Pe@k@P|3`G&-xEFd4@9s16EVg9 znV4$-LQJ!NCHm~&i0St4#0>jSVy69h(=2;ZXtw<&Imf&v+so5$*!Meb+ArkXvZvSGw*S?4 z$3EYF*M2_so{h%dxBt`hzy`AVIsJ(KPJd#6Gk_TA3?v3QgNVV-U}A_flo;v^Cx$tr ziQ$fq7~w<^Bb{hsloL;kb`l7mGlqz8l8Hzsg@|&-646d75#yv0u}%gN=lF?uCzD8U zvWPKG4w2~O5lK!yk?a%@DNZ3V)+r%UoiZZLDJRmMN+QFlBK%H($aH{*BhUnq?T|!{ zQ%&SLHAJ3MON?{sh(@OwO9|1bk3CNj2z|Kqpab^*yGl#&OxdiUaCkSUD5pot2q_c#mc9s$~ z&N8CbSx(eBD~Nh$CDGte!~};S8XcBsa=3@(44#Rn}|MVGcn!SLdTBNh0d3`i=4&eVrRjaCC;wCrOx8QWzGjB%bf$s zE1XfCE1l<>C?~Cqb~Zh%D}?>5lTpSw3w^xfB?`{^0@0Z~Msk+r$WC0U;v9@towy9m z`FF1FT&OafoPg=%mRZga$aennJIp`&SA68J8p?wP=)((sM7r;RONme3b>zz0Qd6{=zbl7 z-0woL`%4IMe+!}R?;*_nGlaYSLWJ8t6mkcINOxeU+8rFKafgIz-C?0RcSNY(9TjSD zM~5c3zEGnZ8ESH)Ld|Y;XrdbvYH?#jt!`YX&5aLDauY(6-NaD4n;hzJQ$n5Y*ie_7 z8tQh_Lp^RrsMqy}rns4*scu$inwuT!b8|w|-Q3U&cU)+ud(uD4Jy1B?O)i_`7WwD8 z%i8C;DmLGJl~~}$6fJb8MlEumNL%bay88{B(U z8{OE-P436ho87%JTih7mR<|#8n`>rocfY`QxI6Hj?iBwnw>EaS`|s#I?y}OoZgc%U zcXRW8_i*6>7l=LR?!gbaw-XM#*XobBvCT)_{LW+U=(gkTxQG+(l){rPA9u?2s!qG# z0%zO>{8yV!rvt&hI%{!sD2-C5Aj%MbPU3PJ0-tXj0FDq`A_XjcCqblck%c|yjKgZ1T4ph$f?nW-~`ll@P z3L6)BVR*3@5xK-0TDH{d>RsmT>R#?WR#e2S5^~zHkUcr zyzhaqH)zT#?`+FzuLD`*#YeC8qWtT;JMHT|&$q#=B{zB*)tkK2+`Zl}1^c|$^Y(jh`ww_>;z93m-yzS5 zI_y1Fa>Uz`d(>+wJmytJ9rxDeo$!Vxp7e4HPI)<%r@a@(p7CBH&U%s4&v`qu&wInb z3toTlqSw}Y$qO`J_ChIFyj0&+@6m{B-Z!z=y{N<+-rs?nUS9ky?;nM?J*VZ4_juaf zho_%=-qFJQ-r~jwUTbE*@E>IV@So&>aDQ@OcmO#lJct||9!w4i4<$i#3ZnG~)flfxjH5{AgJVT?=-2g$TBPNs(mG9w%!{b7>K3|Es`;W{!qTu&fQu26AF}6WJ2pOtyx%kZs|u+#gpZQF;bY{K@CkBi_#`M2uc}1tqto4Y`cA#mai_cO_8dAS zrI8SjRuK-n>wrqx-QC^F?(V&h-QBJ8&c}Fu|7Wcg>E2qmzdMq0pu4H~V0TQ%q3+S) z!`<%}AL;%p>S*`4*kj#~mLBgGb53+u=AG>RrubC%-pte8HJxX=Z{TOUq4aaze^j3D zuBpG!&DCA(em!uhdu7Yz?uRR{boVO0+U+J>>mJ;Cy?bx*jc%O0+5KDWt?qr$?e5EY zce)(biez((jN5r=AQJ0=3exb=HB$x=05bb=Dzgx=6>{z=Kl2U<^lAb z=7IFx=0WuR=E3wo%|qx1fT8q5K!AP}2-1%OQS=i)H2owHLq7$?(k}pU^h-cI{U0EK zei=xlUjdTnSAk^uHDDP129QF(38d2h1=8qufOPs@AcKAn$fW-d7*4+rWYHf0+4N^X z4*fZhOMe06(f>BOr-OGHu~RuJ^gRWn;rpl(xpHbJrbBimjRRM3SbId2~4GHfN69c zFr6L^%%H~rGift+7X8z(*)%?V4n3QkOK*;yM?aA`pPt{jfbN~Yke=MSh-Qix(*@B> zXtru8eI;udy`*9}{Y%UWdTPu{`nPeb=!s>k>0heX(3P=k=|R)h(d!G>)1|c==pF4F zX$RRv&l$Iw{;7Nmy}NuXjYe;ywfyb$(aIh4(WIU9>$$t=^$EM_h4>!2x@#|8mbH&I z8oKFQnKXT_jG@mavGmRWM{f%7w2&dtCptv>PC%mP;4=Mij6!3{D!sTtqvNu4S_l~Q zv0RgWF3X~SX|`zwaOmu2mnLD4o>=bF>q;Z^#+3cE+HipGh(1U&*@tL7|1ga<9-)72 zK1#oW9HU=~K2F!CoS;L=C+U^pQ}n37X*#X=44oT&mi`DmM~@7jr@v~yKo0^h(&?3# z=oi{9(-+&W(DO>J(#JyA=x;Nw)8lh)&@YwTq(232(WOnd>D^QA(CJBc=@jxF{bb-i zy)(84GZyH{GyuJraX@dT5$MA-0ezWfpdSMO{TUD#z(Bx21_K5$Bruo>14Eb=U?|fH z1eozakeL8PF%yAkrVWT;+JRW66NqCb0rAXaAc2_*Br?;0BxX90%*+6WF|&XaW;T$@ z%mLDvxj;HI56EEV1DVVMU^uf7$YK@&+00@fhgkyTGE0FxW*LyrtN;p_l|Ui08W_Q> z1&Ww;Kryo(C}B1OrOXy!B(v?`pwJGWoY@6bFuQ?K%wC|9*#}fH-9R-%12qf>)G|C! z$A~~ZBLSls6&Sd!CO3XPlU}}oNg2J7iOJi9mH zVX~6<2eR7U6kE9-BqK6-6(2^6(Uv(#$ZTKnX=i1ZE z_f=<@(Q#*)UxMeD#ngG`QppA8y9(Ij+v+6ptt?>pE z7=Dv^t@IXiG3hq*Zq*&;qpG`1Ma4a)f9!qcN<$C!VX!Cr2-u5#6zt7D2KHee2m7*5 zfc@Af!T#)1-~je%a3K3EIEZ}?9Lzos4q;yahq5n$0rq7u$i4zbv9E&B?CW3*`vw@x z{uhj6-vZ;=x4{JV9War74@_d;2b0+kz+vo%U<&&Yn96<(rm>%Z>FlRq2KyP9$$kzF zXTJoq*ss8B_G>VQ{RYfszXkKy@4$Tad$5500W4&H1V^wxfko_JU@`kQSi<%IOWB^_ zNVXSP#`Xcr*}h-}+YcPY_6IB3!C)0T1gvI9UBGKv(eyaHU=ES#)4zn zIIw|@2OHT$u!&6qL+miHnN0x!HWdWfG!SAlK$y)05q3C;vRNR;W`j7J3leM|NV54L z#TJ5Lb_CeM7J;p7F*u$r0VlAf;6!#L*v6KD?QA*N!Hxnu*($J$tp+EtHQ;2n7M#M4 z0jIKK!D;L`a5~!v&S0Csne2l#vskZsHd`1ohxHrhvL7VQW1mQ$&wiV{fIVNaklmWQ zh#gnDn6>aF>@TTH*>Y$Z+cS1Kd!=Rtdp~O>dp&m*yCblgJkh+VgE^SStQ$Izl!%+D>lM@T)m$i8-0NNA9#?Rm4Ap` zU2vGiijJ`3vyQS8!pB%W_Bi`e=me{joMgjQr`Wu}X*NKfVarm^veV1YvCF~pY-`>H z*2%lbR*bvEJ^){4g=tsV_oiQE(^IdpU*}(EFNSZhFBaTnGxBe-&t~0b&H6hmm~@w2 zmwt~e%e~KjJF*8C0()}JU@r~=dvgfbheN@>90vB|aIil|fCD%Z9LQ1NAg%=*%(a3; zxbfgnZUPwKCW1k(4UFR2!Dy}njNv-LSgs3<<0gUe+*B}un+7Iw)4?Qe2AIsv1c!06 zz!Yvan99us)3|wHIyWE8;1+_J++uJzw*<`MmV(*bN-&381?FR3%GS) zA-4e>!EFMIxXoZOw*@TW{(V^Fwt*wL?O++V11#ruffd|ta1^%(tmO8BRop(Xn(GE@ zI2x?wSg?-czsRU?F!kYZ3QW$6}6;UBdlYv6Op|SjPQOyqp_evx0lBekJ!+ z+$wHK&1$Z`a}D=aXf1aYU&qDQuIFCP-@xrG+sG}?-Nd!!Z03GS*uuS?xs}^lw~f0Q zyPbPGu!9?2w3CAxcX78mhcbCC z)G2Tewul^_B5_-AnY)H7+*>&+mlV>t{W&^!FW%s!kjdq?TAUTMx%b98+`BC>w$;0L+p#zS0f>tSvRaD?j^eUuvu9pmu!<6OA?1b3|AB&SU} z#Zk4Vxu(=JTw?uMu2;)BZhrfDE~D-Omz;8u%gDaOJw5s|rvO*Dr3F{H$KtPXpN+fD zy-<0Bdw=Xr?!mTOT#u~V+>oR@oEf;wHK*L;>XPqsaY;S+TVPNAHrR{53-;#kfqnS< zU|;?Ls2~3z)SrI{8o)mc4dfqz2Jw$UgZamyA^a22Q2xn(N9(7cApbNJ#Xkc@^Up#t z{Buw&|2!1OzW~MaFF^_Xf1pJEWhjY%1xn^$gNE_1Ln-_lP%8f>l*a!TO6T8#GWfTl zO#U5cIR7q`#lHt-^Zy6s@b5#p{0C4T{~?sme*_iqA47%wr_c!gbEt^_0xIVJ2bJ(& zLZ$py&`ADksEq#xD(An2D){f9QT+E%CI16d#s3IZ^FKi~{LfG=|0`6-{|43bzeA(> zKcO-FU(i_oZ>WLq0X6bHp(ef;6ykeB&3qpS;QK-#-w%TL{t(O$fDnElgz|$Rj2{f) z{1AxXV<3``g(yBA3iAn23!ezJ@=4HmJ{g+8r$7_=RH%(lgWCBFsDsahI{D#H7oQDH z;&Y(Md@eMF&x5A&`Oq}J0GiGhLNoXg&`iE$)GYp;?AiQaY7YNAHJ29~=ka=IKEEVu z0e>-eA%C%W5ue_=nEyO^3IAZ`QogKs89y{}IX@_81^+p@lK-N56@RL9HJ_5WhHo6P zmcLlFjxQOxp8t~Az&}B3=>gjyb~*Og+ng zmVA!CQ*xd!O1i**Q+1JltLhS8oOzjlIdp~Z*L0PCG5Z=nJpVd>IDCWut>z|wg}lZ8 zK;GtePQ1gvntqoDWAE|*i@VS7F6$wbKs|+#P%ohj>Mc}2eS}d^-+$H2{e&v0zfcVg z5Ne=-LM=2%Xodz005n7Zp`ii<1q2uh3J4S>pis0xK`}xYiWOR*IH47a7sf*g!bB)h zXor%74k%gZgoX)SP>L`KN);wUX~HxpU6>AK2s5BeVJ0+Om<44CbD?Zu9+V?2hH{0a zP@b?1$`@8a1;T2mP*@L*5H>(X!bYfA*bJ2jTcA>5D>PEr29*ihp>km-R3YqwMhUy2 zN?|WlCD2f{z(X~H0M!aAR3~UqyB7tK4B=IH zrqH8!mT)6|wvZY%M_3w|D=bZ)C;XN@U+5oNAiUYKP>3p6B$T!;7FO3R5uS-#D)*UxsEJx9v}LUqen{RRJm0cWxEZ}k*j=|- zXsX{L+)vmljL+C6yxg)~2$k#*GE;X7?<1|g^(XI=nlMG?ZBvbgZ z&=Te*+k%$m2!F-9!mHVy&>iOs4ipjoDA_MOJnVpQyz-zh1vw;)C^{^>ntVhULL3#o z&NwDClpYrrjyfTX?K~;`5;!H?C_60>DQAR^+Oxu++2@2|dFO@p>I(vwc~O|0a!D9C z?6UB9;EE96bX6Epd`-YdT^D8sZU|`pO(A;REuk^vws1T5j_}|7yMmo@PXLnd3l9$K zA-)0k6#onN65ob3zkmme|AU8!U&2Gh zui=3B4IC7|gQLXn;b`$kI7a*ljun4_h5S4v!Qw;4*PITrOt86=EJdO3a5V#R9lWEQG7Y5pa!I1lNki zaGh8J*NY?J(PB9~My!Cxilg8Lu?lV!Yv3la77mGZaI;ts1L8Os6dPekY=U7CfDsXb zQ4xkQ5ruIPg9(v$I;^V^^Ew`SXMmW#)*gGd2#1BK|Eh6 zif?C2;%l%h&MZ;Hsr9P(VwNV(%+Gpa}S79LI=h91&74H;tq>H#2pd2qN8G7(J^si;JDZ;`-C_k_N4eu=#=A|MRq#M*4LnF%2M?Ck!$YJE@K9+Z9FR7{L1_ydC2fPFrR{Kxv=fe% zcENGdZa7}r11Cs(;Y6t$PLgOiSz_Q}5)Y?H0-P#|aGE5+>5>d*NIIM;8Srq)gtH_I z&X#OAM{?j?$%XSIAI_H|aDlWRE|df& z(mTjB>0M;H^d2%p`T&_JJy1VO8ksp;dM162gl5i_rZ&x!UP+!W`I!qOpnRcpp=^<~ zsC2OuRlG!MtXL`mBbG@^k>%2t=_{nnz)ETLuvOBO_|?*piEE_SO4dqu#;lXN+Sg0Z zXKj%7HEfiqnoUvzv|0Kfc8l~*$5yF5yiJ1hwo8XncStjWJEe0KyQHTByQO)td!*-+ z_e%eX+b1<At_36h$Q_SlBLUSibR#D(#IK^ z#1GS@zw!*Ju-%kajIyM!M%mK#SVyXFawV|KlV*b%#3f0Jx-7jIcSRabT$Mfnu1RUN*QG}~Zb*Y-Zc69lZb`EfZc7ie-I0)z zyVBZ}d(ys=`%-LP5BWo+r~DDpOa2(?Eq{Xakv~QH%AX<1!w4?7AcWkCkn#kCk|!czxeaNNJCIhn6B#deArs_D$V7QE z(k4$u+U03ThddqWlxHAa@=RosJR6xT&qb!l^N^|Xd}Nxu0GTc?L}ti~keTxHsk7v? zl-ctC70i*_8|TWk@$=*tN6(iBMTMT_MCyhO%3mde4{W%9e(%jMs4 zR>+H5R?1UySIIjYSIaLDYviuzwepIBb#iU&difT-L8gaql=l>GlJ696mft6~$kC}= zhd|mz|(~z}fQ|=RO$=9Q8`DUXd zKN0K7b;X{%r`?ya@`(ImaKC&$ctD;u?x6f<{vmm9{9*Ztwj=V6x}$PCa!fwba9p0A zbV7b6>!kcZ$0>OjbXtBr;fy@G^Q_#GaZcWVpO^Ol7v#j&i?S1YNj{f*Sq`UPkyER# z$~l?WZ<+GYOirX+(sqC1iOa|vG zc_|B&%KC-M>GnlR4`i{z#Vk?6;Q=#C?uzns$yMe1_G`)~#n+XKfg6fibyFD~ zeM|Yd;I{JD$U917%Uz|c>7LS_d|#=q?4kaG_EdjGd#S&nz182*KI$K6U-eJ4pZXWt zU;P^$p!Prqs=d%bYHxI~+7}(7_CtrN{n3Cr01c`G(I|Bg8m$gSW7HvNtU45pQv+zc z8blM+C^S)xMw8SSG+B*BhpBOBiW-lmstIVCnuw;WNoaTonq%|i3lY_velK?~JfbcC9Z7O4ejv08|hs3Xu)wFn)l7Nccq30kg}q7~{$ zbd*|#R;uM_m0E#TtE12wwGypWtI#^N8m(7r(9vowI!3KS$Ex*cgE|InRL7!CY6BWl z8_{MpgaRsnf+~nYDvZJ^f+8x4qAG@BDvshR@vkU`L`juGDK(6S)fTixZADwv@#uJU z0y;sRh)z`7&^EOlZC5+c4z&~QRJ+hFbrL#Bos3Rar=U~RspwR78ahp#j!su+pfl8& z=uEYL&Mftl)Y)oo%N(_}ey;ifF;8`q=c`NN7N`$|7OEqg7pYC?V)cQ>CF(bYOVvQa zGWDm% z7aJM1wTe|k#hf}Ng;!4|3u;=1s6JXKsZEfqz8R&cm(x@=IiRUWYIOBjz)zoy<(U&*+ywzT)q zW}!W`*=R3q4%%Cri}umxp?$UaXg_TM+Fx6U4$u~%1GUBIAZ-acSX+t?(Uze@wdH6) zTY(0(m1vZ<3XRrQqcPeVG*(-S#%b%&cx^qJplv`CwT)1eiQpgEd_=4v*Yr#Wc8=Ai{z1TEAKpd++{XpwdZ zE!GaBCE8K6R6Bu=)J~#h+9|YLJB?OoXVFpGIkZwck5*|H(Q54yTBBV?YqhIropuea z*RG?ZwHxRd?It=_yM;Drx6wxJ4%(#MMMK&>v{}240@^<)s6B{5+CvzuJ&YmRBN(bZ ziecJg7_L2m5!#a&sXc{J+S6EAdj@OKp2b?V=dkhG^VkIK1#F`BBG#t8gtcq`!8){; zu}DpV^4DD@frdAd^OS=@Bt$jOUj#fEr zu2wc}o;ERkzV_+31=_~uh1!R}BJHDp6M*^6OSJy*QcVmm)3V6r8eP3YE6-S|wRf)4 zifdPE@8zx04#ch1j%BUWvV-fj-Ax-bx@x1gA$^l3v~Sj)qPA$apsiXsZku+cc)LcF z?9hHG{ud3)+@*EL?AAW5+M|t4->bbI+^5aR?AA_X(AtNojP`96t1WBcv>g+9ZDWO? zZ7deGUrHryV5_V>nXhPEtg2m!)wJlKt}(5Kb_q8%I@Z$0q}$rAu%jICk@d&EW^M$3h3S!H7c_0-?RdgI1P6`XH=GAB+|2L$DHkC|0Tm zu#tKYE7PN}ay=TW&||PsdMs9{$6-}^JXWnIU^RLoR;wprb$T*ZuMfjU>nYe6Jrx_P zr(q3xI@YLXU`=`^7Se}f&3YCF=-C*k=U|YYi@|yxhUobisuy6GUWnoP2#nB+Fj6nZ zD7^#=>!nzWJ`!uy%dqi!IW|GBz$WUWur|FCYuBr=4!s)d)N8OVy%w9K*JG3Q(byDy z3^r9Ci%ruTu<80ZY=+*5&D1MPX6ahWY~4WS=s@ROy@;5nmrRgUc*)$Be&_h$?f{wi97VwsXO&KV|M9J*?eHy*GJKf4=FE zUJM-8OInWT2gV%L|A{`P-vN*7v-3~rr*co~Ge@4%=Rl|RChCknBH^t5UduT>RDE8r zF1w%~E5E3JKwi>MWnI?ah`FNQE554#L0;3J%e<~nOS+*`!*A;M^KR*xvY^q&4@{(U_^+{0+XdKw|Dm(h&%HUO-T0b+d(2*lu28j(e zC~Sxk#)cX#Sioq-g2s3(%9w~n8*NyO(T>F$9ax;viNzaTSb{MLOEe~9NyZc`*_etA zGp1oF#&j&zn1Q7kGqH4I7M5Ym#xjjL*l=SmmSxPtvW@vzjXu?`z$tj8*i4Oo@25vw*f zVKv5PtoC1#QJt|Bt2ee`qmAv@7-I)E*4T+P7`w1WV>k9MD1n8Hy;!rc4+D&D3^ZsA zG8hatSPU^Z3^o28TMPli4G|*@2_p>|qYMQL8!FafXjrSEW8)12n_!sOM8m?`3>#}V z9IV4|u};Iox(pwiWJIvZ#(r#yaR8fY9K@y>hp_3!VQhwR1e<9bnmEh2**4qwv}TU+ zXu(`#LE$_DkDG4{4JkqaO$@k zDWyA%dks5{cSr0p4%Y8B$};vC-;dmDyqB@hAhNrS1tqkRkk1%T1X$yRbk6vgq>SU0Lj!^kf;jlyx3(J$II;6}$d8|xaSEuPVt z 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

A0LitqsI^PT_}&YjB_9T0FeC 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 - -/* 录音机状态 */ -enum -{ - STA_IDLE = 0, /* 待机状态 */ - STA_RECORDING, /* 录音状态 */ - STA_PLAYING, /* 放音状态 */ - STA_STOP_I2S, /* 临时状态,主程序通知I2S中断服务程序准备停止 */ -}; - -typedef struct -{ - uint8_t ucFmtIdx; /* 音频格式:标准、位长、采样频率 */ - uint8_t ucVolume; /* 当前放音音量 */ - uint8_t ucMicGain; /* 当前MIC增益 */ - int16_t *pAudio; /* 定义一个指针,用于访问外部SRAM */ - uint32_t uiCursor; /* 播放位置 */ - - uint8_t ucSpkOutEn; /* 放音时,是否打开扬声器 */ - - uint8_t ucStatus; /* 录音机状态,0表示待机,1表示录音中,2表示播放中 */ -} REC_T; - -void RecorderDemo(void); - -#endif diff --git a/User/app/inc/old/form_camera.h b/User/app/inc/old/form_camera.h deleted file mode 100755 index 977a08f..0000000 --- a/User/app/inc/old/form_camera.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 摄像头测试程序 -* 文件名称 : camera_test.c -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __CAMERA_TEST_H -#define __CAMERA_TEST_H - -void TestCamera(void); - -#endif diff --git a/User/app/inc/old/form_can.h b/User/app/inc/old/form_can.h deleted file mode 100755 index e2361fc..0000000 --- a/User/app/inc/old/form_can.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : CAN网络测试界面 -* 文件名称 : form_can.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __FORM_CAN_H -#define __FORM_CAN_H - -void FormMainCAN(void); - -#endif diff --git a/User/app/inc/old/form_dac8501.h b/User/app/inc/old/form_dac8501.h deleted file mode 100755 index bd235b1..0000000 --- a/User/app/inc/old/form_dac8501.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : DAC8501测试界面 -* 文件名称 : form_dac8501.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __FORM_DAC8501_H -#define __FORM_DAC8501_H - -void FormMainDAC8501(void); - -#endif diff --git a/User/app/inc/old/form_dac8562.h b/User/app/inc/old/form_dac8562.h deleted file mode 100755 index 319b50c..0000000 --- a/User/app/inc/old/form_dac8562.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : DAC8562测试界面 -* 文件名称 : form_dac8562.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __FORM_DAC8562_H -#define __FORM_DAC8562_H - -void FormMainDAC8562(void); - -#endif diff --git a/User/app/inc/old/form_dso.h b/User/app/inc/old/form_dso.h deleted file mode 100755 index 6346281..0000000 --- a/User/app/inc/old/form_dso.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 双通道示波器程序 -* 文件名称 : form_dso.c -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __FORM_DSO_H -#define __FORM_DSO_H - -#define SAMPLE_COUNT (1 * 1024) /* 采样深度,即最大样本个数 */ -/* - 示波器相关的数据结构 -*/ -typedef struct -{ - // uint16_t Ch1Buf[SAMPLE_COUNT]; /* 通道1数据缓冲区 */ - // uint16_t Ch2Buf[SAMPLE_COUNT]; /* 通道2数据缓冲区 */ - - uint16_t *Ch1Buf; /* 通道1数据缓冲区 */ - uint16_t *Ch2Buf; /* 通道2数据缓冲区 */ - - uint32_t TimeBaseIdHold; /* 暂停时的时基 */ - - uint32_t TimeBaseId; /* 时基索引, 查表可得到 us单位的时基 */ - uint32_t SampleFreq; /* 采样频率,单位Hz */ - uint32_t TimeBase; /* 时基 查表可得到 us单位的时基 */ - - uint8_t Ch1AttId; /* CH1 衰减倍数索引 */ - uint8_t Ch2AttId; /* CH2 衰减倍数索引 */ - int32_t Ch1Attenuation; /* 波形1幅度衰减系数(原始数据x10后,再除以这个数) */ - int32_t Ch2Attenuation; /* 波形2幅度衰减系数(原始数据x10后,再除以这个数) */ - uint16_t Ch1VScale; /* 通道1垂直分度值mV单位 */ - uint16_t Ch2VScale; /* 通道2垂直分度值mV单位 */ - - uint32_t TriggerLevel; /* 触发电平(ADC采样结果比较值) */ - uint32_t TriggerUpEdge; /* 1表示触发模式上跳沿,0表示下跳沿 */ - - int16_t Ch1VOffset; /* 通道1 GND线位置, 可以为负数 */ - int16_t Ch2VOffset; /* 通道1 GND线位置, 可以为负数 */ - - uint8_t ActiveCH; /* 当前焦点通道 1表示CH1, 2表示CH2 */ - uint8_t AdjustMode; /* 当前调节模式,0表示调节幅度,1表示调节偏移 */ - - /* 使用2个缓冲区完成波形的擦除和重现 */ - uint16_t xCh1Buf1[310]; /* 波形数据,坐标数组 */ - uint16_t yCh1Buf1[310]; /* 波形数据,坐标数组 */ - uint16_t xCh1Buf2[310]; /* 波形数据,坐标数组 */ - uint16_t yCh1Buf2[310]; /* 波形数据,坐标数组 */ - - uint16_t xCh2Buf1[310]; /* 波形数据,坐标数组 */ - uint16_t yCh2Buf1[310]; /* 波形数据,坐标数组 */ - uint16_t xCh2Buf2[310]; /* 波形数据,坐标数组 */ - uint16_t yCh2Buf2[310]; /* 波形数据,坐标数组 */ - uint8_t BufUsed; /* 0表示当前用Buf1, 1表示用Buf2 */ - - uint8_t HoldEn; /* 波形采集暂停标志 1表示暂停,0表示运行 */ - - uint8_t CH1_DC; /* 通道1 AC/DC的设置 */ - uint8_t CH2_DC; /* 通道1 AC/DC的设置 */ - - uint8_t CH1_Gain; /* 通道1 增益的设置 */ - uint8_t CH2_Gain; /* 通道1 增益的设置 */ -} DSO_T; - -/* - 定义支持的采样频率 -*/ -typedef enum -{ - SR_1K = 0, /* */ - -} SAMPLE_RATE_E; - -void InitDSO(void); -void SetSampRate(uint32_t freq); -void DsoMain(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_fm_radio.h b/User/app/inc/old/form_fm_radio.h deleted file mode 100755 index 66444f7..0000000 --- a/User/app/inc/old/form_fm_radio.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 收音机测试。 -* 文件名称 : fm_radio.c -* 版 本 : V1.0 -* -* Copyright (C), 2012-2013, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef _FM_RADIO_H_ -#define _FM_RADIO_H_ - -#define FM_RX 0 -#define AM_RX 1 - -#define SI4704 4 -#define SI4730 30 - -/* - Worldwide FM band support (64–108 MHz) - Worldwide AM band support (520–1710 kHz) - - 中国范围: 88-108兆赫信号调制方式是调频(频率调制)每个频道的频率间隔是0.1兆赫 -*/ - -typedef struct -{ - uint8_t ChipType; /* 芯片型号代码 */ - - uint8_t ucMode; /* AM 或 FM */ - uint8_t ucListType; /* 电台列表类型。武汉地区或全国 */ - - uint8_t ucFMCount; /* FM 电台个数 */ - uint16_t usFMList[255]; /* FM 电台列表 */ - uint8_t ucIndexFM; /* 当前电台索引 */ - - uint8_t ucAMCount; /* FM 电台个数 */ - uint16_t usAMList[128]; /* FM 电台列表 */ - uint8_t ucIndexAM; /* 当前电台索引 */ - - uint32_t usFreq; /* 当前电台频率 */ - uint8_t ucVolume; /* 音量 */ - - uint8_t ucSpkOutEn; /* 扬声器输出使能 */ - uint8_t ucRssiEn; /* 信号质量定时刷新 使能 */ -} RADIO_T; - -void RadioMain(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_gprs.h b/User/app/inc/old/form_gprs.h deleted file mode 100755 index 176d1d5..0000000 --- a/User/app/inc/old/form_gprs.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试MG323 GPRS模块 -* 文件名称 : gprs_test.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __GPRS_TEST_H -#define __GPRS_TEST_H - -void TestGPRS(void); - -#endif diff --git a/User/app/inc/old/form_gps.h b/User/app/inc/old/form_gps.h deleted file mode 100755 index cfadd51..0000000 --- a/User/app/inc/old/form_gps.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : GPS定位模块测试程序 -* 文件名称 : gps_test.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __GPS_TEST_H -#define __GPS_TEST_H - -void TestGPS(void); - -#endif diff --git a/User/app/inc/old/form_hard_test.h b/User/app/inc/old/form_hard_test.h deleted file mode 100755 index 99d3c56..0000000 --- a/User/app/inc/old/form_hard_test.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 硬件测试界面 -* 文件名称 : hard_test.h -* 版 本 : V1.0 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef _HARD_TEST_H_ -#define _HARD_TEST_H_ - -extern void HardInfo(void); -extern void PrintfHardInfo(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_http_server.h b/User/app/inc/old/form_http_server.h deleted file mode 100755 index 1d6b8f8..0000000 --- a/User/app/inc/old/form_http_server.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : WEB服务器程序 -* 文件名称 : http_server.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __HTTP_SERVER_H -#define __HTTP_SERVER_H - -void WebServer(void); - -#endif diff --git a/User/app/inc/old/form_mems.h b/User/app/inc/old/form_mems.h deleted file mode 100755 index d9625fd..0000000 --- a/User/app/inc/old/form_mems.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : MEMS 传感器测试(I2C) 三轴陀螺仪,磁力计,气压计, 光照度传感器 -* 文件名称 : mems_test.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __MEMS_TEST_H -#define __MEMS_TEST_H - -void TestMems(void); - -#endif diff --git a/User/app/inc/old/form_mp3_player.h b/User/app/inc/old/form_mp3_player.h deleted file mode 100755 index 1e9854c..0000000 --- a/User/app/inc/old/form_mp3_player.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 等待开发的程序界面 -* 文件名称 : reserve.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __MP3_PLAYER_H -#define __MP3_PLAYER_H - -/* 定义一个用于MP3播放器的结构体 -便于全局变量操作 -*/ -typedef struct -{ - uint8_t ucMuteOn; /* 0 : 静音, 1: 放音 */ - uint8_t ucVolume; /* 当前音量 */ - uint32_t uiProgress; /* 当前进度(已读取的字节数) */ - uint8_t ucPauseEn; /* 暂停使能 */ - - uint8_t ListCount; /* 播放列表的歌曲个数 */ - uint8_t ListIndex; /* 当前歌曲索引 */ -} MP3_T; - -/* 歌曲列表 */ -typedef struct -{ - char FileName[13]; /* 8+3结构文件名 */ - uint32_t FileSize; /* 文件长度 */ - char LenFileName[256]; /* 长文件名, 可以用于显示 */ -} PLAY_LIST_T; - -void MP3Player(void); - -#endif diff --git a/User/app/inc/old/form_oled.h b/User/app/inc/old/form_oled.h deleted file mode 100755 index ed1cf33..0000000 --- a/User/app/inc/old/form_oled.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试OLED显示器 -* 文件名称 : oled_test.c -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __OLED_TEST_H -#define __OLED_TEST_H - -void TestOLED(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_reserve.h b/User/app/inc/old/form_reserve.h deleted file mode 100755 index a98a241..0000000 --- a/User/app/inc/old/form_reserve.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 等待开发的程序界面 -* 文件名称 : reserve.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __RESERVE_H -#define __RESERVE_H - -void ReserveFunc(void); - -#endif diff --git a/User/app/inc/old/form_rs485.h b/User/app/inc/old/form_rs485.h deleted file mode 100755 index ed8f550..0000000 --- a/User/app/inc/old/form_rs485.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : RS485测试界面 -* 文件名称 : form_rs485.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __FORM_RS485_H -#define __FORM_RS485_H - -void FormMainRS485(void); - -#endif diff --git a/User/app/inc/old/form_touch_test.h b/User/app/inc/old/form_touch_test.h deleted file mode 100755 index 8ab6036..0000000 --- a/User/app/inc/old/form_touch_test.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 触摸测试界面 -* 文件名称 : touch_test.h -* 版 本 : V1.0 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef _TOUCH_TEST_H_ -#define _TOUCH_TEST_H_ - -extern void TestTouch(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_usbd_msc.h b/User/app/inc/old/form_usbd_msc.h deleted file mode 100755 index 5722457..0000000 --- a/User/app/inc/old/form_usbd_msc.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : SD卡和NAND Flash模拟U盘测试程序 -* 文件名称 : usbd_msc_test.c -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __USBD_MSC_TEST_H -#define __USBD_MSC_TEST_H - -void TestUsbdMsc(void); - -#endif diff --git a/User/app/inc/old/form_wifi.h b/User/app/inc/old/form_wifi.h deleted file mode 100755 index 60e5413..0000000 --- a/User/app/inc/old/form_wifi.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试ESP8266 WIFI模块 -* 文件名称 : wifi_test.h -* 版 本 : V1.0 -* 说 明 : 头文件 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef __WIFI_TEST_H -#define __WIFI_TEST_H - -void TestWIFI(void); - -#endif diff --git a/User/app/inc/old/status_menu.h b/User/app/inc/old/status_menu.h deleted file mode 100755 index eb53a98..0000000 --- a/User/app/inc/old/status_menu.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 主菜单模块 -* 文件名称 : status_menu.h -* 版 本 : V1.0 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef _STATUS_MENU_H_ -#define _STATUS_MENU_H_ - -void status_MenuMain(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/inc/old/form_main_menu.h b/User/app/inc/status_tvcc_power.h old mode 100755 new mode 100644 similarity index 58% rename from User/app/inc/old/form_main_menu.h rename to User/app/inc/status_tvcc_power.h index 54421d0..a3b9bb3 --- a/User/app/inc/old/form_main_menu.h +++ b/User/app/inc/status_tvcc_power.h @@ -1,20 +1,17 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 主界面 -* 文件名称 : main_menu.h -* 版 本 : V1.0 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#ifndef _MAIN_MENU_H_ -#define _MAIN_MENU_H - -extern uint8_t MainMenu(void); - -#endif - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ +/* +********************************************************************************************************* +* +* 模块名称 : 微型数控电源 +* 文件名称 : status_tvcc_power.h +* +********************************************************************************************************* +*/ + +#ifndef _STATUS_TVCC_POWER_H_ +#define _STATUS_TVCC_POWER_H_ + +void status_TVCCPower(void); + +#endif + +/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/main.c b/User/app/src/main.c index 4b23996..8bcf5ea 100755 --- a/User/app/src/main.c +++ b/User/app/src/main.c @@ -26,6 +26,7 @@ #include "status_temp_meter.h" #include "status_programmer.h" #include "status_system_set.h" +#include "status_tvcc_power.h" #include "wifi_if.h" #include "ff.h" @@ -52,6 +53,7 @@ static const uint16_t StatusOrder[] = MS_RESISTOR_METER, /* 电阻表 */ MS_CURRENT_METER, /* 高侧电流表 */ MS_TEMP_METER, /* 温度表 */ + MS_TVCC_POWER, /* 微型数控电源 */ MS_PROGRAMMER, /* 脱机下载器 */ }; @@ -142,6 +144,10 @@ int main(void) status_ResistorMeter(); break; + case MS_TVCC_POWER: /* 微型电源 */ + status_TVCCPower(); + break; + default: g_MainStatus = MS_LINK_MODE; break; diff --git a/User/app/src/old/bmp_file.c b/User/app/src/old/bmp_file.c deleted file mode 100755 index 71288a8..0000000 --- a/User/app/src/old/bmp_file.c +++ /dev/null @@ -1,226 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : BMP文件处理模块 -* 文件名称 : bmp_file.c -* 版 本 : V1.0 -* 说 明 : 主要实现将屏幕截图保存为BMP文件 -* -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-03-01 armfly 正式发布 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "ff.h" -#include "bmp_file.h" -#include "ff_gen_drv.h" -#include "sd_diskio_dma.h" - -/* - BMP文件的组成结构 : - - 位图文件头(bitmap-file header) - 位图信息头(bitmap-information header) - 彩色表/调色板(color table) - 位图数据(bitmap-data) - - 如果图像是单色、16色和256色,则紧跟着调色板的是位图数据,位图数据是指向调色板的索引序号。 - 如果位图是16位、24位和32位色,则图像文件中不保留调色板,即不存在调色板,图像的颜色直接在位图数据中给出。 - 16位图像使用2字节保存颜色值,常见有两种格式: - 5位红 5位绿 5位蓝 即555格式。555格式只使用了15 位,最后一位保留,设为0。 - 5位红 6位绿 5位蓝 即565格式。 - 24位图像使用3字节保存颜色值,每一个字节代表一种颜色,按红、绿、蓝排列。 - 32位图像使用4字节保存颜色值,每一个字节代表一种颜色,除了原来的红、绿、蓝,还有Alpha通道,即透明色。 - -*/ - -/* BMP文件头结构 必须添加__packed关键字表示结构体成员间紧密排列 */ -__packed typedef struct -{ - /* 14字节 位图文件头 */ - uint16_t bfType; /* 2字节 位图类别, 在Windows中,此字段的值总为'BM'*/ - uint32_t bfSize; /* bmp文件大小 4字节 */ - uint16_t bfReserved1; /* 保留,每字节以"00"填写 2字节 */ - uint16_t bfReserved2; /* 同上 2字节 */ - uint32_t bfOffBits; /* 记录图像数据区的起始位置(图象数据相对于文件头字节的偏移量)。 4字节 */ - - /* 40字节 位图信息头 */ - uint32_t biSize; /* 4字节 本结构的大小,在Windows中,总为28h,40字节 */ - int32_t biWidth; /* 4字节 BMP图像的宽度,单位像素 */ - int32_t biHeight; /* 4字节 BMP图像的高度,单位像素 */ - uint16_t biPlanes; /* 2字节 目标设备的级别(色彩平面数),固定为1 */ - uint16_t biBitCount; /* 2字节 BMP图像的色深,即一个像素用多少位表示。常见的有 1 4 8 16 24 32 */ - uint32_t biCompression; /* 4字节 压缩类型,0(不压缩), 1(BI_RLE8), 2(BI_RLE4) */ - uint32_t biSizeImage; /* 4字节 表示位图数据区域的大小以字节为单位 */ - int32_t biXPelsPerMeter; /* 4字节 用象素/米表示的水平分辨率 */ - int32_t biYPelsPerMeter; /* 4字节 用象素/米表示的垂直分辨率 */ - uint32_t biClrUsed; /* 4字节 实际使用色彩数目,则由位数定 */ - uint32_t biClrImportant; /* 4字节 图像中重要的色彩数目。0表示调色板内所有的颜色都是重要的 */ -} BMP_T; - -/* -********************************************************************************************************* -* 函 数 名: MakeBmpHeader -* 功能说明: 生成BMP文件头结构。 固定按24位色, RGB = 888 结构。存储低字节在前,B前,G中,R后 -* 形 参: _pBmp : BMP文件头结构体指针 -* _Height : 图像高度 -* _Width : 图像宽度 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void MakeBmpHeader(BMP_T *_pBmp, uint16_t _Width, uint16_t _Height) -{ - /* 14字节 位图文件头 */ - _pBmp->bfType = 0x4D42; /* 2字节 位图类别, 在Windows中,此字段的值总为'BM'*/ - _pBmp->bfSize = (_Height * _Width * 3) + 54; /* bmp文件大小 4字节 */ - _pBmp->bfReserved1 = 0; /* 保留,每字节以"00"填写 2字节 */ - _pBmp->bfReserved2 = 0; /* 同上 2字节 */ - _pBmp->bfOffBits = 54; /* 记录图像数据区的起始位置(图象数据相对于文件头字节的偏移量)。 4字节 */ - - /* 40字节 位图信息头 */ - _pBmp->biSize = 40; /* 4字节 本结构的大小,在Windows中,总为28h,40字节 */ - _pBmp->biWidth = _Width; /* 4字节 BMP图像的宽度,单位像素 */ - _pBmp->biHeight = _Height; /* 4字节 BMP图像的高度,单位像素 */ - _pBmp->biPlanes = 1; /* 2字节 目标设备的级别(色彩平面数),固定为1 */ - _pBmp->biBitCount = 24; /* 2字节 BMP图像的色深,即一个像素用多少位表示。常见的有 1 4 8 16 24 32 */ - _pBmp->biCompression = 0; /* 4字节 压缩类型,0(不压缩), 1(BI_RLE8), 2(BI_RLE4) */ - _pBmp->biSizeImage = (_Height * _Width * 3); /* 4字节 表示位图数据区域的大小以字节为单位 */ - _pBmp->biXPelsPerMeter = 0; /* 4字节 用象素/米表示的水平分辨率 */ - _pBmp->biYPelsPerMeter = 0; /* 4字节 用象素/米表示的垂直分辨率 */ - _pBmp->biClrUsed = 0; /* 4字节 实际使用色彩数目,0则由位数定 */ - _pBmp->biClrImportant = 0; /* 4字节 图像中重要的色彩数目。0表示调色板内所有的颜色都是重要的 */ -} - -/* -********************************************************************************************************* -* 函 数 名: SaveScreenToBmp -* 功能说明: 将当前屏幕保存为BMP文件头。结合FatFS文件系统使用。 -* 形 参: _index : 文件序号 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void SaveScreenToBmp(uint16_t _index) -{ - __packed BMP_T tBmpHead; - uint8_t LineData[800 * 3]; /* 按最大 800像素宽度分配缓冲区 */ - uint16_t i, j; - uint16_t pixel; - - /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */ - FRESULT result; - FATFS fs; - FIL file; - uint32_t bw; - char path[32]; - - char DiskPath[4]; /* SD card logical drive path */ - - FATFS_LinkDriver(&SD_Driver, DiskPath); - - bsp_LedOn(1); /* 点亮LED1, 表示开始截屏 */ - - MakeBmpHeader(&tBmpHead, LCD_GetWidth(), LCD_GetHeight()); /* 构建BMP文件头 */ - - /* 文件系统操作 */ - { - /* 挂载文件系统 */ - result = f_mount(&fs, DiskPath, 0); /* Mount a logical drive, 1表示立即执行 */ - if (result != FR_OK) - { - goto quit1; - } - - /* 打开文件 */ - sprintf(path, "%s/%dx%d_%02d.bmp", DiskPath, tBmpHead.biWidth, tBmpHead.biHeight, _index); - //result = f_opendir(&DirInf, path); - result = f_open(&file, path, FA_CREATE_ALWAYS | FA_WRITE); - if (result != FR_OK) - { - printf("创建SD卡文件%s失败 (%d)\r\n", path, result); - goto quit1; - } - } - - /* 写bmp文件头 */ - result = f_write(&file, (char *)&tBmpHead, 54, &bw); - if (result != FR_OK) - { - printf("%s 文件写入失败\r\n", path); - goto quit1; - } - - /* 开始读取屏幕数据,并写入文件 */ - for (i = 0; i < tBmpHead.biHeight; i++) - { - /* 读取1行数据到缓冲区 (注意:BMP文件扫描次序,从左到右,从下到上。和LCD逻辑坐标是垂直翻转的) */ - for (j = 0; j < tBmpHead.biWidth; j++) - { - pixel = LCD_GetPixel(j, tBmpHead.biHeight - i - 1); /* 读取屏幕1个像素 (RGB = 565结构)*/ - -#if 1 - LineData[3 * j + 2] = ((pixel & 0xF800) >> 8); /* R */ - LineData[3 * j + 1] = ((pixel & 0x07E0) >> 3); /* G */ - LineData[3 * j + 0] = ((pixel & 0x001F) << 3); /* B */ -#else - if (_index == 0) - { - LineData[3 * j + 2] = 255; - LineData[3 * j + 1] = 0; - LineData[3 * j + 0] = 0; - } - else if (_index == 1) - { - LineData[3 * j + 2] = 0; - LineData[3 * j + 1] = 255; - LineData[3 * j + 0] = 0; - } - else - { - LineData[3 * j + 2] = 0; - LineData[3 * j + 1] = 0; - LineData[3 * j + 0] = 255; - } -#endif - } - -#if 0 - /* 写1行数据 */ - result = f_write(&file, LineData, tBmpHead.biWidth * 3, &bw); - if (result != FR_OK) - { - printf("%s 文件写入失败\r\n", path); - goto quit1; - } -#else - - for (j = 0; j < tBmpHead.biWidth * 3 / 480; j++) - { - /* 写1行数据 */ - result = f_write(&file, &LineData[480 * j], 480, &bw); - if (result != FR_OK) - { - printf("%s 文件写入失败\r\n", path); - goto quit1; - } - } -#endif - } - -quit1: - /* 关闭文件*/ - f_close(&file); - - /* 卸载文件系统 */ - //f_mount(ucVolume, NULL); - f_mount(NULL, DiskPath, 0); - - FATFS_UnLinkDriver(DiskPath); /* 卸载驱动 */ - - bsp_LedOff(1); /* 关闭LED1, 表示开始截屏结束 */ -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/can_network.c b/User/app/src/old/can_network.c deleted file mode 100755 index a417bac..0000000 --- a/User/app/src/old/can_network.c +++ /dev/null @@ -1,165 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : CAN网络通信程序 -* 文件名称 : can_network.c -* 版 本 : V1.0 -* 说 明 : 实现多个CAN节点(节点的程序相同)之间的通信。 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2015-08-09 armfly ST固件库V3.5.0版本。 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -/* - 应用层协议:(自定义简单协议) - 01 01 01 --- 控制LED指示灯点亮, 第1个字节是命令代码,第2个字节表示00表示关闭,01表示点亮。 - 第3个字节表示指示灯序号(1-4) - 02 00 --- 控制蜂鸣器,第1个字节表示命令代码,第2个字节 00 表示关闭,01表示持续鸣叫, 02表示鸣叫1次 -*/ - -#include "bsp.h" -#include "can_network.h" - -uint8_t g_ucLedNo = 0; /* 点亮的LED灯序号,0-3 */ - -/* -********************************************************************************************************* -* 函 数 名: can_LedOn -* 功能说明: 通过CAN1发送指令,控制LED点亮 -* 形 参: _addr 设备地址 0 表示广播的 -* _led_no : LED指示灯序号 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can_LedOn(uint8_t _addr, uint8_t _led_no) -{ - uint8_t tx_buf[8]; - - tx_buf[0] = 0x01; - tx_buf[1] = 0x01; /* 点亮 */ - tx_buf[2] = _led_no; - can1_SendPacket(tx_buf, 3); -} - -/* -********************************************************************************************************* -* 函 数 名: can_LedOff -* 功能说明: 通过CAN1发送指令,CAN2执行命令,控制LED关闭。 -* 形 参: _addr 设备地址 0 表示广播的 -* _led_no : LED指示灯序号 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can_LedOff(uint8_t _addr, uint8_t _led_no) -{ - uint8_t tx_buf[8]; - - tx_buf[0] = 0x01; - tx_buf[1] = 0x00; /* 关闭 */ - tx_buf[2] = _led_no; - can1_SendPacket(tx_buf, 3); -} - -/* -********************************************************************************************************* -* 函 数 名: can_BeepCtrl -* 功能说明: 通过CAN2发送指令,CAN1执行命令,控制蜂鸣器 -* 形 参: _addr 设备地址 0 表示广播的 -* _cmd : LED指示灯序号 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can_BeepCtrl(uint8_t _addr, uint8_t _cmd) -{ - uint8_t tx_buf[8]; - - tx_buf[0] = 0x01; - tx_buf[1] = _cmd; /* 第2个字节 00 表示关闭,01表示持续鸣叫, 02表示鸣叫1次 */ - can1_SendPacket(tx_buf, 2); -} - -/* -********************************************************************************************************* -* 函 数 名: can_Init -* 功能说明: 配置CAN硬件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can_Init(void) -{ - bsp_InitCan1(); - bsp_InitCan2(); -} - -/* -********************************************************************************************************* -* 函 数 名: can_DeInit -* 功能说明: 退出CAN硬件硬质,恢复CPU相关的GPIO为缺省;关闭CAN中断 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can_DeInit(void) -{ - bsp_DeInitCan1(); - bsp_DeInitCan2(); -} - -/* -********************************************************************************************************* -* 函 数 名: can1_Analyze -* 功能说明: 解析CAN1收到的数据. 执行蜂鸣器动作 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can1_Analyze(void) -{ - if (g_Can1RxHeader.DataLength == 3) - { - if (g_Can1RxData[0] == 0x02) - { - if (g_Can1RxData[1] == 0) - { - BEEP_Stop(); /* 关闭蜂鸣器 */ - } - else - { - BEEP_Start(8, 8, g_Can1RxData[1]); /* 鸣叫80ms,停80ms, n次 */ - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: can2_Analyze -* 功能说明: 解析CAN2收到的数据。执行LED动作 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void can2_Analyze(void) -{ - if (g_Can2RxHeader.DataLength == 2) - { - if (g_Can1RxData[0] == 0x01) - { - if (g_Can1RxData[1] == 0) - { - bsp_LedOff(g_Can1RxData[2]); /* 关闭LED */ - } - else - { - bsp_LedOn(g_Can1RxData[2]); /* 打开LED */ - } - } - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_ad7606.c b/User/app/src/old/form_ad7606.c deleted file mode 100755 index c3940b4..0000000 --- a/User/app/src/old/form_ad7606.c +++ /dev/null @@ -1,354 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : AD7606数据采集模块测试程序 -* 文件名称 : ad7606_test.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "main.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T LabelN[8 + 2]; - LABEL_T LabelV[8 + 2]; - - LABEL_T LabelS1; - - BUTTON_T BtnRet; -} FormAD_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "AD7606数据采集模块测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LabelN1_X (BOX1_X + 6) -#define LabelN1_Y (BOX1_Y + 20) -#define LabelN1_TEXT "通道1 : " - -#define LabelV1_X (LabelN1_X + 64) -#define LabelV1_Y LabelN1_Y -#define LabelV1_TEXT "-" - -#define LabelS1_X (BOX1_X + 6) -#define LabelS1_Y (BOX1_Y + BOX1_H - 20) -#define LabelS1_TEXT "K1键切换量程, 摇杆上下键选择过采样倍率" - -static void InitFormAD(void); -static void DispADInitFace(void); -static void DispADStatus(void); - -FormAD_T *FormAD; - -/* -********************************************************************************************************* -* 函 数 名: TestAD7606 -* 功能说明: 测试AD7606模块。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestAD7606(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - int16_t tpX, tpY; - FormAD_T form; - uint8_t fRefresh; - - FormAD = &form; - - InitFormAD(); - - DispADInitFace(); - - /* 进入主程序循环体 */ - bsp_StartAutoTimer(0, 500); /* 每0.5秒定时显示状态 */ - - bsp_InitAD7606(); /* 配置AD7606相关GPIO */ - AD7606_StartRecord(1000); /* 进入自动采集模式,采样频率1KHz,数据存放在全局FIFO */ - - fRefresh = 1; - while (g_MainStatus == MS_AD7606) - { - bsp_Idle(); - - if (bsp_CheckTimer(0) || (fRefresh == 1)) - { - fRefresh = 0; - DispADStatus(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormAD->BtnRet.Focus = 1; - LCD_DrawButton(&FormAD->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormAD->BtnRet.Focus = 0; - LCD_DrawButton(&FormAD->BtnRet); - g_MainStatus = MS_MAIN_MENU; - } - else /* 按钮失去焦点 */ - { - FormAD->BtnRet.Focus = 0; - LCD_DrawButton(&FormAD->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 切换量程 */ - if (g_tAD7606.ucRange == 0) - { - AD7606_SetInputRange(1); - } - else - { - AD7606_SetInputRange(0); - } - fRefresh = 1; - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - if (g_tAD7606.ucOS < 6) - { - g_tAD7606.ucOS++; - } - AD7606_SetOS(g_tAD7606.ucOS); - fRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_tAD7606.ucOS > 0) - { - g_tAD7606.ucOS--; - } - AD7606_SetOS(g_tAD7606.ucOS); - fRefresh = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - bsp_StopTimer(0); /* 停止软件定时器 */ - AD7606_StopRecord(); /* 停止自动采集 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispADStatus -* 功能说明: 显示AD7606状态 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispADStatus(void) -{ - char buf[128]; - uint8_t i; - int32_t volt; - uint8_t m; - - if (g_tAD7606.ucRange == 1) - { - FormAD->LabelV[8].pCaption = "±10V"; - m = 2; - } - else - { - FormAD->LabelV[8].pCaption = "±5V "; - m = 1; - } - LCD_DrawLabel(&FormAD->LabelV[8]); - - for (i = 0; i < 8; i++) - { - /* 实测 21508 = 3.300V; 个体有差异 */ - volt = m * g_tAD7606.sNowAdc[i] * 3300 / 21508; - sprintf(buf, "%6d %6dmV ", g_tAD7606.sNowAdc[i], volt); - FormAD->LabelV[i].pCaption = buf; - LCD_DrawLabel(&FormAD->LabelV[i]); - } - - sprintf(buf, "%d", g_tAD7606.ucOS); - FormAD->LabelV[9].pCaption = buf; - LCD_DrawLabel(&FormAD->LabelV[9]); -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormAD -* 功能说明: 初始化GPS初始界面控件 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormAD(void) -{ - /* 分组框标题字体 */ - FormAD->FontBox.FontCode = FC_ST_16; - FormAD->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormAD->FontBox.FrontColor = CL_BLACK; - FormAD->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormAD->FontBlack.FontCode = FC_ST_16; - FormAD->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormAD->FontBlack.FrontColor = CL_BLACK; - FormAD->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormAD->FontBlue.FontCode = FC_ST_16; - FormAD->FontBlue.BackColor = CL_BTN_FACE; - FormAD->FontBlue.FrontColor = CL_BLUE; - FormAD->FontBlue.Space = 0; - - /* 按钮字体 */ - FormAD->FontBtn.FontCode = FC_ST_16; - FormAD->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormAD->FontBtn.FrontColor = CL_BLACK; - FormAD->FontBtn.Space = 0; - - /* 分组框 */ - FormAD->Box1.Left = BOX1_X; - FormAD->Box1.Top = BOX1_Y; - FormAD->Box1.Height = BOX1_H; - FormAD->Box1.Width = BOX1_W; - FormAD->Box1.pCaption = BOX1_TEXT; - FormAD->Box1.Font = &FormAD->FontBox; - - /* 标签 */ - { - uint8_t i; - const char *strName[10] = {"通道1", "通道2", "通道3", "通道4", "通道5", "通道6", "通道7", "通道8", "量程", "过采样"}; - - for (i = 0; i < 10; i++) - { - FormAD->LabelN[i].Left = LabelN1_X; - FormAD->LabelN[i].Top = LabelN1_Y + i * 20; - FormAD->LabelN[i].MaxLen = 0; - FormAD->LabelN[i].pCaption = (char *)strName[i]; - FormAD->LabelN[i].Font = &FormAD->FontBlack; /* 黑色 */ - - FormAD->LabelV[i].Left = LabelN1_X + 60; - FormAD->LabelV[i].Top = LabelN1_Y + i * 20; /* 蓝色 */ - FormAD->LabelV[i].MaxLen = 0; - FormAD->LabelV[i].pCaption = "-"; - FormAD->LabelV[i].Font = &FormAD->FontBlue; - } - - FormAD->LabelS1.Left = LabelS1_X; - FormAD->LabelS1.Top = LabelS1_Y; - FormAD->LabelS1.MaxLen = 0; - FormAD->LabelS1.pCaption = LabelS1_TEXT; - FormAD->LabelS1.Font = &FormAD->FontBlack; /* 黑色 */ - } - - /* 按钮 */ - FormAD->BtnRet.Left = BTN_RET_X; - FormAD->BtnRet.Top = BTN_RET_Y; - FormAD->BtnRet.Height = BTN_RET_H; - FormAD->BtnRet.Width = BTN_RET_W; - FormAD->BtnRet.pCaption = BTN_RET_TEXT; - FormAD->BtnRet.Font = &FormAD->FontBtn; - FormAD->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispADInitFace -* 功能说明: 显示初始界面 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispADInitFace(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormAD->Box1); - - /* 标签 */ - { - uint8_t i; - - for (i = 0; i < 10; i++) - { - LCD_DrawLabel(&FormAD->LabelN[i]); - } - - LCD_DrawLabel(&FormAD->LabelS1); - } - - /* 按钮 */ - LCD_DrawButton(&FormAD->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_ad7705_.c b/User/app/src/old/form_ad7705_.c deleted file mode 100755 index 17de193..0000000 --- a/User/app/src/old/form_ad7705_.c +++ /dev/null @@ -1,333 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 等待开发的程序界面 -* 文件名称 : reserve.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_ad7705.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - - BUTTON_T BtnRet; -} FormAD7705_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "AD7705模块测试程序..." - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "通道1 : " - -#define LABEL2_X (LABEL1_X + 64) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "0000.0000" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "通道2 : " - -#define LABEL4_X (LABEL3_X + 64) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "00000.0000" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 3) -#define LABEL5_TEXT "----" - -static void InitFormAD7705(void); -static void DispFormAD7705(void); - -FormAD7705_T *FormAD7705; - -/* -********************************************************************************************************* -* 函 数 名: TestAD7705 -* 功能说明: 测试AD7705模块。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestAD7705(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormAD7705_T form; - uint16_t adc1, adc2; - - FormAD7705 = &form; - InitFormAD7705(); - DispFormAD7705(); - - bsp_InitTM7705(); /* 初始化配置TM7705 */ - - if (g_TM7705_OK == 0) - { - FormAD7705->Label5.pCaption = "未检测到 AD7705"; - LCD_DrawLabel(&FormAD7705->Label5); - } - else - { - FormAD7705->Label5.pCaption = "已检测到 AD7705"; - LCD_DrawLabel(&FormAD7705->Label5); - - TM7705_CalibSelf(1); /* 自校准。执行时间较长,约180ms */ - adc1 = TM7705_ReadAdc(1); - - TM7705_CalibSelf(2); /* 自校准。执行时间较长,约180ms */ - adc2 = TM7705_ReadAdc(2); - } - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - //TM7705_Scan1(); /* 扫描ADC通道1 */ - TM7705_Scan2(); /* 扫描两个个ADC通道, 无等待的 */ - - { - /* 读取扫描结果 (结果定时读取即可) */ - adc1 = TM7705_GetAdc1(); - adc2 = TM7705_GetAdc2(); - - /* 打印采集数据 */ - { - int volt1, volt2; - char buf[64]; - - /* 计算实际电压值(近似估算的),如需准确,请进行校准 */ - volt1 = (adc1 * 5000) / 65535; - volt2 = (adc2 * 5000) / 65535; - - /* 显示ADC采样结果 */ - sprintf(buf, "%5d (%5dmV)", adc1, volt1); - FormAD7705->Label2.pCaption = buf; - LCD_DrawLabel(&FormAD7705->Label2); - - sprintf(buf, "%5d (%5dmV)", adc2, volt2); - FormAD7705->Label4.pCaption = buf; - LCD_DrawLabel(&FormAD7705->Label4); - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormAD7705->BtnRet.Focus = 1; - LCD_DrawButton(&FormAD7705->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormAD7705->BtnRet.Focus = 0; - LCD_DrawButton(&FormAD7705->BtnRet); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormAD7705->BtnRet.Focus = 0; - LCD_DrawButton(&FormAD7705->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormAD7705 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormAD7705(void) -{ - /* 分组框标题字体 */ - FormAD7705->FontBox.FontCode = FC_ST_16; - FormAD7705->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormAD7705->FontBox.FrontColor = CL_BLACK; - FormAD7705->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormAD7705->FontBlack.FontCode = FC_ST_16; - FormAD7705->FontBlack.BackColor = CL_BTN_FACE; /* 透明色 */ - FormAD7705->FontBlack.FrontColor = CL_BLACK; - FormAD7705->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormAD7705->FontBlue.FontCode = FC_ST_16; - FormAD7705->FontBlue.BackColor = CL_BTN_FACE; - FormAD7705->FontBlue.FrontColor = CL_BLUE; - FormAD7705->FontBlue.Space = 0; - - /* 按钮字体 */ - FormAD7705->FontBtn.FontCode = FC_ST_16; - FormAD7705->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormAD7705->FontBtn.FrontColor = CL_BLACK; - FormAD7705->FontBtn.Space = 0; - - /* 分组框 */ - FormAD7705->Box1.Left = BOX1_X; - FormAD7705->Box1.Top = BOX1_Y; - FormAD7705->Box1.Height = BOX1_H; - FormAD7705->Box1.Width = BOX1_W; - FormAD7705->Box1.pCaption = BOX1_TEXT; - FormAD7705->Box1.Font = &FormAD7705->FontBox; - - /* 静态标签 */ - FormAD7705->Label1.Left = LABEL1_X; - FormAD7705->Label1.Top = LABEL1_Y; - FormAD7705->Label1.MaxLen = 0; - FormAD7705->Label1.pCaption = LABEL1_TEXT; - FormAD7705->Label1.Font = &FormAD7705->FontBlack; - - FormAD7705->Label3.Left = LABEL3_X; - FormAD7705->Label3.Top = LABEL3_Y; - FormAD7705->Label3.MaxLen = 0; - FormAD7705->Label3.pCaption = LABEL3_TEXT; - FormAD7705->Label3.Font = &FormAD7705->FontBlack; - - FormAD7705->Label5.Left = LABEL5_X; - FormAD7705->Label5.Top = LABEL5_Y; - FormAD7705->Label5.MaxLen = 0; - FormAD7705->Label5.pCaption = LABEL5_TEXT; - FormAD7705->Label5.Font = &FormAD7705->FontBlack; - - /* 动态标签 */ - FormAD7705->Label2.Left = LABEL2_X; - FormAD7705->Label2.Top = LABEL2_Y; - FormAD7705->Label2.MaxLen = 0; - FormAD7705->Label2.pCaption = LABEL2_TEXT; - FormAD7705->Label2.Font = &FormAD7705->FontBlue; - - FormAD7705->Label4.Left = LABEL4_X; - FormAD7705->Label4.Top = LABEL4_Y; - FormAD7705->Label4.MaxLen = 0; - FormAD7705->Label4.pCaption = LABEL4_TEXT; - FormAD7705->Label4.Font = &FormAD7705->FontBlue; - - /* 按钮 */ - FormAD7705->BtnRet.Left = BTN_RET_X; - FormAD7705->BtnRet.Top = BTN_RET_Y; - FormAD7705->BtnRet.Height = BTN_RET_H; - FormAD7705->BtnRet.Width = BTN_RET_W; - FormAD7705->BtnRet.pCaption = BTN_RET_TEXT; - FormAD7705->BtnRet.Font = &FormAD7705->FontBtn; - FormAD7705->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormAD7705 -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormAD7705(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormAD7705->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormAD7705->Label1); - LCD_DrawLabel(&FormAD7705->Label3); - LCD_DrawLabel(&FormAD7705->Label5); - - /* 动态标签 */ - LCD_DrawLabel(&FormAD7705->Label2); - LCD_DrawLabel(&FormAD7705->Label4); - - /* 按钮 */ - LCD_DrawButton(&FormAD7705->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_ad9833.c b/User/app/src/old/form_ad9833.c deleted file mode 100755 index 9186afb..0000000 --- a/User/app/src/old/form_ad9833.c +++ /dev/null @@ -1,828 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : AD9833波形发生器测试界面 -* 文件名称 : form_ad9833.c -* 版 本 : V1.0 -* 说 明 : 演示AD9833模块的功能 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2015-07-19 armfly 首版 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_ad9833.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 黑色 */ - FONT_T FontBlue; /* 蓝色 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - BUTTON_T Btn7; - BUTTON_T Btn8; - BUTTON_T Btn9; - BUTTON_T Btn10; - BUTTON_T Btn11; - BUTTON_T Btn12; - BUTTON_T Btn13; - BUTTON_T Btn14; - BUTTON_T Btn15; - BUTTON_T Btn16; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - - uint32_t Freq; /* 波形频率。单位 0.1Hz */ - AD9833_WAVE_E WaveType; /* 波形类型 */ - uint8_t ScanBand; /* 扫频波段 */ - uint32_t FreqBegin; /* 开始频率 */ - uint32_t FreqEnd; /* 截止频率 */ -} Form9833_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - 53) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_T "AD9833波形发生器" - -#define BTN1_H 32 -#define BTN1_W 105 - -/* 第1行按钮坐标 */ -#define BTN1_X (BOX1_X + 10) -#define BTN1_Y (BOX1_Y + 20) -#define BTN1_T "正弦波" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_T "三角波" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN3_Y BTN1_Y -#define BTN3_T "方波" - -#define BTN16_H BTN1_H -#define BTN16_W BTN1_W -#define BTN16_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN16_Y BTN1_Y -#define BTN16_T "停止" - -/* 第2行按钮坐标 */ -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X BTN1_X -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_T "频率+0.1Hz" - -#define BTN5_H BTN1_H -#define BTN5_W BTN1_W -#define BTN5_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN5_Y BTN4_Y -#define BTN5_T "频率-0.1Hz" - -#define BTN6_H BTN1_H -#define BTN6_W BTN1_W -#define BTN6_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN6_Y BTN4_Y -#define BTN6_T "频率+1Hz" - -#define BTN7_H BTN1_H -#define BTN7_W BTN1_W -#define BTN7_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN7_Y BTN4_Y -#define BTN7_T "频率-1Hz" - -/* 第3行按钮坐标 */ -#define BTN8_H BTN1_H -#define BTN8_W BTN1_W -#define BTN8_X BTN1_X -#define BTN8_Y (BTN1_Y + 2 * (BTN1_H + 10)) -#define BTN8_T "频率+1kHz" - -#define BTN9_H BTN1_H -#define BTN9_W BTN1_W -#define BTN9_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN9_Y BTN8_Y -#define BTN9_T "频率-1kHz" - -#define BTN10_H BTN1_H -#define BTN10_W BTN1_W -#define BTN10_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN10_Y BTN8_Y -#define BTN10_T "频率+100kHz" - -#define BTN11_H BTN1_H -#define BTN11_W BTN1_W -#define BTN11_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN11_Y BTN8_Y -#define BTN11_T "频率-100kHz" - -/* 第4行按钮坐标 */ -#define BTN12_H BTN1_H -#define BTN12_W BTN1_W -#define BTN12_X BTN1_X -#define BTN12_Y (BTN1_Y + 3 * (BTN1_H + 10)) -#define BTN12_T "频率=10Hz" - -#define BTN13_H BTN1_H -#define BTN13_W BTN1_W -#define BTN13_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN13_Y BTN12_Y -#define BTN13_T "频率=10KHz" - -#define BTN14_H BTN1_H -#define BTN14_W BTN1_W -#define BTN14_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN14_Y BTN12_Y -#define BTN14_T "扫频频段" - -#define BTN15_H BTN1_H -#define BTN15_W BTN1_W -#define BTN15_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN15_Y BTN12_Y -#define BTN15_T "开始扫频" - -#define LBL1_X BOX1_X + 5 -#define LBL1_Y 190 -#define LBL1_T "输出波形:" - -#define LBL2_X LBL1_X + 85 -#define LBL2_Y LBL1_Y -#define LBL2_T " " - -#define LBL3_X LBL1_X -#define LBL3_Y LBL1_Y + 20 -#define LBL3_T "波形频率:" - -#define LBL4_X LBL3_X + 85 -#define LBL4_Y LBL3_Y -#define LBL4_T " " - -#define LBL5_X LBL1_X -#define LBL5_Y LBL3_Y + 25 -#define LBL5_T "扫频频段:" - -#define LBL6_X LBL5_X + 85 -#define LBL6_Y LBL5_Y -#define LBL6_T " " - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_T "返回" - -#define BAND_NUM 6 -static const uint32_t s_FreqBand[BAND_NUM][3] = - { - /* 开始频率 结束频率 步进频率 (单位 0.1Hz) */ - {0, 1000, 10}, - {0, 10000, 10}, - {0, 100000, 100}, - {0, 100000, 1000}, - {0, 1000000, 1000}, - {0, 100000000, 100000}}; - -Form9833_T *Form9833; - -static void InitForm9833(void); -static void DispForm9833(void); -static void Disp9833Info(void); -static void FreqToStr(uint32_t _freq, char *_dispbuf); - -/* -********************************************************************************************************* -* 函 数 名: FormMain9833 -* 功能说明: 步进电机测试主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void FormMain9833(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - Form9833_T form; - uint8_t fDispInfo = 1; - - Form9833 = &form; - - InitForm9833(); - DispForm9833(); - - bsp_InitAD9833(); - - Form9833->Freq = 100000; /* 波形频率。单位 0.1Hz */ - Form9833->WaveType = NONE_WAVE; /* 波形类型 */ - Form9833->ScanBand = 0; - - fDispInfo = 1; - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fDispInfo) - { - fDispInfo = 0; - - AD9833_SetWaveFreq(Form9833->Freq); /*设置频率值 */ - AD9833_SelectWave(Form9833->WaveType); - - Disp9833Info(); /* 显示频率 */ - } - - /* 扫频 */ - if (bsp_CheckTimer(0)) - { - Form9833->Freq += s_FreqBand[Form9833->ScanBand][2]; /* 步进频率 */ - fDispInfo = 1; - - if (Form9833->Freq >= s_FreqBand[Form9833->ScanBand][1]) - { - bsp_StopTimer(0); /* 停止定时器 */ - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&Form9833->BtnRet, tpX, tpY)) - { - //fQuit = 1; 释放时再退出 - } - else if (LCD_ButtonTouchDown(&Form9833->Btn1, tpX, tpY)) - { - Form9833->WaveType = SINE_WAVE; /* 正弦波 */ - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn2, tpX, tpY)) - { - Form9833->WaveType = TRI_WAVE; /* 三角波 */ - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn3, tpX, tpY)) - { - Form9833->WaveType = SQU_WAVE; /* 方波 */ - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn4, tpX, tpY)) /* 频率 +0.1Hz */ - { - if (Form9833->Freq < AD9833_MAX_FREQ) - { - Form9833->Freq++; - } - - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn5, tpX, tpY)) /* 频率 -0.1Hz */ - { - if (Form9833->Freq > 0) - { - Form9833->Freq--; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn6, tpX, tpY)) /* 频率 +1Hz */ - { - if (Form9833->Freq < AD9833_MAX_FREQ) - { - Form9833->Freq += 10; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn7, tpX, tpY)) /* 频率 -1Hz */ - { - if (Form9833->Freq > 10) - { - Form9833->Freq -= 10; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn8, tpX, tpY)) /* 频率 +1kHz */ - { - if (Form9833->Freq < AD9833_MAX_FREQ) - { - Form9833->Freq += 10000; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn9, tpX, tpY)) /* 频率 -1kHz */ - { - if (Form9833->Freq > 10000) - { - Form9833->Freq -= 10000; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn10, tpX, tpY)) /* 频率 +100kHz */ - { - if (Form9833->Freq < AD9833_MAX_FREQ) - { - Form9833->Freq += 1000000; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn11, tpX, tpY)) /* 频率 -100kHz */ - { - if (Form9833->Freq > 1000000) - { - Form9833->Freq -= 1000000; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn12, tpX, tpY)) /* 频率 = 10Hz */ - { - Form9833->Freq = 100; - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn13, tpX, tpY)) /* 频率 = 10KHz */ - { - Form9833->Freq = 100000; - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn14, tpX, tpY)) /* 扫频频段 */ - { - /* 切换扫频频段 */ - if (++Form9833->ScanBand >= BAND_NUM) - { - Form9833->ScanBand = 0; - } - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn15, tpX, tpY)) /* 开始扫频 */ - { - Form9833->Freq = s_FreqBand[Form9833->ScanBand][0]; - - bsp_StartAutoTimer(0, 100); /* 100ms 更新一次频率 */ - fDispInfo = 1; - } - else if (LCD_ButtonTouchDown(&Form9833->Btn16, tpX, tpY)) - { - Form9833->WaveType = NONE_WAVE; /* 输出停止 */ - fDispInfo = 1; - - bsp_StopTimer(0); /* 停止定时器 */ - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&Form9833->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else - { - LCD_ButtonTouchRelease(&Form9833->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn6, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn7, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn8, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn9, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn10, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn11, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn12, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn13, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn14, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn15, tpX, tpY); - LCD_ButtonTouchRelease(&Form9833->Btn16, tpX, tpY); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 + 1*/ - break; - - case KEY_DOWN_K2: /* K2键 - 1 */ - break; - - case KEY_DOWN_K3: /* K3键 - 清0 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitForm9833 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitForm9833(void) -{ - /* 分组框标题字体 */ - Form9833->FontBox.FontCode = FC_ST_16; - Form9833->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - Form9833->FontBox.FrontColor = CL_BLACK; - Form9833->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - Form9833->FontBlack.FontCode = FC_ST_16; - Form9833->FontBlack.BackColor = CL_MASK; /* 透明色 */ - Form9833->FontBlack.FrontColor = CL_BLACK; - Form9833->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - Form9833->FontBlue.FontCode = FC_ST_16; - Form9833->FontBlue.BackColor = CL_BTN_FACE; - Form9833->FontBlue.FrontColor = CL_BLUE; - Form9833->FontBlue.Space = 0; - - /* 按钮字体 */ - Form9833->FontBtn.FontCode = FC_ST_16; - Form9833->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - Form9833->FontBtn.FrontColor = CL_BLACK; - Form9833->FontBtn.Space = 0; - - /* 分组框 */ - Form9833->Box1.Left = BOX1_X; - Form9833->Box1.Top = BOX1_Y; - Form9833->Box1.Height = BOX1_H; - Form9833->Box1.Width = BOX1_W; - Form9833->Box1.pCaption = BOX1_T; - Form9833->Box1.Font = &Form9833->FontBox; - - /* 标签 */ - Form9833->Label1.Left = LBL1_X; - Form9833->Label1.Top = LBL1_Y; - Form9833->Label1.MaxLen = 0; - Form9833->Label1.pCaption = LBL1_T; - Form9833->Label1.Font = &Form9833->FontBlack; - - Form9833->Label2.Left = LBL2_X; - Form9833->Label2.Top = LBL2_Y; - Form9833->Label2.MaxLen = 0; - Form9833->Label2.pCaption = LBL2_T; - Form9833->Label2.Font = &Form9833->FontBlue; - - Form9833->Label3.Left = LBL3_X; - Form9833->Label3.Top = LBL3_Y; - Form9833->Label3.MaxLen = 0; - Form9833->Label3.pCaption = LBL3_T; - Form9833->Label3.Font = &Form9833->FontBlack; - - Form9833->Label4.Left = LBL4_X; - Form9833->Label4.Top = LBL4_Y; - Form9833->Label4.MaxLen = 0; - Form9833->Label4.pCaption = LBL4_T; - Form9833->Label4.Font = &Form9833->FontBlue; - - Form9833->Label5.Left = LBL5_X; - Form9833->Label5.Top = LBL5_Y; - Form9833->Label5.MaxLen = 0; - Form9833->Label5.pCaption = LBL5_T; - Form9833->Label5.Font = &Form9833->FontBlack; - - Form9833->Label6.Left = LBL6_X; - Form9833->Label6.Top = LBL6_Y; - Form9833->Label6.MaxLen = 0; - Form9833->Label6.pCaption = LBL6_T; - Form9833->Label6.Font = &Form9833->FontBlue; - - /* 按钮 */ - Form9833->BtnRet.Left = BTN_RET_X; - Form9833->BtnRet.Top = BTN_RET_Y; - Form9833->BtnRet.Height = BTN_RET_H; - Form9833->BtnRet.Width = BTN_RET_W; - Form9833->BtnRet.pCaption = BTN_RET_T; - Form9833->BtnRet.Font = &Form9833->FontBtn; - Form9833->BtnRet.Focus = 0; - - Form9833->Btn1.Left = BTN1_X; - Form9833->Btn1.Top = BTN1_Y; - Form9833->Btn1.Height = BTN1_H; - Form9833->Btn1.Width = BTN1_W; - Form9833->Btn1.pCaption = BTN1_T; - Form9833->Btn1.Font = &Form9833->FontBtn; - Form9833->Btn1.Focus = 0; - - Form9833->Btn2.Left = BTN2_X; - Form9833->Btn2.Top = BTN2_Y; - Form9833->Btn2.Height = BTN2_H; - Form9833->Btn2.Width = BTN2_W; - Form9833->Btn2.pCaption = BTN2_T; - Form9833->Btn2.Font = &Form9833->FontBtn; - Form9833->Btn2.Focus = 0; - - Form9833->Btn3.Left = BTN3_X; - Form9833->Btn3.Top = BTN3_Y; - Form9833->Btn3.Height = BTN3_H; - Form9833->Btn3.Width = BTN3_W; - Form9833->Btn3.pCaption = BTN3_T; - Form9833->Btn3.Font = &Form9833->FontBtn; - Form9833->Btn3.Focus = 0; - - Form9833->Btn4.Left = BTN4_X; - Form9833->Btn4.Top = BTN4_Y; - Form9833->Btn4.Height = BTN4_H; - Form9833->Btn4.Width = BTN4_W; - Form9833->Btn4.pCaption = BTN4_T; - Form9833->Btn4.Font = &Form9833->FontBtn; - Form9833->Btn4.Focus = 0; - - Form9833->Btn5.Left = BTN5_X; - Form9833->Btn5.Top = BTN5_Y; - Form9833->Btn5.Height = BTN5_H; - Form9833->Btn5.Width = BTN5_W; - Form9833->Btn5.pCaption = BTN5_T; - Form9833->Btn5.Font = &Form9833->FontBtn; - Form9833->Btn5.Focus = 0; - - Form9833->Btn6.Left = BTN6_X; - Form9833->Btn6.Top = BTN6_Y; - Form9833->Btn6.Height = BTN6_H; - Form9833->Btn6.Width = BTN6_W; - Form9833->Btn6.pCaption = BTN6_T; - Form9833->Btn6.Font = &Form9833->FontBtn; - Form9833->Btn6.Focus = 0; - - Form9833->Btn7.Left = BTN7_X; - Form9833->Btn7.Top = BTN7_Y; - Form9833->Btn7.Height = BTN7_H; - Form9833->Btn7.Width = BTN7_W; - Form9833->Btn7.pCaption = BTN7_T; - Form9833->Btn7.Font = &Form9833->FontBtn; - Form9833->Btn7.Focus = 0; - - Form9833->Btn8.Left = BTN8_X; - Form9833->Btn8.Top = BTN8_Y; - Form9833->Btn8.Height = BTN8_H; - Form9833->Btn8.Width = BTN8_W; - Form9833->Btn8.pCaption = BTN8_T; - Form9833->Btn8.Font = &Form9833->FontBtn; - Form9833->Btn8.Focus = 0; - - Form9833->Btn9.Left = BTN9_X; - Form9833->Btn9.Top = BTN9_Y; - Form9833->Btn9.Height = BTN9_H; - Form9833->Btn9.Width = BTN9_W; - Form9833->Btn9.pCaption = BTN9_T; - Form9833->Btn9.Font = &Form9833->FontBtn; - Form9833->Btn9.Focus = 0; - - Form9833->Btn10.Left = BTN10_X; - Form9833->Btn10.Top = BTN10_Y; - Form9833->Btn10.Height = BTN10_H; - Form9833->Btn10.Width = BTN10_W; - Form9833->Btn10.pCaption = BTN10_T; - Form9833->Btn10.Font = &Form9833->FontBtn; - Form9833->Btn10.Focus = 0; - - Form9833->Btn11.Left = BTN11_X; - Form9833->Btn11.Top = BTN11_Y; - Form9833->Btn11.Height = BTN11_H; - Form9833->Btn11.Width = BTN11_W; - Form9833->Btn11.pCaption = BTN11_T; - Form9833->Btn11.Font = &Form9833->FontBtn; - Form9833->Btn11.Focus = 0; - - Form9833->Btn12.Left = BTN12_X; - Form9833->Btn12.Top = BTN12_Y; - Form9833->Btn12.Height = BTN12_H; - Form9833->Btn12.Width = BTN12_W; - Form9833->Btn12.pCaption = BTN12_T; - Form9833->Btn12.Font = &Form9833->FontBtn; - Form9833->Btn12.Focus = 0; - - Form9833->Btn13.Left = BTN13_X; - Form9833->Btn13.Top = BTN13_Y; - Form9833->Btn13.Height = BTN13_H; - Form9833->Btn13.Width = BTN13_W; - Form9833->Btn13.pCaption = BTN13_T; - Form9833->Btn13.Font = &Form9833->FontBtn; - Form9833->Btn13.Focus = 0; - - Form9833->Btn14.Left = BTN14_X; - Form9833->Btn14.Top = BTN14_Y; - Form9833->Btn14.Height = BTN14_H; - Form9833->Btn14.Width = BTN14_W; - Form9833->Btn14.pCaption = BTN14_T; - Form9833->Btn14.Font = &Form9833->FontBtn; - Form9833->Btn14.Focus = 0; - - Form9833->Btn15.Left = BTN15_X; - Form9833->Btn15.Top = BTN15_Y; - Form9833->Btn15.Height = BTN15_H; - Form9833->Btn15.Width = BTN15_W; - Form9833->Btn15.pCaption = BTN15_T; - Form9833->Btn15.Font = &Form9833->FontBtn; - Form9833->Btn15.Focus = 0; - - Form9833->Btn16.Left = BTN16_X; - Form9833->Btn16.Top = BTN16_Y; - Form9833->Btn16.Height = BTN16_H; - Form9833->Btn16.Width = BTN16_W; - Form9833->Btn16.pCaption = BTN16_T; - Form9833->Btn16.Font = &Form9833->FontBtn; - Form9833->Btn16.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispForm9833 -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispForm9833(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&Form9833->Box1); - - LCD_DrawLabel(&Form9833->Label1); - LCD_DrawLabel(&Form9833->Label2); - LCD_DrawLabel(&Form9833->Label3); - LCD_DrawLabel(&Form9833->Label4); - LCD_DrawLabel(&Form9833->Label5); - LCD_DrawLabel(&Form9833->Label6); - - /* 按钮 */ - LCD_DrawButton(&Form9833->Btn1); - LCD_DrawButton(&Form9833->Btn2); - LCD_DrawButton(&Form9833->Btn3); - LCD_DrawButton(&Form9833->Btn4); - LCD_DrawButton(&Form9833->Btn5); - LCD_DrawButton(&Form9833->Btn6); - LCD_DrawButton(&Form9833->Btn5); - LCD_DrawButton(&Form9833->Btn6); - LCD_DrawButton(&Form9833->Btn7); - LCD_DrawButton(&Form9833->Btn8); - LCD_DrawButton(&Form9833->Btn9); - LCD_DrawButton(&Form9833->Btn10); - LCD_DrawButton(&Form9833->Btn11); - LCD_DrawButton(&Form9833->Btn12); - LCD_DrawButton(&Form9833->Btn13); - LCD_DrawButton(&Form9833->Btn14); - LCD_DrawButton(&Form9833->Btn15); - LCD_DrawButton(&Form9833->Btn16); - LCD_DrawButton(&Form9833->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: FreqToStr -* 功能说明: 将频率值转换为显示字符串。 -* 形 参: _freq 频率值,单位是0.1Hz -* _dispbuf 存放显示结果 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void FreqToStr(uint32_t _freq, char *_dispbuf) -{ - if (_freq < 10000) - { - sprintf(_dispbuf, "%d.%dHz", _freq / 10, _freq % 10); - } - else if (_freq >= 10000 && _freq < 10000000) - { - sprintf(_dispbuf, "%d.%04dKHz", _freq / 10000, _freq % 10000); - } - else if (_freq >= 10000000) - { - sprintf(_dispbuf, "%d.%07d%MHz", _freq / 10000000, (_freq % 10000000)); - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispDacVoltage -* 功能说明: 显示电压 -* 形 参: 无 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void Disp9833Info(void) -{ - char buf[128]; - - { - /* 打印当前的波形类型 */ - if (Form9833->WaveType == NONE_WAVE) - { - strcpy(buf, "关闭"); - } - else if (Form9833->WaveType == TRI_WAVE) - { - strcpy(buf, "三角波"); - } - else if (Form9833->WaveType == SINE_WAVE) - { - strcpy(buf, "正弦波"); - } - else if (Form9833->WaveType == SQU_WAVE) - { - strcpy(buf, "方波"); - } - else - { - strcpy(buf, "xxxxx"); - } - - Form9833->Label2.pCaption = buf; - LCD_DrawLabel(&Form9833->Label2); - } - - { - /* 打印当前的扫频频段 */ - uint32_t freq1, freq2, step; - char buf1[32]; - char buf2[32]; - char buf3[32]; - - freq1 = s_FreqBand[Form9833->ScanBand][0]; - freq2 = s_FreqBand[Form9833->ScanBand][1]; - step = s_FreqBand[Form9833->ScanBand][2]; - - FreqToStr(freq1, buf1); - FreqToStr(freq2, buf2); - FreqToStr(step, buf3); - - sprintf(buf, "%s-%s, 步进 %s", buf1, buf2, buf3); - - Form9833->Label6.pCaption = buf; - LCD_DrawLabel(&Form9833->Label6); - } - - { - /* 打印当前的频率值 */ - FreqToStr(Form9833->Freq, buf); /* 将整数格式的频率值转换为可显示的ASCII字符串 */ - - Form9833->Label4.pCaption = buf; - LCD_DrawLabel(&Form9833->Label4); - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_ads1256.c b/User/app/src/old/form_ads1256.c deleted file mode 100755 index b099a95..0000000 --- a/User/app/src/old/form_ads1256.c +++ /dev/null @@ -1,404 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : AD7606数据采集模块测试程序 -* 文件名称 : ad7606_test.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "main.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T LabelN[8 + 2]; - LABEL_T LabelV[8 + 2]; - - LABEL_T LabelS1; - - BUTTON_T BtnRet; -}FormADS1256_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "ADS1256数据采集模块测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LabelN1_X (BOX1_X + 6) -#define LabelN1_Y (BOX1_Y + 20) -#define LabelN1_TEXT "通道1 : " - - #define LabelV1_X (LabelN1_X + 64) - #define LabelV1_Y LabelN1_Y - #define LabelV1_TEXT "-" - -#define LabelS1_X (BOX1_X + 6) -#define LabelS1_Y (BOX1_Y + BOX1_H - 20) -#define LabelS1_TEXT "摇杆上下键选择增益, 左右键选择滤波参数" - -static void InitFormADS1256(void); -static void DispADInitFace(void); -static void DispADStatus(void); - -FormADS1256_T *FormADS1256; - -/* -********************************************************************************************************* -* 函 数 名: TestADS1256 -* 功能说明: 测试ADS1256模块。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestADS1256(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - int16_t tpX, tpY; - FormADS1256_T form; - uint8_t fRefresh; - - FormADS1256 = &form; - - InitFormADS1256(); - - DispADInitFace(); - - bsp_InitADS1256(); - - ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_30SPS); /* 配置ADC参数: 增益1:1, 数据输出速率 30Hz */ - - /* 打印芯片ID (通过读ID可以判断硬件接口是否正常) , 正常时状态寄存器的高4bit = 3 */ - #if 0 - { - uint8_t id; - - id = ADS1256_ReadChipID(); - - if (id != 3) - { - printf("Error, ASD1256 Chip ID = 0x%X\r\n", id); - } - else - { - printf("Ok, ASD1256 Chip ID = 0x%X\r\n", id); - } - } - #endif - - /* 进入主程序循环体 */ - bsp_StartAutoTimer(0, 500); - - ADS1256_StartScan(); /* 启动8通道ADC扫描 */ - fRefresh = 1; - while (g_MainStatus == MS_ADS1256) - { - bsp_Idle(); - - if (bsp_CheckTimer(0) || (fRefresh == 1)) - { - fRefresh = 0; - DispADStatus(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormADS1256->BtnRet.Focus = 1; - LCD_DrawButton(&FormADS1256->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormADS1256->BtnRet.Focus = 0; - LCD_DrawButton(&FormADS1256->BtnRet); - g_MainStatus = MS_MAIN_MENU; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormADS1256->BtnRet.Focus = 0; - LCD_DrawButton(&FormADS1256->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 切换量程 */ - case KEY_DOWN_K2: /* K2键按下 */ - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - if (g_tADS1256.Gain < 6) - { - g_tADS1256.Gain++; - } - ADS1256_CfgADC(g_tADS1256.Gain, g_tADS1256.DataRate); /* 配置ADC参数: 增益和数据输出速率 */ - ADS1256_StartScan(); - fRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_tADS1256.Gain > 0) - { - g_tADS1256.Gain--; - } - ADS1256_CfgADC(g_tADS1256.Gain, g_tADS1256.DataRate); /* 配置ADC参数: 增益和数据输出速率 */ - ADS1256_StartScan(); - fRefresh = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (g_tADS1256.DataRate < ADS1256_2d5SPS) - { - g_tADS1256.DataRate++; - } - ADS1256_CfgADC(g_tADS1256.Gain, g_tADS1256.DataRate); /* 配置ADC参数: 增益和数据输出速率 */ - ADS1256_StartScan(); - fRefresh = 1; - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (g_tADS1256.DataRate > ADS1256_1000SPS) - { - g_tADS1256.DataRate--; - } - ADS1256_CfgADC(g_tADS1256.Gain, g_tADS1256.DataRate); /* 配置ADC参数: 增益和数据输出速率 */ - ADS1256_StartScan(); - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - ADS1256_StopScan(); /* 停止ADS1256的中断响应 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispADStatus -* 功能说明: 显示ADC状态 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispADStatus(void) -{ - char buf[128]; - uint8_t i; - const char *strGain[7] = { "X1 (±5V)", "X2 (±2.5V)", "X4 (±1.25V)", "X8 (±0.625V)", "X16 (±312.5mV)", - "X32 (±156.25mV)", "X64 (±78.125mV)"}; - - const char *strRate[ADS1256_DRATE_MAX] = - { - "1, 30000SPS", - "2, 15000SPS", - "4, 7500SPS", - "8, 3750SPS", - "15, 2000SPS", - "30, 1000SPS", - "60, 500SPS", - "300, 100SPS", - "500, 60SPS", - "600, 50SPS", - "1000, 30SPS", - "1200, 25SPS", - "2000, 15SPS", - "3000, 10SPS", - "6000, 5SPS", - "12000, 2d5SPS" - }; - - /* 显示 ADC结果 */ - for (i = 0; i < 8; i++) - { - int32_t iTemp; - - /* 计算实际电压值(近似估算的),如需准确,请进行校准 */ - iTemp = ((int64_t)g_tADS1256.AdcNow[i] * 2500000) / 4194303; - - if (iTemp < 0) - { - iTemp = -iTemp; - sprintf(buf, "%6d,(-%d.%03d %03d V) ", g_tADS1256.AdcNow[i] , iTemp /1000000, (iTemp%1000000)/1000, iTemp%1000); - } - else - { - sprintf(buf, "%6d,( %d.%03d %03d V) ", g_tADS1256.AdcNow[i] , iTemp/1000000, (iTemp%1000000)/1000, iTemp%1000); - } - - FormADS1256->LabelV[i].pCaption = buf; - LCD_DrawLabel(&FormADS1256->LabelV[i]); - } - - /* 显示 增益 */ - FormADS1256->LabelV[8].pCaption = (char *)strGain[g_tADS1256.Gain]; - LCD_DrawLabel(&FormADS1256->LabelV[8]); - - /* 显示 数据速率 */ - FormADS1256->LabelV[9].pCaption = (char *)strRate[g_tADS1256.DataRate]; - LCD_DrawLabel(&FormADS1256->LabelV[9]); -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormADS1256 -* 功能说明: 初始化GPS初始界面控件 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormADS1256(void) -{ - /* 分组框标题字体 */ - FormADS1256->FontBox.FontCode = FC_ST_16; - FormADS1256->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormADS1256->FontBox.FrontColor = CL_BLACK; - FormADS1256->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormADS1256->FontBlack.FontCode = FC_ST_16; - FormADS1256->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormADS1256->FontBlack.FrontColor = CL_BLACK; - FormADS1256->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormADS1256->FontBlue.FontCode = FC_ST_16; - FormADS1256->FontBlue.BackColor = CL_BTN_FACE; - FormADS1256->FontBlue.FrontColor = CL_BLUE; - FormADS1256->FontBlue.Space = 0; - - /* 按钮字体 */ - FormADS1256->FontBtn.FontCode = FC_ST_16; - FormADS1256->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormADS1256->FontBtn.FrontColor = CL_BLACK; - FormADS1256->FontBtn.Space = 0; - - /* 分组框 */ - FormADS1256->Box1.Left = BOX1_X; - FormADS1256->Box1.Top = BOX1_Y; - FormADS1256->Box1.Height = BOX1_H; - FormADS1256->Box1.Width = BOX1_W; - FormADS1256->Box1.pCaption = BOX1_TEXT; - FormADS1256->Box1.Font = &FormADS1256->FontBox; - - /* 标签 */ - { - uint8_t i; - const char *strName[10] = {"通道1","通道2","通道3","通道4","通道5","通道6","通道7","通道8", - "增益(量程)", "滤波(速率)"}; - - for (i = 0; i < 10; i++) - { - FormADS1256->LabelN[i].Left = LabelN1_X; - FormADS1256->LabelN[i].Top = LabelN1_Y + i * 20; - FormADS1256->LabelN[i].MaxLen = 0; - FormADS1256->LabelN[i].pCaption = (char *)strName[i]; - FormADS1256->LabelN[i].Font = &FormADS1256->FontBlack; /* 黑色 */ - - FormADS1256->LabelV[i].Left = LabelN1_X + 60; - FormADS1256->LabelV[i].Top = LabelN1_Y + i * 20; /* 蓝色 */ - FormADS1256->LabelV[i].MaxLen = 0; - FormADS1256->LabelV[i].pCaption = "-"; - FormADS1256->LabelV[i].Font = &FormADS1256->FontBlue; - } - - FormADS1256->LabelV[8].Left = LabelN1_X + 120; - FormADS1256->LabelV[9].Left = LabelN1_X + 120; - - FormADS1256->LabelS1.Left = LabelS1_X; - FormADS1256->LabelS1.Top = LabelS1_Y; - FormADS1256->LabelS1.MaxLen = 0; - FormADS1256->LabelS1.pCaption = LabelS1_TEXT; - FormADS1256->LabelS1.Font = &FormADS1256->FontBlack; /* 黑色 */ - } - - /* 按钮 */ - FormADS1256->BtnRet.Left = BTN_RET_X; - FormADS1256->BtnRet.Top = BTN_RET_Y; - FormADS1256->BtnRet.Height = BTN_RET_H; - FormADS1256->BtnRet.Width = BTN_RET_W; - FormADS1256->BtnRet.pCaption = BTN_RET_TEXT; - FormADS1256->BtnRet.Font = &FormADS1256->FontBtn; - FormADS1256->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispADInitFace -* 功能说明: 显示初始界面 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispADInitFace(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormADS1256->Box1); - - /* 标签 */ - { - uint8_t i; - - for (i = 0; i < 10; i++) - { - LCD_DrawLabel(&FormADS1256->LabelN[i]); - } - - LCD_DrawLabel(&FormADS1256->LabelS1); - } - - /* 按钮 */ - LCD_DrawButton(&FormADS1256->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_audio_rec.c b/User/app/src/old/form_audio_rec.c deleted file mode 100755 index abd238b..0000000 --- a/User/app/src/old/form_audio_rec.c +++ /dev/null @@ -1,719 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 录音演示程序。 -* 文件名称 : audio_rec.c -* 版 本 : V1.2 -* 说 明 : 演示I2S录音和回放功能。通过串口超级终端作为操作界面。 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* V1.1 2014-11-04 armfly 去掉LED1指示灯的控制。因为这个GPIO将用于3.5寸触摸屏。 -* V1.2 2015-01-08 armfly 修改StartPlay(void)函数,根据扬声器设置决定是否打扬声器 -* -* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -/* - 安富莱开发板配置的I2S音频CODEC芯片为WM8978。 - - 操作提示: - [TAMPER]键 = 选择音频格式 - [WAKEUP]键 = 开始录音 - [USER]键 = 开始回放 - 摇杆上/下键 = 调节音量 - 摇杆左/右键 = 调节MIC增益 - 摇杆OK键 = 终止录放 - - 录音时数据保存在安富莱STM32开发板外扩的2MB SRAM中,缺省使用8K采样率,16bit格式。1MB可以保存64秒录音。 - 放音按相同的格式,从外部SRAM中读取数据。 - - WM8978支持的采样率 : - Support for 8, 11.025, 12, 16, 22.05, 24, 32, 44.1 and 48kHz sample rates - -*/ - -#include "bsp.h" -#include "form_audio_rec.h" - -#define STR_Help1 "摇杆上/下键 = 调节耳机音量" -#define STR_Help2 "摇杆左/右键 = 调节麦克风增益" -#define STR_Help3 "K1键 = 选择音频格式" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BUTTON_RET_H 32 -#define BUTTON_RET_W 60 -#define BUTTON_RET_X (g_LcdWidth - BUTTON_RET_W - 4) -#define BUTTON_RET_Y (g_LcdHeight - BUTTON_RET_H - 4) -#define BUTTON_RET_TEXT "返回" - -#define BUTTON_REC_H 32 -#define BUTTON_REC_W 74 -#define BUTTON_REC_X 5 -#define BUTTON_REC_Y 180 -#define BUTTON_REC_TEXT "开始录音" - -#define BUTTON_PLAY_H 32 -#define BUTTON_PLAY_W 74 -#define BUTTON_PLAY_X (BUTTON_REC_X + BUTTON_REC_W + 10) -#define BUTTON_PLAY_Y BUTTON_REC_Y -#define BUTTON_PLAY_TEXT "开始放音" - -#define BUTTON_STOP_H 32 -#define BUTTON_STOP_W 74 -#define BUTTON_STOP_X (BUTTON_PLAY_X + BUTTON_PLAY_W + 10) -#define BUTTON_STOP_Y BUTTON_REC_Y -#define BUTTON_STOP_TEXT "停止" - -/* 以下是检查框 */ -#define CHECK_SPK_X BUTTON_REC_X -#define CHECK_SPK_Y (BUTTON_REC_Y + BUTTON_REC_H + 5) -#define CHECK_SPK_H CHECK_BOX_H -#define CHECK_SPK_W (CHECK_BOX_W + 5 * 16) /* 决定触摸有效区域 */ -#define CHECK_SPK_TEXT "打开扬声器" - -REC_T g_tRec; - -/* 音频格式切换列表(可以自定义) */ -#define FMT_COUNT 9 /* 音频格式数组元素个数 */ -uint32_t g_FmtList[FMT_COUNT][3] = - { - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_8K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_11K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_16K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_22K}, - - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_32K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_44K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_48K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_96K}, - {I2S_STANDARD_PHILIPS, SAI_DATASIZE_16, I2S_AUDIOFREQ_192K}, -}; - -/* 定义录音放音缓冲区 */ -#define REC_MEM_ADDR SDRAM_APP_BUF -#define REC_MEM_SIZE (2 * 1024 * 1024) - -/* 仅允许本文件内调用的函数声明 */ -static void DispStatus(void); - -static void StartPlay(void); -static void StartRecord(void); -static void StopRec(void); - -/* -********************************************************************************************************* -* 函 数 名: RecorderDemo -* 功能说明: 录音机主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void RecorderDemo(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - uint8_t fQuit = 0; - FONT_T tFont, tFontBtn, tFontChk; /* 定义一个字体结构体变量,用于设置字体参数 */ - - char buf[128]; - uint16_t x, y; - uint16_t usLineCap = 18; - - int16_t tpX, tpY; - BUTTON_T tBtn; - CHECK_T tCheck; - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - /* 按钮字体 */ - tFontBtn.FontCode = FC_ST_16; - tFontBtn.BackColor = CL_MASK; /* 透明色 */ - tFontBtn.FrontColor = CL_BLACK; - tFontBtn.Space = 0; - - /* CheckBox 字体 */ - tFontChk.FontCode = FC_ST_16; - tFontChk.BackColor = CL_MASK; /* 透明色 */ - tFontChk.FrontColor = CL_YELLOW; - tFontChk.Space = 0; - } - - x = 5; - y = 3; - LCD_DispStr(x, y, "WM8978录音机", &tFont); /* 在(8,3)坐标处显示一串汉字 */ - y += usLineCap; - - /* 测试I2C设备 */ - { - if (i2c_CheckDevice(WM8978_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "WM8978 Ok (0x%02X)", WM8978_SLAVE_ADDRESS); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "WM8978 Err (0x%02X)", WM8978_SLAVE_ADDRESS); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - - tFont.FrontColor = CL_YELLOW; - LCD_DispStr(x, y, STR_Help1, &tFont); - y += usLineCap; - - LCD_DispStr(x, y, STR_Help2, &tFont); - y += usLineCap; - - LCD_DispStr(x, y, STR_Help3, &tFont); - y += usLineCap; - - tFont.FrontColor = CL_WHITE; - } - - /* 配置外部SRAM接口已经在 bsp.c 中的 bsp_Init() 函数执行过 */ - - /* 检测WM8978芯片,此函数会自动配置CPU的GPIO */ - if (!wm8978_Init()) - { - bsp_DelayMS(500); - return; - } - - /* 显示按钮 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 未选中 */ - tBtn.pCaption = BUTTON_RET_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_REC_X; - tBtn.Top = BUTTON_REC_Y; - tBtn.Height = BUTTON_REC_H; - tBtn.Width = BUTTON_REC_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_REC_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_PLAY_X; - tBtn.Top = BUTTON_PLAY_Y; - tBtn.Height = BUTTON_PLAY_H; - tBtn.Width = BUTTON_PLAY_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_PLAY_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_STOP_X; - tBtn.Top = BUTTON_STOP_Y; - tBtn.Height = BUTTON_STOP_H; - tBtn.Width = BUTTON_STOP_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_STOP_TEXT; - LCD_DrawButton(&tBtn); - - /* 显示检查框 */ - tCheck.Font = &tFontChk; - - tCheck.Left = CHECK_SPK_X; - tCheck.Top = CHECK_SPK_Y; - tCheck.Height = CHECK_SPK_H; - tCheck.Width = CHECK_SPK_W; - if (g_tRec.ucSpkOutEn == 1) - { - tCheck.Checked = 1; - } - else - { - tCheck.Checked = 0; - } - tCheck.pCaption = CHECK_SPK_TEXT; - LCD_DrawCheckBox(&tCheck); - } - - /* 初始化全局变量 */ - g_tRec.ucVolume = 52; /* 缺省音量 */ - g_tRec.ucMicGain = 34; /* 缺省PGA增益 */ - - fRefresh = 1; - - g_tRec.ucFmtIdx = 1; /* 缺省音频格式(16Bit, 16KHz) */ - g_tRec.pAudio = (int16_t *)SDRAM_APP_BUF; /* 通过 init16_t * 型指针访问外部SRAM */ - - /* 清零录音缓冲区. SRAM容量2M字节 */ - // { - // int i; - - // for (i = 0 ; i < 1 * 1024 * 1024; i++) - // { - // g_tRec.pAudio[i] = 0; - // } - // } - - /* 生成正弦波数组 */ - AUDIO_MakeSine16bit((int16_t *)REC_MEM_ADDR, 1000, 16000, 16000 * 5); - - g_tRec.ucStatus = STA_IDLE; /* 首先进入空闲状态 */ - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - AUDIO_Poll(); - - /* 集中处理显示界面刷新 */ - if (fRefresh == 1) - { - fRefresh = 0; - DispStatus(); /* 显示当前状态,频率,音量等 */ - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_RET_TEXT; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_REC_X, BUTTON_REC_Y, BUTTON_REC_H, BUTTON_REC_W)) - { - tBtn.Left = BUTTON_REC_X; - tBtn.Top = BUTTON_REC_Y; - tBtn.Height = BUTTON_REC_H; - tBtn.Width = BUTTON_REC_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_REC_TEXT; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_PLAY_X, BUTTON_PLAY_Y, BUTTON_PLAY_H, BUTTON_PLAY_W)) - { - tBtn.Left = BUTTON_PLAY_X; - tBtn.Top = BUTTON_PLAY_Y; - tBtn.Height = BUTTON_PLAY_H; - tBtn.Width = BUTTON_PLAY_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_PLAY_TEXT; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_STOP_X, BUTTON_STOP_Y, BUTTON_STOP_H, BUTTON_STOP_W)) - { - tBtn.Left = BUTTON_STOP_X; - tBtn.Top = BUTTON_STOP_Y; - tBtn.Height = BUTTON_STOP_H; - tBtn.Width = BUTTON_STOP_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_STOP_TEXT; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, CHECK_SPK_X, CHECK_SPK_Y, CHECK_SPK_H, CHECK_SPK_W)) - { - if (g_tRec.ucSpkOutEn) - { - g_tRec.ucSpkOutEn = 0; - tCheck.Checked = 0; - - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 */ - /* 在 StartPlay() 函数内部配置 */ - } - else - { - g_tRec.ucSpkOutEn = 1; - tCheck.Checked = 1; - - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 和 扬声器 */ - /* 在 StartPlay() 函数内部配置 */ - } - - tCheck.Left = CHECK_SPK_X; - tCheck.Top = CHECK_SPK_Y; - tCheck.Height = CHECK_SPK_H; - tCheck.Width = CHECK_SPK_W; - tCheck.pCaption = CHECK_SPK_TEXT; - LCD_DrawCheckBox(&tCheck); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_RET_TEXT; - LCD_DrawButton(&tBtn); - - fQuit = 1; /* 返回 */ - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_REC_X, BUTTON_REC_Y, BUTTON_REC_H, BUTTON_REC_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_REC_X; - tBtn.Top = BUTTON_REC_Y; - tBtn.Height = BUTTON_REC_H; - tBtn.Width = BUTTON_REC_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_REC_TEXT; - LCD_DrawButton(&tBtn); - - StartRecord(); /* 开始录音 */ - fRefresh = 1; - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_PLAY_X, BUTTON_PLAY_Y, BUTTON_PLAY_H, BUTTON_PLAY_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_PLAY_X; - tBtn.Top = BUTTON_PLAY_Y; - tBtn.Height = BUTTON_PLAY_H; - tBtn.Width = BUTTON_PLAY_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_PLAY_TEXT; - LCD_DrawButton(&tBtn); - - StartPlay(); /* 开始放音 */ - fRefresh = 1; - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_STOP_X, BUTTON_STOP_Y, BUTTON_STOP_H, BUTTON_STOP_W)) - { - tBtn.Left = BUTTON_STOP_X; - tBtn.Top = BUTTON_STOP_Y; - tBtn.Height = BUTTON_STOP_H; - tBtn.Width = BUTTON_STOP_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = BUTTON_STOP_TEXT; - LCD_DrawButton(&tBtn); - - StopRec(); /* 停止录音和放音 */ - fRefresh = 1; - } - else /* 按钮失去焦点 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Focus = 0; /* 未选中 */ - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.pCaption = BUTTON_RET_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_REC_X; - tBtn.Top = BUTTON_REC_Y; - tBtn.Height = BUTTON_REC_H; - tBtn.Width = BUTTON_REC_W; - tBtn.pCaption = BUTTON_REC_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_PLAY_X; - tBtn.Top = BUTTON_PLAY_Y; - tBtn.Height = BUTTON_PLAY_H; - tBtn.Width = BUTTON_PLAY_W; - tBtn.pCaption = BUTTON_PLAY_TEXT; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_STOP_X; - tBtn.Top = BUTTON_STOP_Y; - tBtn.Height = BUTTON_STOP_H; - tBtn.Width = BUTTON_STOP_W; - tBtn.pCaption = BUTTON_STOP_TEXT; - LCD_DrawButton(&tBtn); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键切换音频格式,在下次开始录音和放音时有效 */ - if (++g_tRec.ucFmtIdx >= FMT_COUNT) - { - g_tRec.ucFmtIdx = 0; - } - fRefresh = 1; - break; - - case KEY_DOWN_K2: /* K2键按下,录音 */ - StartRecord(); - fRefresh = 1; - break; - - case KEY_DOWN_K3: /* K3键按下,放音 */ - StartPlay(); - fRefresh = 1; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - if (g_tRec.ucVolume <= VOLUME_MAX - VOLUME_STEP) - { - g_tRec.ucVolume += VOLUME_STEP; - wm8978_SetEarVolume(g_tRec.ucVolume); - wm8978_SetSpkVolume(g_tRec.ucVolume); - fRefresh = 1; - } - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_tRec.ucVolume >= VOLUME_STEP) - { - g_tRec.ucVolume -= VOLUME_STEP; - wm8978_SetEarVolume(g_tRec.ucVolume); - wm8978_SetSpkVolume(g_tRec.ucVolume); - fRefresh = 1; - } - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (g_tRec.ucMicGain >= GAIN_STEP) - { - g_tRec.ucMicGain -= GAIN_STEP; - wm8978_SetMicGain(g_tRec.ucMicGain); - fRefresh = 1; - } - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (g_tRec.ucMicGain <= GAIN_MAX - GAIN_STEP) - { - g_tRec.ucMicGain += GAIN_STEP; - wm8978_SetMicGain(g_tRec.ucMicGain); - fRefresh = 1; - } - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - StopRec(); /* 停止录音和放音 */ - fRefresh = 1; - break; - - default: - break; - } - } - - /* 处理消息 */ - { - MSG_T msg; - - if (bsp_GetMsg(&msg)) - { - switch (msg.MsgCode) - { - case MSG_WM8978_DMA_END: - StopRec(); /* 停止录音和放音 */ - fRefresh = 1; - break; - - default: - break; - } - } - } - } - - StopRec(); /* 停止录音和放音 */ -} - -/* -********************************************************************************************************* -* 函 数 名: StartPlay -* 功能说明: 配置WM8978和STM32的I2S开始放音。 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void StartPlay(void) -{ - /* 如果已经再录音和放音状态,则需要先停止再开启 */ - AUDIO_Stop(); /* 停止I2S录音和放音 */ - wm8978_Init(); /* 复位WM8978到复位状态 */ - - bsp_DelayMS(20); /* 延迟一段时间,等待I2S中断结束 */ - - g_tRec.ucStatus = STA_PLAYING; /* 放音状态 */ - - g_tRec.uiCursor = 0; /* 数据指针复位为0,从头开始放音 */ - - /* 配置WM8978芯片,输入为DAC,输出为耳机 */ - if (g_tRec.ucSpkOutEn == 1) - { - wm8978_CfgAudioPath(DAC_ON, EAR_LEFT_ON | EAR_RIGHT_ON | SPK_ON); /* 打开扬声器 */ - } - else - { - wm8978_CfgAudioPath(DAC_ON, EAR_LEFT_ON | EAR_RIGHT_ON); /* 关闭扬声器 */ - } - - /* 调节音量,左右相同音量 */ - wm8978_SetEarVolume(g_tRec.ucVolume); - wm8978_SetSpkVolume(g_tRec.ucVolume); - - /* 配置WM8978音频接口为飞利浦标准I2S接口,16bit */ - wm8978_CfgAudioIF(I2S_STANDARD_PHILIPS, 16); - - /* 配置STM32的I2S音频接口(比如飞利浦标准I2S接口,16bit, 8K采样率), 开始放音 */ - AUDIO_Init(1, I2S_STANDARD_PHILIPS, g_FmtList[g_tRec.ucFmtIdx][1], g_FmtList[g_tRec.ucFmtIdx][2]); - - { - int16_t *pWave = (int16_t *)REC_MEM_ADDR; - - AUDIO_Play(pWave, AUDIO_GetRecordSampleCount()); - } -} - -/* -********************************************************************************************************* -* 函 数 名: StartRecord -* 功能说明: 配置WM8978和STM32的I2S开始录音。 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void StartRecord(void) -{ - /* 如果已经再录音和放音状态,则需要先停止再开启 */ - AUDIO_Stop(); /* 停止I2S录音和放音 */ - wm8978_Init(); /* 复位WM8978到复位状态 */ - - bsp_DelayMS(20); /* 延迟一段时间,等待I2S中断结束 */ - - g_tRec.ucStatus = STA_RECORDING; /* 录音状态 */ - - g_tRec.uiCursor = 0; /* 数据指针复位为0,从头开始录音 */ - - /* 配置WM8978芯片,输入为Mic,输出为耳机 */ - //wm8978_CfgAudioPath(MIC_LEFT_ON | ADC_ON, EAR_LEFT_ON | EAR_RIGHT_ON); - //wm8978_CfgAudioPath(MIC_RIGHT_ON | ADC_ON, EAR_LEFT_ON | EAR_RIGHT_ON); - wm8978_CfgAudioPath(MIC_LEFT_ON | MIC_RIGHT_ON | ADC_ON, EAR_LEFT_ON | EAR_RIGHT_ON); - - /* 调节放音音量,左右相同音量 */ - wm8978_SetEarVolume(g_tRec.ucVolume); - - /* 设置MIC通道增益 */ - wm8978_SetMicGain(g_tRec.ucMicGain); - - /* 配置WM8978音频接口为飞利浦标准I2S接口,16bit */ - wm8978_CfgAudioIF(I2S_STANDARD_PHILIPS, 16); - - /* 配置STM32的I2S音频接口(比如飞利浦标准I2S接口,16bit, 8K采样率), 开始放音 */ - AUDIO_Init(3, I2S_STANDARD_PHILIPS, g_FmtList[g_tRec.ucFmtIdx][1], g_FmtList[g_tRec.ucFmtIdx][2]); - - { - int16_t *pWave1 = (int16_t *)REC_MEM_ADDR; - int16_t *pWave2 = (int16_t *)(REC_MEM_ADDR + 1 * 1024 * 1024); - - AUDIO_Play(pWave2, 1 * 1024 * 1024); - AUDIO_Record(pWave1, 1 * 1024 * 1024); - } -} - -/* -********************************************************************************************************* -* 函 数 名: StopRec -* 功能说明: 停止录音和放音 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void StopRec(void) -{ - g_tRec.ucStatus = STA_IDLE; /* 待机状态 */ - AUDIO_Stop(); /* 停止I2S录音和放音 */ - wm8978_Init(); /* 复位WM8978到复位状态 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispStatus -* 功能说明: 显示当前状态 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispStatus(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = 5; - y = 100; - /* 显示当前音频格式 */ - sprintf(buf, "音频格式: Philips,16Bit,%d.%dkHz ", - g_FmtList[g_tRec.ucFmtIdx][2] / 1000, - (g_FmtList[g_tRec.ucFmtIdx][2] % 1000) / 100); - - sprintf(&buf[strlen(buf)], "录音时长: %d.%03d秒 ", - (REC_MEM_SIZE / 2) / g_FmtList[g_tRec.ucFmtIdx][2], - (((REC_MEM_SIZE / 2) * 1000) / g_FmtList[g_tRec.ucFmtIdx][2]) % 1000); - - LCD_DispStr(x, y, buf, &tFont); - y += 18; - - sprintf(buf, "麦克风增益 = %d ", g_tRec.ucMicGain); - sprintf(&buf[strlen(buf)], "耳机音量 = %d ", g_tRec.ucVolume); - LCD_DispStr(x, y, buf, &tFont); - y += 18; - - if (g_tRec.ucStatus == STA_IDLE) - { - sprintf(buf, "状态 = 空闲 "); - } - else if (g_tRec.ucStatus == STA_RECORDING) - { - sprintf(buf, "状态 = 正在录音"); - } - else if (g_tRec.ucStatus == STA_PLAYING) - { - sprintf(buf, "状态 = 正在回放"); - } - LCD_DispStr(x, y, buf, &tFont); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_camera.c b/User/app/src/old/form_camera.c deleted file mode 100755 index 2d89763..0000000 --- a/User/app/src/old/form_camera.c +++ /dev/null @@ -1,478 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 摄像头模块程序。 -* 文件名称 : camera_test.c -* 版 本 : V1.1 -* 说 明 : 使用STM32F429的DCMI摄像头接口,显示图像 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 STM32F407 -* v1.1 2015-10-17 armfly 移植到STM32F429 -* -* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_camera.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 蓝色 */ - FONT_T FontRed; /* 变化的文字字体 红色 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; /* 状态 */ - LABEL_T Label3; - LABEL_T Label4; /* 状态 */ - LABEL_T Label5; - LABEL_T Label6; /* 状态 */ - - BUTTON_T Btn1; /* 打开摄像头 */ - BUTTON_T Btn2; /* 暂停 */ - - BUTTON_T BtnRet; - -} FormCAM_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 4个框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 5 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "摄像头0V7670测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define BTN1_H 32 -#define BTN1_W 100 -#define BTN1_X (BOX1_X + 330) -#define BTN1_Y (BOX1_Y + 100) -#define BTN1_TEXT "打开摄像头" - -#define BTN2_H 32 -#define BTN2_W 100 -#define BTN2_X BTN1_X -#define BTN2_Y (BTN1_Y + BTN1_H + 10) -#define BTN2_TEXT "关闭摄像头" - -/* 标签 */ -#define LABEL1_X (BOX1_X + 330) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "Chip ID : " - -#define LABEL2_X (LABEL1_X + 80) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "--" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "状态1 : " - -#define LABEL4_X (LABEL3_X + 80) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "--" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "状态2 : " - -#define LABEL6_X (LABEL5_X + 80) -#define LABEL6_Y (LABEL5_Y) -#define LABEL6_TEXT "--" - -/* 摄像显示窗口位置和大小 */ -#define PHOTO_X 10 -#define PHOTO_Y 22 -#define PHOTO_H 240 -#define PHOTO_W 320 - -static void InitFormCam(void); -static void DispCamInitFace(void); - -FormCAM_T *FormCam; - -/* Buffer location should aligned to cache line size (32 bytes) */ -#define CAN_BUF_SIZE (320 * 265 * 2) -ALIGN_32BYTES(uint16_t s_CamCache[CAN_BUF_SIZE]); - -/* -********************************************************************************************************* -* 函 数 名: TestCamera -* 功能说明: 测试摄像头 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestCamera(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - uint16_t usChipID; - char buf[128]; - uint8_t fStop = 0; - - FormCAM_T form; - uint8_t fRefresh; - - FormCam = &form; - - InitFormCam(); - - bsp_InitCamera(); - DispCamInitFace(); - - if (i2c_CheckDevice(OV7670_SLAVE_ADDRESS) == 0) - { - usChipID = OV_ReadID(); - sprintf(buf, "0x%04X", usChipID); - - FormCam->Label2.Font = &FormCam->FontBlue; - FormCam->Label2.pCaption = buf; - } - else - { - sprintf(buf, "None "); - - FormCam->Label2.Font = &FormCam->FontRed; - FormCam->Label2.pCaption = buf; - } - LCD_DrawLabel(&FormCam->Label2); - - LCD_DrawRect(PHOTO_X - 1, PHOTO_Y - 1, PHOTO_H + 2, PHOTO_W + 2, CL_RED); - - fRefresh = 1; - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - //LCD_DrawLabel(&FormCam->Label6); - } - - if (g_tCam.CaptureOk == 1) - { - g_tCam.CaptureOk = 0; - - /* 开始绘图 ,图片在 s_CamCache */ - SCB_CleanInvalidateDCache(); - LCD429_DrawBMP(PHOTO_X, PHOTO_Y, PHOTO_H, PHOTO_W, (uint16_t *)s_CamCache); - - if (fStop == 0) - { - bsp_StartTimer(0, 50); /* 启动定时器 */ - } - } - - if (bsp_CheckTimer(0)) - { - { - //g_tTP.Enable = 0; - - //RA8875_StartDirectDraw(PHOTO_X, PHOTO_Y, PHOTO_H, PHOTO_W); - CAM_Start((uint32_t)s_CamCache); - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormCam->BtnRet.Focus = 1; - LCD_DrawButton(&FormCam->BtnRet); - } - else if (TOUCH_InRect(tpX, tpY, BTN1_X, BTN1_Y, BTN1_H, BTN1_W)) - { - FormCam->Btn1.Focus = 1; - LCD_DrawButton(&FormCam->Btn1); - } - else if (TOUCH_InRect(tpX, tpY, BTN2_X, BTN2_Y, BTN2_H, BTN2_W)) - { - FormCam->Btn2.Focus = 1; - LCD_DrawButton(&FormCam->Btn2); - } - break; - - case TOUCH_MOVE: /* 触笔移动事件 */ - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormCam->BtnRet.Focus = 0; - LCD_DrawButton(&FormCam->BtnRet); - fQuit = 1; /* 返回 */ - } - else if (TOUCH_InRect(tpX, tpY, BTN1_X, BTN1_Y, BTN1_H, BTN1_W)) /* 打开摄像头 */ - { - FormCam->Btn1.Focus = 0; - LCD_DrawButton(&FormCam->Btn1); - - { - if (i2c_CheckDevice(OV7670_SLAVE_ADDRESS) == 0) - { - usChipID = OV_ReadID(); - sprintf(buf, "0x%04X", usChipID); - - FormCam->Label2.Font = &FormCam->FontBlue; - FormCam->Label2.pCaption = buf; - } - else - { - sprintf(buf, "None "); - - FormCam->Label2.Font = &FormCam->FontRed; - FormCam->Label2.pCaption = buf; - } - LCD_DrawLabel(&FormCam->Label2); - } - - { - //g_tTP.Enable = 0; - - //RA8875_StartDirectDraw(PHOTO_X, PHOTO_Y, PHOTO_H, PHOTO_W); - CAM_Start((uint32_t)s_CamCache); /* 摄像头DMA的目标地址设置为显存 */ - } - fStop = 0; - fRefresh = 1; - } - else if (TOUCH_InRect(tpX, tpY, BTN2_X, BTN2_Y, BTN2_H, BTN2_W)) - { - FormCam->Btn2.Focus = 0; - LCD_DrawButton(&FormCam->Btn2); - - bsp_StopTimer(0); /* 停止自动定时器 */ - - fStop = 1; - fRefresh = 1; - } - else /* 按钮失去焦点 */ - { - FormCam->BtnRet.Focus = 0; - LCD_DrawButton(&FormCam->BtnRet); - - FormCam->Btn1.Focus = 0; - LCD_DrawButton(&FormCam->Btn1); - - FormCam->Btn2.Focus = 0; - LCD_DrawButton(&FormCam->Btn2); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - CAM_Stop(); /* 停止摄像头DMA */ - g_tTP.Enable = 1; - break; - - default: - break; - } - } - } - - bsp_StopTimer(0); /* 停止自动定时器 */ - - CAM_Stop(); - // RA8875_QuitDirectDraw(); - g_tTP.Enable = 1; -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormCam -* 功能说明: 初始化GPS初始界面控件 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormCam(void) -{ - /* 分组框标题字体 */ - FormCam->FontBox.FontCode = FC_ST_16; - FormCam->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormCam->FontBox.FrontColor = CL_BLACK; - FormCam->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormCam->FontBlack.FontCode = FC_ST_16; - FormCam->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormCam->FontBlack.FrontColor = CL_BLACK; - FormCam->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormCam->FontBlue.FontCode = FC_ST_16; - FormCam->FontBlue.BackColor = CL_BTN_FACE; - FormCam->FontBlue.FrontColor = CL_BLUE; - FormCam->FontBlue.Space = 0; - - /* 字体3 用于变化的文字 */ - FormCam->FontRed.FontCode = FC_ST_16; - FormCam->FontRed.BackColor = CL_BTN_FACE; - FormCam->FontRed.FrontColor = CL_RED; - FormCam->FontRed.Space = 0; - - /* 按钮字体 */ - FormCam->FontBtn.FontCode = FC_ST_16; - FormCam->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormCam->FontBtn.FrontColor = CL_BLACK; - FormCam->FontBtn.Space = 0; - - /* 分组框 */ - FormCam->Box1.Left = BOX1_X; - FormCam->Box1.Top = BOX1_Y; - FormCam->Box1.Height = BOX1_H; - FormCam->Box1.Width = BOX1_W; - FormCam->Box1.pCaption = BOX1_TEXT; - FormCam->Box1.Font = &FormCam->FontBox; - - /* 静态标签 */ - FormCam->Label1.Left = LABEL1_X; - FormCam->Label1.Top = LABEL1_Y; - FormCam->Label1.MaxLen = 0; - FormCam->Label1.pCaption = LABEL1_TEXT; - FormCam->Label1.Font = &FormCam->FontBlack; - - FormCam->Label3.Left = LABEL3_X; - FormCam->Label3.Top = LABEL3_Y; - FormCam->Label3.MaxLen = 0; - FormCam->Label3.pCaption = LABEL3_TEXT; - FormCam->Label3.Font = &FormCam->FontBlack; - - FormCam->Label5.Left = LABEL5_X; - FormCam->Label5.Top = LABEL5_Y; - FormCam->Label5.MaxLen = 0; - FormCam->Label5.pCaption = LABEL5_TEXT; - FormCam->Label5.Font = &FormCam->FontBlack; - - /* 动态标签 */ - FormCam->Label2.Left = LABEL2_X; - FormCam->Label2.Top = LABEL2_Y; - FormCam->Label2.MaxLen = 0; - FormCam->Label2.pCaption = LABEL2_TEXT; - FormCam->Label2.Font = &FormCam->FontBlue; - - FormCam->Label4.Left = LABEL4_X; - FormCam->Label4.Top = LABEL4_Y; - FormCam->Label4.MaxLen = 0; - FormCam->Label4.pCaption = LABEL4_TEXT; - FormCam->Label4.Font = &FormCam->FontBlue; - - FormCam->Label6.Left = LABEL6_X; - FormCam->Label6.Top = LABEL6_Y; - FormCam->Label6.MaxLen = 0; - FormCam->Label6.pCaption = LABEL6_TEXT; - FormCam->Label6.Font = &FormCam->FontBlue; - - /* 按钮 */ - FormCam->BtnRet.Left = BTN_RET_X; - FormCam->BtnRet.Top = BTN_RET_Y; - FormCam->BtnRet.Height = BTN_RET_H; - FormCam->BtnRet.Width = BTN_RET_W; - FormCam->BtnRet.pCaption = BTN_RET_TEXT; - FormCam->BtnRet.Font = &FormCam->FontBtn; - FormCam->BtnRet.Focus = 0; - - FormCam->Btn1.Left = BTN1_X; - FormCam->Btn1.Top = BTN1_Y; - FormCam->Btn1.Height = BTN1_H; - FormCam->Btn1.Width = BTN1_W; - FormCam->Btn1.pCaption = BTN1_TEXT; - FormCam->Btn1.Font = &FormCam->FontBtn; - FormCam->Btn1.Focus = 0; - - FormCam->Btn2.Left = BTN2_X; - FormCam->Btn2.Top = BTN2_Y; - FormCam->Btn2.Height = BTN2_H; - FormCam->Btn2.Width = BTN2_W; - FormCam->Btn2.pCaption = BTN2_TEXT; - FormCam->Btn2.Font = &FormCam->FontBtn; - FormCam->Btn2.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispUSBInitFace -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispCamInitFace(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormCam->Box1); - - /* 标签 */ - LCD_DrawLabel(&FormCam->Label1); - LCD_DrawLabel(&FormCam->Label2); - LCD_DrawLabel(&FormCam->Label3); - LCD_DrawLabel(&FormCam->Label4); - LCD_DrawLabel(&FormCam->Label5); - LCD_DrawLabel(&FormCam->Label6); - - /* 按钮 */ - LCD_DrawButton(&FormCam->BtnRet); - LCD_DrawButton(&FormCam->Btn1); - LCD_DrawButton(&FormCam->Btn2); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_can.c b/User/app/src/old/form_can.c deleted file mode 100755 index d5fb91e..0000000 --- a/User/app/src/old/form_can.c +++ /dev/null @@ -1,501 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : CAN网络测试界面 -* 文件名称 : form_can.c -* 版 本 : V1.0 -* 说 明 : 两个开发板之间进行CAN网络互通测试 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2015-08-09 armfly 首发 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_can.h" -#include "can_network.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - - LABEL_T LblInfo1; - LABEL_T LblInfo2; -} FormCAN_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H 100 -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "CAN网络测试" - -/* 第1个框内的按钮 */ -#define BTN1_H 32 -#define BTN1_W 100 -#define BTN1_X (BOX1_X + 10) -#define BTN1_Y (BOX1_Y + 20) -#define BTN1_TEXT "点亮LED2" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_TEXT "关闭LED2" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X BTN1_X -#define BTN3_Y (BTN1_Y + BTN1_H + 10) -#define BTN3_TEXT "蜂鸣2声" - -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X (BTN1_X + BTN1_W + 10) -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_TEXT "蜂鸣3声" - -#define BTN5_H BTN1_H -#define BTN5_W BTN1_W -#define BTN5_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN5_Y (BTN1_Y + BTN1_H + 10) -#define BTN5_TEXT "蜂鸣20声" - -#define BTN6_H BTN1_H -#define BTN6_W BTN1_W -#define BTN6_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN6_Y (BTN1_Y + BTN1_H + 10) -#define BTN6_TEXT "停止蜂鸣" - -#define LABEL1_X (BTN5_X + 10) -#define LABEL1_Y BTN2_Y -#define LABEL1_TEXT "地址: " - -#define LABEL2_X (LABEL1_X + 48) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "0" - -#define LABEL3_X (LABEL2_X + 32) -#define LABEL3_Y LABEL1_Y -#define LABEL3_TEXT "波特率: " - -#define LABEL4_X (LABEL3_X + 64) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "0" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20) -#define LABEL5_TEXT "接收:" - -#define LABEL6_X (LABEL5_X + 48) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT " " - -#define LBL_INFO1_X (BOX1_X) -#define LBL_INFO1_Y (BOX1_Y + BOX1_H + 10) -#define LBL_INFO1_TEXT "请将两个开发板的CAN接口互联" - -#define LBL_INFO2_X LBL_INFO1_X -#define LBL_INFO2_Y (LBL_INFO1_Y + 20) -#define LBL_INFO2_TEXT "可以互相控制对方的LED2和蜂鸣器" - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -static void InitFormCAN(void); -static void DispFormCAN(void); - -static void DispLabelBaud(uint32_t _Baud); -static void DispLabelRx(uint8_t *_buf, uint8_t _len); - -FormCAN_T *FormCAN; - -/* -********************************************************************************************************* -* 函 数 名: FormMainCAN -* 功能说明: CAN测试主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void FormMainCAN(void) -{ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormCAN_T form; - uint32_t baud; - - FormCAN = &form; - - InitFormCAN(); - DispFormCAN(); - - baud = 500000; - DispLabelBaud(baud); - - can_Init(); /* 初始化STM32 CAN硬件 */ - - /* 进入主程序循环体 */ - bsp_StartAutoTimer(2, 10); - while (fQuit == 0) - { - bsp_Idle(); - - // MODBUS_Poll(); - - if (bsp_CheckTimer(2)) - { - can_LedOn(1, 1); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&FormCAN->BtnRet, tpX, tpY)) - { - //fQuit = 1; - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn1, tpX, tpY)) - { - can_LedOn(1, 2); - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn2, tpX, tpY)) - { - can_LedOff(1, 2); - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn3, tpX, tpY)) - { - can_BeepCtrl(1, 2); /* 控制蜂鸣器鸣叫2声 */ - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn4, tpX, tpY)) - { - can_BeepCtrl(1, 3); /* 控制蜂鸣器鸣叫3声 */ - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn5, tpX, tpY)) - { - can_BeepCtrl(1, 20); /* 控制蜂鸣器鸣叫20声 */ - } - else if (LCD_ButtonTouchDown(&FormCAN->Btn6, tpX, tpY)) - { - can_BeepCtrl(1, 0); /* 控制蜂鸣器停止鸣叫 */ - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormCAN->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else - { - LCD_ButtonTouchRelease(&FormCAN->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&FormCAN->Btn6, tpX, tpY); - } - break; - } - } - - /* 处理应用层消息 */ - { - MSG_T msg; - - if (bsp_GetMsg(&msg)) - { - switch (msg.MsgCode) - { - case MSG_CAN1_RX: /* 接收到CAN设备的应答 */ - DispLabelRx(g_Can1RxData, g_Can1RxHeader.DataLength); - can1_Analyze(); - break; - - case MSG_CAN2_RX: /* 接收到CAN设备的应答 */ - DispLabelRx(g_Can2RxData, g_Can2RxHeader.DataLength); - can1_Analyze(); - break; - } - } - } - } - - can_DeInit(); /* 关闭CAN时钟 */ -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormCAN -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormCAN(void) -{ - /* 分组框标题字体 */ - FormCAN->FontBox.FontCode = FC_ST_16; - FormCAN->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormCAN->FontBox.FrontColor = CL_BLACK; - FormCAN->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormCAN->FontBlack.FontCode = FC_ST_16; - FormCAN->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormCAN->FontBlack.FrontColor = CL_BLACK; - FormCAN->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormCAN->FontBlue.FontCode = FC_ST_16; - FormCAN->FontBlue.BackColor = CL_BTN_FACE; - FormCAN->FontBlue.FrontColor = CL_BLUE; - FormCAN->FontBlue.Space = 0; - - /* 按钮字体 */ - FormCAN->FontBtn.FontCode = FC_ST_16; - FormCAN->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormCAN->FontBtn.FrontColor = CL_BLACK; - FormCAN->FontBtn.Space = 0; - - /* 分组框 */ - FormCAN->Box1.Left = BOX1_X; - FormCAN->Box1.Top = BOX1_Y; - FormCAN->Box1.Height = BOX1_H; - FormCAN->Box1.Width = BOX1_W; - FormCAN->Box1.pCaption = BOX1_TEXT; - FormCAN->Box1.Font = &FormCAN->FontBox; - - /* 静态标签 */ - FormCAN->Label1.Left = LABEL1_X; - FormCAN->Label1.Top = LABEL1_Y; - FormCAN->Label1.MaxLen = 0; - FormCAN->Label1.pCaption = LABEL1_TEXT; - FormCAN->Label1.Font = &FormCAN->FontBlack; - - FormCAN->Label3.Left = LABEL3_X; - FormCAN->Label3.Top = LABEL3_Y; - FormCAN->Label3.MaxLen = 0; - FormCAN->Label3.pCaption = LABEL3_TEXT; - FormCAN->Label3.Font = &FormCAN->FontBlack; - - FormCAN->Label5.Left = LABEL5_X; - FormCAN->Label5.Top = LABEL5_Y; - FormCAN->Label5.MaxLen = 0; - FormCAN->Label5.pCaption = LABEL5_TEXT; - FormCAN->Label5.Font = &FormCAN->FontBlack; - - /* 动态标签 */ - FormCAN->Label2.Left = LABEL2_X; - FormCAN->Label2.Top = LABEL2_Y; - FormCAN->Label2.MaxLen = 0; - FormCAN->Label2.pCaption = LABEL2_TEXT; - FormCAN->Label2.Font = &FormCAN->FontBlue; - - FormCAN->Label4.Left = LABEL4_X; - FormCAN->Label4.Top = LABEL4_Y; - FormCAN->Label4.MaxLen = 0; - FormCAN->Label4.pCaption = LABEL4_TEXT; - FormCAN->Label4.Font = &FormCAN->FontBlue; - - FormCAN->Label6.Left = LABEL6_X; - FormCAN->Label6.Top = LABEL6_Y; - FormCAN->Label6.MaxLen = 0; - FormCAN->Label6.pCaption = LABEL6_TEXT; - FormCAN->Label6.Font = &FormCAN->FontBlue; - - /* 按钮 */ - FormCAN->BtnRet.Left = BTN_RET_X; - FormCAN->BtnRet.Top = BTN_RET_Y; - FormCAN->BtnRet.Height = BTN_RET_H; - FormCAN->BtnRet.Width = BTN_RET_W; - FormCAN->BtnRet.pCaption = BTN_RET_TEXT; - FormCAN->BtnRet.Font = &FormCAN->FontBtn; - FormCAN->BtnRet.Focus = 0; - - FormCAN->Btn1.Left = BTN1_X; - FormCAN->Btn1.Top = BTN1_Y; - FormCAN->Btn1.Height = BTN1_H; - FormCAN->Btn1.Width = BTN1_W; - FormCAN->Btn1.pCaption = BTN1_TEXT; - FormCAN->Btn1.Font = &FormCAN->FontBtn; - FormCAN->Btn1.Focus = 0; - - FormCAN->Btn2.Left = BTN2_X; - FormCAN->Btn2.Top = BTN2_Y; - FormCAN->Btn2.Height = BTN2_H; - FormCAN->Btn2.Width = BTN2_W; - FormCAN->Btn2.pCaption = BTN2_TEXT; - FormCAN->Btn2.Font = &FormCAN->FontBtn; - FormCAN->Btn2.Focus = 0; - - FormCAN->Btn3.Left = BTN3_X; - FormCAN->Btn3.Top = BTN3_Y; - FormCAN->Btn3.Height = BTN3_H; - FormCAN->Btn3.Width = BTN3_W; - FormCAN->Btn3.pCaption = BTN3_TEXT; - FormCAN->Btn3.Font = &FormCAN->FontBtn; - FormCAN->Btn3.Focus = 0; - - FormCAN->Btn4.Left = BTN4_X; - FormCAN->Btn4.Top = BTN4_Y; - FormCAN->Btn4.Height = BTN4_H; - FormCAN->Btn4.Width = BTN4_W; - FormCAN->Btn4.pCaption = BTN4_TEXT; - FormCAN->Btn4.Font = &FormCAN->FontBtn; - FormCAN->Btn4.Focus = 0; - - FormCAN->Btn5.Left = BTN5_X; - FormCAN->Btn5.Top = BTN5_Y; - FormCAN->Btn5.Height = BTN5_H; - FormCAN->Btn5.Width = BTN5_W; - FormCAN->Btn5.pCaption = BTN5_TEXT; - FormCAN->Btn5.Font = &FormCAN->FontBtn; - FormCAN->Btn5.Focus = 0; - - FormCAN->Btn6.Left = BTN6_X; - FormCAN->Btn6.Top = BTN6_Y; - FormCAN->Btn6.Height = BTN6_H; - FormCAN->Btn6.Width = BTN6_W; - FormCAN->Btn6.pCaption = BTN6_TEXT; - FormCAN->Btn6.Font = &FormCAN->FontBtn; - FormCAN->Btn6.Focus = 0; - - { - FormCAN->LblInfo1.Left = LBL_INFO1_X; - FormCAN->LblInfo1.Top = LBL_INFO1_Y; - FormCAN->LblInfo1.MaxLen = 0; - FormCAN->LblInfo1.pCaption = LBL_INFO1_TEXT; - FormCAN->LblInfo1.Font = &FormCAN->FontBlack; - - FormCAN->LblInfo2.Left = LBL_INFO2_X; - FormCAN->LblInfo2.Top = LBL_INFO2_Y; - FormCAN->LblInfo2.MaxLen = 0; - FormCAN->LblInfo2.pCaption = LBL_INFO2_TEXT; - FormCAN->LblInfo2.Font = &FormCAN->FontBlack; - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormCAN -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormCAN(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormCAN->Box1); - - LCD_DrawLabel(&FormCAN->Label1); - LCD_DrawLabel(&FormCAN->Label3); - LCD_DrawLabel(&FormCAN->Label5); - - LCD_DrawLabel(&FormCAN->Label2); - LCD_DrawLabel(&FormCAN->Label4); - LCD_DrawLabel(&FormCAN->Label6); - - /* 按钮 */ - LCD_DrawButton(&FormCAN->Btn1); - LCD_DrawButton(&FormCAN->Btn2); - LCD_DrawButton(&FormCAN->Btn3); - LCD_DrawButton(&FormCAN->Btn4); - LCD_DrawButton(&FormCAN->Btn5); - LCD_DrawButton(&FormCAN->Btn6); - - LCD_DrawLabel(&FormCAN->LblInfo1); - LCD_DrawLabel(&FormCAN->LblInfo2); - - LCD_DrawButton(&FormCAN->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: DispLabelTx -* 功能说明: 显示发送的数据 -* 形 参: _Baud 波特率 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispLabelBaud(uint32_t _Baud) -{ - char buf[10]; - - sprintf(buf, "%d", _Baud); - - /* 动态标签 */ - FormCAN->Label4.pCaption = buf; - LCD_DrawLabel(&FormCAN->Label4); -} - -/* -********************************************************************************************************* -* 函 数 名: DispLabelTx -* 功能说明: 显示发送的数据 -* 形 参: _buf 要发送的数据 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispLabelRx(uint8_t *_buf, uint8_t _len) -{ - char disp_buf[32]; - uint8_t len; - - len = _len; - if (len > sizeof(disp_buf) / 3) - { - len = sizeof(disp_buf) / 3; - } - - HexToAscll(_buf, disp_buf, len); - - /* 动态标签 */ - FormCAN->Label6.pCaption = disp_buf; - LCD_DrawLabel(&FormCAN->Label6); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_dac8501.c b/User/app/src/old/form_dac8501.c deleted file mode 100755 index f889f35..0000000 --- a/User/app/src/old/form_dac8501.c +++ /dev/null @@ -1,763 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : DAC8501 DAC8562模块测试界面 -* 文件名称 : form_dac8501.c -* 版 本 : V1.0 -* 说 明 : 驱动安富莱DAC8501模块和DAC8562模块。 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2014-10-15 armfly 首发 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_dac8501.h" -#include "math.h" - -#define TIMx TIM5 -#define TIMx_IRQHandler TIM5_IRQHandler - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 黑色 */ - FONT_T FontBlue; /* 蓝色 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - BUTTON_T Btn7; - BUTTON_T Btn8; - BUTTON_T Btn9; - BUTTON_T Btn10; - BUTTON_T Btn11; - BUTTON_T Btn12; - BUTTON_T Btn13; - BUTTON_T Btn14; - BUTTON_T Btn15; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - - uint16_t DacValue; /* DAC数据 */ - int32_t Voltage; /* 输出电压 */ -} Form8501_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - 53) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_T "DAC8501 双路DAC模块(16bit, 0 -> 5V)" - -#define BTN1_H 32 -#define BTN1_W 105 - -/* 第1行按钮坐标 */ -#define BTN1_X (BOX1_X + 10) -#define BTN1_Y (BOX1_Y + 20) -#define BTN1_T "0V" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_T "2.5V" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN3_Y BTN1_Y -#define BTN3_T "5.0V" - -/* 第2行按钮坐标 */ -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X BTN1_X -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_T "DAC值+1" - -#define BTN5_H BTN1_H -#define BTN5_W BTN1_W -#define BTN5_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN5_Y BTN4_Y -#define BTN5_T "DAC值-1" - -#define BTN6_H BTN1_H -#define BTN6_W BTN1_W -#define BTN6_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN6_Y BTN4_Y -#define BTN6_T "DAC值+100" - -#define BTN7_H BTN1_H -#define BTN7_W BTN1_W -#define BTN7_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN7_Y BTN4_Y -#define BTN7_T "DAC值-100" - -/* 第3行按钮坐标 */ -#define BTN8_H BTN1_H -#define BTN8_W BTN1_W -#define BTN8_X BTN1_X -#define BTN8_Y (BTN1_Y + 2 * (BTN1_H + 10)) -#define BTN8_T "电压+1mV" - -#define BTN9_H BTN1_H -#define BTN9_W BTN1_W -#define BTN9_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN9_Y BTN8_Y -#define BTN9_T "电压-1mV" - -#define BTN10_H BTN1_H -#define BTN10_W BTN1_W -#define BTN10_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN10_Y BTN8_Y -#define BTN10_T "电压+100mV" - -#define BTN11_H BTN1_H -#define BTN11_W BTN1_W -#define BTN11_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN11_Y BTN8_Y -#define BTN11_T "电压-100mV" - -/* 第4行按钮坐标 */ -#define BTN12_H BTN1_H -#define BTN12_W BTN1_W -#define BTN12_X BTN1_X -#define BTN12_Y (BTN1_Y + 3 * (BTN1_H + 10)) -#define BTN12_T "同步正弦波" - -#define BTN13_H BTN1_H -#define BTN13_W BTN1_W -#define BTN13_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN13_Y BTN12_Y -#define BTN13_T "相差90度正弦" - -#define BTN14_H BTN1_H -#define BTN14_W BTN1_W -#define BTN14_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN14_Y BTN12_Y -#define BTN14_T "相差180度正弦" - -#define BTN15_H BTN1_H -#define BTN15_W BTN1_W -#define BTN15_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN15_Y BTN12_Y -#define BTN15_T "停止正弦输出" - -#define LBL1_X BOX1_X + 5 -#define LBL1_Y 190 -#define LBL1_T "当前DAC值:" - -#define LBL2_X LBL1_X + 85 -#define LBL2_Y LBL1_Y -#define LBL2_T "" - -#define LBL3_X LBL1_X -#define LBL3_Y LBL1_Y + 20 -#define LBL3_T " 输出电压:" - -#define LBL4_X LBL3_X + 85 -#define LBL4_Y LBL3_Y -#define LBL4_T " " - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_T "返回" - -static void InitForm8501(void); -static void DispForm8501(void); - -static void DispDacValue(void); -static void DispDacVoltage(void); -static void MakeSinTable(uint16_t *_pBuf, uint16_t _usSamples, uint16_t _usBottom, uint16_t _usTop); - -Form8501_T *Form8501; - -#define DAC_OUT_FREQ 10000 /* DAC 输出样本频率 10KHz */ -#define WAVE_SAMPLES 200 /* 每周期样本数, 越大波形幅度越细腻,但是输出最大频率会降低 */ - -static uint16_t s_WaveBuf[WAVE_SAMPLES]; -static uint16_t s_WavePos1, s_WavePos2; -/* -********************************************************************************************************* -* 函 数 名: InitForm8501 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitForm8501(void) -{ - /* 分组框标题字体 */ - Form8501->FontBox.FontCode = FC_ST_16; - Form8501->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - Form8501->FontBox.FrontColor = CL_BLACK; - Form8501->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - Form8501->FontBlack.FontCode = FC_ST_16; - Form8501->FontBlack.BackColor = CL_MASK; /* 透明色 */ - Form8501->FontBlack.FrontColor = CL_BLACK; - Form8501->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - Form8501->FontBlue.FontCode = FC_ST_16; - Form8501->FontBlue.BackColor = CL_BTN_FACE; - Form8501->FontBlue.FrontColor = CL_BLUE; - Form8501->FontBlue.Space = 0; - - /* 按钮字体 */ - Form8501->FontBtn.FontCode = FC_ST_16; - Form8501->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - Form8501->FontBtn.FrontColor = CL_BLACK; - Form8501->FontBtn.Space = 0; - - /* 分组框 */ - Form8501->Box1.Left = BOX1_X; - Form8501->Box1.Top = BOX1_Y; - Form8501->Box1.Height = BOX1_H; - Form8501->Box1.Width = BOX1_W; - Form8501->Box1.pCaption = BOX1_T; - Form8501->Box1.Font = &Form8501->FontBox; - - /* 标签 */ - Form8501->Label1.Left = LBL1_X; - Form8501->Label1.Top = LBL1_Y; - Form8501->Label1.MaxLen = 0; - Form8501->Label1.pCaption = LBL1_T; - Form8501->Label1.Font = &Form8501->FontBlack; - - Form8501->Label2.Left = LBL2_X; - Form8501->Label2.Top = LBL2_Y; - Form8501->Label2.MaxLen = 0; - Form8501->Label2.pCaption = LBL2_T; - Form8501->Label2.Font = &Form8501->FontBlue; - - Form8501->Label3.Left = LBL3_X; - Form8501->Label3.Top = LBL3_Y; - Form8501->Label3.MaxLen = 0; - Form8501->Label3.pCaption = LBL3_T; - Form8501->Label3.Font = &Form8501->FontBlack; - - Form8501->Label4.Left = LBL4_X; - Form8501->Label4.Top = LBL4_Y; - Form8501->Label4.MaxLen = 0; - Form8501->Label4.pCaption = LBL4_T; - Form8501->Label4.Font = &Form8501->FontBlue; - - /* 按钮 */ - Form8501->BtnRet.Left = BTN_RET_X; - Form8501->BtnRet.Top = BTN_RET_Y; - Form8501->BtnRet.Height = BTN_RET_H; - Form8501->BtnRet.Width = BTN_RET_W; - Form8501->BtnRet.pCaption = BTN_RET_T; - Form8501->BtnRet.Font = &Form8501->FontBtn; - Form8501->BtnRet.Focus = 0; - - Form8501->Btn1.Left = BTN1_X; - Form8501->Btn1.Top = BTN1_Y; - Form8501->Btn1.Height = BTN1_H; - Form8501->Btn1.Width = BTN1_W; - Form8501->Btn1.pCaption = BTN1_T; - Form8501->Btn1.Font = &Form8501->FontBtn; - Form8501->Btn1.Focus = 0; - - Form8501->Btn2.Left = BTN2_X; - Form8501->Btn2.Top = BTN2_Y; - Form8501->Btn2.Height = BTN2_H; - Form8501->Btn2.Width = BTN2_W; - Form8501->Btn2.pCaption = BTN2_T; - Form8501->Btn2.Font = &Form8501->FontBtn; - Form8501->Btn2.Focus = 0; - - Form8501->Btn3.Left = BTN3_X; - Form8501->Btn3.Top = BTN3_Y; - Form8501->Btn3.Height = BTN3_H; - Form8501->Btn3.Width = BTN3_W; - Form8501->Btn3.pCaption = BTN3_T; - Form8501->Btn3.Font = &Form8501->FontBtn; - Form8501->Btn3.Focus = 0; - - Form8501->Btn4.Left = BTN4_X; - Form8501->Btn4.Top = BTN4_Y; - Form8501->Btn4.Height = BTN4_H; - Form8501->Btn4.Width = BTN4_W; - Form8501->Btn4.pCaption = BTN4_T; - Form8501->Btn4.Font = &Form8501->FontBtn; - Form8501->Btn4.Focus = 0; - - Form8501->Btn5.Left = BTN5_X; - Form8501->Btn5.Top = BTN5_Y; - Form8501->Btn5.Height = BTN5_H; - Form8501->Btn5.Width = BTN5_W; - Form8501->Btn5.pCaption = BTN5_T; - Form8501->Btn5.Font = &Form8501->FontBtn; - Form8501->Btn5.Focus = 0; - - Form8501->Btn6.Left = BTN6_X; - Form8501->Btn6.Top = BTN6_Y; - Form8501->Btn6.Height = BTN6_H; - Form8501->Btn6.Width = BTN6_W; - Form8501->Btn6.pCaption = BTN6_T; - Form8501->Btn6.Font = &Form8501->FontBtn; - Form8501->Btn6.Focus = 0; - - Form8501->Btn7.Left = BTN7_X; - Form8501->Btn7.Top = BTN7_Y; - Form8501->Btn7.Height = BTN7_H; - Form8501->Btn7.Width = BTN7_W; - Form8501->Btn7.pCaption = BTN7_T; - Form8501->Btn7.Font = &Form8501->FontBtn; - Form8501->Btn7.Focus = 0; - - Form8501->Btn8.Left = BTN8_X; - Form8501->Btn8.Top = BTN8_Y; - Form8501->Btn8.Height = BTN8_H; - Form8501->Btn8.Width = BTN8_W; - Form8501->Btn8.pCaption = BTN8_T; - Form8501->Btn8.Font = &Form8501->FontBtn; - Form8501->Btn8.Focus = 0; - - Form8501->Btn9.Left = BTN9_X; - Form8501->Btn9.Top = BTN9_Y; - Form8501->Btn9.Height = BTN9_H; - Form8501->Btn9.Width = BTN9_W; - Form8501->Btn9.pCaption = BTN9_T; - Form8501->Btn9.Font = &Form8501->FontBtn; - Form8501->Btn9.Focus = 0; - - Form8501->Btn10.Left = BTN10_X; - Form8501->Btn10.Top = BTN10_Y; - Form8501->Btn10.Height = BTN10_H; - Form8501->Btn10.Width = BTN10_W; - Form8501->Btn10.pCaption = BTN10_T; - Form8501->Btn10.Font = &Form8501->FontBtn; - Form8501->Btn10.Focus = 0; - - Form8501->Btn11.Left = BTN11_X; - Form8501->Btn11.Top = BTN11_Y; - Form8501->Btn11.Height = BTN11_H; - Form8501->Btn11.Width = BTN11_W; - Form8501->Btn11.pCaption = BTN11_T; - Form8501->Btn11.Font = &Form8501->FontBtn; - Form8501->Btn11.Focus = 0; - - Form8501->Btn12.Left = BTN12_X; - Form8501->Btn12.Top = BTN12_Y; - Form8501->Btn12.Height = BTN12_H; - Form8501->Btn12.Width = BTN12_W; - Form8501->Btn12.pCaption = BTN12_T; - Form8501->Btn12.Font = &Form8501->FontBtn; - Form8501->Btn12.Focus = 0; - - Form8501->Btn13.Left = BTN13_X; - Form8501->Btn13.Top = BTN13_Y; - Form8501->Btn13.Height = BTN13_H; - Form8501->Btn13.Width = BTN13_W; - Form8501->Btn13.pCaption = BTN13_T; - Form8501->Btn13.Font = &Form8501->FontBtn; - Form8501->Btn13.Focus = 0; - - Form8501->Btn14.Left = BTN14_X; - Form8501->Btn14.Top = BTN14_Y; - Form8501->Btn14.Height = BTN14_H; - Form8501->Btn14.Width = BTN14_W; - Form8501->Btn14.pCaption = BTN14_T; - Form8501->Btn14.Font = &Form8501->FontBtn; - Form8501->Btn14.Focus = 0; - - Form8501->Btn15.Left = BTN15_X; - Form8501->Btn15.Top = BTN15_Y; - Form8501->Btn15.Height = BTN15_H; - Form8501->Btn15.Width = BTN15_W; - Form8501->Btn15.pCaption = BTN15_T; - Form8501->Btn15.Font = &Form8501->FontBtn; - Form8501->Btn15.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: FormMainDAC8501 -* 功能说明: DAC8501 DAC8562测试主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void FormMainDAC8501(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - Form8501_T form; - uint8_t fDispVolt = 1; - - Form8501 = &form; - - InitForm8501(); - DispForm8501(); - - bsp_InitDAC8501(); - - MakeSinTable(s_WaveBuf, WAVE_SAMPLES, 0, 65535); - - Form8501->DacValue = 0; - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fDispVolt) - { - fDispVolt = 0; - - DAC8501_SetDacData(0, Form8501->DacValue); - DAC8501_SetDacData(1, Form8501->DacValue); - - DispDacValue(); - DispDacVoltage(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&Form8501->BtnRet, tpX, tpY)) - { - //fQuit = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn1, tpX, tpY)) - { - Form8501->DacValue = 0; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn2, tpX, tpY)) - { - Form8501->DacValue = 32767; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn3, tpX, tpY)) - { - Form8501->DacValue = 65535; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn4, tpX, tpY)) - { - Form8501->DacValue++; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn5, tpX, tpY)) - { - Form8501->DacValue--; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn6, tpX, tpY)) - { - Form8501->DacValue += 100; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn7, tpX, tpY)) - { - Form8501->DacValue -= 100; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn8, tpX, tpY)) - { - /* +1mV */ - Form8501->Voltage = DAC8501_DacToVoltage(Form8501->DacValue); - Form8501->Voltage += 10; - Form8501->DacValue = DAC8501_VoltageToDac(Form8501->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn9, tpX, tpY)) - { - /* -1mV */ - Form8501->Voltage = DAC8501_DacToVoltage(Form8501->DacValue); - Form8501->Voltage -= 10; - Form8501->DacValue = DAC8501_VoltageToDac(Form8501->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn10, tpX, tpY)) - { - /* +100mV */ - Form8501->Voltage = DAC8501_DacToVoltage(Form8501->DacValue); - Form8501->Voltage += 1000; - Form8501->DacValue = DAC8501_VoltageToDac(Form8501->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn11, tpX, tpY)) - { - /* -100mV */ - Form8501->Voltage = DAC8501_DacToVoltage(Form8501->DacValue); - Form8501->Voltage -= 1000; - Form8501->DacValue = DAC8501_VoltageToDac(Form8501->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn12, tpX, tpY)) - { - bsp_SetTIMforInt(TIMx, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = 0; /* 波形1超前 0度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn13, tpX, tpY)) - { - bsp_SetTIMforInt(TIM4, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = WAVE_SAMPLES / 4; /* 波形1超前 90度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn14, tpX, tpY)) - { - bsp_SetTIMforInt(TIM4, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = WAVE_SAMPLES / 2; /* 波形1超前 180度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8501->Btn15, tpX, tpY)) - { - bsp_SetTIMforInt(TIM4, 0, 0, 0); /* 关闭用于波形发生的定时器 */ - fDispVolt = 1; - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&Form8501->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else - { - LCD_ButtonTouchRelease(&Form8501->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn6, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn7, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn8, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn9, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn10, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn11, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn12, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn13, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn14, tpX, tpY); - LCD_ButtonTouchRelease(&Form8501->Btn15, tpX, tpY); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 + 1*/ - break; - - case KEY_DOWN_K2: /* K2键 - 1 */ - break; - - case KEY_DOWN_K3: /* K3键 - 清0 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - bsp_SetTIMforInt(TIM4, 0, 0, 0); /* 关闭用于波形发生的定时器 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispForm8501 -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispForm8501(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&Form8501->Box1); - - LCD_DrawLabel(&Form8501->Label1); - LCD_DrawLabel(&Form8501->Label2); - LCD_DrawLabel(&Form8501->Label3); - LCD_DrawLabel(&Form8501->Label4); - - /* 按钮 */ - LCD_DrawButton(&Form8501->Btn1); - LCD_DrawButton(&Form8501->Btn2); - LCD_DrawButton(&Form8501->Btn3); - LCD_DrawButton(&Form8501->Btn4); - LCD_DrawButton(&Form8501->Btn5); - LCD_DrawButton(&Form8501->Btn6); - LCD_DrawButton(&Form8501->Btn5); - LCD_DrawButton(&Form8501->Btn6); - LCD_DrawButton(&Form8501->Btn7); - LCD_DrawButton(&Form8501->Btn8); - LCD_DrawButton(&Form8501->Btn9); - LCD_DrawButton(&Form8501->Btn10); - LCD_DrawButton(&Form8501->Btn11); - LCD_DrawButton(&Form8501->Btn12); - LCD_DrawButton(&Form8501->Btn13); - LCD_DrawButton(&Form8501->Btn14); - LCD_DrawButton(&Form8501->Btn15); - LCD_DrawButton(&Form8501->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: DispDacValue -* 功能说明: 显示当前DAC数值 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDacValue(void) -{ - char buf[10]; - - sprintf(buf, "%d", Form8501->DacValue); - - Form8501->Label2.pCaption = buf; - LCD_DrawLabel(&Form8501->Label2); -} - -/* -********************************************************************************************************* -* 函 数 名: DispDacVoltage -* 功能说明: 显示电压 -* 形 参: 无 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDacVoltage(void) -{ - char buf[10]; - - Form8501->Voltage = DAC8501_DacToVoltage(Form8501->DacValue); - - sprintf(buf, "%d.%04dV", Form8501->Voltage / 10000, Form8501->Voltage % 10000); - - Form8501->Label4.pCaption = buf; - LCD_DrawLabel(&Form8501->Label4); -} - -/* -********************************************************************************************************* -* 函 数 名: MakeSinTable -* 功能说明: 计算产生正弦波数组 -* 形 参: _pBuf : 目标缓冲区 -* _usSamples : 每个周期的样本数 (建议大于32,并且是偶数) -* _usBottom : 波谷值 -* _usTop : 波峰值 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void MakeSinTable(uint16_t *_pBuf, uint16_t _usSamples, uint16_t _usBottom, uint16_t _usTop) -{ - uint16_t i; - uint16_t mid; /* 中值 */ - uint16_t att; /* 幅度 */ - - mid = (_usBottom + _usTop) / 2; /* 0位的值 */ - att = (_usTop - _usBottom) / 2; /* 正弦波幅度,峰峰值除以2 */ - - for (i = 0; i < _usSamples; i++) - { - _pBuf[i] = mid + (int32_t)(att * sin((i * 2 * 3.14159) / _usSamples)); - } -} - -/* -********************************************************************************************************* -* 函 数 名: TIM4_IRQHandler -* 功能说明: TIM4 中断服务程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ - -void TIMx_IRQHandler(void) -{ - uint16_t dac; - - if (READ_BIT(TIMx->SR, TIM_IT_UPDATE) != 0) - { - CLEAR_BIT(TIMx->SR, TIM_IT_UPDATE); - - /* 3.5寸屏,如果触摸程序正在访问SPI触摸芯片TSC2046,则丢弃本次 */ - if (bsp_SpiBusBusy()) - { - return; - } - - /* 波形1 */ - dac = s_WaveBuf[s_WavePos1++]; - if (s_WavePos1 >= WAVE_SAMPLES) - { - s_WavePos1 = 0; - } - DAC8501_SetDacData(0, dac); /* 改变第1通道 DAC输出电压 */ - - /* 波形1 */ - dac = s_WaveBuf[s_WavePos2++]; - if (s_WavePos2 >= WAVE_SAMPLES) - { - s_WavePos2 = 0; - } - DAC8501_SetDacData(1, dac); /* 改变第2通道 DAC输出电压 */ - } -} -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_dac8562.c b/User/app/src/old/form_dac8562.c deleted file mode 100755 index 547fde4..0000000 --- a/User/app/src/old/form_dac8562.c +++ /dev/null @@ -1,762 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : DAC8562模块测试界面 -* 文件名称 : form_dac8562.c -* 版 本 : V1.0 -* 说 明 : 驱动安富莱DAC8562模块。 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2014-10-15 armfly 首发 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_dac8562.h" -#include "math.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 黑色 */ - FONT_T FontBlue; /* 蓝色 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - BUTTON_T Btn7; - BUTTON_T Btn8; - BUTTON_T Btn9; - BUTTON_T Btn10; - BUTTON_T Btn11; - BUTTON_T Btn12; - BUTTON_T Btn13; - BUTTON_T Btn14; - BUTTON_T Btn15; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - - uint16_t DacValue; /* DAC数据 */ - int32_t Voltage; /* 输出电压 */ -} Form8562_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - 53) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_T "DAC8562 双路DAC模块(16bit, -10V -> +10V)" - -#define BTN1_H 32 -#define BTN1_W 105 - -/* 第1行按钮坐标 */ -#define BTN1_X (BOX1_X + 10) -#define BTN1_Y (BOX1_Y + 20) -#define BTN1_T "-10V" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_T "0V" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN3_Y BTN1_Y -#define BTN3_T "+10V" - -/* 第2行按钮坐标 */ -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X BTN1_X -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_T "DAC值+1" - -#define BTN5_H BTN1_H -#define BTN5_W BTN1_W -#define BTN5_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN5_Y BTN4_Y -#define BTN5_T "DAC值-1" - -#define BTN6_H BTN1_H -#define BTN6_W BTN1_W -#define BTN6_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN6_Y BTN4_Y -#define BTN6_T "DAC值+100" - -#define BTN7_H BTN1_H -#define BTN7_W BTN1_W -#define BTN7_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN7_Y BTN4_Y -#define BTN7_T "DAC值-100" - -/* 第3行按钮坐标 */ -#define BTN8_H BTN1_H -#define BTN8_W BTN1_W -#define BTN8_X BTN1_X -#define BTN8_Y (BTN1_Y + 2 * (BTN1_H + 10)) -#define BTN8_T "电压+1mV" - -#define BTN9_H BTN1_H -#define BTN9_W BTN1_W -#define BTN9_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN9_Y BTN8_Y -#define BTN9_T "电压-1mV" - -#define BTN10_H BTN1_H -#define BTN10_W BTN1_W -#define BTN10_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN10_Y BTN8_Y -#define BTN10_T "电压+100mV" - -#define BTN11_H BTN1_H -#define BTN11_W BTN1_W -#define BTN11_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN11_Y BTN8_Y -#define BTN11_T "电压-100mV" - -/* 第4行按钮坐标 */ -#define BTN12_H BTN1_H -#define BTN12_W BTN1_W -#define BTN12_X BTN1_X -#define BTN12_Y (BTN1_Y + 3 * (BTN1_H + 10)) -#define BTN12_T "同步正弦波" - -#define BTN13_H BTN1_H -#define BTN13_W BTN1_W -#define BTN13_X (BTN1_X + 1 * (BTN1_W + 10)) -#define BTN13_Y BTN12_Y -#define BTN13_T "2路90度正弦" - -#define BTN14_H BTN1_H -#define BTN14_W BTN1_W -#define BTN14_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN14_Y BTN12_Y -#define BTN14_T "2路180度正弦" - -#define BTN15_H BTN1_H -#define BTN15_W BTN1_W -#define BTN15_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN15_Y BTN12_Y -#define BTN15_T "停止正弦输出" - -#define LBL1_X BOX1_X + 5 -#define LBL1_Y 190 -#define LBL1_T "当前DAC值:" - -#define LBL2_X LBL1_X + 85 -#define LBL2_Y LBL1_Y -#define LBL2_T "" - -#define LBL3_X LBL1_X -#define LBL3_Y LBL1_Y + 20 -#define LBL3_T " 输出电压:" - -#define LBL4_X LBL3_X + 85 -#define LBL4_Y LBL3_Y -#define LBL4_T " " - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_T "返回" - -static void InitForm8562(void); -static void DispForm8562(void); - -static void DispDacValue(void); -static void DispDacVoltage(void); -static void MakeSinTable(uint16_t *_pBuf, uint16_t _usSamples, uint16_t _usBottom, uint16_t _usTop); - -Form8562_T *Form8562; - -#define DAC_OUT_FREQ 10000 /* DAC 输出样本频率 10KHz */ -#define WAVE_SAMPLES 200 /* 每周期样本数, 越大波形幅度越细腻,但是输出最大频率会降低 */ - -static uint16_t s_WaveBuf[WAVE_SAMPLES]; -static uint16_t s_WavePos1, s_WavePos2; -/* -********************************************************************************************************* -* 函 数 名: InitForm8562 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitForm8562(void) -{ - /* 分组框标题字体 */ - Form8562->FontBox.FontCode = FC_ST_16; - Form8562->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - Form8562->FontBox.FrontColor = CL_BLACK; - Form8562->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - Form8562->FontBlack.FontCode = FC_ST_16; - Form8562->FontBlack.BackColor = CL_MASK; /* 透明色 */ - Form8562->FontBlack.FrontColor = CL_BLACK; - Form8562->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - Form8562->FontBlue.FontCode = FC_ST_16; - Form8562->FontBlue.BackColor = CL_BTN_FACE; - Form8562->FontBlue.FrontColor = CL_BLUE; - Form8562->FontBlue.Space = 0; - - /* 按钮字体 */ - Form8562->FontBtn.FontCode = FC_ST_16; - Form8562->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - Form8562->FontBtn.FrontColor = CL_BLACK; - Form8562->FontBtn.Space = 0; - - /* 分组框 */ - Form8562->Box1.Left = BOX1_X; - Form8562->Box1.Top = BOX1_Y; - Form8562->Box1.Height = BOX1_H; - Form8562->Box1.Width = BOX1_W; - Form8562->Box1.pCaption = BOX1_T; - Form8562->Box1.Font = &Form8562->FontBox; - - /* 标签 */ - Form8562->Label1.Left = LBL1_X; - Form8562->Label1.Top = LBL1_Y; - Form8562->Label1.MaxLen = 0; - Form8562->Label1.pCaption = LBL1_T; - Form8562->Label1.Font = &Form8562->FontBlack; - - Form8562->Label2.Left = LBL2_X; - Form8562->Label2.Top = LBL2_Y; - Form8562->Label2.MaxLen = 0; - Form8562->Label2.pCaption = LBL2_T; - Form8562->Label2.Font = &Form8562->FontBlue; - - Form8562->Label3.Left = LBL3_X; - Form8562->Label3.Top = LBL3_Y; - Form8562->Label3.MaxLen = 0; - Form8562->Label3.pCaption = LBL3_T; - Form8562->Label3.Font = &Form8562->FontBlack; - - Form8562->Label4.Left = LBL4_X; - Form8562->Label4.Top = LBL4_Y; - Form8562->Label4.MaxLen = 0; - Form8562->Label4.pCaption = LBL4_T; - Form8562->Label4.Font = &Form8562->FontBlue; - - /* 按钮 */ - Form8562->BtnRet.Left = BTN_RET_X; - Form8562->BtnRet.Top = BTN_RET_Y; - Form8562->BtnRet.Height = BTN_RET_H; - Form8562->BtnRet.Width = BTN_RET_W; - Form8562->BtnRet.pCaption = BTN_RET_T; - Form8562->BtnRet.Font = &Form8562->FontBtn; - Form8562->BtnRet.Focus = 0; - - Form8562->Btn1.Left = BTN1_X; - Form8562->Btn1.Top = BTN1_Y; - Form8562->Btn1.Height = BTN1_H; - Form8562->Btn1.Width = BTN1_W; - Form8562->Btn1.pCaption = BTN1_T; - Form8562->Btn1.Font = &Form8562->FontBtn; - Form8562->Btn1.Focus = 0; - - Form8562->Btn2.Left = BTN2_X; - Form8562->Btn2.Top = BTN2_Y; - Form8562->Btn2.Height = BTN2_H; - Form8562->Btn2.Width = BTN2_W; - Form8562->Btn2.pCaption = BTN2_T; - Form8562->Btn2.Font = &Form8562->FontBtn; - Form8562->Btn2.Focus = 0; - - Form8562->Btn3.Left = BTN3_X; - Form8562->Btn3.Top = BTN3_Y; - Form8562->Btn3.Height = BTN3_H; - Form8562->Btn3.Width = BTN3_W; - Form8562->Btn3.pCaption = BTN3_T; - Form8562->Btn3.Font = &Form8562->FontBtn; - Form8562->Btn3.Focus = 0; - - Form8562->Btn4.Left = BTN4_X; - Form8562->Btn4.Top = BTN4_Y; - Form8562->Btn4.Height = BTN4_H; - Form8562->Btn4.Width = BTN4_W; - Form8562->Btn4.pCaption = BTN4_T; - Form8562->Btn4.Font = &Form8562->FontBtn; - Form8562->Btn4.Focus = 0; - - Form8562->Btn5.Left = BTN5_X; - Form8562->Btn5.Top = BTN5_Y; - Form8562->Btn5.Height = BTN5_H; - Form8562->Btn5.Width = BTN5_W; - Form8562->Btn5.pCaption = BTN5_T; - Form8562->Btn5.Font = &Form8562->FontBtn; - Form8562->Btn5.Focus = 0; - - Form8562->Btn6.Left = BTN6_X; - Form8562->Btn6.Top = BTN6_Y; - Form8562->Btn6.Height = BTN6_H; - Form8562->Btn6.Width = BTN6_W; - Form8562->Btn6.pCaption = BTN6_T; - Form8562->Btn6.Font = &Form8562->FontBtn; - Form8562->Btn6.Focus = 0; - - Form8562->Btn7.Left = BTN7_X; - Form8562->Btn7.Top = BTN7_Y; - Form8562->Btn7.Height = BTN7_H; - Form8562->Btn7.Width = BTN7_W; - Form8562->Btn7.pCaption = BTN7_T; - Form8562->Btn7.Font = &Form8562->FontBtn; - Form8562->Btn7.Focus = 0; - - Form8562->Btn8.Left = BTN8_X; - Form8562->Btn8.Top = BTN8_Y; - Form8562->Btn8.Height = BTN8_H; - Form8562->Btn8.Width = BTN8_W; - Form8562->Btn8.pCaption = BTN8_T; - Form8562->Btn8.Font = &Form8562->FontBtn; - Form8562->Btn8.Focus = 0; - - Form8562->Btn9.Left = BTN9_X; - Form8562->Btn9.Top = BTN9_Y; - Form8562->Btn9.Height = BTN9_H; - Form8562->Btn9.Width = BTN9_W; - Form8562->Btn9.pCaption = BTN9_T; - Form8562->Btn9.Font = &Form8562->FontBtn; - Form8562->Btn9.Focus = 0; - - Form8562->Btn10.Left = BTN10_X; - Form8562->Btn10.Top = BTN10_Y; - Form8562->Btn10.Height = BTN10_H; - Form8562->Btn10.Width = BTN10_W; - Form8562->Btn10.pCaption = BTN10_T; - Form8562->Btn10.Font = &Form8562->FontBtn; - Form8562->Btn10.Focus = 0; - - Form8562->Btn11.Left = BTN11_X; - Form8562->Btn11.Top = BTN11_Y; - Form8562->Btn11.Height = BTN11_H; - Form8562->Btn11.Width = BTN11_W; - Form8562->Btn11.pCaption = BTN11_T; - Form8562->Btn11.Font = &Form8562->FontBtn; - Form8562->Btn11.Focus = 0; - - Form8562->Btn12.Left = BTN12_X; - Form8562->Btn12.Top = BTN12_Y; - Form8562->Btn12.Height = BTN12_H; - Form8562->Btn12.Width = BTN12_W; - Form8562->Btn12.pCaption = BTN12_T; - Form8562->Btn12.Font = &Form8562->FontBtn; - Form8562->Btn12.Focus = 0; - - Form8562->Btn13.Left = BTN13_X; - Form8562->Btn13.Top = BTN13_Y; - Form8562->Btn13.Height = BTN13_H; - Form8562->Btn13.Width = BTN13_W; - Form8562->Btn13.pCaption = BTN13_T; - Form8562->Btn13.Font = &Form8562->FontBtn; - Form8562->Btn13.Focus = 0; - - Form8562->Btn14.Left = BTN14_X; - Form8562->Btn14.Top = BTN14_Y; - Form8562->Btn14.Height = BTN14_H; - Form8562->Btn14.Width = BTN14_W; - Form8562->Btn14.pCaption = BTN14_T; - Form8562->Btn14.Font = &Form8562->FontBtn; - Form8562->Btn14.Focus = 0; - - Form8562->Btn15.Left = BTN15_X; - Form8562->Btn15.Top = BTN15_Y; - Form8562->Btn15.Height = BTN15_H; - Form8562->Btn15.Width = BTN15_W; - Form8562->Btn15.pCaption = BTN15_T; - Form8562->Btn15.Font = &Form8562->FontBtn; - Form8562->Btn15.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: FormMainDAC8562 -* 功能说明: DAC8562测试主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void FormMainDAC8562(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - Form8562_T form; - uint8_t fDispVolt = 1; - - Form8562 = &form; - - InitForm8562(); - DispForm8562(); - - bsp_InitDAC8562(); - - MakeSinTable(s_WaveBuf, WAVE_SAMPLES, 0, 65535); - - Form8562->DacValue = 0; - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fDispVolt) - { - fDispVolt = 0; - - bsp_SetTIMforInt(TIM7, 0, 0, 0); /* 关闭用于波形发生的定时器 */ - - DAC8562_SetDacData(0, Form8562->DacValue); - DAC8562_SetDacData(1, Form8562->DacValue); - - DispDacValue(); - DispDacVoltage(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&Form8562->BtnRet, tpX, tpY)) - { - //fQuit = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn1, tpX, tpY)) - { - Form8562->DacValue = 0; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn2, tpX, tpY)) - { - Form8562->DacValue = 32767; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn3, tpX, tpY)) - { - Form8562->DacValue = 65535; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn4, tpX, tpY)) - { - Form8562->DacValue++; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn5, tpX, tpY)) - { - Form8562->DacValue--; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn6, tpX, tpY)) - { - Form8562->DacValue += 100; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn7, tpX, tpY)) - { - Form8562->DacValue -= 100; - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn8, tpX, tpY)) - { - /* +1mV */ - Form8562->Voltage = DAC8562_DacToVoltage(Form8562->DacValue); - Form8562->Voltage += 10; - Form8562->DacValue = DAC8562_VoltageToDac(Form8562->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn9, tpX, tpY)) - { - /* -1mV */ - Form8562->Voltage = DAC8562_DacToVoltage(Form8562->DacValue); - Form8562->Voltage -= 10; - Form8562->DacValue = DAC8562_VoltageToDac(Form8562->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn10, tpX, tpY)) - { - /* +100mV */ - Form8562->Voltage = DAC8562_DacToVoltage(Form8562->DacValue); - Form8562->Voltage += 1000; - Form8562->DacValue = DAC8562_VoltageToDac(Form8562->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn11, tpX, tpY)) - { - /* -100mV */ - Form8562->Voltage = DAC8562_DacToVoltage(Form8562->DacValue); - Form8562->Voltage -= 1000; - Form8562->DacValue = DAC8562_VoltageToDac(Form8562->Voltage); - fDispVolt = 1; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn12, tpX, tpY)) - { - bsp_SetTIMforInt(TIM7, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = 0; /* 波形1超前 0度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn13, tpX, tpY)) - { - bsp_SetTIMforInt(TIM7, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = WAVE_SAMPLES / 4; /* 波形1超前 90度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn14, tpX, tpY)) - { - bsp_SetTIMforInt(TIM7, DAC_OUT_FREQ, 0, 0); - s_WavePos1 = WAVE_SAMPLES / 2; /* 波形1超前 180度 */ - s_WavePos2 = 0; - } - else if (LCD_ButtonTouchDown(&Form8562->Btn15, tpX, tpY)) - { - bsp_SetTIMforInt(TIM7, 0, 0, 0); /* 关闭用于波形发生的定时器 */ - fDispVolt = 1; - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&Form8562->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else - { - LCD_ButtonTouchRelease(&Form8562->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn6, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn7, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn8, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn9, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn10, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn11, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn12, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn13, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn14, tpX, tpY); - LCD_ButtonTouchRelease(&Form8562->Btn15, tpX, tpY); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 + 1*/ - break; - - case KEY_DOWN_K2: /* K2键 - 1 */ - break; - - case KEY_DOWN_K3: /* K3键 - 清0 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - bsp_SetTIMforInt(TIM7, 0, 0, 0); /* 关闭用于波形发生的定时器 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispForm8562 -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispForm8562(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&Form8562->Box1); - - LCD_DrawLabel(&Form8562->Label1); - LCD_DrawLabel(&Form8562->Label2); - LCD_DrawLabel(&Form8562->Label3); - LCD_DrawLabel(&Form8562->Label4); - - /* 按钮 */ - LCD_DrawButton(&Form8562->Btn1); - LCD_DrawButton(&Form8562->Btn2); - LCD_DrawButton(&Form8562->Btn3); - LCD_DrawButton(&Form8562->Btn4); - LCD_DrawButton(&Form8562->Btn5); - LCD_DrawButton(&Form8562->Btn6); - LCD_DrawButton(&Form8562->Btn5); - LCD_DrawButton(&Form8562->Btn6); - LCD_DrawButton(&Form8562->Btn7); - LCD_DrawButton(&Form8562->Btn8); - LCD_DrawButton(&Form8562->Btn9); - LCD_DrawButton(&Form8562->Btn10); - LCD_DrawButton(&Form8562->Btn11); - LCD_DrawButton(&Form8562->Btn12); - LCD_DrawButton(&Form8562->Btn13); - LCD_DrawButton(&Form8562->Btn14); - LCD_DrawButton(&Form8562->Btn15); - LCD_DrawButton(&Form8562->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: DispDacValue -* 功能说明: 显示当前DAC数值 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDacValue(void) -{ - char buf[10]; - - sprintf(buf, "%d", Form8562->DacValue); - - Form8562->Label2.pCaption = buf; - LCD_DrawLabel(&Form8562->Label2); -} - -/* -********************************************************************************************************* -* 函 数 名: DispDacVoltage -* 功能说明: 显示电压 -* 形 参: 无 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDacVoltage(void) -{ - char buf[10]; - - Form8562->Voltage = DAC8562_DacToVoltage(Form8562->DacValue); - - sprintf(buf, "%d.%04dV", Form8562->Voltage / 10000, (abs(Form8562->Voltage) % 10000)); - - Form8562->Label4.pCaption = buf; - LCD_DrawLabel(&Form8562->Label4); -} - -/* -********************************************************************************************************* -* 函 数 名: MakeSinTable -* 功能说明: 计算产生正弦波数组 -* 形 参: _pBuf : 目标缓冲区 -* _usSamples : 每个周期的样本数 (建议大于32,并且是偶数) -* _usBottom : 波谷值 -* _usTop : 波峰值 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void MakeSinTable(uint16_t *_pBuf, uint16_t _usSamples, uint16_t _usBottom, uint16_t _usTop) -{ - uint16_t i; - uint16_t mid; /* 中值 */ - uint16_t att; /* 幅度 */ - - mid = (_usBottom + _usTop) / 2; /* 0位的值 */ - att = (_usTop - _usBottom) / 2; /* 正弦波幅度,峰峰值除以2 */ - - for (i = 0; i < _usSamples; i++) - { - _pBuf[i] = mid + (int32_t)(att * sin((i * 2 * 3.14159) / _usSamples)); - } -} - -/* -********************************************************************************************************* -* 函 数 名: TIM7_IRQHandler -* 功能说明: TIM7 中断服务程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TIM7_IRQHandler(void) -{ - uint16_t dac; - - if (READ_BIT(TIM7->SR, TIM_IT_UPDATE) != 0) - { - CLEAR_BIT(TIM7->SR, TIM_IT_UPDATE); - - /* 3.5寸屏,如果触摸程序正在访问SPI触摸芯片TSC2046,则丢弃本次 */ - if (bsp_SpiBusBusy()) - { - return; - } - - /* 波形1 */ - dac = s_WaveBuf[s_WavePos1++]; - if (s_WavePos1 >= WAVE_SAMPLES) - { - s_WavePos1 = 0; - } - DAC8562_SetDacData(0, dac); /* 改变第1通道 DAC输出电压 */ - - /* 波形1 */ - dac = s_WaveBuf[s_WavePos2++]; - if (s_WavePos2 >= WAVE_SAMPLES) - { - s_WavePos2 = 0; - } - DAC8562_SetDacData(1, dac); /* 改变第2通道 DAC输出电压 */ - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_dso.c b/User/app/src/old/form_dso.c deleted file mode 100755 index 18ace54..0000000 --- a/User/app/src/old/form_dso.c +++ /dev/null @@ -1,1221 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 双通道示波器程序 -* 文件名称 : form_dso.c -* 版 本 : V1.0 -* 说 明 : 使用STM32内部ADC测量波形。CH1 = PC0, CH2 = PC1 -* -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2015-06-23 armfly 正式发布 -* V1.1 2015-08-07 armfly 使用堆栈保存大尺寸的数据缓冲区,解决全局变量。 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_dso.h" - -#define DSO_VER "V0.6" /* 当前版本 */ - -/* 主程序状态字 */ -enum -{ - S_HELP = 0, /* 帮助页面 */ - S_RUN = 1, /* 采集状态 */ - - S_EXIT = 3 -}; - -/* 时间分度表, g_DSO->TimeBaseId作为数组索引 */ -const uint32_t g_TimeTable[] = - { - 10, - 20, 50, 100, - 200, 500, 1000, - 2000, 5000, 10000, - 20000, 50000, 100000, - 200000, 500000, 1000000}; - -/* 衰减倍数表 - - -计算公式: - iTemp = g_DSO->Ch1VOffset + (int16_t)((2024 - g_DSO->Ch1Buf[i + 1]) * 10) / g_DSO->Ch1Attenuation; - - g_DSO->Ch1Attenuation 是ADC值和像素之间的倍率的10倍。 - - 1V 档位时: ADC = 4096 / 5.0 = 819; 像素 = 25 - g_DSO->Ch1Attenuation = 819 / 25 = 32.76 - -*/ -#define ATT_COUNT 6 - -#ifdef D112_2 -const uint32_t g_AttTable[ATT_COUNT][2] = - { - /* {除数*0.1, 每大格电压} 1:1 */ - {327, 5000}, /* GAIN = 3, 放大1倍 */ - {260, 2000}, /* GAIN = 2 放大 2倍 */ - - {155 * 2, 1000}, /* GAIN = 1 放大 5 倍 */ - {155, 500}, /* GAIN = 1 放大 5倍 */ - {112, 200}, /* Gain = 0 放大 10倍 */ - {112 / 2, 100}, /* Gain = 0 放大 10倍 */ -}; -#else - -#define Y_RATE 327 - -const uint32_t g_AttTable[ATT_COUNT][2] = - { - /* {除数*0.1, 每大格电压} 1:1 */ - //{Y_RATE * 5, 5000}, - //{Y_RATE * 2, 2000}, - {Y_RATE * 5 / 5, 5000}, /* GAIN = 3 */ - {Y_RATE * 2 / 5, 2000}, - - {Y_RATE, 1000}, /* GAIN = 1 */ - {Y_RATE / 2, 500}, - {Y_RATE / 5, 200}, /* Gain = 0 */ - {Y_RATE / 10, 100}, /* Gain = 0, 放大 */ -}; -#endif - -static void DsoHelp(uint8_t *pMainStatus); -static void DsoRun(uint8_t *pMainStatus); - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_T "返回" - -DSO_T *g_DSO; /* 全局变量,是一个结构体 */ - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBtn; /* 按钮的字体 */ - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - BUTTON_T Btn7; - BUTTON_T Btn8; -} FormDSO_T; - -FormDSO_T *FormDSO; - -static void InitFormDSO(void); - -/* -********************************************************************************************************* -* 函 数 名: InitFormDSO -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormDSO(void) -{ - /* 按钮字体 */ - FormDSO->FontBtn.FontCode = FC_ST_16; - FormDSO->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormDSO->FontBtn.FrontColor = CL_BLACK; - FormDSO->FontBtn.Space = 0; - - /* 按钮 */ - FormDSO->BtnRet.Left = BTN_RET_X; - FormDSO->BtnRet.Top = BTN_RET_Y; - FormDSO->BtnRet.Height = BTN_RET_H; - FormDSO->BtnRet.Width = BTN_RET_W; - FormDSO->BtnRet.pCaption = BTN_RET_T; - FormDSO->BtnRet.Font = &FormDSO->FontBtn; - FormDSO->BtnRet.Focus = 0; - - /* AC/DC 的Y坐标 = 224 */ - /* void LCD_InitButton(BUTTON_T *_btn, uint16_t _x, uint16_t _y, uint16_t _h, uint16_t _w, - char *_pCaption, FONT_T *_pFont); */ - - LCD_InitButton(&FormDSO->Btn1, 10, 244, 24, 30, "AC", &FormDSO->FontBtn); /* 通道1 AC-DC切换 */ - LCD_InitButton(&FormDSO->Btn2, 10 + 35, 244, 24, 30, "+", &FormDSO->FontBtn); /* 通道1 幅度+ */ - LCD_InitButton(&FormDSO->Btn3, 10 + 65, 244, 24, 30, "-", &FormDSO->FontBtn); /* 通道1 幅度- */ - LCD_InitButton(&FormDSO->Btn4, 10 + 110, 244, 24, 30, "AC", &FormDSO->FontBtn); /* 通道2 AC-DC切换 */ - LCD_InitButton(&FormDSO->Btn5, 10 + 145, 244, 24, 30, "+", &FormDSO->FontBtn); /* 通道2 幅度+ */ - LCD_InitButton(&FormDSO->Btn6, 10 + 175, 244, 24, 30, "-", &FormDSO->FontBtn); /* 通道2 幅度- */ - - LCD_InitButton(&FormDSO->Btn7, 10 + 225, 244, 24, 30, "+", &FormDSO->FontBtn); /* 时基+ */ - LCD_InitButton(&FormDSO->Btn8, 10 + 265, 244, 24, 30, "-", &FormDSO->FontBtn); /* 时基- */ - - /* 绘制按钮 */ - LCD_DrawButton(&FormDSO->BtnRet); - LCD_DrawButton(&FormDSO->Btn1); - LCD_DrawButton(&FormDSO->Btn2); - LCD_DrawButton(&FormDSO->Btn3); - LCD_DrawButton(&FormDSO->Btn4); - LCD_DrawButton(&FormDSO->Btn5); - LCD_DrawButton(&FormDSO->Btn6); - LCD_DrawButton(&FormDSO->Btn7); - LCD_DrawButton(&FormDSO->Btn8); -} - -/* -********************************************************************************************************* -* 函 数 名: DsoMain -* 功能说明: 示波器程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void DsoMain(void) -{ - uint8_t MainStatus = S_RUN; /* 程序执行状态 */ - DSO_T tDSO; /* 很大的一个变量,存放在堆栈。节约全局变量空间 */ - - memset(&tDSO, 0, sizeof(tDSO)); - g_DSO = &tDSO; - - /* DAC1输出10KHz,峰峰值2V的正弦波 */ - dac1_SetSinWave(1638, 10000); /* 使用STM32内部DAC1输出正弦波, 第1个参数是幅度(0-2048) 第2个是频率 */ - - /* PE6/TIM15_CH2 输出10KHz PWM,占空比5000 = 50% */ - bsp_SetTIMOutPWM(GPIOE, GPIO_PIN_6, TIM15, 2, 10000, 5000); - - { - DSO_ConfigCtrlGPIO(); /* 配置示波器模块的控制GPIO: 耦合通道和增益 */ - - g_DSO->CH1_DC = 0; /* CH1选择AC耦合 */ - g_DSO->CH2_DC = 0; /* CH1选择AC耦合 */ - g_DSO->CH1_Gain = 0; /* CH1选择小增益 衰减1/5, 第2个参数1表示不衰减1;1 */ - g_DSO->CH2_Gain = 0; /* CH2选择小增益 衰减1/5, 第2个参数1表示不衰减1;1 */ - - DSO_SetDC(1, g_DSO->CH1_DC); - DSO_SetDC(2, g_DSO->CH2_DC); - DSO_SetGain(1, g_DSO->CH1_Gain); - DSO_SetGain(2, g_DSO->CH2_Gain); - } - - /* 因为蜂鸣器用了TIM1_CH1, 和示波器的ADC采集冲突,因此临时屏蔽按钮提示音 */ - BEEP_Pause(); - - /* 进入主程序循环体 */ - while (1) - { - switch (MainStatus) - { - case S_HELP: - DsoHelp(&MainStatus); /* 显示帮助 */ - break; - - case S_RUN: - DsoRun(&MainStatus); /* 全速采集,实时显示 */ - break; - - case S_EXIT: - dac1_StopWave(); /* 关闭DAC1输出 */ - // dac2_StopWave(); /* 关闭DAC2输出 */ - // bsp_SetTIMOutPWM(GPIOF, GPIO_PIN_9, TIM14, 1, 0, 5000); - - BEEP_Resume(); /* 恢复蜂鸣器功能 */ - return; - - default: - break; - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispHelp1 -* 功能说明: 显示操作提示 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispHelp1(void) -{ - uint16_t y; - uint16_t LineCap; - FONT_T font; - - /* 分组框标题字体 */ - font.FontCode = FC_ST_16; - font.BackColor = CL_BLUE; /* 和背景色相同 */ - font.FrontColor = CL_WHITE; /* 白色文字 */ - font.Space = 0; - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - y = 0; - LineCap = 18; /* 行间距 */ - LCD_DispStr(20, y, "安富莱STM32-V5开发板 www.armfly.com", &font); - - font.FrontColor = CL_YELLOW; /* 黄色文字 */ - - y += LineCap; - LCD_DispStr(30, y, "QQ:1295744630 Email:armfly@qq.com", &font); - y += LineCap; - - y += LineCap; - - LCD_DispStr(30, y, "操作提示:", &font); - y += LineCap; - LCD_DispStr(50, y, "K1键 = 切换通道焦点。CH1或CH2", &font); - y += LineCap; - LCD_DispStr(50, y, "K2键 = 显示帮助或退出帮助", &font); - y += LineCap; - LCD_DispStr(50, y, "K3键 = 暂停或实时运行", &font); - y += LineCap; - LCD_DispStr(50, y, "摇杆上键 = 放大波形垂直幅度或向上移动", &font); - y += LineCap; - LCD_DispStr(50, y, "摇杆下键 = 缩小波形垂直幅度或向下移动", &font); - y += LineCap; - LCD_DispStr(50, y, "摇杆左键 = 水平展宽波形", &font); - y += LineCap; - LCD_DispStr(50, y, "摇杆右键 = 水平缩小波形", &font); - y += LineCap; - LCD_DispStr(50, y, "摇杆OK键 = 切换摇杆调节模式。幅度或位置", &font); -} - -/* -********************************************************************************************************* -* 函 数 名: DsoHelp -* 功能说明: 显示操作提示的状态机 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DsoHelp(uint8_t *pMainStatus) -{ - uint8_t KeyCode; - - uint8_t fRefresh = 1; /* LCD刷新标志 */ - uint8_t SubStatus = 0; - - while (*pMainStatus == S_HELP) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - if (SubStatus == 0) - { - DispHelp1(); - } - } - - /* 读取按键,大于0表示有键按下 */ - KeyCode = bsp_GetKey(); - if (KeyCode > 0) - { - /* 有键按下 */ - switch (KeyCode) - { - case KEY_DOWN_K2: - /* 退出,进入全速运行状态 */ - *pMainStatus = S_RUN; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - case KEY_DOWN_K3: - case JOY_DOWN_OK: /* 摇杆OK键 */ - /* 退出,进入全速运行状态 */ - *pMainStatus = S_EXIT; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispFrame -* 功能说明: 能:显示波形窗口的边框和刻度线 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFrame(void) -{ - uint16_t x, y; - - /* 绘制一个实线矩形框 x, y, h, w */ - LCD_DrawRect(9, 19, 202, 302, CL_WHITE); - - /* 绘制垂直刻度点 */ - for (x = 0; x < 13; x++) - { - for (y = 0; y < 41; y++) - { - LCD_PutPixel(10 + (x * 25), 20 + (y * 5), CL_WHITE); - } - } - - /* 绘制水平刻度点 */ - for (y = 0; y < 9; y++) - { - for (x = 0; x < 61; x++) - { - LCD_PutPixel(10 + (x * 5), 20 + (y * 25), CL_WHITE); - } - } - - /* 绘制垂直中心刻度点 */ - for (y = 0; y < 41; y++) - { - LCD_PutPixel(9 + (6 * 25), 20 + (y * 5), CL_WHITE); - LCD_PutPixel(11 + (6 * 25), 20 + (y * 5), CL_WHITE); - } - - /* 绘制水平中心刻度点 */ - for (x = 0; x < 61; x++) - { - LCD_PutPixel(10 + (x * 5), 19 + (4 * 25), CL_WHITE); - LCD_PutPixel(10 + (x * 5), 21 + (4 * 25), CL_WHITE); - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispButton -* 功能说明: 显示波形窗口右边的功能按钮(待扩展) -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispButton(void) -{ -} - -/* -********************************************************************************************************* -* 函 数 名: DispCh1Wave -* 功能说明: 显示通道1波形 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispCh1Wave(void) -{ - int16_t i; /* 有符号数 */ - //uint16_t pos; - uint16_t *px; - uint16_t *py; - int16_t iTemp; - - if (g_DSO->Ch1Buf == 0) - { - return; /* 还未采集数据直接返回 */ - } - - /* 显示通道1电平标记 */ - { - static uint16_t y = 70; - - LCD_DrawLine(1, y, 7, y, CL_BLUE); /* 选择蓝色 */ - - y = g_DSO->Ch1VOffset; - - if (y < 20) - { - y = 20; - } - else if (y > 220) - { - y = 220; - } - LCD_DrawLine(1, y, 5, y, CL_YELLOW); - } - - // if (s_DispFirst == 0) - // { - // s_DispFirst = 1; - // LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - // } - - if (g_DSO->BufUsed == 0) - { - g_DSO->BufUsed = 1; - } - else - { - g_DSO->BufUsed = 0; - } - - if (g_DSO->BufUsed == 0) - { - px = g_DSO->xCh1Buf1; - py = g_DSO->yCh1Buf1; - } - else - { - px = g_DSO->xCh1Buf2; - py = g_DSO->yCh1Buf2; - } - - /* 计算当前最新的数据位置,向前递减400个样本 */ - //pos = SAMPLE_COUNT - DMA_GetCurrDataCounter(DMA1_Channel1); - //pos = 0; - - for (i = 0; i < 300; i++) - { - px[i] = 10 + i; - /* ADC = 2048 是BNC悬空输入时的ADC数值,统计多块板子获得的 */ - iTemp = g_DSO->Ch1VOffset + (int16_t)((2048 - g_DSO->Ch1Buf[i + 1]) * 10) / g_DSO->Ch1Attenuation; - - if (iTemp > 220) - { - iTemp = 220; - } - else if (iTemp < 20) - { - iTemp = 20; - } - py[i] = iTemp; - } - - /* 清除上帧波形 */ - if (g_DSO->BufUsed == 0) - { - LCD_DrawPoints(g_DSO->xCh1Buf2, g_DSO->yCh1Buf2, 300, CL_BLUE); - } - else - { - LCD_DrawPoints(g_DSO->xCh1Buf1, g_DSO->yCh1Buf1, 300, CL_BLUE); - } - - /* 显示更新的波形 */ - LCD_DrawPoints((uint16_t *)px, (uint16_t *)py, 300, CL_YELLOW); -} - -/* -********************************************************************************************************* -* 函 数 名: DispCh2Wave -* 功能说明: 显示通道2波形 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispCh2Wave(void) -{ - int16_t i; /* 有符号数 */ - //uint16_t pos; - uint16_t *px; - uint16_t *py; - int16_t iTemp; - - if (g_DSO->Ch2Buf == 0) - { - return; /* 还未采集数据直接返回 */ - } - - /* 显示通道2电平标记 */ - { - static uint16_t y = 170; - - LCD_DrawLine(1, y, 5, y, CL_BLUE); - - y = g_DSO->Ch2VOffset; - - if (y < 20) - { - y = 20; - } - else if (y > 220) - { - y = 220; - } - LCD_DrawLine(1, y, 5, y, CL_GREEN); - } - - if (g_DSO->BufUsed == 0) - { - px = g_DSO->xCh2Buf1; - py = g_DSO->yCh2Buf1; - } - else - { - px = g_DSO->xCh2Buf2; - py = g_DSO->yCh2Buf2; - } - - /* 计算当前最新的数据位置,向前递减400个样本 */ - //pos = SAMPLE_COUNT - DMA_GetCurrDataCounter(DMA2_Channel5); - //pos = 0; - - for (i = 0; i < 300; i++) - { - px[i] = 10 + i; - - /* ADC = 2048 是BNC悬空输入时的ADC数值,统计多块板子获得的 */ - iTemp = g_DSO->Ch2VOffset + (int16_t)((2048 - g_DSO->Ch2Buf[i + 1]) * 10) / g_DSO->Ch2Attenuation; - - if (iTemp > 220) - { - iTemp = 220; - } - else if (iTemp < 20) - { - iTemp = 20; - } - py[i] = iTemp; - } - - /* 清除上帧波形 */ - if (g_DSO->BufUsed == 0) - { - LCD_DrawPoints(g_DSO->xCh2Buf2, g_DSO->yCh2Buf2, 300, CL_BLUE); - } - else - { - LCD_DrawPoints(g_DSO->xCh2Buf1, g_DSO->yCh2Buf1, 300, CL_BLUE); - } - /* 显示更新的波形 */ - LCD_DrawPoints((uint16_t *)px, (uint16_t *)py, 300, CL_GREEN); -} - -/* -********************************************************************************************************* -* 函 数 名: DispChInfo -* 功能说明: 显示通道信息 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispChInfo(void) -{ - char buf[32]; /* 字符显示缓冲区 */ - FONT_T font; - - /* 分组框标题字体 */ - font.FontCode = FC_ST_16; - font.BackColor = CL_BLUE; /* 和背景色相同 */ - font.FrontColor = CL_WHITE; /* 白色文字 */ - font.Space = 0; - - /* 显示示波器程序版本 */ - LCD_DispStr(10, 2, DSO_VER, &font); - - /* 显示通道1信息 */ - if (g_DSO->CH1_DC == 1) - { - strcpy(buf, "CH1 DC "); - } - else - { - strcpy(buf, "CH1 AC "); - } - - if (g_DSO->Ch1VScale >= 1000) - { - sprintf(&buf[7], "%d.00V", g_DSO->Ch1VScale / 1000); - } - else - { - sprintf(&buf[7], "%dmV", g_DSO->Ch1VScale); - } - - if (g_DSO->ActiveCH == 1) - { - font.BackColor = CL_YELLOW; /* 黄色 */ - font.FrontColor = CL_MAGENTA; /* 紫色 */ - } - else - { - font.BackColor = CL_YELLOW; /* 黄色 */ - font.FrontColor = CL_BLUE; /* 蓝色 */ - } - - LCD_DispStr(10, 224, buf, &font); - - /* 显示通道2信息 */ - font.FrontColor = CL_RED; /* CH2 红色 */ - if (g_DSO->CH2_DC == 1) - { - strcpy(buf, "CH2 DC "); - } - else - { - strcpy(buf, "CH2 AC "); - } - - if (g_DSO->Ch2VScale >= 1000) - { - sprintf(&buf[7], "%d.00V", g_DSO->Ch2VScale / 1000); - } - else - { - sprintf(&buf[7], "%dmV", g_DSO->Ch2VScale); - } - if (g_DSO->ActiveCH == 2) - { - font.BackColor = CL_GREEN; /* 绿色 */ - font.FrontColor = CL_MAGENTA; /* 紫色 */ - } - else - { - font.BackColor = CL_GREEN; /* 绿色 */ - font.FrontColor = CL_BLUE; /* 紫色 */ - } - LCD_DispStr(120, 224, buf, &font); - - /* 显示时基 */ - font.FrontColor = CL_WHITE; /* 白色 */ - font.BackColor = CL_BLUE; /* 蓝色 */ - - if (g_DSO->TimeBase < 1000) - { - sprintf(buf, "Time %3dus", g_DSO->TimeBase); - } - else if (g_DSO->TimeBase < 1000000) - { - sprintf(buf, "Time %3dms", g_DSO->TimeBase / 1000); - } - else - { - sprintf(buf, "Time %3ds ", g_DSO->TimeBase / 1000000); - } - LCD_DispStr(230, 224, buf, &font); - - /* 显示调节模式 */ - font.FrontColor = CL_WHITE; /* 白字 */ - font.BackColor = CL_BLUE; /* 蓝底 */ - - if (g_DSO->AdjustMode == 1) - { - LCD_DispStr(245, 2, "调节位置", &font); - } - else - { - LCD_DispStr(245, 2, "调节幅度", &font); - } - - sprintf(buf, "采样频率:%7dHz", g_DSO->SampleFreq); - LCD_DispStr(75, 2, buf, &font); -} - -/* -********************************************************************************************************* -* 函 数 名: DispDSO -* 功能说明: DispDSO -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDSO(void) -{ - DispButton(); - - DispFrame(); /* 绘制刻度框 */ - DispChInfo(); /* 显示通道信息(幅度,时间档位) */ - - DispCh1Wave(); /* 显示波形1 */ - DispCh2Wave(); /* 显示波形2 */ -} - -/* -********************************************************************************************************* -* 函 数 名: InitDsoParam -* 功能说明: 初始化全局参数变量 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitDsoParam(void) -{ - g_DSO->Ch1Attenuation = 23; /* 设置缺省衰减系数 */ - g_DSO->Ch2Attenuation = 23; /* 设置缺省衰减系数 */ - g_DSO->Ch1VScale = 1000; /* 缺省是1V */ - g_DSO->Ch2VScale = 1000; /* 缺省是1V */ - - g_DSO->Ch1VOffset = 70; /* 通道1 GND线位置 */ - g_DSO->Ch2VOffset = 170; /* 通道2 GND线位置 */ - - g_DSO->ActiveCH = 1; /* 缺省是CH1 */ - g_DSO->AdjustMode = 1; /* 缺省是调节垂直偏移, 可以切换到2调节幅度 */ - - g_DSO->HoldEn = 0; - - g_DSO->TimeBaseId = 2; - g_DSO->TimeBase = g_TimeTable[g_DSO->TimeBaseId]; - g_DSO->SampleFreq = 25000000 / g_DSO->TimeBase; - - g_DSO->Ch1AttId = 2; - g_DSO->Ch1Attenuation = g_AttTable[g_DSO->Ch1AttId][0]; - g_DSO->Ch1VScale = g_AttTable[g_DSO->Ch1AttId][1]; - - g_DSO->Ch2AttId = 2; - g_DSO->Ch2Attenuation = g_AttTable[g_DSO->Ch2AttId][0]; - g_DSO->Ch2VScale = g_AttTable[g_DSO->Ch2AttId][1]; -} - -/* -********************************************************************************************************* -* 函 数 名: IncSampleFreq -* 功能说明: 增加采样频率,按 1-2-5 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -/* - 时间轴分度(每1个大格的时长) - 10us 2500000 - 20us 1250000 - 50us 500000 - 100us 250000 - 200us 125000 - 500us 50000 - 1ms 2500 - 2ms 1250 - 5ms 500 - 10ms 250 - 20ms 125 - 50ms 50 - 100ms 25 - -// 200ms 12.5 -// 500ms 5 - - g_DSO->TimeScale = 25000000 / g_DSO->SampleRate; -*/ -static void IncSampleFreq(void) -{ - if (g_DSO->TimeBaseId < (sizeof(g_TimeTable) / 4) - 1) - { - g_DSO->TimeBaseId++; - } - - g_DSO->TimeBase = g_TimeTable[g_DSO->TimeBaseId]; - g_DSO->SampleFreq = 25000000 / g_DSO->TimeBase; - - DSO_SetSampRate(g_DSO->SampleFreq); /* 改变采样频率 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DecSampleFreq -* 功能说明: 降低采样频率,按 1-2-5 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DecSampleFreq(void) -{ - if (g_DSO->TimeBaseId > 0) - { - g_DSO->TimeBaseId--; - } - - g_DSO->TimeBase = g_TimeTable[g_DSO->TimeBaseId]; - g_DSO->SampleFreq = 25000000 / g_DSO->TimeBase; - - DSO_SetSampRate(g_DSO->SampleFreq); /* 改变采样频率 */ -} - -/* -********************************************************************************************************* -* 函 数 名: AdjustAtt -* 功能说明: 调节电压衰减档位,按 1-2-5 -* 形 参: ch : 通道号,1或2 -* mode : 0 降低, 1增加 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void AdjustAtt(uint8_t ch, uint8_t mode) -{ - - if (ch == 1) - { - if (mode == 0) /* 降低 */ - { - if (g_DSO->Ch1AttId > 0) - { - g_DSO->Ch1AttId--; - } - } - else /* 增加 */ - { - if (g_DSO->Ch1AttId < ATT_COUNT - 1) - { - g_DSO->Ch1AttId++; - } - } - - g_DSO->Ch1Attenuation = g_AttTable[g_DSO->Ch1AttId][0]; - g_DSO->Ch1VScale = g_AttTable[g_DSO->Ch1AttId][1]; - } - else if (ch == 2) - { - if (mode == 0) /* 降低 */ - { - if (g_DSO->Ch2AttId > 0) - { - g_DSO->Ch2AttId--; - } - } - else /* 增加 */ - { - if (g_DSO->Ch2AttId < ATT_COUNT - 1) - { - g_DSO->Ch2AttId++; - } - } - g_DSO->Ch2Attenuation = g_AttTable[g_DSO->Ch2AttId][0]; - g_DSO->Ch2VScale = g_AttTable[g_DSO->Ch2AttId][1]; - } -} - -/* -********************************************************************************************************* -* 函 数 名: DsoRun -* 功能说明: DSO运行状态 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DsoRun(uint8_t *pMainStatus) -{ - uint8_t KeyCode; - uint8_t fRefresh = 1; /* LCD刷新标志 */ - FormDSO_T form; - uint8_t ucTouch; - int16_t tpX, tpY; - - InitDsoParam(); /* 初始化示波器参数 */ - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - FormDSO = &form; - - InitFormDSO(); /* 绘制按钮 */ - - bsp_StartTimer(1, 150); /* 启动定时器1,100ms刷新1次 */ - while (*pMainStatus == S_RUN) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - DSO_SetDC(1, g_DSO->CH1_DC); - DSO_SetDC(2, g_DSO->CH2_DC); - - /* 自动切换硬件量程 */ - switch (g_DSO->Ch1AttId) - { - case 0: /* 5V */ - DSO_SetGain(1, 3); - break; - - case 1: /* 2V */ - DSO_SetGain(1, 2); - break; - - case 2: /* 1V */ - case 3: /* 500mV */ - DSO_SetGain(1, 1); - break; - - case 4: /* 200mV */ - case 5: /* 100mV */ - DSO_SetGain(1, 0); - break; - } - - switch (g_DSO->Ch2AttId) - { - case 0: /* 5V */ - DSO_SetGain(2, 3); - break; - - case 1: /* 2V */ - DSO_SetGain(2, 2); - break; - - case 2: /* 1V */ - case 3: /* 500mV */ - DSO_SetGain(2, 1); - break; - - case 4: /* 200mV */ - case 5: /* 100mV */ - DSO_SetGain(2, 0); - break; - } - - /* 根据增益设置,改变硬件衰减 */ - - if (g_DSO->HoldEn == 1) - { - DispDSO(); - } - } - - if (bsp_CheckTimer(1)) - { - bsp_StartTimer(1, 200); /* 启动定时器1,200ms刷新1次 */ - - /* 运行状态。每隔100ms刷新1次波形 */ - if (g_DSO->HoldEn == 0) - { - DSO_PauseADC(); /* 暂停采样 */ - - DispDSO(); /* 显示波形 */ - - /* 开始采样 */ - DSO_StartADC(&g_DSO->Ch1Buf, &g_DSO->Ch2Buf, g_DSO->SampleFreq); - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&FormDSO->BtnRet, tpX, tpY)) - { - // *pMainStatus = S_EXIT; <--- 在松开时退出界面 - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn1, tpX, tpY)) - { - /* 通道1 AC-DC耦合切换 */ - if (g_DSO->CH1_DC == 0) - { - g_DSO->CH1_DC = 1; - } - else - { - g_DSO->CH1_DC = 0; - } - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn2, tpX, tpY)) - { - AdjustAtt(1, 1); /* 通道1 幅度调节+ */ - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn3, tpX, tpY)) - { - AdjustAtt(1, 0); /* 通道1 幅度调节- */ - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn4, tpX, tpY)) - { - /* 通道2 AC-DC耦合切换 */ - if (g_DSO->CH2_DC == 0) - { - g_DSO->CH2_DC = 1; - } - else - { - g_DSO->CH2_DC = 0; - } - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn5, tpX, tpY)) - { - AdjustAtt(2, 1); /* 通道2 幅度调节+ */ - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn6, tpX, tpY)) - { - AdjustAtt(2, 0); /* 通道2 幅度调节- */ - fRefresh = 1; - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn7, tpX, tpY)) - { - DecSampleFreq(); /* 递减采样频率 */ - fRefresh = 1; /* 请求刷新LCD */ - } - else if (LCD_ButtonTouchDown(&FormDSO->Btn8, tpX, tpY)) - { - IncSampleFreq(); /* 递增采样频率 */ - fRefresh = 1; /* 请求刷新LCD */ - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormDSO->BtnRet, tpX, tpY)) - { - *pMainStatus = S_EXIT; /* 返回键退出 */ - } - else - { - LCD_ButtonTouchRelease(&FormDSO->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn6, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn7, tpX, tpY); - LCD_ButtonTouchRelease(&FormDSO->Btn8, tpX, tpY); - } - break; - } - } - - /* 读取按键,大于0表示有键按下 */ - KeyCode = bsp_GetKey(); - if (KeyCode > 0) - { - /* 有键按下 */ - switch (KeyCode) - { - case KEY_DOWN_K1: /* TAMPER 键,通道选择(CH1或CH2) */ - if (g_DSO->ActiveCH == 1) - { - g_DSO->ActiveCH = 2; - } - else - { - g_DSO->ActiveCH = 1; - } - fRefresh = 1; /* 请求刷新LCD */ - break; - - case KEY_DOWN_K2: /* WAKEUP 键, 调节模式选择(幅度或者垂直偏移) */ - /* 退出,进入全速运行状态 */ - *pMainStatus = S_HELP; - break; - - case KEY_DOWN_K3: /* USER 键 */ - if (g_DSO->HoldEn == 0) - { - g_DSO->HoldEn = 1; - - /* 保存暂停时的时基,为了水平扩展用 */ - g_DSO->TimeBaseIdHold = g_DSO->TimeBaseId; - - DSO_StopADC(); - } - else - { - g_DSO->HoldEn = 0; - } - fRefresh = 1; /* 请求刷新LCD */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (g_DSO->HoldEn == 0) - { - DecSampleFreq(); /* 递减采样频率 */ - fRefresh = 1; /* 请求刷新LCD */ - } - else - { - ; /* 波形水平移动,待完善 */ - } - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (g_DSO->HoldEn == 0) - { - IncSampleFreq(); /* 递增采样频率 */ - fRefresh = 1; /* 请求刷新LCD */ - } - else - { - ; /* 波形水平移动,待完善 */ - } - break; - - case JOY_DOWN_OK: /* 摇杆OK键 */ - if (g_DSO->AdjustMode == 0) - { - g_DSO->AdjustMode = 1; - } - else - { - g_DSO->AdjustMode = 0; - } - fRefresh = 1; /* 请求刷新LCD */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - if (g_DSO->ActiveCH == 1) /* 当前激活的是CH1 */ - { - if (g_DSO->AdjustMode == 0) /* 调节幅度放大倍数 */ - { - AdjustAtt(1, 1); - } - else /* 调节上下偏移 */ - { - g_DSO->Ch1VOffset -= 5; - } - } - else /* 当前激活的是CH2 */ - { - if (g_DSO->AdjustMode == 0) /* 调节幅度放大倍数 */ - { - AdjustAtt(2, 1); - } - else /* 调节上下偏移 */ - { - g_DSO->Ch2VOffset -= 5; - } - } - fRefresh = 1; /* 请求刷新LCD */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_DSO->ActiveCH == 1) /* 当前激活的是CH1 */ - { - if (g_DSO->AdjustMode == 0) /* 调节幅度放大倍数 */ - { - AdjustAtt(1, 0); - } - else /* 调节上下偏移 */ - { - g_DSO->Ch1VOffset += 5; - } - } - else /* 当前激活的是CH2 */ - { - if (g_DSO->AdjustMode == 0) /* 调节幅度放大倍数 */ - { - AdjustAtt(2, 0); - } - else /* 调节上下偏移 */ - { - g_DSO->Ch2VOffset += 5; - } - } - fRefresh = 1; /* 请求刷新LCD */ - break; - - default: - break; - } - } - } - - DSO_StopADC(); /* 关闭采样 */ -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_fm_radio.c b/User/app/src/old/form_fm_radio.c deleted file mode 100755 index 11fb36a..0000000 --- a/User/app/src/old/form_fm_radio.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 收音机测试。 -* 文件名称 : fm_radio.c -* 版 本 : V1.1 -* 说 明 : 主要用于测试Si4730收音芯片的功能 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-01-01 armfly 正式发布 -* V1.1 2014-09-06 armfly 完善音量调节函数。WM8978和Si47XX芯片的音量同步调节。 -* Volume 单词显示错误. 支持Si4704, 增加FM 调谐电容显示。 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" /* printf函数定向输出到串口,所以必须包含这个文件 */ -#include "form_fm_radio.h" -#include "param.h" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BUTTON_RET_H 32 -#define BUTTON_RET_W 60 -#define BUTTON_RET_X (g_LcdWidth - BUTTON_RET_W - 4) -#define BUTTON_RET_Y (g_LcdHeight - BUTTON_RET_H - 4) - -#define BUTTON_RET2_H 32 -#define BUTTON_RET2_W 120 -#define BUTTON_RET2_X (BUTTON_RET_X - BUTTON_RET2_W - 5) -#define BUTTON_RET2_Y BUTTON_RET_Y -#define BUTTON_RET2_TEXT "保持收音,返回" - -#define BUTTON_FM_H 32 -#define BUTTON_FM_W 60 -#define BUTTON_FM_X 5 -#define BUTTON_FM_Y 120 - -#define BUTTON_AM_H 32 -#define BUTTON_AM_W 60 -#define BUTTON_AM_X (BUTTON_FM_X + 70) -#define BUTTON_AM_Y BUTTON_FM_Y - -#define BUTTON_VOLP_H 32 -#define BUTTON_VOLP_W 48 -#define BUTTON_VOLP_X 32 -#define BUTTON_VOLP_Y 48 - -#define BUTTON_CHP_H 32 -#define BUTTON_CHP_W 48 -#define BUTTON_CHP_X 32 -#define BUTTON_CHP_Y 48 - -#define BUTTON_FREQ_ (BUTTON_FM_X + 70) -#define BUTTON__Y BUTTON_FM_Y - -/* 以下是检查框 */ -#define CHECK_SPK_X BUTTON_FM_X -#define CHECK_SPK_Y (BUTTON_FM_Y + BUTTON_FM_H + 5) -#define CHECK_SPK_H CHECK_BOX_H -#define CHECK_SPK_W (CHECK_BOX_W + 5 * 16) /* 决定触摸有效区域 */ -#define CHECK_SPK_TEXT "打开扬声器" - -#define CHECK_RSSI_X BUTTON_FM_X -#define CHECK_RSSI_Y (CHECK_SPK_Y + 30) -#define CHECK_RSSI_H CHECK_BOX_H -#define CHECK_RSSI_W (CHECK_BOX_W + 14 * 16) /* 决定触摸有效区域 */ -#define CHECK_RSSI_TEXT "显示信号质量(可能引起噪音)" - -#define CHECK_LIST_X BUTTON_FM_X -#define CHECK_LIST_Y (CHECK_RSSI_Y + 30) -#define CHECK_LIST_H CHECK_BOX_H -#define CHECK_LIST_W (CHECK_BOX_W + 5 * 16) /* 决定触摸有效区域 */ -#define CHECK_LIST_TEXT "选择全国电台列表" - -/* -AM873,FM88.4,武汉人民广播电台(新闻综合频率) - - - - 武汉地区FM电台频率表: - 88.4 - - FM89.6 武汉广播电台交通台 - 90.7 - 91.2 - FM91.6 楚天广播电台卫星台 - - FM92.7 楚天广播电台交通体育台 - FM93.6 武汉广播电台中波台 - FM95.6 中央广播电台中国之声 - 96.0== - FM96.6 湖北广播电台生活频道 - - FM97.8 中央广播电台经济之声 - - FM99.8 湖北广播电台经济频道 - FM100.6 长江经济广播电台 - FM101.8 武汉广播电台文艺台 - FM102.6 湖北广播电台妇女儿童频道 - FM103.8 湖北广播电台音乐频道 - FM104.6 湖北广播电台中波频道 - FM105.8 楚天广播电台音乐台 - FM107.8 湖北广播电台交通频道 -*/ - -const uint16_t g_InitListFM[] = { - 8640, - 8840, - 8960, - 9060, - 9120, - 9270, - 9360, - 9440, - 9560, - 9660, - 9780, - 9980, - 10060, - 10180, - 10260, - 10380, - 10460, - 10580, - 10780}; - -const uint16_t g_InitListAM[] = { - 531, - 540, - 549, - 558, - 603, - 639, - 855, - 873, - 882, - 900, - 909, - 918, - 927, -}; - -RADIO_T g_tRadio; - -static void radio_DispStatus(void); -static void radio_SignalQuality(void); -static void radio_FM_FreqList(uint8_t _ucAll); -static void radio_AM_FreqList(uint8_t _ucAll); -static void radio_LoadParam(void); -static void radio_SaveParam(void); -static void radio_AdjustVolume(uint8_t _ucVolume); - -/* -********************************************************************************************************* -* 函 数 名: RadioMain -* 功能说明: 收音机主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void RadioMain(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - uint8_t fQuit = 0; - FONT_T tFont, tFontBtn, tFontChk; /* 定义一个字体结构体变量,用于设置字体参数 */ - - char buf[128]; - uint16_t x, y; - uint16_t usLineCap = 18; - - int16_t tpX, tpY; - BUTTON_T tBtn; - CHECK_T tCheck; - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - radio_LoadParam(); /* 读取电台和音量参数 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - /* 按钮字体 */ - tFontBtn.FontCode = FC_ST_16; - tFontBtn.BackColor = CL_MASK; /* 透明色 */ - tFontBtn.FrontColor = CL_BLACK; - tFontBtn.Space = 0; - - /* CheckBox 字体 */ - tFontChk.FontCode = FC_ST_16; - tFontChk.BackColor = CL_MASK; /* 透明色 */ - tFontChk.FrontColor = CL_YELLOW; - tFontChk.Space = 0; - } - - x = 5; - y = 3; - LCD_DispStr(x, y, "Si4730/Si4704 收音机", &tFont); /* 在(8,3)坐标处显示一串汉字 */ - y += usLineCap; - - /* 测试I2C设备 */ - { - if (i2c_CheckDevice(I2C_ADDR_SI4730_W) == 0) - { - sprintf(buf, "Si47xx Ok (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - - wm8978_OutMute(1); /* 先静音输出, 避免上电嘎哒声 */ - - SI4730_PowerUp_FM_Revice(); - bsp_DelayMS(10); - - y += usLineCap; - /* 打印芯片的版本 */ - { - uint8_t read_buf[8]; - - if (SI4730_GetRevision(read_buf)) - { - sprintf(buf, "%d-%c%c-%02X%02X-%c%c-%c", /* Si4730 */ - read_buf[0], read_buf[1], read_buf[2], /* 固件版本 */ - read_buf[3], read_buf[4], /* 补丁ID */ - read_buf[5], read_buf[6], /* 组件版本 */ - read_buf[7] /* 芯片硬件版本 */ - ); /* 芯片型号标识 */ - - if (strcmp(buf, "30-60-0000-70-D") == 0) - { - g_tRadio.ChipType = SI4730; - - LCD_DispStr(x, y, buf, &tFont); - LCD_DispStr(x + 130, y, "Si4730", &tFont); - } - else if (strcmp(buf, "4-60-0000-70-D") == 0 || - strcmp(buf, "4-20-0000-20-B") == 0) - { - g_tRadio.ChipType = SI4704; - LCD_DispStr(x, y, buf, &tFont); - LCD_DispStr(x + 130, y, "Si4704", &tFont); - - g_tRadio.ucMode = FM_RX; - - //SI4704_SetFMIntput(1); /* 切换天线为PCB天线 */ - // 0 表示FM引脚输入(耳机天线) 1 表示LPI天线输入(PCB天线) - SI4704_SetFMIntput(0); /* 切换天线为耳机天线 */ - } - else - { - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - } - } - } - else - { - sprintf(buf, "Si47xx Err (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - } - - /* 显示按钮 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 未选中 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_RET2_X; - tBtn.Top = BUTTON_RET2_Y; - tBtn.Height = BUTTON_RET2_H; - tBtn.Width = BUTTON_RET2_W; - tBtn.Focus = 0; /* 未选中 */ - tBtn.pCaption = BUTTON_RET2_TEXT; /* 保持收音 返回 */ - LCD_DrawButton(&tBtn); - - if (g_tRadio.ChipType == SI4730) - { - tBtn.Left = BUTTON_FM_X; - tBtn.Top = BUTTON_FM_Y; - tBtn.Height = BUTTON_FM_H; - tBtn.Width = BUTTON_FM_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "FM"; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_AM_X; - tBtn.Top = BUTTON_AM_Y; - tBtn.Height = BUTTON_AM_H; - tBtn.Width = BUTTON_AM_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "AM"; - LCD_DrawButton(&tBtn); - } - - /* 显示检查框 */ - tCheck.Font = &tFontChk; - - tCheck.Left = CHECK_SPK_X; - tCheck.Top = CHECK_SPK_Y; - tCheck.Height = CHECK_SPK_H; - tCheck.Width = CHECK_SPK_W; - if (g_tRadio.ucSpkOutEn == 1) - { - tCheck.Checked = 1; - } - else - { - tCheck.Checked = 0; - } - tCheck.pCaption = CHECK_SPK_TEXT; - LCD_DrawCheckBox(&tCheck); - - tCheck.Left = CHECK_RSSI_X; - tCheck.Top = CHECK_RSSI_Y; - tCheck.Height = CHECK_RSSI_H; - tCheck.Width = CHECK_RSSI_W; - tCheck.Checked = 0; - tCheck.pCaption = CHECK_RSSI_TEXT; - - LCD_DrawCheckBox(&tCheck); - - tCheck.Left = CHECK_LIST_X; - tCheck.Top = CHECK_LIST_Y; - tCheck.Height = CHECK_LIST_H; - tCheck.Width = CHECK_LIST_W; - if (g_tRadio.ucListType == 1) - { - tCheck.Checked = 1; - } - else - { - tCheck.Checked = 0; - } - tCheck.pCaption = CHECK_LIST_TEXT; - LCD_DrawCheckBox(&tCheck); - } - - { - if (g_tRadio.ucSpkOutEn == 0) - { - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 */ - wm8978_CfgAudioPath(AUX_ON, EAR_LEFT_ON | EAR_RIGHT_ON); - } - else - { - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 和 扬声器 */ - wm8978_CfgAudioPath(AUX_ON, EAR_LEFT_ON | EAR_RIGHT_ON | SPK_ON); - } - - //g_tRadio.ucSpkOutEn = 0 - - SI4730_PowerDown(); - bsp_DelayMS(10); - - //SI4730_PowerUp_AM_Revice(); - SI4730_PowerUp_FM_Revice(); - bsp_DelayMS(10); - - /* 调节音量 */ - radio_AdjustVolume(g_tRadio.ucVolume); - - tFont.FrontColor = CL_YELLOW; - LCD_DispStr(x, y, "请操作摇杆换台和调节音量,K2 K3键微调频率", &tFont); - if (g_tRadio.ChipType == SI4704) - { - LCD_DispStr(x, y + 75, "请将耳机插到绿色插座,用作FM天线", &tFont); /* 在(8,3)坐标处显示一串汉字 */ - } - tFont.FrontColor = CL_WHITE; - - /* 预填武汉地区的电台列表 */ - { - if (g_tRadio.ucListType == 0) /* 0 表示 武汉地区列表 1 表示全国列表 */ - { - radio_FM_FreqList(0); /* 预设武汉地区的FM电台列表 */ - radio_AM_FreqList(0); /* 预设武汉地区的AM电台列表 */ - //g_tRadio.ucIndexFM = 1; - } - else - { - radio_FM_FreqList(1); /* 预设全国地区的FM电台列表 */ - radio_AM_FreqList(1); /* 预设全国地区的AM电台列表 */ - //g_tRadio.ucIndexAM = 1; - } - //g_tRadio.ucMode = FM_RX; /* 缺省是FM接收 */ - //g_tRadio.ucMode = AM_RX; /* 缺省是FM接收 */ - } - - bsp_DelayMS(300); /* 必须延迟一段时间后,才能保证每次上电后,能够选中一个台 */ - if (g_tRadio.ucMode == FM_RX) - { - g_tRadio.usFreq = g_tRadio.usFMList[g_tRadio.ucIndexFM]; - SI4730_SetFMFreq(g_tRadio.usFreq); - } - else - { - g_tRadio.usFreq = g_tRadio.usAMList[g_tRadio.ucIndexAM]; - SI4730_SetAMFreq(g_tRadio.usFreq); - } - - bsp_DelayMS(100); /* 延迟100ms,避免强烈的嘎哒声 */ - - wm8978_OutMute(0); - } - - fRefresh = 1; /* 1表示需要刷新LCD */ - bsp_StartAutoTimer(0, 1000); - while (fQuit == 0) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - radio_DispStatus(); - } - - if (g_tRadio.ucRssiEn) - { - if (bsp_CheckTimer(0)) - { - radio_SignalQuality(); /* 刷新信号质量状态栏 */ - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_RET2_X, BUTTON_RET2_Y, BUTTON_RET2_H, BUTTON_RET2_W)) - { - tBtn.Left = BUTTON_RET2_X; - tBtn.Top = BUTTON_RET2_Y; - tBtn.Height = BUTTON_RET2_H; - tBtn.Width = BUTTON_RET2_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = BUTTON_RET2_TEXT; - LCD_DrawButton(&tBtn); - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_FM_X, BUTTON_FM_Y, BUTTON_FM_H, BUTTON_FM_W)) - { - if (g_tRadio.ChipType == SI4730) - { - tBtn.Left = BUTTON_FM_X; - tBtn.Top = BUTTON_FM_Y; - tBtn.Height = BUTTON_FM_H; - tBtn.Width = BUTTON_FM_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "FM"; - LCD_DrawButton(&tBtn); - } - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_AM_X, BUTTON_AM_Y, BUTTON_AM_H, BUTTON_AM_W)) - { - if (g_tRadio.ChipType == SI4730) - { - tBtn.Left = BUTTON_AM_X; - tBtn.Top = BUTTON_AM_Y; - tBtn.Height = BUTTON_AM_H; - tBtn.Width = BUTTON_AM_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "AM"; - LCD_DrawButton(&tBtn); - } - } - else if (TOUCH_InRect(tpX, tpY, CHECK_SPK_X, CHECK_SPK_Y, CHECK_SPK_H, CHECK_SPK_W)) - { - if (g_tRadio.ucSpkOutEn) - { - g_tRadio.ucSpkOutEn = 0; - tCheck.Checked = 0; - - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 */ - wm8978_CfgAudioPath(AUX_ON, EAR_LEFT_ON | EAR_RIGHT_ON); - } - else - { - g_tRadio.ucSpkOutEn = 1; - tCheck.Checked = 1; - - /* 配置WM8978芯片,输入为AUX接口(收音机),输出为耳机 和 扬声器 */ - wm8978_CfgAudioPath(AUX_ON, EAR_LEFT_ON | EAR_RIGHT_ON | SPK_ON); - } - - tCheck.Left = CHECK_SPK_X; - tCheck.Top = CHECK_SPK_Y; - tCheck.Height = CHECK_SPK_H; - tCheck.Width = CHECK_SPK_W; - tCheck.pCaption = CHECK_SPK_TEXT; - LCD_DrawCheckBox(&tCheck); - } - else if (TOUCH_InRect(tpX, tpY, CHECK_RSSI_X, CHECK_RSSI_Y, CHECK_RSSI_H, CHECK_RSSI_W)) - { - if (g_tRadio.ucRssiEn) - { - g_tRadio.ucRssiEn = 0; - tCheck.Checked = 0; - - /* 清除信号质量显示内容 */ - LCD_DispStr(5, 100, " ", &tFont); - } - else - { - g_tRadio.ucRssiEn = 1; - tCheck.Checked = 1; - } - - tCheck.Left = CHECK_RSSI_X; - tCheck.Top = CHECK_RSSI_Y; - tCheck.Height = CHECK_RSSI_H; - tCheck.Width = CHECK_RSSI_W; - tCheck.pCaption = CHECK_RSSI_TEXT; - LCD_DrawCheckBox(&tCheck); - } - else if (TOUCH_InRect(tpX, tpY, CHECK_LIST_X, CHECK_LIST_Y, CHECK_LIST_H, CHECK_LIST_W)) - { - if (g_tRadio.ucListType) - { - g_tRadio.ucListType = 0; /* 武汉地区电台列表 */ - radio_FM_FreqList(0); - radio_AM_FreqList(0); - - tCheck.Checked = 0; - } - else - { - g_tRadio.ucListType = 1; /* 全国电台列表 */ - radio_FM_FreqList(1); - radio_AM_FreqList(1); - - tCheck.Checked = 1; - } - - g_tRadio.ucIndexFM = 0; - g_tRadio.ucIndexAM = 0; - - tCheck.Left = CHECK_LIST_X; - tCheck.Top = CHECK_LIST_Y; - tCheck.Height = CHECK_LIST_H; - tCheck.Width = CHECK_LIST_W; - - tCheck.pCaption = CHECK_LIST_TEXT; - LCD_DrawCheckBox(&tCheck); - - fRefresh = 1; - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - - fQuit = 1; /* 返回 */ - //return; - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_RET2_X, BUTTON_RET2_Y, BUTTON_RET2_H, BUTTON_RET2_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET2_X; - tBtn.Top = BUTTON_RET2_Y; - tBtn.Height = BUTTON_RET2_H; - tBtn.Width = BUTTON_RET2_W; - tBtn.Focus = 0; /* 焦点 */ - tBtn.pCaption = BUTTON_RET2_TEXT; - LCD_DrawButton(&tBtn); - - fQuit = 2; /* 保留收音 返回 */ - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_FM_X, BUTTON_FM_Y, BUTTON_FM_H, BUTTON_FM_W)) - { - if (g_tRadio.ChipType == SI4730) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_FM_X; - tBtn.Top = BUTTON_FM_Y; - tBtn.Height = BUTTON_FM_H; - tBtn.Width = BUTTON_FM_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "FM"; - LCD_DrawButton(&tBtn); - - /* 切换到 FM 状态 */ - //SI4730_SetOutVolume(0); /* 先静音,避免切换噶嗒声 */ - wm8978_OutMute(1); - - g_tRadio.ucMode = FM_RX; - - SI4730_PowerDown(); - bsp_DelayMS(5); - SI4730_PowerUp_FM_Revice(); - bsp_DelayMS(10); - - SI4730_SetOutVolume(g_tRadio.ucVolume); /* 缺省音量是最大值63, 修改为32 */ - - g_tRadio.usFreq = g_tRadio.usFMList[g_tRadio.ucIndexFM]; - SI4730_SetFMFreq(g_tRadio.usFreq); - - bsp_DelayMS(100); /* 延迟100ms,避免强烈的嘎哒声 */ - - wm8978_OutMute(0); - - fRefresh = 1; - } - } - else if (TOUCH_InRect(tpX, tpY, BUTTON_AM_X, BUTTON_AM_Y, BUTTON_AM_H, BUTTON_AM_W)) - { - if (g_tRadio.ChipType == SI4730) - { - tBtn.Left = BUTTON_AM_X; - tBtn.Top = BUTTON_AM_Y; - tBtn.Height = BUTTON_AM_H; - tBtn.Width = BUTTON_AM_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "AM"; - LCD_DrawButton(&tBtn); - - /* 切换到 AM 状态 */ - //SI4730_SetOutVolume(0); /* 先静音,避免切换噶嗒声 */ - wm8978_OutMute(1); - - g_tRadio.ucMode = AM_RX; /* 缺省是AM接收 */ - SI4730_PowerDown(); - bsp_DelayMS(5); - SI4730_PowerUp_AM_Revice(); - bsp_DelayMS(10); - - SI4730_SetOutVolume(g_tRadio.ucVolume); /* 缺省音量是最大值63, 修改为32 */ - - g_tRadio.usFreq = g_tRadio.usAMList[g_tRadio.ucIndexAM]; - SI4730_SetAMFreq(g_tRadio.usFreq); - - bsp_DelayMS(100); /* 延迟100ms,避免强烈的嘎哒声 */ - - wm8978_OutMute(0); - - fRefresh = 1; - } - } - else /* 按钮失去焦点 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Focus = 0; /* 未选中 */ - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_RET2_X; - tBtn.Top = BUTTON_RET2_Y; - tBtn.Height = BUTTON_RET2_H; - tBtn.Width = BUTTON_RET2_W; - tBtn.pCaption = BUTTON_RET2_TEXT; - LCD_DrawButton(&tBtn); - - if (g_tRadio.ChipType == SI4730) - { - tBtn.Left = BUTTON_FM_X; - tBtn.Top = BUTTON_FM_Y; - tBtn.Height = BUTTON_FM_H; - tBtn.Width = BUTTON_FM_W; - tBtn.pCaption = "FM"; - LCD_DrawButton(&tBtn); - - tBtn.Left = BUTTON_AM_X; - tBtn.Top = BUTTON_AM_Y; - tBtn.Height = BUTTON_AM_H; - tBtn.Width = BUTTON_AM_W; - tBtn.pCaption = "AM"; - LCD_DrawButton(&tBtn); - } - } - } - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* - 对于按键弹起事件,缺省的bsp_button.c 仅检测了TAMPER、WAKEUP、USER键、摇杆OK键的弹起事件 - 如果您的应用程序需要其它键(比如方向键)的弹起事件,您需要简单修改一下bsp_button.c文件 - */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 */ - - break; - - case KEY_DOWN_K2: /* K2键按下 */ - - if (g_tRadio.ucMode == FM_RX) - { - g_tRadio.usFreq -= 10; - SI4730_SetFMFreq(g_tRadio.usFreq); - } - else - { - g_tRadio.usFreq--; - SI4730_SetAMFreq(g_tRadio.usFreq); - } - fRefresh = 1; - break; - - case KEY_DOWN_K3: /* K3键按下 */ - - if (g_tRadio.ucMode == FM_RX) - { - g_tRadio.usFreq += 10; - SI4730_SetFMFreq(g_tRadio.usFreq); - } - else - { - g_tRadio.usFreq++; - SI4730_SetAMFreq(g_tRadio.usFreq); - } - fRefresh = 1; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - g_tRadio.ucVolume += VOLUME_STEP; - if (g_tRadio.ucVolume > VOLUME_MAX) - { - g_tRadio.ucVolume = VOLUME_MAX; - } - radio_AdjustVolume(g_tRadio.ucVolume); - fRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_tRadio.ucVolume > 0) - { - g_tRadio.ucVolume -= VOLUME_STEP; - } - else - { - g_tRadio.ucVolume = 0; - } - radio_AdjustVolume(g_tRadio.ucVolume); - fRefresh = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (g_tRadio.ucMode == FM_RX) - { - if (g_tRadio.ucIndexFM > 0) - { - g_tRadio.ucIndexFM--; - g_tRadio.usFreq = g_tRadio.usFMList[g_tRadio.ucIndexFM]; - SI4730_SetFMFreq(g_tRadio.usFreq); - fRefresh = 1; - } - } - else - { - if (g_tRadio.ucIndexAM > 0) - { - g_tRadio.ucIndexAM--; - g_tRadio.usFreq = g_tRadio.usAMList[g_tRadio.ucIndexAM]; - SI4730_SetAMFreq(g_tRadio.usFreq); - fRefresh = 1; - } - } - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (g_tRadio.ucMode == FM_RX) - { - if (g_tRadio.ucIndexFM < g_tRadio.ucFMCount - 1) - { - g_tRadio.ucIndexFM++; - g_tRadio.usFreq = g_tRadio.usFMList[g_tRadio.ucIndexFM]; - SI4730_SetFMFreq(g_tRadio.usFreq); - fRefresh = 1; - } - } - else - { - if (g_tRadio.ucIndexAM < g_tRadio.ucAMCount - 1) - { - g_tRadio.ucIndexAM++; - g_tRadio.usFreq = g_tRadio.usAMList[g_tRadio.ucIndexAM]; - SI4730_SetAMFreq(g_tRadio.usFreq); - fRefresh = 1; - } - } - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - /* 其他的键值不处理 */ - break; - } - } - } //while (fQuit == 0) - - if (fQuit == 1) - { - SI4730_PowerDown(); - } - - bsp_StopTimer(0); /* 停止定时器0 */ - - radio_SaveParam(); /* 保存电台参数 */ -} - -/* -********************************************************************************************************* -* 函 数 名: radio_DispStatus -* 功能说明: 显示当前状态 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_DispStatus(void) -{ - char buf[128]; - FONT_T tFont; /* 定义一个字体结构体变量,用于设置字体参数 */ - uint16_t usLineCap = 18; - uint16_t x, y; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - if (g_tRadio.ucMode == FM_RX) - { - sprintf(buf, "FM (%3d/%d) 频率=%5d.%dMHz, Volume = %2d ", g_tRadio.ucIndexFM + 1, - g_tRadio.ucFMCount, g_tRadio.usFreq / 100, - (g_tRadio.usFreq % 100) / 10, g_tRadio.ucVolume); - } - else - { - sprintf(buf, "AM (%3d/%d) 频率=%5dKHz, Volume = %2d ", g_tRadio.ucIndexAM + 1, - g_tRadio.ucAMCount, g_tRadio.usFreq, g_tRadio.ucVolume); - } - - x = 5; - y = 80; - LCD_DispStr(x, y, buf, &tFont); - y += usLineCap; -} - -/* -********************************************************************************************************* -* 函 数 名: radio_SignalQuality -* 功能说明: 显示当前信号质量 RSSI SNR -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_SignalQuality(void) -{ - char buf[128]; - FONT_T tFont; /* 定义一个字体结构体变量,用于设置字体参数 */ - uint8_t read_buf[7]; - uint16_t x, y; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - x = 5; - y = 100; - - if (g_tRadio.ucMode == FM_RX) - { - uint8_t rssi, snr, cap; - - SI4730_GetFMSignalQuality(read_buf); - /* - CMD 0x23 FM_RSQ_STATUS - ARG1 0x01 Clear RSQINT - STATUS ?0x80 Reply Status. Clear-to-send high. - RESP1 ?0x00 No blend, SNR high, low, RSSI high or low interrupts. - RESP2 ?0x01 Soft mute is not engaged, no AFC rail, valid frequency. - RESP3 ?0xD9 Pilot presence, 89% blend - RESP4 ?0x2D RSSI = 45 dBμV - RESP5 ?0x33 SNR = 51 dB - RESP6 ?0x00 - RESP7 ?0x00 Freq offset = 0 kHz - */ - rssi = read_buf[3]; - snr = read_buf[4]; - - SI4730_GetFMTuneStatus(read_buf); - /* - CMD 0x22 FM_TUNE_STATUS - ARG1 0x01 Clear STC interrupt. - STATUS ?0x80 Reply Status. Clear-to-send high. - - RESP1 ?0x01 Valid Frequency. - RESP2 ?0x27 Frequency = 0x27F6 = 102.3 MHz - RESP3 ?0xF6 - RESP4 ?0x2D RSSI = 45 dBμV - RESP5 ?0x33 SNR = 51 dB - RESP6 ?0x00 MULT[7:0] - RESP7 ?0x00 Antenna tuning capacitor = 0 (range = 0–191) READANTCAP[7:0] (Si4704/05/06/2x only) - */ - cap = read_buf[6]; - - sprintf(buf, "RSSI = %ddBuV SNR = %ddB CAP = %d", rssi, snr, cap); - - LCD_DispStrEx(x, y, buf, &tFont, 300, ALIGN_LEFT); - } - else - { - uint32_t cap; - - /* 读取AM调谐状态 */ - SI4730_GetAMTuneStatus(read_buf); - /* - CMD 0x42 AM_TUNE_STATUS - ARG1 0x01 Clear STC interrupt. - STATUS ?0x80 Reply Status. Clear-to-send high. - - RESP1 ?0x01 Channel is valid - RESP2 ?0x03 - RESP3 ?0xE8 Frequency = 0x03E8 = 1000 kHz - RESP4 ?0x2A RSSI = 0x2A = 42d = 42 dBμV - RESP5 ?0x1A SNR = 0x1A = 26d = 26 dB - RESP6 ?0x0D Value the antenna tuning capacitor is set to. - RESP7 ?0x95 0x0D95 = 3477 dec. - - 电容计算 The tuning capacitance is 95 fF x READANTCAP + 7 pF - */ - cap = (read_buf[5] << 8) | read_buf[6]; - cap = (cap * 95) + 7000; /* 实测 342pF -- 10pF */ - - /* 读取AM信号质量 */ - SI4730_GetAMSignalQuality(read_buf); - - sprintf(buf, "RSSI = %ddBuV SNR = %ddB Tuning Cap. = %d.%03dpF ", - read_buf[3], read_buf[4], cap / 1000, cap % 1000); - LCD_DispStr(x, y, buf, &tFont); - } -} - -/* -********************************************************************************************************* -* 函 数 名: radio_FM_FreqList -* 功能说明: 预设电台列表 -* 形 参:_ucAll = 0 表示武汉地区FM台, 1 表示所有的台,步长0.1M -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_FM_FreqList(uint8_t _ucAll) -{ - /* 预填武汉地区的电台列表 */ - uint32_t i; - - if (_ucAll == 0) - { - g_tRadio.ucFMCount = sizeof(g_InitListFM) / 2; - for (i = 0; i < g_tRadio.ucFMCount; i++) - { - g_tRadio.usFMList[i] = g_InitListFM[i]; - } - } - else - { - /* - 中国范围: 88-108兆赫信号调制方式是调频(频率调制)每个频道的频率间隔是0.1兆赫 - */ - g_tRadio.ucFMCount = 0; - for (i = 8800; i <= 10800; i += 10) - { - g_tRadio.usFMList[g_tRadio.ucFMCount++] = i; - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: radio_AM_FreqList -* 功能说明: 预设AM电台列表 -* 形 参:_ucAll = 0 表示武汉地区AM台, 1 表示所有的台,步长9KHz -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_AM_FreqList(uint8_t _ucAll) -{ - /* 预填武汉地区的电台列表 */ - uint8_t i; - - if (_ucAll == 0) - { - g_tRadio.ucAMCount = sizeof(g_InitListAM) / 2; - for (i = 0; i < g_tRadio.ucAMCount; i++) - { - g_tRadio.usAMList[i] = g_InitListAM[i]; - } - } - else - { - /* - 步长 9KHz - */ - g_tRadio.ucAMCount = 120; - for (i = 0; i < g_tRadio.ucAMCount; i++) - { - g_tRadio.usAMList[i] = 531 + i * 9; - } - g_tRadio.ucIndexAM = 0; - } -} - -/* -********************************************************************************************************* -* 函 数 名: radio_LoadParam -* 功能说明: 读取电台参数 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_LoadParam(void) -{ - //LoadPara(); 不需要读取,main() 中已读取 - - g_tRadio.ucMode = g_tParam.ucRadioMode; /* AM 或 FM */ - g_tRadio.ucListType = g_tParam.ucRadioListType; /* 电台列表类型。武汉地区或全国 */ - g_tRadio.ucIndexFM = g_tParam.ucIndexFM; /* 当前FM电台索引 */ - g_tRadio.ucIndexAM = g_tParam.ucIndexAM; /* 当前电台索引 */ - g_tRadio.ucVolume = g_tParam.ucRadioVolume; /* 音量 */ - g_tRadio.ucSpkOutEn = g_tParam.ucSpkOutEn; /* 扬声器输出使能 */ -} - -/* -********************************************************************************************************* -* 函 数 名: radio_LoadParam -* 功能说明: 保存当前的电台和音量 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_SaveParam(void) -{ - g_tParam.ucRadioMode = g_tRadio.ucMode; /* AM 或 FM */ - g_tParam.ucRadioListType = g_tRadio.ucListType; /* 电台列表类型。武汉地区或全国 */ - g_tParam.ucIndexFM = g_tRadio.ucIndexFM; /* 当前FM电台索引 */ - g_tParam.ucIndexAM = g_tRadio.ucIndexAM; /* 当前电台索引 */ - g_tParam.ucRadioVolume = g_tRadio.ucVolume; /* 音量 */ - g_tParam.ucSpkOutEn = g_tRadio.ucSpkOutEn; /* 扬声器输出使能 */ - - SaveParam(); -} - -/* -********************************************************************************************************* -* 函 数 名: radio_AdjustVolume -* 功能说明: 调节音量 -* 形 参: _ucVolume : 0-63 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void radio_AdjustVolume(uint8_t _ucVolume) -{ - uint8_t volume; - - wm8978_SetEarVolume(g_tRadio.ucVolume); - wm8978_SetSpkVolume(g_tRadio.ucVolume); - - if (g_tRadio.ucVolume == 0) - { - SI4730_SetOutVolume(0); - } - else - { - volume = 21 + (g_tRadio.ucVolume * 2) / 3; - SI4730_SetOutVolume(volume); - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_gprs_t.c b/User/app/src/old/form_gprs_t.c deleted file mode 100755 index 968a2d3..0000000 --- a/User/app/src/old/form_gprs_t.c +++ /dev/null @@ -1,660 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试SIM800 GPRS模块 -* 文件名称 : gprs_test.c -* 版 本 : V1.0 -* 说 明 : 测试GPRS模块 SIM800 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2015-08-01 armfly 首发 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_gprs.h" -#include "num_pad.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontRed; - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - LABEL_T Label7; - LABEL_T Label8; - - LABEL_T Label9; - - EDIT_T Edit1; /* 电话号码 */ - - BUTTON_T Btn1; /* 拨号 */ - BUTTON_T Btn2; /* 挂机 */ - BUTTON_T Btn3; /* 接听来话 */ - BUTTON_T Btn4; /* 拨打10086 */ - BUTTON_T Btn5; /* 拨打10010 */ - - BUTTON_T BtnRet; /* 返回 */ - - char strHardInfo[32]; /* 模块硬件信息 */ - uint8_t ucNetStatus; /* 网络状态 */ - uint8_t ucAudioCh; /* 当前音频通道 0, 1 */ - uint8_t ucEarVolume; /* 耳机音量 0 - 5 */ - int16_t ucMicGain; /* MIC音量 -12:最小增益 12:最大增益 13:静音*/ - -} FormGPRS_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "GPRS模块测试程序." - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "模块版本 : " - -#define LABEL2_X (LABEL1_X + 100) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "---" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "网络状态 : " - -#define LABEL4_X (LABEL3_X + 100) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "---" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "音频通道 : " - -#define LABEL6_X (LABEL5_X + 100) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT "1" - -#define LABEL7_X (LABEL1_X) -#define LABEL7_Y (LABEL1_Y + 20 * 3) -#define LABEL7_TEXT "耳机音量和MIC增益 : " - -#define LABEL8_X (LABEL7_X + 160) -#define LABEL8_Y LABEL7_Y -#define LABEL8_TEXT "---" - -#define LABEL9_X (LABEL1_X) -#define LABEL9_Y (LABEL1_Y + 20 * 5) -#define LABEL9_TEXT "电话号码 : " - -/* Edit */ -#define EDIT1_X (LABEL9_X + 90) -#define EDIT1_Y (LABEL9_Y - 4) -#define EDIT1_H 26 -#define EDIT1_W 132 - -/* 按钮 */ -#define BTN1_H 32 -#define BTN1_W 60 -#define BTN1_X LABEL1_X -#define BTN1_Y (EDIT1_Y + EDIT1_H + 10) -#define BTN1_TEXT "拨号" - -#define BTN2_H 32 -#define BTN2_W 60 -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_TEXT "挂机" - -#define BTN3_H 32 -#define BTN3_W 90 -#define BTN3_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN3_Y BTN1_Y -#define BTN3_TEXT "接听来话" - -#define BTN4_H 32 -#define BTN4_W 124 -#define BTN4_X BTN1_X -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_TEXT "拨打10086" - -#define BTN5_H 32 -#define BTN5_W 124 -#define BTN5_X BTN4_X + BTN4_W + 10 -#define BTN5_Y (BTN1_Y + BTN1_H + 10) -#define BTN5_TEXT "拨打10010" - -static void InitFormGPRS(void); -static void DispFormGPRS(void); - -FormGPRS_T *FormGPRS; - -void TestGPRS_SIM800(void); -void TestGPRS_MG323(void); - -/* -********************************************************************************************************* -* 函 数 名: TestGPRS -* 功能说明: 测试华为GPRS模块 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestGPRS(void) -{ - TestGPRS_SIM800(); -} - -/* -********************************************************************************************************* -* 函 数 名: TestGPRS_SIM800 -* 功能说明: 测试SIM800 GPRS模块 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestGPRS_SIM800(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - uint8_t ucValue; - uint8_t fRefresh = 1; - FormGPRS_T form; - - FormGPRS = &form; - - LCD_ClrScr(CL_BTN_FACE); - - InitFormGPRS(); - - DispFormGPRS(); - - bsp_InitSIM800(); - - printf("正在给GPRS模块上电...\r\n"); - - /* 给GSM模块上电 */ - if (SIM800_PowerOn()) - { - printf("\r\n上电完成\r\n"); - } - else - { - printf("\r\n模块无应答\r\n"); - } - - { - SIM800_INFO_T tInfo; - - if (SIM800_GetHardInfo(&tInfo)) - { - FormGPRS->Label2.Font = &FormGPRS->FontBlue; - sprintf(FormGPRS->strHardInfo, "%s %s %s", tInfo.Manfacture, tInfo.Model, tInfo.Revision); - } - else - { - FormGPRS->Label2.Font = &FormGPRS->FontRed; - sprintf(FormGPRS->strHardInfo, "未检测到模块"); - } - FormGPRS->Label2.pCaption = FormGPRS->strHardInfo; - LCD_DrawLabel(&FormGPRS->Label2); - } - - //SIM800_SetAutoReport(); /* 设置事件自动上报 */ - - SIM800_SetMicGain(0, FormGPRS->ucMicGain); /* 设置MIC增益 */ - SIM800_SetEarVolume(FormGPRS->ucEarVolume); /* 设置耳机音量 */ - - bsp_DelayMS(100); - SIM800_SendAT("AT+CMICBIAS=0"); /* 打开MIC偏置电路 */ - - bsp_StartAutoTimer(0, 500); - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - /* 从MG323收到的数据发送到串口1 */ - if (comGetChar(COM_SIM800, &ucValue)) - { - comSendChar(COM1, ucValue); - continue; - } - /* 将串口1的数据发送到MG323模块 */ - if (comGetChar(COM1, &ucValue)) - { - comSendChar(COM_SIM800, ucValue); - continue; - } - - /* 每隔0.5秒查询一下网络注册状态 */ - if (bsp_CheckTimer(0)) - { - FormGPRS->ucNetStatus = SIM800_GetNetStatus(); - - if ((FormGPRS->ucNetStatus == CREG_LOCAL_OK) || (FormGPRS->ucNetStatus == CREG_REMOTE_OK)) - { - bsp_StopTimer(0); /* 停止自动刷新 */ - - /* 配置WM8978芯片,输入为LINE接口,输出为耳机 和 扬声器 */ - wm8978_CfgAudioPath(LINE_ON, EAR_LEFT_ON | EAR_RIGHT_ON | SPK_ON); - } - else if (FormGPRS->ucNetStatus == CREG_NO_REG) - { - bsp_StopTimer(0); /* 停止自动刷新 */ - } - fRefresh = 1; - } - - if (fRefresh) - { - fRefresh = 0; - - DispFormGPRS(); /* 刷新所有控件 */ - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - LCD_ButtonTouchDown(&FormGPRS->BtnRet, tpX, tpY); - LCD_ButtonTouchDown(&FormGPRS->Btn1, tpX, tpY); - LCD_ButtonTouchDown(&FormGPRS->Btn2, tpX, tpY); - LCD_ButtonTouchDown(&FormGPRS->Btn3, tpX, tpY); - LCD_ButtonTouchDown(&FormGPRS->Btn4, tpX, tpY); - LCD_ButtonTouchDown(&FormGPRS->Btn5, tpX, tpY); - - /* 编辑框 */ - if (TOUCH_InRect(tpX, tpY, EDIT1_X, EDIT1_Y, EDIT1_H, EDIT1_W)) - { - { - if (InputNumber(NUMPAD_TEL, "设置电话号码", 0, (void *)FormGPRS->Edit1.Text)) - { - ; - } - - ClearWinNumPad(FORM_BACK_COLOR); /* 清除数字键盘窗口 */ - fRefresh = 1; - } - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormGPRS->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else if (LCD_ButtonTouchRelease(&FormGPRS->Btn1, tpX, tpY)) /* 拨号 */ - { - /* 拨打电话 */ - SIM800_DialTel(FormGPRS->Edit1.Text); - } - else if (LCD_ButtonTouchRelease(&FormGPRS->Btn2, tpX, tpY)) - { - /* 挂机 */ - SIM800_Hangup(); - } - else if (LCD_ButtonTouchRelease(&FormGPRS->Btn3, tpX, tpY)) /* 接听来话 */ - { - SIM800_SendAT("ATA"); - } - else if (LCD_ButtonTouchRelease(&FormGPRS->Btn4, tpX, tpY)) /* 拨打10086 */ - { - SIM800_DialTel("10086"); - } - else if (LCD_ButtonTouchRelease(&FormGPRS->Btn5, tpX, tpY)) /* 拨打10010 */ - { - SIM800_DialTel("10010"); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - SIM800_SendAT("ATD10086;"); /* 拨打10086 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - SIM800_SendAT("ATH"); /* 挂断电话 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - fRefresh = 1; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 调节耳机音量 */ - if (FormGPRS->ucEarVolume < EAR_VOL_MAX) - { - FormGPRS->ucEarVolume++; - SIM800_SetEarVolume(FormGPRS->ucEarVolume); - } - fRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 调节耳机音量 */ - if (FormGPRS->ucEarVolume > EAR_VOL_MIN) - { - FormGPRS->ucEarVolume--; - SIM800_SetEarVolume(FormGPRS->ucEarVolume); - } - fRefresh = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 调节MIC增益 */ - if (FormGPRS->ucMicGain > MIC_GAIN_MIN) - { - FormGPRS->ucMicGain--; - SIM800_SetMicGain(0, FormGPRS->ucMicGain); - } - fRefresh = 1; - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 调节MIC增益 */ - if (FormGPRS->ucMicGain < MIC_GAIN_MAX) - { - FormGPRS->ucMicGain++; - SIM800_SetMicGain(0, FormGPRS->ucMicGain); - } - fRefresh = 1; - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - /* 关闭WM8978芯片 */ - wm8978_PowerDown(); - - SIM800_PowerOff(); /* 下电 */ - printf("GPRS模块已下电.\r\n"); -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormGPRS -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormGPRS(void) -{ - /* 分组框标题字体 */ - FormGPRS->FontBox.FontCode = FC_ST_16; - FormGPRS->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormGPRS->FontBox.FrontColor = CL_BLACK; - FormGPRS->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormGPRS->FontBlack.FontCode = FC_ST_16; - FormGPRS->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormGPRS->FontBlack.FrontColor = CL_BLACK; - FormGPRS->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormGPRS->FontBlue.FontCode = FC_ST_16; - FormGPRS->FontBlue.BackColor = CL_BTN_FACE; - FormGPRS->FontBlue.FrontColor = CL_BLUE; - FormGPRS->FontBlue.Space = 0; - - FormGPRS->FontRed.FontCode = FC_ST_16; - FormGPRS->FontRed.BackColor = CL_BTN_FACE; - FormGPRS->FontRed.FrontColor = CL_RED; - FormGPRS->FontRed.Space = 0; - - /* 按钮字体 */ - FormGPRS->FontBtn.FontCode = FC_ST_16; - FormGPRS->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormGPRS->FontBtn.FrontColor = CL_BLACK; - FormGPRS->FontBtn.Space = 0; - - /* 分组框 */ - FormGPRS->Box1.Left = BOX1_X; - FormGPRS->Box1.Top = BOX1_Y; - FormGPRS->Box1.Height = BOX1_H; - FormGPRS->Box1.Width = BOX1_W; - FormGPRS->Box1.pCaption = BOX1_TEXT; - FormGPRS->Box1.Font = &FormGPRS->FontBox; - - /* 静态标签 */ - FormGPRS->Label1.Left = LABEL1_X; - FormGPRS->Label1.Top = LABEL1_Y; - FormGPRS->Label1.MaxLen = 0; - FormGPRS->Label1.pCaption = LABEL1_TEXT; - FormGPRS->Label1.Font = &FormGPRS->FontBlack; - - FormGPRS->Label3.Left = LABEL3_X; - FormGPRS->Label3.Top = LABEL3_Y; - FormGPRS->Label3.MaxLen = 0; - FormGPRS->Label3.pCaption = LABEL3_TEXT; - FormGPRS->Label3.Font = &FormGPRS->FontBlack; - - FormGPRS->Label5.Left = LABEL5_X; - FormGPRS->Label5.Top = LABEL5_Y; - FormGPRS->Label5.MaxLen = 0; - FormGPRS->Label5.pCaption = LABEL5_TEXT; - FormGPRS->Label5.Font = &FormGPRS->FontBlack; - - FormGPRS->Label7.Left = LABEL7_X; - FormGPRS->Label7.Top = LABEL7_Y; - FormGPRS->Label7.MaxLen = 0; - FormGPRS->Label7.pCaption = LABEL7_TEXT; - FormGPRS->Label7.Font = &FormGPRS->FontBlack; - - FormGPRS->Label9.Left = LABEL9_X; - FormGPRS->Label9.Top = LABEL9_Y; - FormGPRS->Label9.MaxLen = 0; - FormGPRS->Label9.pCaption = LABEL9_TEXT; - FormGPRS->Label9.Font = &FormGPRS->FontBlack; - - /* 动态标签 */ - FormGPRS->Label2.Left = LABEL2_X; - FormGPRS->Label2.Top = LABEL2_Y; - FormGPRS->Label2.MaxLen = 0; - FormGPRS->Label2.pCaption = LABEL2_TEXT; - FormGPRS->Label2.Font = &FormGPRS->FontBlue; - - FormGPRS->Label4.Left = LABEL4_X; - FormGPRS->Label4.Top = LABEL4_Y; - FormGPRS->Label4.MaxLen = 0; - FormGPRS->Label4.pCaption = LABEL4_TEXT; - FormGPRS->Label4.Font = &FormGPRS->FontBlue; - - FormGPRS->Label6.Left = LABEL6_X; - FormGPRS->Label6.Top = LABEL6_Y; - FormGPRS->Label6.MaxLen = 0; - FormGPRS->Label6.pCaption = LABEL6_TEXT; - FormGPRS->Label6.Font = &FormGPRS->FontBlue; - - FormGPRS->Label8.Left = LABEL8_X; - FormGPRS->Label8.Top = LABEL8_Y; - FormGPRS->Label8.MaxLen = 0; - FormGPRS->Label8.pCaption = LABEL8_TEXT; - FormGPRS->Label8.Font = &FormGPRS->FontBlue; - - /* 按钮 */ - FormGPRS->BtnRet.Left = BTN_RET_X; - FormGPRS->BtnRet.Top = BTN_RET_Y; - FormGPRS->BtnRet.Height = BTN_RET_H; - FormGPRS->BtnRet.Width = BTN_RET_W; - FormGPRS->BtnRet.pCaption = BTN_RET_TEXT; - FormGPRS->BtnRet.Font = &FormGPRS->FontBtn; - FormGPRS->BtnRet.Focus = 0; - - FormGPRS->Btn1.Left = BTN1_X; - FormGPRS->Btn1.Top = BTN1_Y; - FormGPRS->Btn1.Height = BTN1_H; - FormGPRS->Btn1.Width = BTN1_W; - FormGPRS->Btn1.pCaption = BTN1_TEXT; - FormGPRS->Btn1.Font = &FormGPRS->FontBtn; - FormGPRS->Btn1.Focus = 0; - - FormGPRS->Btn2.Left = BTN2_X; - FormGPRS->Btn2.Top = BTN2_Y; - FormGPRS->Btn2.Height = BTN2_H; - FormGPRS->Btn2.Width = BTN2_W; - FormGPRS->Btn2.pCaption = BTN2_TEXT; - FormGPRS->Btn2.Font = &FormGPRS->FontBtn; - FormGPRS->Btn2.Focus = 0; - - FormGPRS->Btn3.Left = BTN3_X; - FormGPRS->Btn3.Top = BTN3_Y; - FormGPRS->Btn3.Height = BTN3_H; - FormGPRS->Btn3.Width = BTN3_W; - FormGPRS->Btn3.pCaption = BTN3_TEXT; - FormGPRS->Btn3.Font = &FormGPRS->FontBtn; - FormGPRS->Btn3.Focus = 0; - - FormGPRS->Btn4.Left = BTN4_X; - FormGPRS->Btn4.Top = BTN4_Y; - FormGPRS->Btn4.Height = BTN4_H; - FormGPRS->Btn4.Width = BTN4_W; - FormGPRS->Btn4.pCaption = BTN4_TEXT; - FormGPRS->Btn4.Font = &FormGPRS->FontBtn; - FormGPRS->Btn4.Focus = 0; - - FormGPRS->Btn5.Left = BTN5_X; - FormGPRS->Btn5.Top = BTN5_Y; - FormGPRS->Btn5.Height = BTN5_H; - FormGPRS->Btn5.Width = BTN5_W; - FormGPRS->Btn5.pCaption = BTN5_TEXT; - FormGPRS->Btn5.Font = &FormGPRS->FontBtn; - FormGPRS->Btn5.Focus = 0; - - /* 编辑框 */ - FormGPRS->Edit1.Left = EDIT1_X; - FormGPRS->Edit1.Top = EDIT1_Y; - FormGPRS->Edit1.Height = EDIT1_H; - FormGPRS->Edit1.Width = EDIT1_W; - sprintf(FormGPRS->Edit1.Text, "10086"); - FormGPRS->Edit1.pCaption = FormGPRS->Edit1.Text; - FormGPRS->Edit1.Font = &FormGPRS->FontBtn; - - FormGPRS->ucMicGain = MIC_GAIN_DEFAULT; /* 缺省MIC增益 */ - FormGPRS->ucEarVolume = EAR_VOL_DEFAULT; /* 缺省耳机音量 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormGPRS -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormGPRS(void) -{ - //LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormGPRS->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormGPRS->Label1); - LCD_DrawLabel(&FormGPRS->Label3); - LCD_DrawLabel(&FormGPRS->Label5); - LCD_DrawLabel(&FormGPRS->Label7); - LCD_DrawLabel(&FormGPRS->Label9); - - /* 按钮 */ - LCD_DrawButton(&FormGPRS->BtnRet); - LCD_DrawButton(&FormGPRS->Btn1); - LCD_DrawButton(&FormGPRS->Btn2); - LCD_DrawButton(&FormGPRS->Btn3); - LCD_DrawButton(&FormGPRS->Btn4); - LCD_DrawButton(&FormGPRS->Btn5); - - /* 编辑框 */ - LCD_DrawEdit(&FormGPRS->Edit1); - - /* 动态标签 */ - LCD_DrawLabel(&FormGPRS->Label2); - - /* 网络注册状态 */ - if (FormGPRS->ucNetStatus == CREG_NO_REG) - { - FormGPRS->Label4.pCaption = "没有注册, 已停止搜寻"; - } - else if (FormGPRS->ucNetStatus == CREG_LOCAL_OK) - { - FormGPRS->Label4.pCaption = "已注册到本地网络 "; - } - else if (FormGPRS->ucNetStatus == CREG_SEARCH) - { - FormGPRS->Label4.pCaption = "正在搜寻网络运营商 "; - } - else if (FormGPRS->ucNetStatus == CREG_REJECT) - { - FormGPRS->Label4.pCaption = "注册被拒绝 "; - } - else if (FormGPRS->ucNetStatus == CREG_REMOTE_OK) - { - FormGPRS->Label4.pCaption = "已注册到漫游网络 "; - } - else - { - FormGPRS->Label4.pCaption = "xxx "; - } - LCD_DrawLabel(&FormGPRS->Label4); - - if (FormGPRS->ucAudioCh == 0) - { - FormGPRS->Label6.pCaption = "第1通道 INTMIC, INTEAR"; - } - else - { - FormGPRS->Label6.pCaption = "第2通道 EXTMIC, EXTEAR"; - } - LCD_DrawLabel(&FormGPRS->Label6); - - /* 耳机音量 */ - { - char buf[64]; - - sprintf(buf, "Ear = %d, Mic = %d", FormGPRS->ucEarVolume, FormGPRS->ucMicGain); - FormGPRS->Label8.pCaption = buf; - LCD_DrawLabel(&FormGPRS->Label8); - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_gps.c b/User/app/src/old/form_gps.c deleted file mode 100755 index bc1cecc..0000000 --- a/User/app/src/old/form_gps.c +++ /dev/null @@ -1,457 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : GPS定位模块测试程序 -* 文件名称 : gps_test.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_gps.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontRed; /* 红色字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; /* 纬度 */ - LABEL_T Label3; - LABEL_T Label4; /* 经度 */ - LABEL_T Label5; - LABEL_T Label6; /* 速度 */ - LABEL_T Label7; - LABEL_T Label8; /* 海拔 */ - - LABEL_T Label9; - LABEL_T Label10; /* 状态 */ - - BUTTON_T BtnRet; -} FormGPS_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "GPS定位模块测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "纬度 : " - -#define LABEL2_X (LABEL1_X + 64) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "0000.0000" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "经度 : " - -#define LABEL4_X (LABEL3_X + 64) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "00000.0000" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "速度 : " - -#define LABEL6_X (LABEL5_X + 64) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT "0.0KM" - -#define LABEL7_X (LABEL1_X) -#define LABEL7_Y (LABEL1_Y + 20 * 3) -#define LABEL7_TEXT "海拔 : " - -#define LABEL8_X (LABEL7_X + 64) -#define LABEL8_Y LABEL7_Y -#define LABEL8_TEXT "0.0M" - -#define LABEL9_X (LABEL1_X) -#define LABEL9_Y (LABEL1_Y + 20 * 5) -#define LABEL9_TEXT "硬件 : " - -#define LABEL10_X (LABEL9_X + 64) -#define LABEL10_Y LABEL9_Y -#define LABEL10_TEXT "" - -static void InitFormGPS(void); -static void DispGPSInitFace(void); -static void DispGPSStatus(void); - -FormGPS_T *FormGPS; - -/* -********************************************************************************************************* -* 函 数 名: TestGPS -* 功能说明: 测试GPS模块。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestGPS(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormGPS_T form; - - FormGPS = &form; - - bsp_InitGPS(); - - InitFormGPS(); - - DispGPSInitFace(); - - bsp_StartAutoTimer(0, 1000); /* 每秒定时显示GPS状态 */ - - bsp_StartTimer(1, 3000); /* 3秒超时没有收到GPS数据,则认为串口连接失败 */ - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - gps_pro(); - - if (bsp_CheckTimer(0)) - { - DispGPSStatus(); - } - - /* 这段代码用于判断CPU是否能够收到GPS模块返回的数据 */ - { - if (bsp_CheckTimer(1)) - { - FormGPS->Label10.Font = &FormGPS->FontRed; - FormGPS->Label10.pCaption = "未检测到GPS模块"; - LCD_DrawLabel(&FormGPS->Label10); - } - if (g_tGPS.UartOk == 1) /* 串口通信正常的标志, 如果以后收到了校验合格的命令串则设置为1 */ - { - bsp_StartTimer(1, 3000); /* 3秒超时没有收到GPS数据,则认为串口连接失败 */ - - FormGPS->Label10.Font = &FormGPS->FontBlue; - FormGPS->Label10.pCaption = "检测到GPS模块. 串口数据收发OK"; - LCD_DrawLabel(&FormGPS->Label10); - - g_tGPS.UartOk = 0; - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormGPS->BtnRet.Focus = 1; - LCD_DrawButton(&FormGPS->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormGPS->BtnRet.Focus = 0; - LCD_DrawButton(&FormGPS->BtnRet); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormGPS->BtnRet.Focus = 0; - LCD_DrawButton(&FormGPS->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - bsp_StopTimer(0); -} - -/* -********************************************************************************************************* -* 函 数 名: DispGPSStatus -* 功能说明: 显示GPS状态 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispGPSStatus(void) -{ - char buf[128]; - - /* 纬度 */ - if (g_tGPS.NS == 'S') - { - sprintf(buf, "南纬 %02d°%02d.%04d'=%02d.%06d°", g_tGPS.WeiDu_Du, - g_tGPS.WeiDu_Fen / 10000, g_tGPS.WeiDu_Fen % 10000, - g_tGPS.WeiDu_Du, gps_FenToDu(g_tGPS.WeiDu_Fen)); - - sprintf(&buf[strlen(buf)], "=%02d°%02d'%02d\"", g_tGPS.WeiDu_Du, - g_tGPS.WeiDu_Fen / 10000, gps_FenToMiao(g_tGPS.WeiDu_Fen)); - } - else - { - sprintf(buf, "北纬 %02d°%02d.%04d'=%02d.%06d°", g_tGPS.WeiDu_Du, - g_tGPS.WeiDu_Fen / 10000, g_tGPS.WeiDu_Fen % 10000, - g_tGPS.WeiDu_Du, gps_FenToDu(g_tGPS.WeiDu_Fen)); - - sprintf(&buf[strlen(buf)], "=%02d°%02d'%02d\"", g_tGPS.WeiDu_Du, - g_tGPS.WeiDu_Fen / 10000, gps_FenToMiao(g_tGPS.WeiDu_Fen)); - } - FormGPS->Label2.pCaption = buf; - LCD_DrawLabel(&FormGPS->Label2); - - /* 经度 */ - if (g_tGPS.EW == 'E') - { - sprintf(buf, "东经 %03d°%02d.%04d'=%03d.%06d°", g_tGPS.JingDu_Du, - g_tGPS.JingDu_Fen / 10000, g_tGPS.JingDu_Fen % 10000, - g_tGPS.JingDu_Du, gps_FenToDu(g_tGPS.JingDu_Fen)); - - sprintf(&buf[strlen(buf)], "=%03d°%02d'%02d\"", g_tGPS.JingDu_Du, - g_tGPS.WeiDu_Fen / 10000, gps_FenToMiao(g_tGPS.JingDu_Fen)); - } - else - { - sprintf(buf, "西经 %03d°%02d.%04d'=%03d.%06d°", g_tGPS.JingDu_Du, - g_tGPS.JingDu_Fen / 10000, g_tGPS.JingDu_Fen % 10000, - g_tGPS.JingDu_Du, gps_FenToDu(g_tGPS.JingDu_Fen)); - - sprintf(&buf[strlen(buf)], "=%03d°%02d'%02d\"", g_tGPS.JingDu_Du, - g_tGPS.JingDu_Fen / 10000, gps_FenToMiao(g_tGPS.JingDu_Fen)); - } - FormGPS->Label4.pCaption = buf; - LCD_DrawLabel(&FormGPS->Label4); - - /* 速度 */ - sprintf(buf, "%5d.%d KM/h", g_tGPS.SpeedKM / 10, g_tGPS.SpeedKM % 10); - FormGPS->Label6.pCaption = buf; - LCD_DrawLabel(&FormGPS->Label6); - - /* 海拔 */ - sprintf(buf, "%5d.%d M", g_tGPS.Altitude / 10, g_tGPS.Altitude % 10); - FormGPS->Label8.pCaption = buf; - LCD_DrawLabel(&FormGPS->Label8); -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormGPS -* 功能说明: 初始化GPS初始界面控件 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormGPS(void) -{ - /* 分组框标题字体 */ - FormGPS->FontBox.FontCode = FC_ST_16; - FormGPS->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormGPS->FontBox.FrontColor = CL_BLACK; - FormGPS->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormGPS->FontBlack.FontCode = FC_ST_16; - FormGPS->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormGPS->FontBlack.FrontColor = CL_BLACK; - FormGPS->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormGPS->FontBlue.FontCode = FC_ST_16; - FormGPS->FontBlue.BackColor = CL_BTN_FACE; - FormGPS->FontBlue.FrontColor = CL_BLUE; - FormGPS->FontBlue.Space = 0; - - FormGPS->FontRed.FontCode = FC_ST_16; - FormGPS->FontRed.BackColor = CL_BTN_FACE; - FormGPS->FontRed.FrontColor = CL_RED; - FormGPS->FontRed.Space = 0; - - /* 按钮字体 */ - FormGPS->FontBtn.FontCode = FC_ST_16; - FormGPS->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormGPS->FontBtn.FrontColor = CL_BLACK; - FormGPS->FontBtn.Space = 0; - - /* 分组框 */ - FormGPS->Box1.Left = BOX1_X; - FormGPS->Box1.Top = BOX1_Y; - FormGPS->Box1.Height = BOX1_H; - FormGPS->Box1.Width = BOX1_W; - FormGPS->Box1.pCaption = BOX1_TEXT; - FormGPS->Box1.Font = &FormGPS->FontBox; - - /* 静态标签 */ - FormGPS->Label1.Left = LABEL1_X; - FormGPS->Label1.Top = LABEL1_Y; - FormGPS->Label1.MaxLen = 0; - FormGPS->Label1.pCaption = LABEL1_TEXT; - FormGPS->Label1.Font = &FormGPS->FontBlack; - - FormGPS->Label3.Left = LABEL3_X; - FormGPS->Label3.Top = LABEL3_Y; - FormGPS->Label3.MaxLen = 0; - FormGPS->Label3.pCaption = LABEL3_TEXT; - FormGPS->Label3.Font = &FormGPS->FontBlack; - - FormGPS->Label5.Left = LABEL5_X; - FormGPS->Label5.Top = LABEL5_Y; - FormGPS->Label5.MaxLen = 0; - FormGPS->Label5.pCaption = LABEL5_TEXT; - FormGPS->Label5.Font = &FormGPS->FontBlack; - - FormGPS->Label7.Left = LABEL7_X; - FormGPS->Label7.Top = LABEL7_Y; - FormGPS->Label7.MaxLen = 0; - FormGPS->Label7.pCaption = LABEL7_TEXT; - FormGPS->Label7.Font = &FormGPS->FontBlack; - - FormGPS->Label9.Left = LABEL9_X; - FormGPS->Label9.Top = LABEL9_Y; - FormGPS->Label9.MaxLen = 0; - FormGPS->Label9.pCaption = LABEL9_TEXT; - FormGPS->Label9.Font = &FormGPS->FontBlack; - - /* 动态标签 */ - FormGPS->Label2.Left = LABEL2_X; - FormGPS->Label2.Top = LABEL2_Y; - FormGPS->Label2.MaxLen = 0; - FormGPS->Label2.pCaption = LABEL2_TEXT; - FormGPS->Label2.Font = &FormGPS->FontBlue; - - FormGPS->Label4.Left = LABEL4_X; - FormGPS->Label4.Top = LABEL4_Y; - FormGPS->Label4.MaxLen = 0; - FormGPS->Label4.pCaption = LABEL4_TEXT; - FormGPS->Label4.Font = &FormGPS->FontBlue; - - FormGPS->Label6.Left = LABEL6_X; - FormGPS->Label6.Top = LABEL6_Y; - FormGPS->Label6.MaxLen = 0; - FormGPS->Label6.pCaption = LABEL6_TEXT; - FormGPS->Label6.Font = &FormGPS->FontBlue; - - FormGPS->Label8.Left = LABEL8_X; - FormGPS->Label8.Top = LABEL8_Y; - FormGPS->Label8.MaxLen = 0; - FormGPS->Label8.pCaption = LABEL8_TEXT; - FormGPS->Label8.Font = &FormGPS->FontBlue; - - FormGPS->Label10.Left = LABEL10_X; - FormGPS->Label10.Top = LABEL10_Y; - FormGPS->Label10.MaxLen = 0; - FormGPS->Label10.pCaption = LABEL10_TEXT; - FormGPS->Label10.Font = &FormGPS->FontBlue; - - /* 按钮 */ - FormGPS->BtnRet.Left = BTN_RET_X; - FormGPS->BtnRet.Top = BTN_RET_Y; - FormGPS->BtnRet.Height = BTN_RET_H; - FormGPS->BtnRet.Width = BTN_RET_W; - FormGPS->BtnRet.pCaption = BTN_RET_TEXT; - FormGPS->BtnRet.Font = &FormGPS->FontBtn; - FormGPS->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispGPSInitFace -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispGPSInitFace(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormGPS->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormGPS->Label1); - LCD_DrawLabel(&FormGPS->Label3); - LCD_DrawLabel(&FormGPS->Label5); - LCD_DrawLabel(&FormGPS->Label7); - LCD_DrawLabel(&FormGPS->Label9); - - /* 动态标签 */ - LCD_DrawLabel(&FormGPS->Label2); - LCD_DrawLabel(&FormGPS->Label4); - LCD_DrawLabel(&FormGPS->Label6); - LCD_DrawLabel(&FormGPS->Label8); - LCD_DrawLabel(&FormGPS->Label10); - - /* 按钮 */ - LCD_DrawButton(&FormGPS->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_hard_test.c b/User/app/src/old/form_hard_test.c deleted file mode 100755 index 5955e1f..0000000 --- a/User/app/src/old/form_hard_test.c +++ /dev/null @@ -1,601 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 硬件测试界面。 -* 文件名称 : hard_test.c -* 版 本 : V1.0 -* 说 明 : 显示硬件信息。自动测试一些芯片。 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-01-01 armfly 正式发布 -* -* Copyright (C), 2012-2013, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" /* printf函数定向输出到串口,所以必须包含这个文件 */ -#include "form_hard_test.h" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BUTTON_RET_H 32 -#define BUTTON_RET_W 60 -#define BUTTON_RET_X (g_LcdWidth - BUTTON_RET_W - 4) -#define BUTTON_RET_Y (g_LcdHeight - BUTTON_RET_H - 4) - -/* -********************************************************************************************************* -* 函 数 名: HardInfo -* 功能说明: 自动检测硬件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void HardInfo(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - FONT_T tFont, tFontBtn; /* 定义一个字体结构体变量,用于设置字体参数 */ - char buf[128]; - uint16_t x, y; - uint16_t usLineCap = 18; - - int16_t tpX, tpY; - BUTTON_T tBtn; - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - /* 按钮字体 */ - tFontBtn.FontCode = FC_ST_16; - tFontBtn.BackColor = CL_MASK; /* 透明色 */ - tFontBtn.FrontColor = CL_BLACK; - tFontBtn.Space = 0; - } - - x = 5; - y = 3; - LCD_DispStr(x, y, "安富莱STM32-V6开发板硬件信息", &tFont); /* 在(8,3)坐标处显示一串汉字 */ - y += usLineCap; - - /* 检测CPU ID */ - { - uint32_t id[3]; - - bsp_GetCpuID(id); - - printf("\r\nCPU : STM32H743, 主频: %dMHz\r\n", SystemCoreClock / 1000000); - - LCD_DispStr(x, y, "CPU : STM32H743", &tFont); - y += usLineCap; - - sprintf(buf, " UID = %08X %08X %08X", id[0], id[1], id[2]); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - y += usLineCap; - } - - /* 显示TFT控制器型号和屏幕分辨率 */ - { - strcpy(buf, "TFT Driver : "); - LCD_GetChipDescribe(&buf[strlen(buf)]); /* 读取TFT驱动芯片型号 */ - sprintf(&buf[strlen(buf)], " %d x %d", LCD_GetWidth(), LCD_GetHeight()); - LCD_DispStr(x, y, buf, &tFont); - y += usLineCap; - } - - /* 测试SRAM */ - { - sprintf(buf, "SDRAM Model ... "); - - LCD_DispStr(x, y, buf, &tFont); - if (bsp_TestExtSDRAM2() == 0) - { - sprintf(buf, "SDRAM, 32Bit, Test OK"); - printf("%s\r\n", buf); - - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, " SDRAM, Test Err"); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - } - -/* 测试NADN Flash */ -#if 1 - { - uint32_t id; - - NAND_Init(); /* 初始化NAND */ - - id = NAND_ReadID(); - - sprintf(buf, "NAND Flash ID = 0x%04X, Type = ", id); - if (id == HY27UF081G2A) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = HY27UF081G2A, OK", id); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else if (id == H27U1G8F2BTR) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = H27U1G8F2BTR, OK", id); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else if (id == H27U4G8F2DTR) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = H27U4G8F2DTR, OK", id); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = Unknow, Err", id); - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - //NAND_DispBadBlockInfo(); /* 向串口1打印NAND Flash坏块信息 (此函数开头初始FSMC) */ - } -#endif - /* 测试I2C设备 */ - { - if (i2c_CheckDevice(EE_DEV_ADDR) == 0) - { - sprintf(buf, "AT24C128 Ok (0x%02X)", EE_DEV_ADDR); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "AT24C128 Err (0x%02X)", EE_DEV_ADDR); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - - if (i2c_CheckDevice(I2C_ADDR_SI4730_W) == 0) - { - sprintf(buf, "Si4730/4704 Ok (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "Si4730/4704 Err (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; -#if 0 - if (i2c_CheckDevice(HMC5883L_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "HMC5883L Ok (0x%02X)", HMC5883L_SLAVE_ADDRESS); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "HMC5883L / MAG3110 Err"); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; -#endif - - if (i2c_CheckDevice(MPU6050_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "MPU6050 Ok (0x%02X)", MPU6050_SLAVE_ADDRESS); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "MPU6050 Err (0x%02X)", MPU6050_SLAVE_ADDRESS); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - - if (i2c_CheckDevice(BMP085_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "BMP180 Ok (0x%02X)", BMP085_SLAVE_ADDRESS); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "BMP180 Err (0x%02X)", BMP085_SLAVE_ADDRESS); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - - if (i2c_CheckDevice(WM8978_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "WM8978 Ok (0x%02X)", WM8978_SLAVE_ADDRESS); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "WM8978 Err (0x%02X)", WM8978_SLAVE_ADDRESS); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - - if (i2c_CheckDevice(BH1750_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "BH1750 Ok (0x%02X)", BH1750_SLAVE_ADDRESS); - printf("%s\r\n", buf); - LCD_DispStr(x, y, buf, &tFont); - } - else - { - sprintf(buf, "BH1750 Err (0x%02X)", BH1750_SLAVE_ADDRESS); - printf("%s\r\n", buf); - - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - y += usLineCap; - } - - /* 测试SPI Flash */ - { - bsp_InitSFlash(); /* 初始化SPI硬件 */ - - sf_ReadInfo(); - - /* 检测串行Flash OK */ - sprintf(buf, "SPI Flash ID = %08X, Model = %s", g_tSF.ChipID, g_tSF.ChipName); - printf("%s\r\n", buf); - - if (g_tSF.ChipID == W25Q64BV_ID) - { - LCD_DispStr(x, y, buf, &tFont); - } - else - { - tFont.FrontColor = CL_RED; - LCD_DispStr(x, y, buf, &tFont); - tFont.FrontColor = CL_WHITE; - } - } - - fRefresh = 1; /* 1表示需要刷新LCD */ - bsp_StartAutoTimer(0, 1000); - while (1) - { - bsp_Idle(); - - /* 显示时钟 */ - if (bsp_CheckTimer(0)) - { - uint16_t x, y; - - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - RTC_ReadClock(); /* 读时钟,结果在 g_tRTC */ - - x = 5; - y = LCD_GetHeight() - 20; - - sprintf(buf, "%4d-%02d-%02d %02d:%02d:%02d", - g_tRTC.Year, g_tRTC.Mon, g_tRTC.Day, g_tRTC.Hour, g_tRTC.Min, g_tRTC.Sec); - LCD_DispStr(x, y, buf, &tFont); - } - - if (fRefresh) - { - fRefresh = 0; - - /* 显示按钮 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - - return; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - } - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case JOY_DOWN_OK: /* 摇杆OK键 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: PrintfHardInfo -* 功能说明: 自动检测硬件. printf到串口。不显示。 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -extern uint32_t dm9k_ReadID(void); -void PrintfHardInfo(void) -{ - char buf[128]; - - /* 检测CPU ID */ - { - uint32_t id[3]; - - bsp_GetCpuID(id); - - printf("\r\nCPU : STM32H743, 主频: %dMHz\r\n", SystemCoreClock / 1000000); - sprintf(buf, " UID = %08X %08X %08X", id[0], id[1], id[2]); - printf("%s\r\n", buf); - } - - /* 显示TFT控制器型号和屏幕分辨率 */ - { - strcpy(buf, "TFT Driver : "); - LCD_GetChipDescribe(&buf[strlen(buf)]); /* 读取TFT驱动芯片型号 */ - sprintf(&buf[strlen(buf)], " %d x %d", LCD_GetWidth(), LCD_GetHeight()); - printf("%s\r\n", buf); - } - -/* 测试SRAM */ -#if 0 - { - if (bsp_TestExtSDRAM2() == 0) - { - sprintf(buf, "SDRAM Test OK"); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "SDRAM Test Err"); - printf("%s\r\n", buf); - } - } -#endif - -/* 测试NADN Flash */ -#if 1 - { - uint32_t id; - - NAND_Init(); /* 初始化NAND */ - - id = NAND_ReadID(); - - sprintf(buf, "NAND Flash ID = 0x%04X, Type = ", id); - if (id == HY27UF081G2A) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = HY27UF081G2A, OK", id); - printf("%s\r\n", buf); - } - else if (id == H27U1G8F2BTR) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = H27U1G8F2BTR, OK", id); - printf("%s\r\n", buf); - } - else if (id == H27U4G8F2DTR) - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = H27U4G8F2DTR, OK", id); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "NAND Flash ID = 0x%04X, Model = Unknow, Err", id); - printf("%s\r\n", buf); - } - } -#endif - /* 测试I2C设备 */ - { - if (i2c_CheckDevice(EE_DEV_ADDR) == 0) - { - sprintf(buf, "AT24C128 Ok (0x%02X)", EE_DEV_ADDR); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "AT24C128 Err (0x%02X)", EE_DEV_ADDR); - printf("%s\r\n", buf); - } - - if (i2c_CheckDevice(I2C_ADDR_SI4730_W) == 0) - { - sprintf(buf, "Si4730 Ok (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "Si4730 Err (0x%02X)", I2C_ADDR_SI4730_W); - printf("%s\r\n", buf); - } -#if 0 - if (i2c_CheckDevice(HMC5883L_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "HMC5883L Ok (0x%02X)", HMC5883L_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "HMC5883L Err (0x%02X)", HMC5883L_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } -#endif - - if (i2c_CheckDevice(MPU6050_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "MPU6050 Ok (0x%02X)", MPU6050_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "MPU6050 Err (0x%02X)", MPU6050_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - - if (i2c_CheckDevice(BMP085_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "BMP180 Ok (0x%02X)", BMP085_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "BMP180 Err (0x%02X)", BMP085_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - - if (i2c_CheckDevice(WM8978_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "WM8978 Ok (0x%02X)", WM8978_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "WM8978 Err (0x%02X)", WM8978_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - - if (i2c_CheckDevice(BH1750_SLAVE_ADDRESS) == 0) - { - sprintf(buf, "BH1750 Ok (0x%02X)", BH1750_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - else - { - sprintf(buf, "BH1750 Err (0x%02X)", BH1750_SLAVE_ADDRESS); - printf("%s\r\n", buf); - } - } - - /* 测试SPI Flash */ - { - //bsp_InitSFlash(); /* 初始化SPI硬件, bsp.c 中已经初始化 */ - - /* 检测串行Flash OK */ - sprintf(buf, "SPI Flash ID= = %08X, Model = %s", g_tSF.ChipID, g_tSF.ChipName); - printf("%s\r\n", buf); - } - -/* 检测DM9000 */ -#if 0 - { - uint32_t id; - - id = dm9k_ReadID(); - - if (id == 0x0A469000) - { - printf("DM9000AEP OK, ID = %8X\r\n", id); - } - else - { - printf("DM9000AEP Error, ID = %8X\r\n", id); - } - } -#endif -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_http_server.c b/User/app/src/old/form_http_server.c deleted file mode 100755 index 2f723e4..0000000 --- a/User/app/src/old/form_http_server.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : web server 演示 -* 文件名称 : http_server.c -* 版 本 : V1.0 -* 说 明 : 提供WEB服务器功能。主要目的是测试DM9000AEP网卡电路和DM9161 PHY电路。 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-01-01 armfly 正式发布 -* -* Copyright (C), 2012-2013, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "stdio.h" -#include "bsp.h" -#include "num_pad.h" -#include "param.h" - -/* for LwIP */ -//#include "netconf.h" -//#include "main_lwip.h" -//#include "httpd_w.h" -#include "lwip/opt.h" -#include "lwip/init.h" -#include "netif/etharp.h" -#include "lwip/netif.h" -#include "lwip/timeouts.h" -#include "lwip/dhcp.h" - -#include "ethernetif.h" -#include "app_ethernet.h" -#include "http_cgi_ssi.h" - -void lwip_start(void); -void lwip_pro(void); - -/* -********************************************************************************************************* -* 函 数 名: WebServer -* 功能说明: web服务器程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void WebServer(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - int16_t tpX, tpY; - uint16_t x, y; - uint16_t usLineCap = 18; - char buf[128]; - uint8_t fRefresh; - FONT_T tFont; /* 定义字体结构体变量 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLACK; /* 字体颜色 */ - tFont.BackColor = FORM_BACK_COLOR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - LCD_ClrScr(FORM_BACK_COLOR); /* 清屏,背景蓝色 */ - - LCD_DispStr(5, 3, "逻辑分析仪示波器", &tFont); - } - - /* LwIP 初始化 */ - { - /* 如果不插网线,此函数执行时间过长 */ - /* 网络参数存在在全局变量 g_tParam.lwip_ip, g_tParam.lwip_net_mask, g_tParam.lwip_gateway */ - lwip_start(); - } - - LCD_ClrScr(FORM_BACK_COLOR); /* 清屏,背景蓝色 */ - - fRefresh = 1; - while (1) - { - bsp_Idle(); - - uip_pro(); - lwip_pro(); - - if (fRefresh) /* 刷新整个界面 */ - { - fRefresh = 0; - } - - if (PHYLinkChanged == 1) /* DM9162联网状态变化 */ - { - PHYLinkChanged = 0; - - fRefresh = 1; - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_S: /* S键 */ - break; - - case KEY_DOWN_C: /* C键 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 下面是 LwIP 部分的代码 -********************************************************************************************************* -*/ - -struct netif gnetif; - -/* -********************************************************************************************************* -* 函 数 名: uip_ChangeNetParam -* 功能说明: 重新设置网络参数, 网络参数存在在全局变量 g_tParam.uip_ip, g_tParam.uip_net_mask, -* g_tParam.uip_gateway -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void lwip_ChangeNetParam(void) -{ - // //uip_ipaddr(ipaddr, 192,168,1,10); /* 缺省IP */ - // uip_sethostaddr((uint16_t *)g_tParam.uip_ip); - - // //uip_ipaddr(ipaddr, 255,255,255,0); /* 地址掩码 */ - // uip_setnetmask((uint16_t *)g_tParam.uip_net_mask); - - // //uip_ipaddr(ipaddr, 192,168,1,1); /* 默认网关 */ - // uip_setdraddr((uint16_t *)g_tParam.uip_gateway); -} - -/** - * @brief Setup the network interface - * @param None - * @retval None - */ -/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */ -#define IP_ADDR0 ((uint8_t)192U) -#define IP_ADDR1 ((uint8_t)168U) -#define IP_ADDR2 ((uint8_t)1U) -#define IP_ADDR3 ((uint8_t)86U) - -/*NETMASK*/ -#define NETMASK_ADDR0 ((uint8_t)255U) -#define NETMASK_ADDR1 ((uint8_t)255U) -#define NETMASK_ADDR2 ((uint8_t)255U) -#define NETMASK_ADDR3 ((uint8_t)0U) - -/*Gateway Address*/ -#define GW_ADDR0 ((uint8_t)192U) -#define GW_ADDR1 ((uint8_t)168U) -#define GW_ADDR2 ((uint8_t)1U) -#define GW_ADDR3 ((uint8_t)1U) - -static void Netif_Config(void) -{ - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gw; - -#if LWIP_DHCP - ip_addr_set_zero_ip4(&ipaddr); - ip_addr_set_zero_ip4(&netmask); - ip_addr_set_zero_ip4(&gw); -#else - - /* IP address default setting */ - IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); - IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); - IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); - -#endif - - /* add the network interface */ - netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); - - /* Registers the default network interface */ - netif_set_default(&gnetif); - - ethernet_link_status_updated(&gnetif); - -#if LWIP_NETIF_LINK_CALLBACK - netif_set_link_callback(&gnetif, ethernet_link_status_updated); -#endif -} - -/* -********************************************************************************************************* -* 函 数 名: lwip_start -* 功能说明: 启动lwip_start, 网络参数存在在全局变量 g_tParam.lwip_ip, g_tParam.lwip_net_mask, -* g_tParam.lwip_gateway -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void lwip_start(void) -{ - /* Initialize the LwIP stack */ - lwip_init(); - - /* Configure the Network interface */ - Netif_Config(); - - /* Http webserver Init */ - http_server_init(); -} - -/* -********************************************************************************************************* -* 函 数 名: lwip_pro -* 功能说明: lwip 轮询,插入到主循环中 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void lwip_pro(void) -{ - /* Read a received packet from the Ethernet buffers and send it - to the lwIP for handling */ - ethernetif_input(&gnetif); - - /* Handle timeouts */ - sys_check_timeouts(); - -#if LWIP_NETIF_LINK_CALLBACK - Ethernet_Link_Periodic_Handle(&gnetif); -#endif - -#if LWIP_DHCP - DHCP_Periodic_Handle(&gnetif); -#endif -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_main_menu.c b/User/app/src/old/form_main_menu.c deleted file mode 100755 index b9305a5..0000000 --- a/User/app/src/old/form_main_menu.c +++ /dev/null @@ -1,571 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 主界面模块。 -* 文件名称 : main_menu.c -* 版 本 : V1.0 -* 说 明 : -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2012-08-08 armfly ST固件库V3.5.0版本。 -* -* Copyright (C), 2012-2013, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" /* printf函数定向输出到串口,所以必须包含这个文件 */ -#include "images.h" /* 图标文件 */ -#include "form_main_menu.h" -#include "main.h" - -#define KEY_INFO "K3:校准 K1:背景 OK:显示方向" - -#define ICON_LEFT 16 -#define ICON_TOP 25 - -#define TOP_BAR_H 20 /* 顶部栏高度 */ -#define BOTTOM_BAR_H 20 /* 底部栏高度 */ -#define CL_BAR RGB(0, 73, 108) /* 顶部栏和底部栏背景颜色 */ - -extern const unsigned char acRecorder[48 * 48 * 4]; -extern const unsigned char acTape[48 * 48 * 4]; -extern const unsigned char acCamera[48 * 48 * 4]; -extern const unsigned char acChiLun[48 * 48 * 4]; -extern const unsigned char acchujiao[48 * 48 * 4]; - -#define ICONS_COUNT 28 -static ICON_T s_tMainIcons[ICONS_COUNT] = - { - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)achwinfo, "硬件信息"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acLCD, "触摸屏和按键"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acRadio, "收音机"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acRecorder, "录音机"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acchujiao, "MEMS传感器"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acweb, "WEB服务器"}, - - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acGPS, "GPS定位模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acPhone, "GPRS模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acMP3, "MP3模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acUSBDisk, "模拟U盘"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acCamera, "摄像头"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "OLED显示器"}, - - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acADC, "AD7606模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acADC, "AD7705模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acADC, "ADS1256模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "RS485数码管"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "DAC8501"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "DAC8562"}, - - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "示波器"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "串口WiFi"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "CAN网络"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "AD9833模块"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留4"}, - - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留5"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留6"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留7"}, - {ID_ICON, 0, 0, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acChiLun, "预留8"}, - -}; - -/* 图标点击后,切换程序状态 */ -static const uint8_t s_RetStatus[ICONS_COUNT] = - { - MS_HARDWARE_INFO, /* 硬件信息 */ - MS_TEST_TOUCH, /* 测试触摸屏 */ - MS_RADIO, /* 收音机 */ - MS_WM8978_REC, /* 录音机 */ - MS_MEMS, /* MEMS 传感器测试(I2C) 三轴陀螺仪,磁力计,气压计 */ - MS_ETH_WEB, /* 以太网DM9000和DM9161 WEB服务器 */ - - MS_GPS, /* GPS测试 */ - MS_GPRS, /* GPRS模块测试 */ - MS_MP3, /* 校准触摸状态 */ - MS_MASS_STORAGE, /* SD卡,NAND模拟U盘 */ - MS_CAMERA, /* 摄像头 */ - MS_OLED, /* OLED显示器 */ - - MS_AD7606, /* 测试 AD7606 */ - MS_AD7705, /* AD7705模块 */ - MS_ADS1256, /* ADS1256模块 */ - MS_RS485, /* RS485通信 */ - MS_DAC8501, /* DAC8501 模块 */ - MS_DAC8562, /* DAC8562 模块 */ - - MS_RA8875, /* RA8875字库 */ - MS_DSO, /* 示波器 */ - MS_WIFI, /* 串口WIFI */ - MS_CAN, /* CAN网络测试 */ - MS_AD9833, /* AD9833模块 */ - MS_RESERVED, - - MS_RESERVED, - MS_RESERVED, - MS_RESERVED, - MS_RESERVED}; - -static uint8_t s_IconsPageNo = 0; /* 图标页面, 一屏显示不下时,自动排列到第2屏 */ -static uint8_t s_IconsPageMax; /* 图标页面个数 */ -static uint8_t s_IconNumPerPage; /* 每页面最多包含几个图片 */ - -static int16_t s_IconsCursor = 0; /* 选中的图标, -1表示无选中 */ -static uint16_t s_down_x; /* 触笔按下时的x坐标 ; 用于识别滑动方向 */ -static uint16_t s_down_y; /* 触笔按下时的y坐标 ; 用于识别滑动方向 */ - -#define STYLE_COUNT 7 /* 颜色方案个数 */ - -/* 主界面风格 */ -typedef struct -{ - uint16_t *pBmp; /* 背景图片指针,如果是0, 则取单色背景参数 BackColor */ - uint16_t BackColor; /* 背景颜色 */ - uint16_t TextColor; /* 图标文本的颜色 */ -} STYLE_T; - -/* - 背景图片(RGB565格式,存放在NOR Flash - NOR Flash 基地址 0x6400 0000 - - 0x0020 0000 255K字节 480x272_海滩.bin + 0x3FC00 - 0x0023 FC00 255K字节 480x272_树叶.bin - 0x0027 F800 255K字节 480x272_水珠.bin - - 0x002B F400 755K字节 800x480_海滩.bin + 0xBB800 - 0x0037 AC00 755K字节 800x480_树叶.bin - 0x0043 6400 755K字节 800x480_水珠.bin -*/ - -static const STYLE_T s_UI480[STYLE_COUNT] = - { - /* 背景图片, 背景颜色, 图标文字颜色 */ - {0, CL_WHITE, CL_BLACK}, /* 白色背景 */ - {0, RGB(0, 78, 152), CL_WHITE}, /* XP桌面蓝背景 */ - {0, RGB(185, 193, 204), CL_BLACK}, /* 灰色背景 */ - {0, RGB(38, 38, 38), CL_WHITE}, /* 深黑色背景 */ - - {(uint16_t *)(0x64000000 + 0x00200000), 0, CL_BLACK}, /* 480x272 沙滩背景 */ - {(uint16_t *)(0x64000000 + 0x0023FC00), 0, CL_WHITE}, /* 480x272 树叶背景 */ - {(uint16_t *)(0x64000000 + 0x0027F800), 0, CL_BLACK}, /* 480x272 水珠背景 */ -}; - -static const STYLE_T s_UI800[STYLE_COUNT] = - { - /* 背景图片, 背景颜色, 图标文字颜色 */ - {0, CL_WHITE, CL_BLACK}, /* 白色背景 */ - {0, RGB(0, 78, 152), CL_WHITE}, /* XP桌面蓝背景 */ - {0, RGB(185, 193, 204), CL_BLACK}, /* 灰色背景 */ - {0, RGB(38, 38, 38), CL_WHITE}, /* 深黑色背景 */ - - {(uint16_t *)(0x64000000 + 0x002BF400), 0, CL_BLACK}, /* 800x480 沙滩背景 */ - {(uint16_t *)(0x64000000 + 0x0037AC00), 0, CL_WHITE}, /* 800x480 树叶背景 */ - {(uint16_t *)(0x64000000 + 0x00436400), 0, CL_BLACK}, /* 800x480 水珠背景 */ -}; - -static uint16_t s_ColorIndex = 0; /* 当前选中的颜色方案序号 */ - -/* 图标文字颜色 */ -#define MAIN_TEXT_COLOR ((g_LcdWidth == 480) ? s_UI480[s_ColorIndex].TextColor : s_UI800[s_ColorIndex].TextColor) - -static void DispBackground(void); -static void ArrayIcon(void); -static void DispTopBar(void); -static void DispBottomBar(void); - -/* -********************************************************************************************************* -* 函 数 名: MainMenu -* 功能说明: 主界面 -* 形 参:无 -* 返 回 值: 状态字 -********************************************************************************************************* -*/ -uint8_t MainMenu(void) -{ -#if 0 - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - FONT_T tIconFont; /* 定义一个字体结构体变量,用于图标文本 */ - - int16_t tpX, tpY; - uint16_t i; - - DispTopBar(); /* 显示顶部栏 */ - DispBottomBar(); /* 显示底部栏 */ - DispBackground(); /* 显示图标背景 */ - - /* 设置字体参数 */ - { - tIconFont.FontCode = FC_ST_12; /* 字体代码 16点阵 */ - tIconFont.FrontColor = MAIN_TEXT_COLOR; /* 字体颜色 */ - tIconFont.BackColor = CL_MASK; /* 文字背景颜色 */ - tIconFont.Space = 1; /* 文字间距,单位 = 像素 */ - } - - //s_IconsPageNo = 0; /* 图标页面号,不要清零。 */ - - fRefresh = 1; /* 1表示需要刷新LCD */ - while (g_MainStatus == MS_MAIN_MENU) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - /* 显示图标阵列 */ - ArrayIcon(); /* 排列图标 */ - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - /* 绘制图标阵列 */ - { - s_IconsCursor = -1; /* -1 表示当前没有图标被激活点亮 */ - - for (i = s_IconNumPerPage * s_IconsPageNo; - i < s_IconNumPerPage * s_IconsPageNo + s_IconNumPerPage && i < ICONS_COUNT; - i++) - { - if (TOUCH_InRect(tpX, tpY, s_tMainIcons[i].Left, s_tMainIcons[i].Top, - s_tMainIcons[i].Height, s_tMainIcons[i].Width)) - { - s_IconsCursor = i; - LCD_DrawIcon32(&s_tMainIcons[i], &tIconFont, 1); /* 0 表示正常显示, 1表示选中 */ - } - } - s_down_x = tpX; - s_down_y = tpY; - } - break; - - case TOUCH_MOVE: /* 触笔移动事件 */ - if (s_IconsCursor >= 0) - { - if (TOUCH_InRect(tpX, tpY, s_tMainIcons[s_IconsCursor].Left, s_tMainIcons[s_IconsCursor].Top, - s_tMainIcons[s_IconsCursor].Height, s_tMainIcons[s_IconsCursor].Width)) - { - ; - } - else - { - LCD_DrawIcon32(&s_tMainIcons[s_IconsCursor], &tIconFont, 0); /* 0 表示正常显示, 1表示选中 */ - s_IconsCursor = -1; - } - } - - if (s_down_x > 0) - { - if (tpX - s_down_x > 50) - { - /* 向右滑动 */ - if (s_IconsPageNo > 0) - { - s_IconsPageNo--; - DispBackground(); - ArrayIcon(); /* 排列图标 */ - } - s_down_x = 0; - } - else if (tpX - s_down_x < -50) - { - /* 向左滑动 */ - if (s_IconsPageNo < s_IconsPageMax - 1) - { - s_IconsPageNo++; - DispBackground(); - ArrayIcon(); /* 排列图标 */ - } - s_down_x = 0; - } - - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (s_IconsCursor >= 0) - { - /* 按下时的坐标和弹起时坐标都在图标内才算有效点击 */ - if (TOUCH_InRect(tpX, tpY, s_tMainIcons[s_IconsCursor].Left, s_tMainIcons[s_IconsCursor].Top, - s_tMainIcons[s_IconsCursor].Height, s_tMainIcons[s_IconsCursor].Width) - && TOUCH_InRect(s_down_x, s_down_y, s_tMainIcons[s_IconsCursor].Left, s_tMainIcons[s_IconsCursor].Top, - s_tMainIcons[s_IconsCursor].Height, s_tMainIcons[s_IconsCursor].Width)) - { - g_MainStatus = s_RetStatus[s_IconsCursor]; /* 返回程序状态 */ - } - else - { - LCD_DrawIcon32(&s_tMainIcons[s_IconsCursor], &tIconFont, 0); /* 0 表示正常显示, 1表示选中 */ - s_IconsCursor = -1; - } - } - break; - - default: - break; - } - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case JOY_DOWN_L: /* 遥杆右键 2014-08-22 */ - return MS_RA8875; /* 进入RA8875界面 */ - - case JOY_DOWN_U: /* 遥杆上键 2014-08-22 */ - return MS_TEST_TOUCH; /* 进入触摸界面 */ - - case JOY_DOWN_OK: /* 遥感OK键 */ - if (++g_LcdDirection > 3) - { - g_LcdDirection = 0; - } - /* 显示方向代码 0 横屏正常, 1=横屏180度翻转, 2=竖屏, 3=竖屏180度翻转 */ - LCD_SetDirection(g_LcdDirection); - - DispTopBar(); /* 显示顶部栏 */ - DispBottomBar(); /* 显示底部栏 */ - DispBackground(); /* 显示背景 */ - fRefresh = 1; - break; - - case KEY_DOWN_K3: /* K3键 */ - return MS_CALIBRATION; /* 进入触摸界面 */ - //break; - - case KEY_DOWN_K1: /* K1键 */ - if (++s_ColorIndex >= STYLE_COUNT) - { - s_ColorIndex = 0; - } - /* 重新绘制背景 */ - { - DispBackground(); /* 显示背景 */ - - /* 设置字体参数 */ - { - tIconFont.FontCode = FC_ST_12; /* 字体代码 16点阵 */ - tIconFont.FrontColor = MAIN_TEXT_COLOR; /* 字体颜色 */ - tIconFont.BackColor = CL_MASK; /* 文字背景颜色 */ - tIconFont.Space = 1; /* 文字间距,单位 = 像素 */ - } - } - fRefresh = 1; - break; - - default: - break; - } - } - } -#endif - return 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispTopBar -* 功能说明: 显示抬头栏(标题栏) -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispTopBar(void) -{ - FONT_T tFont; /* 定义一个字体结构体变量,用于设置字体参数 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BAR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - LCD_Fill_Rect(0, 0, TOP_BAR_H, g_LcdWidth, CL_BAR); - LCD_DispStr(5, 2, VER_INFO, &tFont); /* 显示软件版本信息 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispBottomBar -* 功能说明: 显示底部栏 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispBottomBar(void) -{ - FONT_T tFont; /* 定义一个字体结构体变量,用于设置字体参数 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BAR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - LCD_Fill_Rect(0, g_LcdHeight - BOTTOM_BAR_H, BOTTOM_BAR_H, g_LcdWidth, CL_BAR); - LCD_DispStr(5, g_LcdHeight - 18, KEY_INFO, &tFont); /* 显示按键操作提示 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispBackground -* 功能说明: 显示界面背景 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispBackground(void) -{ -#if 1 - if ((g_LcdWidth == 480) && (g_LcdHeight == 272)) /* 480 x 272 */ - { - if (s_UI480[s_ColorIndex].pBmp == 0) - { - //LCD_ClrScr(s_UI480[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - LCD_Fill_Rect(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI480[s_ColorIndex].BackColor); - } - else - { - LCD_DrawBMP(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI480[s_ColorIndex].pBmp); - } - } - else if ((g_LcdWidth == 480) && (g_LcdHeight == 320)) /* 480 x 320 */ - { - if (s_UI480[s_ColorIndex].pBmp == 0) - { - //LCD_ClrScr(s_UI800[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - LCD_Fill_Rect(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI800[s_ColorIndex].BackColor); - } - else - { - LCD_DrawBMP(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI800[s_ColorIndex].pBmp); - } - } - else /* 800 x 480 */ - { - if (s_UI800[s_ColorIndex].pBmp == 0) - { - //LCD_ClrScr(s_UI800[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - LCD_Fill_Rect(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI800[s_ColorIndex].BackColor); - } - else - { - LCD_DrawBMP(0, TOP_BAR_H, g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H, g_LcdWidth, s_UI800[s_ColorIndex].pBmp); - } - } -#else - if ((g_LcdWidth == 480) && (g_LcdHeight == 272)) /* 480 x 272 */ - { - if (s_UI480[s_ColorIndex].pBmp == 0) - { - LCD_ClrScr(s_UI480[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - } - else - { - LCD_DrawBMP(0, 0, g_LcdHeight, g_LcdWidth, s_UI480[s_ColorIndex].pBmp); - } - } - else if ((g_LcdWidth == 480) && (g_LcdHeight == 320)) /* 480 x 320 */ - { - if (s_UI480[s_ColorIndex].pBmp == 0) - { - LCD_ClrScr(s_UI800[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - } - else - { - LCD_DrawBMP(0, 0, g_LcdHeight, g_LcdWidth, s_UI800[s_ColorIndex].pBmp); - } - } - else /* 800 x 480 */ - { - if (s_UI800[s_ColorIndex].pBmp == 0) - { - LCD_ClrScr(s_UI800[s_ColorIndex].BackColor); /* 清屏, 填充单色 */ - } - else - { - LCD_DrawBMP(0, 0, g_LcdHeight, g_LcdWidth, s_UI800[s_ColorIndex].pBmp); - } - } -#endif -} - -/* -********************************************************************************************************* -* 函 数 名: ArrayIcon -* 功能说明: 排列图标 s_tMainIcons 的坐标, 全局变量 s_IconsPageNo 表示页号 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void ArrayIcon(void) -{ - uint16_t x; - uint16_t y; - uint8_t h_count; /* 水平方向图标排列个数 */ - uint8_t v_count; /* 垂直方向图标排列个数 */ - uint16_t icon_index; /* 图标索引 */ - uint16_t icons_left; /* 图标阵列 X 坐标 */ - uint16_t icons_top; /* 图标阵列 Y 坐标 */ - uint8_t m, n; - FONT_T tIconFont; - - tIconFont.FontCode = FC_ST_12; /* 字体代码 16点阵 */ - tIconFont.FrontColor = MAIN_TEXT_COLOR; /* 字体颜色 */ - tIconFont.BackColor = CL_MASK; /* 文字背景颜色 */ - tIconFont.Space = 1; /* 文字间距,单位 = 像素 */ - - h_count = g_LcdWidth / ICON_STEP_X; - v_count = (g_LcdHeight - TOP_BAR_H - BOTTOM_BAR_H) / ICON_STEP_Y; - - s_IconNumPerPage = h_count * v_count; /* 每个页面包含的图标个数 */ - - /* 计算需要几个图片页面 */ - s_IconsPageMax = (ICONS_COUNT - 1) / (h_count * v_count) + 1; - - icons_left = (g_LcdWidth - (h_count - 1) * ICON_STEP_X - ICON_WIDTH) / 2; - icons_top = ICON_TOP; - - icon_index = s_IconsPageNo * h_count * v_count; - - x = icons_left; - y = icons_top; - for (m = 0; m < v_count; m++) - { - x = icons_left; - y = icons_top + m * ICON_STEP_Y; - for (n = 0; n < h_count; n++) - { - s_tMainIcons[icon_index].Left = x; - s_tMainIcons[icon_index].Top = y; - - LCD_DrawIcon32(&s_tMainIcons[icon_index], &tIconFont, 0); /* 0 表示正常显示, 1表示选中 */ - - icon_index++; - if (icon_index >= ICONS_COUNT) - { - break; - } - x += ICON_STEP_X; - } - if (icon_index >= ICONS_COUNT) - { - break; - } - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_mems.c b/User/app/src/old/form_mems.c deleted file mode 100755 index f88e0a2..0000000 --- a/User/app/src/old/form_mems.c +++ /dev/null @@ -1,662 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : MEMS 传感器测试(I2C) 三轴陀螺仪,磁力计,气压计, 光照度传感器 -* 文件名称 : mems_test.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_mems.h" - -/* 4个框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H 120 -#define BOX1_W 190 -#define BOX1_TEXT "MPU6050 陀螺仪" - -#define BOX2_X (BOX1_X + BOX1_W + 5) -#define BOX2_Y BOX1_Y -#define BOX2_H BOX1_H -#define BOX2_W 250 -#define BOX2_TEXT "磁力计" - -#define BOX3_X BOX1_X -#define BOX3_Y (BOX1_Y + BOX1_H + 5) -#define BOX3_H 52 -#define BOX3_W 220 -#define BOX3_TEXT "BMP085 气压计和温度" - -#define BOX4_X (BOX1_X + BOX3_W + 5) -#define BOX4_Y (BOX1_Y + BOX1_H + 5) -#define BOX4_H 52 -#define BOX4_W 220 -#define BOX4_TEXT "BH1750 光照度" - -#define BOX5_X BOX1_X -#define BOX5_Y (BOX3_Y + BOX3_H + 5) -#define BOX5_H 52 -#define BOX5_W 220 -#define BOX5_TEXT "DS18B20 温度传感器" - -#define BOX6_X (BOX1_X + BOX5_W + 5) -#define BOX6_Y (BOX3_Y + BOX3_H + 5) -#define BOX6_H 52 -#define BOX6_W 220 -#define BOX6_TEXT "DHT11 温湿度传感器" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BUTTON_RET_ID 0 -#define BUTTON_RET_H 32 -#define BUTTON_RET_W 60 -#define BUTTON_RET_X (g_LcdWidth - BUTTON_RET_W - 4) -#define BUTTON_RET_Y (g_LcdHeight - BUTTON_RET_H - 4) -#define BUTTON_RET_TEXT "返回" - -static void DispInitFace(void); -static void DispMPU6050(void); -static void DispHMC5833L(void); -static void DispBMP085(void); -static void DispBH1750(float _value); -static void DispDS18B20(void); -static void DispDHT11(void); - -static void DispButton(uint8_t _id, uint8_t _focus); - -static uint8_t s_use_dht11 = 0; /* 用来自动选择 DS18B20和 DHT11 */ - -/* -********************************************************************************************************* -* 函 数 名: TestMems -* 功能说明: 测试陀螺仪,加速度计,磁力计,气压计,光照度 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestMems(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - // uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - uint8_t fQuit = 0; - - int16_t tpX, tpY; - - DispInitFace(); - - // fRefresh = 1; - - /* 重新配置1次BMP085 */ - bsp_InitBMP085(); - BMP085_ReadTempPress(); /* 读取结果存放在全局变量 */ - - if (i2c_CheckDevice(HMC5883L_SLAVE_ADDRESS) == 0) - { - bsp_InitHMC5883L(); - } - - bsp_InitMPU6050(); - - bsp_InitDS18B20(); - - /* 进入主程序循环体 */ - bsp_StartAutoTimer(0, 250); /* 陀螺仪 加速度 磁力计 定时采样周期 */ - bsp_DelayMS(125); - bsp_StartAutoTimer(1, 1000); /* 气压计和光照度定时采样周期 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (bsp_CheckTimer(0)) - { - MPU6050_ReadData(); - - DispMPU6050(); - - HMC5883L_ReadData(); - DispHMC5833L(); - - DispDS18B20(); /* 读取并显示DS18B20的数据 */ - } - - if (bsp_CheckTimer(1)) - { - BMP085_ReadTempPress(); - DispBMP085(); - - DispBH1750(BH1750_GetLux()); - - DispDHT11(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - DispButton(BUTTON_RET_ID, 1); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - DispButton(BUTTON_RET_ID, 0); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - DispButton(BUTTON_RET_ID, 0); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键切换音频格式,在下次开始录音和放音时有效 */ - break; - - case KEY_DOWN_K2: /* K2键按下,录音 */ - break; - - case KEY_DOWN_K3: /* K3键按下,放音 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - bsp_StopTimer(0); - bsp_StopTimer(1); -} - -/* -********************************************************************************************************* -* 函 数 名: DispMPU6050 -* 功能说明: 显示MPU6050输出数据 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispMPU6050(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - uint8_t ucLineCap = 17; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = BOX1_X + 5; - y = BOX1_Y + 18; - - sprintf(buf, "GYRO_X = %6d", g_tMPU6050.GYRO_X); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "GYRO_Y = %6d", g_tMPU6050.GYRO_Y); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "GYRO_Z = %6d", g_tMPU6050.GYRO_Z); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Accel_X = %6d", g_tMPU6050.Accel_X); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Accel_Y = %6d", g_tMPU6050.Accel_Y); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Accel_Z = %6d", g_tMPU6050.Accel_Z); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; -} - -/* -********************************************************************************************************* -* 函 数 名: DispHMC5833L -* 功能说明: 显示HMC5833L输出的数据 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispHMC5833L(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - uint8_t ucLineCap = 17; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = BOX2_X + 5; - y = BOX2_Y + 18; - - sprintf(buf, " 当前 | 最小, 最大,范围"); - tFont.FrontColor = CL_GREY; /* 红色 异常*/ - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "X =%5d|%5d,%5d,%5d", g_tMag.X, g_tMag.X_Min, g_tMag.X_Max, - g_tMag.X_Max - g_tMag.X_Min); - if (g_tMag.X_Max - g_tMag.X_Min < 500) - { - tFont.FrontColor = CL_RED; /* 红色 异常*/ - } - else - { - tFont.FrontColor = CL_BLACK; /* 白色 正常 */ - } - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Y =%5d|%5d,%5d,%5d", g_tMag.Y, g_tMag.Y_Min, g_tMag.Y_Max, - g_tMag.Y_Max - g_tMag.Y_Min); - if (g_tMag.Y_Max - g_tMag.Y_Min < 500) - { - tFont.FrontColor = CL_RED; /* 红色 异常*/ - } - else - { - tFont.FrontColor = CL_BLACK; /* 白色 正常 */ - } - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Z =%5d|%5d,%5d,%5d", g_tMag.Z, g_tMag.Z_Min, g_tMag.Z_Max, - g_tMag.Z_Max - g_tMag.Z_Min); - if (g_tMag.Z_Max - g_tMag.Z_Min < 500) - { - tFont.FrontColor = CL_RED; /* 红色 异常*/ - } - else - { - tFont.FrontColor = CL_BLACK; /* 白色 正常 */ - } - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - /* 显示配置寄存器和ID寄存器 */ - y += 3; - tFont.FrontColor = CL_GREY; /* 字体颜色 */ - - sprintf(buf, "CFG_A = 0x%02X,CFG_B = 0x%02X", g_tMag.CfgRegA, g_tMag.CfgRegB); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "Mode = 0x%02d,ID = %s", g_tMag.ModeReg, (char *)g_tMag.IDReg); - LCD_DispStr(x, y, buf, &tFont); -} - -/* -********************************************************************************************************* -* 函 数 名: DispBMP085 -* 功能说明: 显示BMP085输出的数据 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispBMP085(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - uint8_t ucLineCap = 17; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = BOX3_X + 5; - y = BOX3_Y + 18; - - /* 温度值, 单位 0.1摄氏度 */ - /* 压力值, 单位 Pa */ - sprintf(buf, "环境温度 = %3d.%d℃", g_tBMP085.Temp / 10, g_tBMP085.Temp % 10); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; - - sprintf(buf, "大气压力 = %3d.%03dKPa", g_tBMP085.Press / 1000, g_tBMP085.Press % 1000); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; -} - -/* -********************************************************************************************************* -* 函 数 名: DispBH1750 -* 功能说明: 显示BH1750输出的数据 -* 形 参: _value : 浮点格式的光照度值 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispBH1750(float _value) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - uint8_t ucLineCap = 17; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = BOX4_X + 5; - y = BOX4_Y + 18; - - sprintf(buf, "光照度 = %6.2f lux", _value); - LCD_DispStr(x, y, buf, &tFont); - y += ucLineCap; -} - -/* -********************************************************************************************************* -* 函 数 名: DispDS18B20 -* 功能说明: 显示DS18B20输出的数据 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDS18B20(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - - if (s_use_dht11 == 1) - { - /* 在DS18B20程序中 暂时屏蔽, 避免印象 DHT11 */ - return; - } - - /* 读 ROM ID */ - { - uint8_t id[8]; - uint8_t ret; - uint8_t i; - - x = BOX5_X + 5; - y = BOX5_Y + 18; - - ret = DS18B20_ReadID(id); - - if (ret == 0) - { - /* 设置字体参数 红色 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_RED; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - } - else - { - /* 设置字体参数 蓝色 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - } - - sprintf(buf, "id = "); - for (i = 0; i < 8; i++) - { - sprintf(&buf[strlen(buf)], "%02X", id[i]); - if (i == 3) - { - sprintf(&buf[strlen(buf)], " "); - } - } - LCD_DispStr(x, y, buf, &tFont); - } - - { - int16_t reg; - - reg = DS18B20_ReadTempReg(); - sprintf(buf, "reg = 0x%04X -> %-4.04f℃ ", (uint16_t)reg, (float)reg / 16); - - x = BOX5_X + 5; - y += 17; - - /* 设置字体参数 蓝色 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - LCD_DispStr(x, y, buf, &tFont); - - LCD_DispStr(x, y + 26, "DS18B20和DHT11不能同时接入开发板", &tFont); - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispDHT11 -* 功能说明: 显示DHT11输出的数据 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispDHT11(void) -{ - FONT_T tFont; - char buf[128]; - uint16_t x, y; - - DHT11_T tDHT; - uint8_t ret; - - x = BOX6_X + 5; - y = BOX6_Y + 18; - - ret = DHT11_ReadData(&tDHT); - if (ret == 1) - { - /* 设置字体参数 蓝色 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_BLUE; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - sprintf(buf, "湿度 %d%%,温度 %d℃ ", tDHT.Hum, tDHT.Temp); - LCD_DispStr(x, y, buf, &tFont); - - s_use_dht11 = 1; /* 在DS18B20程序中 暂时屏蔽 */ - } - else - { - /* 设置字体参数 红色 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_RED; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - sprintf(buf, "未发现DHT11 "); - LCD_DispStr(x, y, buf, &tFont); - - s_use_dht11 = 0; /* 在DS18B20程序中 取消屏蔽 */ - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispInitFace -* 功能说明: 显示初始界面 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispInitFace(void) -{ - FONT_T tFontBox; /* 定义一个字体结构体变量,用于设置字体参数 */ - GROUP_T tBox; - - LCD_ClrScr(CL_BTN_FACE); /* 清屏,背景蓝色 */ - - /* 设置字体参数 */ - { - /* 分组框字体 */ - tFontBox.FontCode = FC_ST_16; - tFontBox.BackColor = CL_BTN_FACE; - tFontBox.FrontColor = CL_BLACK; - tFontBox.Space = 0; - } - - /* 显示分组框 */ - { - tBox.Font = &tFontBox; - - tBox.Left = BOX1_X; - tBox.Top = BOX1_Y; - tBox.Height = BOX1_H; - tBox.Width = BOX1_W; - tBox.pCaption = BOX1_TEXT; - LCD_DrawGroupBox(&tBox); - - tBox.Left = BOX2_X; - tBox.Top = BOX2_Y; - tBox.Height = BOX2_H; - tBox.Width = BOX2_W; - tBox.pCaption = BOX2_TEXT; - LCD_DrawGroupBox(&tBox); - - tBox.Left = BOX3_X; - tBox.Top = BOX3_Y; - tBox.Height = BOX3_H; - tBox.Width = BOX3_W; - tBox.pCaption = BOX3_TEXT; - LCD_DrawGroupBox(&tBox); - - tBox.Left = BOX4_X; - tBox.Top = BOX4_Y; - tBox.Height = BOX4_H; - tBox.Width = BOX4_W; - tBox.pCaption = BOX4_TEXT; - LCD_DrawGroupBox(&tBox); - - tBox.Left = BOX5_X; - tBox.Top = BOX5_Y; - tBox.Height = BOX5_H; - tBox.Width = BOX5_W; - tBox.pCaption = BOX5_TEXT; - LCD_DrawGroupBox(&tBox); - - tBox.Left = BOX6_X; - tBox.Top = BOX6_Y; - tBox.Height = BOX6_H; - tBox.Width = BOX6_W; - tBox.pCaption = BOX6_TEXT; - LCD_DrawGroupBox(&tBox); - } - - DispButton(BUTTON_RET_ID, 0); -} - -/* -********************************************************************************************************* -* 函 数 名: DispButton -* 功能说明: 显示指定位置的按钮 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispButton(uint8_t _id, uint8_t _focus) -{ - FONT_T tFontBtn; /* 定义一个字体结构体变量,用于设置字体参数 */ - BUTTON_T tBtn; - - /* 设置字体参数 */ - { - /* 按钮字体 */ - tFontBtn.FontCode = FC_ST_16; - tFontBtn.BackColor = CL_MASK; /* 透明色 */ - tFontBtn.FrontColor = CL_BLACK; - tFontBtn.Space = 0; - } - - tBtn.Font = &tFontBtn; - - switch (_id) - { - case BUTTON_RET_ID: - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = _focus; - tBtn.pCaption = BUTTON_RET_TEXT; - break; - - default: - return; - } - - LCD_DrawButton(&tBtn); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_mp3_player.c b/User/app/src/old/form_mp3_player.c deleted file mode 100755 index 322967c..0000000 --- a/User/app/src/old/form_mp3_player.c +++ /dev/null @@ -1,799 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : MP3播放器界面 -* 文件名称 : "mp3_player.h" -* 版 本 : V1.1 -* 说 明 : 测试VS1053 MP3模块 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-02-01 armfly 首发 -* V1.1 2015-10-17 armfly f_opendir后必须f_closedir -* -* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_mp3_player.h" -#include "ff.h" /* FatFS 文件系统头文件 */ -#include "ff_gen_drv.h" -#include "sd_diskio_dma.h" - -/* 自动播放指定磁盘指定目录下的MP3文件 */ -#define MP3_FOLDER "/Music" /* MP3文件夹, 不含磁盘盘符 */ - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - LABEL_T Label7; - LABEL_T Label8; - - LABEL_T Label9; - BUTTON_T BtnRet; -} FormMP3_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "MP3模块测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "芯片型号 :" - -#define LABEL2_X (LABEL1_X + 90) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT " " - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "输出音量 :" - -#define LABEL4_X (LABEL3_X + 90) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT " " - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "播放进度 : " - -#define LABEL6_X (LABEL5_X + 90) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT " " - -#define LABEL7_X (LABEL1_X) -#define LABEL7_Y (LABEL1_Y + 20 * 3) -#define LABEL7_TEXT "文件名 : " - -#define LABEL8_X (LABEL7_X + 90) -#define LABEL8_Y LABEL7_Y -#define LABEL8_TEXT "---" - -#define LABEL9_X LABEL1_X -#define LABEL9_Y 120 -#define LABEL9_TEXT "请将MP3文件放到SD卡Music目录下" - -#define SONG_LIST_MAX 10 /* 歌曲列表最大数目 */ - -static void InitFormMP3(void); -static void DispFormMP3(void); -static void FillSongList(void); -static void MP3HardInit(void); -static void ViewDir(char *_path); -static uint8_t Mp3Pro(void); -static void Mp3DispStatus(void); - -FormMP3_T *FormMP3; - -MP3_T g_tMP3; -PLAY_LIST_T g_tPlayList[SONG_LIST_MAX]; - -/* 访问Fatfs用到的全局变量 */ -FATFS g_fs; -FIL g_Mp3File; - -char DiskPath[4]; /* 保存FatFS 磁盘路径 */ - -/* -********************************************************************************************************* -* 函 数 名: ReserveFunc -* 功能说明: 保留功能。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void MP3Player(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormMP3_T form; - uint8_t ucRefresh; - uint8_t ucNextSong; - - FormMP3 = &form; - - InitFormMP3(); - DispFormMP3(); - MP3HardInit(); /* 配置VS1053B硬件和WM8978硬件 */ - - //FATFS_LinkDriver(&USBH_Driver, DiskPath); - FATFS_LinkDriver(&SD_Driver, DiskPath); - - /* 挂载文件系统 */ - if (f_mount(&g_fs, DiskPath, 0) != FR_OK) - { - printf("f_mount文件系统失败"); - } - -#if 1 - /* 打印NAND Flash 根目录和MP3目录下的文件 */ - { - char path[60]; - - sprintf(path, "%s", DiskPath); /* 根目录 */ - ViewDir(path); - - sprintf(path, "%s%s", DiskPath, MP3_FOLDER); /* 音乐目录 */ - ViewDir(path); - } -#endif - - FillSongList(); /* 搜索NAND Flash 根目录下的MP3文件,并填充到播放列表数组 */ - - ucRefresh = 1; - g_tMP3.ucPauseEn = 0; /* 缺省开始播放 */ - - if (g_tMP3.ListCount > 0) - { - ucNextSong = 1; /* 定位下一首歌曲的标志 */ - } - else - { - ucNextSong = 0; - } - g_tMP3.ListIndex = 0; - bsp_StartAutoTimer(0, 100); /* 100ms 刷新进度条 */ - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - /* 打开歌曲文件 */ - if (ucNextSong == 1) - { - ucNextSong = 0; - - /* 关闭上一个文件*/ - f_close(&g_Mp3File); - - printf("\r\n\r\n"); /* 换一行显示 */ - - /* 打开MUSIC目录下的mp3 文件 */ - { - char FileName[256]; - FRESULT result; - - sprintf(FileName, "%s%s/%s", DiskPath, MP3_FOLDER, g_tPlayList[g_tMP3.ListIndex].FileName); - result = f_open(&g_Mp3File, FileName, FA_OPEN_EXISTING | FA_READ); - if (result != FR_OK) - { - printf("Open MP3 file Error, %s\r\n", g_tPlayList[g_tMP3.ListIndex].FileName); - FormMP3->Label8.pCaption = "打开MP3文件失败"; - LCD_DrawLabel(&FormMP3->Label8); - } - else - { - printf("正在播放: %s\r\n", g_tPlayList[g_tMP3.ListIndex].FileName); - - /* 显示文件名 */ - FormMP3->Label8.pCaption = g_tPlayList[g_tMP3.ListIndex].FileName; - LCD_DrawLabel(&FormMP3->Label8); - } - } - - g_tMP3.uiProgress = 0; /* 进度 */ - } - - if (g_tMP3.ucPauseEn == 0) - { - if (Mp3Pro() == 1) - { - /* 歌曲播放完毕,自动切换到下一首歌 */ - - if (g_tMP3.ListCount > 0) - { - /* 模拟一个摇杆右键按下,执行换歌操作 */ - bsp_PutKey(JOY_DOWN_R); - } - } - } - - /* 刷新状态栏 */ - if ((ucRefresh == 1) || (bsp_CheckTimer(0))) - { - ucRefresh = 0; - Mp3DispStatus(); /* 显示当前状态,音量等 */ - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormMP3->BtnRet.Focus = 1; - LCD_DrawButton(&FormMP3->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormMP3->BtnRet.Focus = 0; - LCD_DrawButton(&FormMP3->BtnRet); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormMP3->BtnRet.Focus = 0; - LCD_DrawButton(&FormMP3->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 */ - if (g_tMP3.ucPauseEn == 0) - { - g_tMP3.ucPauseEn = 1; - } - else - { - g_tMP3.ucPauseEn = 0; - } - ucRefresh = 1; - break; - - case KEY_DOWN_K2: /* K2键按下 */ - f_lseek(&g_Mp3File, 0); /* 修改文件当前指针到文件头, 从头开始播放 */ - g_tMP3.uiProgress = 0; /* 进度 */ - ucRefresh = 1; - break; - - case KEY_DOWN_K3: /* K3键按下 */ - if (g_tMP3.ucMuteOn == 1) - { - g_tMP3.ucMuteOn = 0; - VS1053_SetBASS(0, 0, 0, 0); /* 原音,低音不增强 */ - } - else - { - g_tMP3.ucMuteOn = 1; - VS1053_SetBASS(0, 0, 10, 100); /* 设置低音增强(截止频率100Hz),高音不变 */ - } - ucRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - if (g_tMP3.ucVolume > VS_VOL_MIN) - { - g_tMP3.ucVolume--; - VS1053_SetVolume(g_tMP3.ucVolume); - ucRefresh = 1; - } - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - if (g_tMP3.ucVolume < VS_VOL_MAX) - { - g_tMP3.ucVolume++; - VS1053_SetVolume(g_tMP3.ucVolume); - ucRefresh = 1; - } - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (g_tMP3.ListIndex > 0) - { - g_tMP3.ListIndex--; /* 前一首歌 */ - } - else - { - g_tMP3.ListIndex = g_tMP3.ListCount - 1; /* 循环 */ - } - ucRefresh = 1; - ucNextSong = 1; /* 打开下一首歌曲 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (g_tMP3.ListIndex < g_tMP3.ListCount - 1) - { - g_tMP3.ListIndex++; /* 下一首歌 */ - } - else - { - g_tMP3.ListIndex = 0; /* 循环 */ - } - ucRefresh = 1; - ucNextSong = 1; /* 打开下一首歌曲 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - ucRefresh = 1; - break; - - default: - break; - } - } - } - - bsp_StopTimer(0); /* 关闭自动定时器 */ - - /* 关闭文件*/ - f_close(&g_Mp3File); - - /* 卸载文件系统 */ - f_mount(NULL, DiskPath, 0); - - FATFS_UnLinkDriver(DiskPath); /* 卸载驱动 */ -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormMP3 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormMP3(void) -{ - /* 分组框标题字体 */ - FormMP3->FontBox.FontCode = FC_ST_16; - FormMP3->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormMP3->FontBox.FrontColor = CL_BLACK; - FormMP3->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormMP3->FontBlack.FontCode = FC_ST_16; - FormMP3->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormMP3->FontBlack.FrontColor = CL_BLACK; - FormMP3->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormMP3->FontBlue.FontCode = FC_ST_16; - FormMP3->FontBlue.BackColor = CL_BTN_FACE; - FormMP3->FontBlue.FrontColor = CL_BLUE; - FormMP3->FontBlue.Space = 0; - - /* 按钮字体 */ - FormMP3->FontBtn.FontCode = FC_ST_16; - FormMP3->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormMP3->FontBtn.FrontColor = CL_BLACK; - FormMP3->FontBtn.Space = 0; - - /* 分组框 */ - FormMP3->Box1.Left = BOX1_X; - FormMP3->Box1.Top = BOX1_Y; - FormMP3->Box1.Height = BOX1_H; - FormMP3->Box1.Width = BOX1_W; - FormMP3->Box1.pCaption = BOX1_TEXT; - FormMP3->Box1.Font = &FormMP3->FontBox; - - /* 静态标签 */ - FormMP3->Label1.Left = LABEL1_X; - FormMP3->Label1.Top = LABEL1_Y; - FormMP3->Label1.MaxLen = 0; - FormMP3->Label1.pCaption = LABEL1_TEXT; - FormMP3->Label1.Font = &FormMP3->FontBlack; - - FormMP3->Label3.Left = LABEL3_X; - FormMP3->Label3.Top = LABEL3_Y; - FormMP3->Label3.MaxLen = 0; - FormMP3->Label3.pCaption = LABEL3_TEXT; - FormMP3->Label3.Font = &FormMP3->FontBlack; - - FormMP3->Label5.Left = LABEL5_X; - FormMP3->Label5.Top = LABEL5_Y; - FormMP3->Label5.MaxLen = 0; - FormMP3->Label5.pCaption = LABEL5_TEXT; - FormMP3->Label5.Font = &FormMP3->FontBlack; - - FormMP3->Label7.Left = LABEL7_X; - FormMP3->Label7.Top = LABEL7_Y; - FormMP3->Label7.MaxLen = 0; - FormMP3->Label7.pCaption = LABEL7_TEXT; - FormMP3->Label7.Font = &FormMP3->FontBlack; - - FormMP3->Label9.Left = LABEL9_X; - FormMP3->Label9.Top = LABEL9_Y; - FormMP3->Label9.MaxLen = 0; - FormMP3->Label9.pCaption = LABEL9_TEXT; - FormMP3->Label9.Font = &FormMP3->FontBlack; - - /* 动态标签 */ - FormMP3->Label2.Left = LABEL2_X; - FormMP3->Label2.Top = LABEL2_Y; - FormMP3->Label2.MaxLen = 0; - FormMP3->Label2.pCaption = LABEL2_TEXT; - FormMP3->Label2.Font = &FormMP3->FontBlue; - - FormMP3->Label4.Left = LABEL4_X; - FormMP3->Label4.Top = LABEL4_Y; - FormMP3->Label4.MaxLen = 0; - FormMP3->Label4.pCaption = LABEL4_TEXT; - FormMP3->Label4.Font = &FormMP3->FontBlue; - - FormMP3->Label6.Left = LABEL6_X; - FormMP3->Label6.Top = LABEL6_Y; - FormMP3->Label6.MaxLen = 0; - FormMP3->Label6.pCaption = LABEL6_TEXT; - FormMP3->Label6.Font = &FormMP3->FontBlue; - - FormMP3->Label8.Left = LABEL8_X; - FormMP3->Label8.Top = LABEL8_Y; - FormMP3->Label8.MaxLen = 0; - FormMP3->Label8.pCaption = LABEL8_TEXT; - FormMP3->Label8.Font = &FormMP3->FontBlue; - - /* 按钮 */ - FormMP3->BtnRet.Left = BTN_RET_X; - FormMP3->BtnRet.Top = BTN_RET_Y; - FormMP3->BtnRet.Height = BTN_RET_H; - FormMP3->BtnRet.Width = BTN_RET_W; - FormMP3->BtnRet.pCaption = BTN_RET_TEXT; - FormMP3->BtnRet.Font = &FormMP3->FontBtn; - FormMP3->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormMP3 -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormMP3(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormMP3->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormMP3->Label1); - LCD_DrawLabel(&FormMP3->Label3); - LCD_DrawLabel(&FormMP3->Label5); - LCD_DrawLabel(&FormMP3->Label7); - - LCD_DrawLabel(&FormMP3->Label9); - - /* 动态标签 */ - LCD_DrawLabel(&FormMP3->Label2); - LCD_DrawLabel(&FormMP3->Label4); - LCD_DrawLabel(&FormMP3->Label6); - LCD_DrawLabel(&FormMP3->Label8); - - /* 按钮 */ - LCD_DrawButton(&FormMP3->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: MP3HardInit -* 功能说明: 配置MP3播放相关的硬件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void MP3HardInit(void) -{ - /* 配置VS1053硬件 */ - { - VS1053_Init(); - - /* 等待芯片内部操作完成 */ - if (VS1053_WaitTimeOut()) - { - /* 如果没有插VS1053B模块,DREQ口线将返回低电平,这是一种异常情况 */ - FormMP3->Label2.pCaption = "没有检测到MP3模块硬件"; - LCD_DrawLabel(&FormMP3->Label2); /* 显示芯片型号 */ - - return; - } - - VS1053_SoftReset(); - - /* 打印MP3解码芯片型号 */ - { - char *pModel; - - switch (VS1053_ReadChipID()) - { - case VS1001: - pModel = "VS1001"; - break; - - case VS1011: - pModel = "VS1011"; - break; - - case VS1002: - pModel = "VS1002"; - break; - - case VS1003: - pModel = "VS1003"; - break; - - case VS1053: - pModel = "VS1053"; - break; - - case VS1033: - pModel = "VS1033"; - break; - - case VS1103: - pModel = "VS1103"; - break; - - default: - pModel = "unknow"; - break; - } - FormMP3->Label2.pCaption = pModel; - LCD_DrawLabel(&FormMP3->Label2); /* 显示芯片型号 */ - } - - g_tMP3.ucVolume = 200; /* 缺省音量,越大声音越小 */ - VS1053_SetVolume(g_tMP3.ucVolume); - - VS1053_SetBASS(0, 0, 0, 0); /* 高频和低音不增强 */ - } - - /* 配置WM8978音频通道, 可以将VS1053B的输出音频接入WM8978的Line输入插座, 驱动板子上的扬声器放音 */ - { - /* bsp.c 中已经初始化I2C总线 */ - wm8978_Init(); /* 复位WM8978到复位状态 */ - - wm8978_SetSpkVolume(0); /* 临时静音扬声器 */ - - /* 配置WM8978芯片,输入为LINE IN,输出为耳机和扬声器 */ - wm8978_CfgAudioPath(LINE_ON, EAR_LEFT_ON | EAR_RIGHT_ON | SPK_ON); - /* 调节放音音量,左右相同音量 */ - wm8978_SetEarVolume(30); /* 设置耳机音量,最大63 */ - wm8978_SetSpkVolume(60); /* 设置扬声器音量,最大63 */ - wm8978_SetLineGain(6); /* 设置Line输入增益, 0-7 */ - } -} - -/* -********************************************************************************************************* -* 函 数 名: FillSongList -* 功能说明: 填充歌曲播放列表。搜索NAND Flash根目录下的歌曲,最多10个 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void FillSongList(void) -{ - /* 访问Fatfs用到的全局变量 */ - FRESULT result; - FILINFO FileInf; - DIR DirInf; - char path[128]; - - /* 打开歌曲目录 */ - sprintf(path, "%s%s", DiskPath, MP3_FOLDER); - result = f_opendir(&DirInf, path); /* path可以带盘符,最后一个字符不能是/ */ - if (result != FR_OK) - { - printf("Open Root Directory Error (%d)\r\n", result); - } - - g_tMP3.ListIndex = 0; - g_tMP3.ListCount = 0; /* 歌曲个数 */ - for (;;) - { - result = f_readdir(&DirInf, &FileInf); /* 读取目录项,索引会自动下移 */ - if (result != FR_OK || FileInf.fname[0] == 0) - { - break; - } - - if (FileInf.fname[0] == '.') /* 表示目录 */ - { - continue; - } - - if (FileInf.fattrib != AM_DIR) - { - uint8_t Len; - //altname fname - Len = strlen(FileInf.altname); - if (Len >= 5) - { - if (memcmp(&FileInf.altname[Len - 3], "MP3", 3) == 0) - { - /* 复制MP3文件名到播放列表 */ - strcpy(g_tPlayList[g_tMP3.ListCount].FileName, FileInf.altname); - g_tPlayList[g_tMP3.ListCount].FileSize = FileInf.fsize; - g_tMP3.ListCount++; /* 歌曲个数 */ - - /* 如果MP3文件已填满,则退出 */ - if (g_tMP3.ListCount > SONG_LIST_MAX) - { - break; - } - } - } - } - } - - if (g_tMP3.ListCount == 0) - { - printf("没有在根目录下找到 MP3 文件\r\n"); - } -} - -/* -********************************************************************************************************* -* 函 数 名: Mp3Pro -* 功能说明: MP3文件播放,在主程序while循环中调用. 每次向VS105B发送32字节。 -* 形 参: 无 -* 返 回 值: 0 表示正常播放; 1 表示文件播放完毕,主程序据此切换到下一首歌曲 -********************************************************************************************************* -*/ -static uint8_t Mp3Pro(void) -{ - uint32_t bw, i; - char buf[32]; - - /* 如果VS1003空闲,则写入新的数据 */ - if (VS1053_ReqNewData()) - { - f_read(&g_Mp3File, &buf, 32, &bw); - if (bw <= 0) - { - return 1; - } - - /* 计算进度 */ - g_tMP3.uiProgress += bw; - - VS1053_PreWriteData(); /* 写数据准备,设置好片选 */ - for (i = 0; i < bw; i++) - { - VS1053_WriteData(buf[i]); - } - } - return 0; -} - -/* -********************************************************************************************************* -* 函 数 名: Mp3DispStatus -* 功能说明: 显示当前状态 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void Mp3DispStatus(void) -{ - char buf[5]; - - /* 显示音量 */ - sprintf(buf, "%3d ", g_tMP3.ucVolume); - FormMP3->Label4.pCaption = buf; - LCD_DrawLabel(&FormMP3->Label4); - - /* 显示进度 */ - sprintf(buf, "%3d%%", g_tMP3.uiProgress * 100 / g_tPlayList[g_tMP3.ListIndex].FileSize); - FormMP3->Label6.pCaption = buf; - LCD_DrawLabel(&FormMP3->Label6); -} - -/* -********************************************************************************************************* -* 函 数 名: ViewDir -* 功能说明: 显示根目录下的文件名 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void ViewDir(char *_path) -{ - /* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */ - FRESULT result; - DIR DirInf; - FILINFO FileInf; - uint32_t cnt = 0; - - /* 打开根文件夹 - 用完后需要 f_closedir */ - result = f_opendir(&DirInf, _path); /* 1: 表示盘符 */ - if (result != FR_OK) - { - printf("打开根目录失败 (%d)\r\n", result); - return; - } - - printf("\r\n当前目录:%s\r\n", _path); - - /* 读取当前文件夹下的文件和目录 */ - printf("属性 | 文件大小 | 短文件名 | 长文件名\r\n"); - for (cnt = 0;; cnt++) - { - result = f_readdir(&DirInf, &FileInf); /* 读取目录项,索引会自动下移 */ - if (result != FR_OK || FileInf.fname[0] == 0) - { - break; - } - - if (FileInf.fname[0] == '.') - { - continue; - } - - /* 判断是文件还是子目录 */ - if (FileInf.fattrib & AM_DIR) - { - printf("(0x%02d)目录 ", FileInf.fattrib); - } - else - { - printf("(0x%02d)文件 ", FileInf.fattrib); - } - - /* 打印文件大小, 最大4G */ - printf(" %10d", FileInf.fsize); - - printf(" %s |", FileInf.altname); /* 短文件名 */ - - printf(" %s\r\n", (char *)FileInf.fname); /* 长文件名 */ - } - - f_closedir(&DirInf); /* 关闭打开的目录 */ -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_oled_.c b/User/app/src/old/form_oled_.c deleted file mode 100755 index e45f8aa..0000000 --- a/User/app/src/old/form_oled_.c +++ /dev/null @@ -1,483 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试OLED显示器 -* 文件名称 : oled_test.c -* 版 本 : V1.1 -* 说 明 : 测试OLED显示器模块 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* v1.1 2015-10-14 armfly 增加24点阵和32点阵汉字和ASCII显示功能 -* -* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_oled.h" - -#define DEMO_PAGE_COUNT 7 /* OLED演示页面的个数 */ - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - LABEL_T Label7; - LABEL_T Label8; - - BUTTON_T BtnRet; -} FormOLED_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "OLED显示模块测试程序" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "摇杆左、右键: " - -#define LABEL2_X (LABEL1_X + 135) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "切换OLED显示界面" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "摇杆上、下键: " - -#define LABEL4_X (LABEL3_X + 135) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "调节OLED对比度" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "摇杆OK键 : " - -#define LABEL6_X (LABEL5_X + 135) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT "切换显示方向" - -#define LABEL7_X (LABEL1_X) -#define LABEL7_Y (LABEL1_Y + 20 * 3) -#define LABEL7_TEXT "当前状态 :" - -#define LABEL8_X (LABEL7_X + 135) -#define LABEL8_Y LABEL7_Y -#define LABEL8_TEXT "80" - -static void InitFormOLED(void); -static void DispFormOLED(void); - -FormOLED_T *FormOLED; - -/* -********************************************************************************************************* -* 函 数 名: TestOLED -* 功能说明: 测试OLED显示模块 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestOLED(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormOLED_T form; - uint8_t fRefreshTFT; - FONT_T tFont12, tFont16, tFont24, tFont32; - uint8_t fRefreshOled; - uint8_t ucItem; - uint8_t ucContrast = 0x80; /* 对比度 */ - uint8_t ucDir = 0; /* 显示方向, 0 表示正常方向,1表示倒180度 */ - - FormOLED = &form; - InitFormOLED(); - DispFormOLED(); - - OLED_InitHard(); /* 初始化OLED硬件 */ - OLED_ClrScr(0x00); /* 清屏,0x00表示黑底; 0xFF 表示白底 */ - - /* 设置字体参数 */ - { - tFont16.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont16.FrontColor = 1; /* 字体颜色 0 或 1 */ - tFont16.BackColor = 0; /* 文字背景颜色 0 或 1 */ - tFont16.Space = 0; /* 文字间距,单位 = 像素 */ - - tFont12.FontCode = FC_ST_12; /* 字体代码 12点阵 */ - tFont12.FrontColor = 1; /* 字体颜色 0 或 1 */ - tFont12.BackColor = 0; /* 文字背景颜色 0 或 1 */ - tFont12.Space = 1; /* 文字间距,单位 = 像素 */ - - tFont24.FontCode = FC_ST_24; /* 字体代码 24点阵 */ - tFont24.FrontColor = 1; /* 字体颜色 0 或 1 */ - tFont24.BackColor = 0; /* 文字背景颜色 0 或 1 */ - tFont24.Space = 1; /* 文字间距,单位 = 像素 */ - - tFont32.FontCode = FC_ST_32; /* 字体代码 32点阵 */ - tFont32.FrontColor = 1; /* 字体颜色 0 或 1 */ - tFont32.BackColor = 0; /* 文字背景颜色 0 或 1 */ - tFont32.Space = 1; /* 文字间距,单位 = 像素 */ - } - ucItem = 0; - fRefreshOled = 1; - fRefreshTFT = 1; - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fRefreshTFT) - { - char buf[32]; - - fRefreshTFT = 0; - - sprintf(buf, "第%d页 对比度 = %3d", ucItem + 1, ucContrast); - - FormOLED->Label8.pCaption = buf; - LCD_DrawLabel(&FormOLED->Label8); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormOLED->BtnRet.Focus = 1; - LCD_DrawButton(&FormOLED->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormOLED->BtnRet.Focus = 0; - LCD_DrawButton(&FormOLED->BtnRet); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormOLED->BtnRet.Focus = 0; - LCD_DrawButton(&FormOLED->BtnRet); - } - break; - } - } - - if (fRefreshOled == 1) - { - fRefreshOled = 0; - - switch (ucItem) - { - case 0: - OLED_ClrScr(0); /* 清屏,黑底 */ - OLED_DrawRect(0, 0, 64, 128, 1); - OLED_DispStr(8, 3, "安富莱OLED例程", &tFont16); /* 在(8,3)坐标处显示一串汉字 */ - OLED_DispStr(10, 22, "请操作摇杆!", &tFont16); - OLED_DispStr(5, 22 + 20, "www.ARMfly.com", &tFont16); - break; - - case 1: - //OLED_StartDraw(); 调用改函数,只刷新缓冲区,不送显示 - OLED_ClrScr(0); - OLED_DispStr(0, 0, "故人西辞黄鹤楼,", &tFont16); - OLED_DispStr(0, 16, "烟花三月下扬州。", &tFont16); - OLED_DispStr(0, 32, "孤帆远影碧空尽,", &tFont16); - OLED_DispStr(0, 48, "唯见长江天际流。", &tFont16); - //OLED_EndDraw(); 调用改函数,将缓冲区中数据送显示 - break; - - case 2: - OLED_ClrScr(0); - OLED_DispStr(5, 0, "《送孟浩然之广陵》", &tFont12); - OLED_DispStr(0, 13, "故人西辞黄鹤楼,", &tFont12); - OLED_DispStr(0, 26, "烟花三月下扬州。", &tFont12); - OLED_DispStr(0, 39, "孤帆远影碧空尽,", &tFont12); - OLED_DispStr(0, 52, "唯见长江天际流。", &tFont12); - - OLED_DispStr(110, 14, "安", &tFont16); - OLED_DispStr(110, 30, "富", &tFont16); - OLED_DispStr(110, 46, "莱", &tFont16); - OLED_DrawRect(109, 13, 50, 17, 1); - break; - - case 3: - OLED_ClrScr(0); - OLED_DispStr(5, 0, "安富莱123", &tFont24); - OLED_DispStr(0, 26, "开发板8", &tFont32); - break; - - case 4: - OLED_ClrScr(0); - OLED_DrawRect(0, 0, 10, 10, 1); /* 在(0,0)坐标处绘制一个高10宽10的矩形 */ - OLED_DrawRect(10, 10, 20, 30, 1); /* 在(10,10)坐标处绘制一个高20宽30的矩形 */ - OLED_DrawCircle(64, 32, 30, 1); /* 在(64,32)绘制半径30的圆 */ - OLED_DrawLine(127, 0, 0, 63, 1); /* 在(127,0) 和 (0,63) 之间绘制一条直线 */ - break; - - case 5: - OLED_ClrScr(0x00); /* 清屏,黑底 */ - break; - - case 6: - OLED_ClrScr(0xFF); /* 清屏,白底 */ - { - //char buf[32]; - - //sprintf(buf, "%d", ucContrast); - //OLED_DispStr(10,10,buf,&tFont16); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆上键按下 */ - if (ucContrast < 255) - { - ucContrast++; - } - OLED_SetContrast(ucContrast); - fRefreshOled = 1; - fRefreshTFT = 1; - break; - - case JOY_DOWN_D: /* 摇杆下键按下 */ - if (ucContrast > 0) - { - ucContrast--; - } - OLED_SetContrast(ucContrast); - fRefreshOled = 1; - fRefreshTFT = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - if (ucItem > 0) - { - ucItem--; - } - else - { - ucItem = DEMO_PAGE_COUNT - 1; - } - fRefreshOled = 1; - fRefreshTFT = 1; - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - if (ucItem < DEMO_PAGE_COUNT - 1) - { - ucItem++; - } - else - { - ucItem = 0; - } - fRefreshOled = 1; - fRefreshTFT = 1; - break; - - case JOY_DOWN_OK: /* 摇杆OK键 */ - if (ucDir == 0) - { - ucDir = 1; - OLED_SetDir(1); /* 设置显示方向 */ - } - else - { - ucDir = 0; - OLED_SetDir(0); /* 设置显示方向 */ - } - fRefreshOled = 1; - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormOLED -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormOLED(void) -{ - /* 分组框标题字体 */ - FormOLED->FontBox.FontCode = FC_ST_16; - FormOLED->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormOLED->FontBox.FrontColor = CL_BLACK; - FormOLED->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormOLED->FontBlack.FontCode = FC_ST_16; - FormOLED->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormOLED->FontBlack.FrontColor = CL_BLACK; - FormOLED->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormOLED->FontBlue.FontCode = FC_ST_16; - FormOLED->FontBlue.BackColor = CL_BTN_FACE; - FormOLED->FontBlue.FrontColor = CL_BLUE; - FormOLED->FontBlue.Space = 0; - - /* 按钮字体 */ - FormOLED->FontBtn.FontCode = FC_ST_16; - FormOLED->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormOLED->FontBtn.FrontColor = CL_BLACK; - FormOLED->FontBtn.Space = 0; - - /* 分组框 */ - FormOLED->Box1.Left = BOX1_X; - FormOLED->Box1.Top = BOX1_Y; - FormOLED->Box1.Height = BOX1_H; - FormOLED->Box1.Width = BOX1_W; - FormOLED->Box1.pCaption = BOX1_TEXT; - FormOLED->Box1.Font = &FormOLED->FontBox; - - /* 静态标签 */ - FormOLED->Label1.Left = LABEL1_X; - FormOLED->Label1.Top = LABEL1_Y; - FormOLED->Label1.MaxLen = 0; - FormOLED->Label1.pCaption = LABEL1_TEXT; - FormOLED->Label1.Font = &FormOLED->FontBlack; - - FormOLED->Label3.Left = LABEL3_X; - FormOLED->Label3.Top = LABEL3_Y; - FormOLED->Label3.MaxLen = 0; - FormOLED->Label3.pCaption = LABEL3_TEXT; - FormOLED->Label3.Font = &FormOLED->FontBlack; - - FormOLED->Label5.Left = LABEL5_X; - FormOLED->Label5.Top = LABEL5_Y; - FormOLED->Label5.MaxLen = 0; - FormOLED->Label5.pCaption = LABEL5_TEXT; - FormOLED->Label5.Font = &FormOLED->FontBlack; - - FormOLED->Label7.Left = LABEL7_X; - FormOLED->Label7.Top = LABEL7_Y; - FormOLED->Label7.MaxLen = 0; - FormOLED->Label7.pCaption = LABEL7_TEXT; - FormOLED->Label7.Font = &FormOLED->FontBlack; - - /* 动态标签 */ - FormOLED->Label2.Left = LABEL2_X; - FormOLED->Label2.Top = LABEL2_Y; - FormOLED->Label2.MaxLen = 0; - FormOLED->Label2.pCaption = LABEL2_TEXT; - FormOLED->Label2.Font = &FormOLED->FontBlue; - - FormOLED->Label4.Left = LABEL4_X; - FormOLED->Label4.Top = LABEL4_Y; - FormOLED->Label4.MaxLen = 0; - FormOLED->Label4.pCaption = LABEL4_TEXT; - FormOLED->Label4.Font = &FormOLED->FontBlue; - - FormOLED->Label6.Left = LABEL6_X; - FormOLED->Label6.Top = LABEL6_Y; - FormOLED->Label6.MaxLen = 0; - FormOLED->Label6.pCaption = LABEL6_TEXT; - FormOLED->Label6.Font = &FormOLED->FontBlue; - - FormOLED->Label8.Left = LABEL8_X; - FormOLED->Label8.Top = LABEL8_Y; - FormOLED->Label8.MaxLen = 0; - FormOLED->Label8.pCaption = LABEL8_TEXT; - FormOLED->Label8.Font = &FormOLED->FontBlue; - - /* 按钮 */ - FormOLED->BtnRet.Left = BTN_RET_X; - FormOLED->BtnRet.Top = BTN_RET_Y; - FormOLED->BtnRet.Height = BTN_RET_H; - FormOLED->BtnRet.Width = BTN_RET_W; - FormOLED->BtnRet.pCaption = BTN_RET_TEXT; - FormOLED->BtnRet.Font = &FormOLED->FontBtn; - FormOLED->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispRSVInitFace -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormOLED(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormOLED->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormOLED->Label1); - LCD_DrawLabel(&FormOLED->Label3); - LCD_DrawLabel(&FormOLED->Label5); - LCD_DrawLabel(&FormOLED->Label7); - - /* 动态标签 */ - LCD_DrawLabel(&FormOLED->Label2); - LCD_DrawLabel(&FormOLED->Label4); - LCD_DrawLabel(&FormOLED->Label6); - LCD_DrawLabel(&FormOLED->Label8); - - /* 按钮 */ - LCD_DrawButton(&FormOLED->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_reserve.c b/User/app/src/old/form_reserve.c deleted file mode 100755 index 75d5bec..0000000 --- a/User/app/src/old/form_reserve.c +++ /dev/null @@ -1,323 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 等待开发的程序界面 -* 文件名称 : reserve.c -* 版 本 : V1.0 -* 说 明 : 测试MPU-6050, HCM5833L, BMP085, BH1750 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_reserve.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - LABEL_T Label7; - LABEL_T Label8; - - BUTTON_T BtnRet; -} FormRSV_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "程序开发中..." - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "xxxx : " - -#define LABEL2_X (LABEL1_X + 64) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "0000.0000" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "xxxx : " - -#define LABEL4_X (LABEL3_X + 64) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "00000.0000" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "xxxx : " - -#define LABEL6_X (LABEL5_X + 64) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT "0.0" - -#define LABEL7_X (LABEL1_X) -#define LABEL7_Y (LABEL1_Y + 20 * 3) -#define LABEL7_TEXT "xxxx : " - -#define LABEL8_X (LABEL7_X + 64) -#define LABEL8_Y LABEL7_Y -#define LABEL8_TEXT "0.0" - -static void InitFormRSV(void); -static void DispFormRSV(void); - -FormRSV_T *FormRSV; - -/* -********************************************************************************************************* -* 函 数 名: ReserveFunc -* 功能说明: 保留功能。 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void ReserveFunc(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormRSV_T form; - - FormRSV = &form; - - InitFormRSV(); - - DispFormRSV(); - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormRSV->BtnRet.Focus = 1; - LCD_DrawButton(&FormRSV->BtnRet); - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (TOUCH_InRect(tpX, tpY, BTN_RET_X, BTN_RET_Y, BTN_RET_H, BTN_RET_W)) - { - FormRSV->BtnRet.Focus = 0; - LCD_DrawButton(&FormRSV->BtnRet); - fQuit = 1; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - FormRSV->BtnRet.Focus = 0; - LCD_DrawButton(&FormRSV->BtnRet); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormRSV -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormRSV(void) -{ - /* 分组框标题字体 */ - FormRSV->FontBox.FontCode = FC_ST_16; - FormRSV->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormRSV->FontBox.FrontColor = CL_BLACK; - FormRSV->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormRSV->FontBlack.FontCode = FC_ST_16; - FormRSV->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormRSV->FontBlack.FrontColor = CL_BLACK; - FormRSV->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormRSV->FontBlue.FontCode = FC_ST_16; - FormRSV->FontBlue.BackColor = CL_BTN_FACE; - FormRSV->FontBlue.FrontColor = CL_BLUE; - FormRSV->FontBlue.Space = 0; - - /* 按钮字体 */ - FormRSV->FontBtn.FontCode = FC_ST_16; - FormRSV->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormRSV->FontBtn.FrontColor = CL_BLACK; - FormRSV->FontBtn.Space = 0; - - /* 分组框 */ - FormRSV->Box1.Left = BOX1_X; - FormRSV->Box1.Top = BOX1_Y; - FormRSV->Box1.Height = BOX1_H; - FormRSV->Box1.Width = BOX1_W; - FormRSV->Box1.pCaption = BOX1_TEXT; - FormRSV->Box1.Font = &FormRSV->FontBox; - - /* 静态标签 */ - FormRSV->Label1.Left = LABEL1_X; - FormRSV->Label1.Top = LABEL1_Y; - FormRSV->Label1.MaxLen = 0; - FormRSV->Label1.pCaption = LABEL1_TEXT; - FormRSV->Label1.Font = &FormRSV->FontBlack; - - FormRSV->Label3.Left = LABEL3_X; - FormRSV->Label3.Top = LABEL3_Y; - FormRSV->Label3.MaxLen = 0; - FormRSV->Label3.pCaption = LABEL3_TEXT; - FormRSV->Label3.Font = &FormRSV->FontBlack; - - FormRSV->Label5.Left = LABEL5_X; - FormRSV->Label5.Top = LABEL5_Y; - FormRSV->Label5.MaxLen = 0; - FormRSV->Label5.pCaption = LABEL5_TEXT; - FormRSV->Label5.Font = &FormRSV->FontBlack; - - FormRSV->Label7.Left = LABEL7_X; - FormRSV->Label7.Top = LABEL7_Y; - FormRSV->Label7.MaxLen = 0; - FormRSV->Label7.pCaption = LABEL7_TEXT; - FormRSV->Label7.Font = &FormRSV->FontBlack; - - /* 动态标签 */ - FormRSV->Label2.Left = LABEL2_X; - FormRSV->Label2.Top = LABEL2_Y; - FormRSV->Label2.MaxLen = 0; - FormRSV->Label2.pCaption = LABEL2_TEXT; - FormRSV->Label2.Font = &FormRSV->FontBlue; - - FormRSV->Label4.Left = LABEL4_X; - FormRSV->Label4.Top = LABEL4_Y; - FormRSV->Label4.MaxLen = 0; - FormRSV->Label4.pCaption = LABEL4_TEXT; - FormRSV->Label4.Font = &FormRSV->FontBlue; - - FormRSV->Label6.Left = LABEL6_X; - FormRSV->Label6.Top = LABEL6_Y; - FormRSV->Label6.MaxLen = 0; - FormRSV->Label6.pCaption = LABEL6_TEXT; - FormRSV->Label6.Font = &FormRSV->FontBlue; - - FormRSV->Label8.Left = LABEL8_X; - FormRSV->Label8.Top = LABEL8_Y; - FormRSV->Label8.MaxLen = 0; - FormRSV->Label8.pCaption = LABEL8_TEXT; - FormRSV->Label8.Font = &FormRSV->FontBlue; - - /* 按钮 */ - FormRSV->BtnRet.Left = BTN_RET_X; - FormRSV->BtnRet.Top = BTN_RET_Y; - FormRSV->BtnRet.Height = BTN_RET_H; - FormRSV->BtnRet.Width = BTN_RET_W; - FormRSV->BtnRet.pCaption = BTN_RET_TEXT; - FormRSV->BtnRet.Font = &FormRSV->FontBtn; - FormRSV->BtnRet.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormRSV -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormRSV(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormRSV->Box1); - - /* 静态标签 */ - LCD_DrawLabel(&FormRSV->Label1); - LCD_DrawLabel(&FormRSV->Label3); - LCD_DrawLabel(&FormRSV->Label5); - LCD_DrawLabel(&FormRSV->Label7); - - /* 动态标签 */ - LCD_DrawLabel(&FormRSV->Label2); - LCD_DrawLabel(&FormRSV->Label4); - LCD_DrawLabel(&FormRSV->Label6); - LCD_DrawLabel(&FormRSV->Label8); - - /* 按钮 */ - LCD_DrawButton(&FormRSV->BtnRet); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_rs485.c b/User/app/src/old/form_rs485.c deleted file mode 100755 index 7e1dee3..0000000 --- a/User/app/src/old/form_rs485.c +++ /dev/null @@ -1,752 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : RS485测试界面 -* 文件名称 : form_rs485.c -* 版 本 : V1.0 -* 说 明 : 驱动安富莱LED-485系列数码管显示屏。 -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2014-10-15 armfly 首发 -* -* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_rs485.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - GROUP_T Box2; - GROUP_T Box3; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - - BUTTON_T BtnRet; - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - BUTTON_T Btn5; - BUTTON_T Btn6; - - BUTTON_T BtnBright[8]; /* 设置亮度 */ - - LABEL_T LabelOldAddr; - LABEL_T LabelNewAddr; - EDIT_T EditOldAddr; - EDIT_T EditNewAddr; - BUTTON_T BtnSetAddr; - - LABEL_T LblInfo1; - LABEL_T LblInfo2; -} FormRS485_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H 100 -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "RS485 LED数码管" - -/* 第1个框内的按钮 */ -#define BTN1_H 32 -#define BTN1_W 100 -#define BTN1_X (BOX1_X + 10) -#define BTN1_Y (BOX1_Y + 20) -#define BTN1_TEXT "ASCII协议" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_TEXT "Modbus协议" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X BTN1_X -#define BTN3_Y (BTN1_Y + BTN1_H + 10) -#define BTN3_TEXT "读设备型号" - -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X (BTN1_X + BTN1_W + 10) -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_TEXT "读固件版本" - -#define BTN5_H BTN1_H -#define BTN5_W BTN1_W -#define BTN5_X (BTN1_X + 2 * (BTN1_W + 10)) -#define BTN5_Y (BTN1_Y + BTN1_H + 10) -#define BTN5_TEXT "测试应答" - -#define BTN6_H BTN1_H -#define BTN6_W BTN1_W -#define BTN6_X (BTN1_X + 3 * (BTN1_W + 10)) -#define BTN6_Y (BTN1_Y + BTN1_H + 10) -#define BTN6_TEXT "读亮度参数" - -#define LABEL1_X (BTN5_X + 10) -#define LABEL1_Y BTN2_Y -#define LABEL1_TEXT "地址: " - -#define LABEL2_X (LABEL1_X + 48) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "0" - -#define LABEL3_X (LABEL2_X + 32) -#define LABEL3_Y LABEL1_Y -#define LABEL3_TEXT "波特率: " - -#define LABEL4_X (LABEL3_X + 64) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "0" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20) -#define LABEL5_TEXT "接收:" - -#define LABEL6_X (LABEL5_X + 48) -#define LABEL6_Y LABEL5_Y -#define LABEL6_TEXT " " - -/* 第2个框 */ -#define BOX2_X BOX1_X -#define BOX2_Y (BOX1_Y + BOX1_H + 10) -#define BOX2_H 60 -#define BOX2_W (g_LcdWidth - 2 * BOX1_X) -#define BOX2_TEXT "设置亮度" - -#define BTNB_H 32 -#define BTNB_W 45 -#define BTNB_X (BOX2_X + 10) -#define BTNB_Y (BOX2_Y + 20) - -/* 第3个框 */ -#define BOX3_X BOX1_X -#define BOX3_Y (BOX2_Y + BOX2_H + 10) -#define BOX3_H 72 -#define BOX3_W (g_LcdWidth - 2 * BOX1_X) -#define BOX3_TEXT "修改485地址" - -#define LABEL_OLDADDR_X (BOX3_X + 10) -#define LABEL_OLDADDR_Y (BOX3_Y + 20) -#define LABEL_OLDADDR_TEXT "当前地址:" - -#define EDIT_OLDADDR_X (LABEL_OLDADDR_X + 80) -#define EDIT_OLDADDR_Y LABEL_OLDADDR_Y -#define EDIT_OLDADDR_H 20 -#define EDIT_OLDADDR_W 50 - -#define LABEL_NEWADDR_X LABEL_OLDADDR_X -#define LABEL_NEWADDR_Y (LABEL_OLDADDR_Y + 30) -#define LABEL_NEWADDR_TEXT " 新地址:" - -#define EDIT_NEWADDR_X EDIT_OLDADDR_X -#define EDIT_NEWADDR_Y LABEL_NEWADDR_Y -#define EDIT_NEWDDR_H EDIT_OLDADDR_H -#define EDIT_NEWADDR_W EDIT_OLDADDR_W - -#define BTN_SETADDR_H 50 -#define BTN_SETADDR_W 100 -#define BTN_SETADDR_X (EDIT_NEWADDR_X + EDIT_NEWADDR_W + 10) -#define BTN_SETADDR_Y EDIT_OLDADDR_Y -#define BTN_SETADDR_TEXT "修改485地址" - -#define LBL_INFO1_X (BOX3_X + 270) -#define LBL_INFO1_Y (BOX3_Y + 11) -#define LBL_INFO1_TEXT "摇杆上下键: 修改新地址" - -#define LBL_INFO2_X LBL_INFO1_X -#define LBL_INFO2_Y (LBL_INFO1_Y + 20) -#define LBL_INFO2_TEXT "摇杆左右键: 修改当前地址" - -/* 按钮 */ -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 80 -#define BTN_RET_X (g_LcdWidth - BTN_RET_W - 8) -#define BTN_RET_Y (g_LcdHeight - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -static void InitFormRS485(void); -static void DispFormRS485(void); - -static void DispLabelAddr(uint8_t _addr1, uint8_t _addr2); -static void DispLabelBaud(uint32_t _Baud); -static void DispLabelRx(uint8_t *_buf, uint8_t _len); - -FormRS485_T *FormRS485; -/* -********************************************************************************************************* -* 函 数 名: FormMainRS485 -* 功能说明: RS485测试主程序 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void FormMainRS485(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - FormRS485_T form; - uint8_t OldAddr; - uint8_t NewAddr; - uint32_t baud; - uint32_t i; - uint32_t count = 0; - uint8_t fUpdateCount = 1; - uint8_t fUpdateAddr = 1; - uint8_t fLed888 = 0; - - FormRS485 = &form; - - InitFormRS485(); - - DispFormRS485(); - - OldAddr = 1; - NewAddr = 1; - baud = 9600; - - DispLabelBaud(baud); - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - MODH_Poll(); - - if (fUpdateAddr == 1) - { - fUpdateAddr = 0; - - DispLabelAddr(OldAddr, NewAddr); - } - - if (fUpdateCount == 1) - { - fUpdateCount = 0; - - LED485_DispNumberA(OldAddr, count); /* 命令LED数码管显示计数值 */ - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - if (LCD_ButtonTouchDown(&FormRS485->BtnRet, tpX, tpY)) - { - //fQuit = 1; - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn1, tpX, tpY)) - { - LED485_SetProtAscii(OldAddr); /* 设置为ASCII协议 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn2, tpX, tpY)) - { - LED485_SetProtRTU(OldAddr); /* 设置为Modbus RTU 协议 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn3, tpX, tpY)) - { - LED485_ReadModel(OldAddr); /* 读设备型号 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn4, tpX, tpY)) - { - LED485_ReadVersion(OldAddr); /* 读固件版本 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn5, tpX, tpY)) - { - LED485_TestOk(OldAddr); /* 测试OK应答 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->Btn6, tpX, tpY)) - { - LED485_ReadBright(OldAddr); /* 读亮度参数 */ - } - else if (LCD_ButtonTouchDown(&FormRS485->BtnSetAddr, tpX, tpY)) - { - /* 修改地址 */ - LED485_ModifyAddrA(OldAddr, NewAddr); - } - else - { - for (i = 0; i < 8; i++) - { - if (LCD_ButtonTouchDown(&FormRS485->BtnBright[i], tpX, tpY)) - { - LED485_SetBrightA(OldAddr, i); /* 设置亮度参数(ASCII协议) */ - } - } - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormRS485->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else - { - LCD_ButtonTouchRelease(&FormRS485->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn4, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn5, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->Btn6, tpX, tpY); - LCD_ButtonTouchRelease(&FormRS485->BtnSetAddr, tpX, tpY); - for (i = 0; i < 8; i++) - { - LCD_ButtonTouchRelease(&FormRS485->BtnBright[i], tpX, tpY); - } - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case MSG_485_RX_NOT_RTU: /* 接收到485设备的应答 */ - DispLabelRx(g_tModH.AppRxBuf, g_tModH.AppRxCount); - break; - - case KEY_DOWN_K1: /* K1键 + 1*/ - count++; - fUpdateCount = 1; - break; - - case KEY_DOWN_K2: /* K2键 - 1 */ - if (count > 0) - { - count--; - } - fUpdateCount = 1; - break; - - case KEY_DOWN_K3: /* K3键 - 清0 */ - count = 0; - fUpdateCount = 1; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - NewAddr++; - fUpdateAddr = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - NewAddr--; - fUpdateAddr = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - OldAddr++; - fUpdateAddr = 1; - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - OldAddr--; - fUpdateAddr = 1; - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - /* 自动测试 */ - if (fLed888 == 0) - { - fLed888 = 1; - LED485_DispStrA(OldAddr, "8.8.8."); - } - else if (fLed888 == 1) - { - fLed888 = 2; - LED485_DispStrA(OldAddr, "8.8.8.8"); - } - else - { - fLed888 = 0; - LED485_DispStrA(OldAddr, " "); - } - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormRS485 -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormRS485(void) -{ - /* 分组框标题字体 */ - FormRS485->FontBox.FontCode = FC_ST_16; - FormRS485->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormRS485->FontBox.FrontColor = CL_BLACK; - FormRS485->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormRS485->FontBlack.FontCode = FC_ST_16; - FormRS485->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormRS485->FontBlack.FrontColor = CL_BLACK; - FormRS485->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormRS485->FontBlue.FontCode = FC_ST_16; - FormRS485->FontBlue.BackColor = CL_BTN_FACE; - FormRS485->FontBlue.FrontColor = CL_BLUE; - FormRS485->FontBlue.Space = 0; - - /* 按钮字体 */ - FormRS485->FontBtn.FontCode = FC_ST_16; - FormRS485->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormRS485->FontBtn.FrontColor = CL_BLACK; - FormRS485->FontBtn.Space = 0; - - /* 分组框 */ - FormRS485->Box1.Left = BOX1_X; - FormRS485->Box1.Top = BOX1_Y; - FormRS485->Box1.Height = BOX1_H; - FormRS485->Box1.Width = BOX1_W; - FormRS485->Box1.pCaption = BOX1_TEXT; - FormRS485->Box1.Font = &FormRS485->FontBox; - - FormRS485->Box2.Left = BOX2_X; - FormRS485->Box2.Top = BOX2_Y; - FormRS485->Box2.Height = BOX2_H; - FormRS485->Box2.Width = BOX2_W; - FormRS485->Box2.pCaption = BOX2_TEXT; - FormRS485->Box2.Font = &FormRS485->FontBox; - - /* 静态标签 */ - FormRS485->Label1.Left = LABEL1_X; - FormRS485->Label1.Top = LABEL1_Y; - FormRS485->Label1.MaxLen = 0; - FormRS485->Label1.pCaption = LABEL1_TEXT; - FormRS485->Label1.Font = &FormRS485->FontBlack; - - FormRS485->Label3.Left = LABEL3_X; - FormRS485->Label3.Top = LABEL3_Y; - FormRS485->Label3.MaxLen = 0; - FormRS485->Label3.pCaption = LABEL3_TEXT; - FormRS485->Label3.Font = &FormRS485->FontBlack; - - FormRS485->Label5.Left = LABEL5_X; - FormRS485->Label5.Top = LABEL5_Y; - FormRS485->Label5.MaxLen = 0; - FormRS485->Label5.pCaption = LABEL5_TEXT; - FormRS485->Label5.Font = &FormRS485->FontBlack; - - /* 动态标签 */ - FormRS485->Label2.Left = LABEL2_X; - FormRS485->Label2.Top = LABEL2_Y; - FormRS485->Label2.MaxLen = 0; - FormRS485->Label2.pCaption = LABEL2_TEXT; - FormRS485->Label2.Font = &FormRS485->FontBlue; - - FormRS485->Label4.Left = LABEL4_X; - FormRS485->Label4.Top = LABEL4_Y; - FormRS485->Label4.MaxLen = 0; - FormRS485->Label4.pCaption = LABEL4_TEXT; - FormRS485->Label4.Font = &FormRS485->FontBlue; - - FormRS485->Label6.Left = LABEL6_X; - FormRS485->Label6.Top = LABEL6_Y; - FormRS485->Label6.MaxLen = 0; - FormRS485->Label6.pCaption = LABEL6_TEXT; - FormRS485->Label6.Font = &FormRS485->FontBlue; - - /* 按钮 */ - FormRS485->BtnRet.Left = BTN_RET_X; - FormRS485->BtnRet.Top = BTN_RET_Y; - FormRS485->BtnRet.Height = BTN_RET_H; - FormRS485->BtnRet.Width = BTN_RET_W; - FormRS485->BtnRet.pCaption = BTN_RET_TEXT; - FormRS485->BtnRet.Font = &FormRS485->FontBtn; - FormRS485->BtnRet.Focus = 0; - - FormRS485->Btn1.Left = BTN1_X; - FormRS485->Btn1.Top = BTN1_Y; - FormRS485->Btn1.Height = BTN1_H; - FormRS485->Btn1.Width = BTN1_W; - FormRS485->Btn1.pCaption = BTN1_TEXT; - FormRS485->Btn1.Font = &FormRS485->FontBtn; - FormRS485->Btn1.Focus = 0; - - FormRS485->Btn2.Left = BTN2_X; - FormRS485->Btn2.Top = BTN2_Y; - FormRS485->Btn2.Height = BTN2_H; - FormRS485->Btn2.Width = BTN2_W; - FormRS485->Btn2.pCaption = BTN2_TEXT; - FormRS485->Btn2.Font = &FormRS485->FontBtn; - FormRS485->Btn2.Focus = 0; - - FormRS485->Btn3.Left = BTN3_X; - FormRS485->Btn3.Top = BTN3_Y; - FormRS485->Btn3.Height = BTN3_H; - FormRS485->Btn3.Width = BTN3_W; - FormRS485->Btn3.pCaption = BTN3_TEXT; - FormRS485->Btn3.Font = &FormRS485->FontBtn; - FormRS485->Btn3.Focus = 0; - - FormRS485->Btn4.Left = BTN4_X; - FormRS485->Btn4.Top = BTN4_Y; - FormRS485->Btn4.Height = BTN4_H; - FormRS485->Btn4.Width = BTN4_W; - FormRS485->Btn4.pCaption = BTN4_TEXT; - FormRS485->Btn4.Font = &FormRS485->FontBtn; - FormRS485->Btn4.Focus = 0; - - FormRS485->Btn5.Left = BTN5_X; - FormRS485->Btn5.Top = BTN5_Y; - FormRS485->Btn5.Height = BTN5_H; - FormRS485->Btn5.Width = BTN5_W; - FormRS485->Btn5.pCaption = BTN5_TEXT; - FormRS485->Btn5.Font = &FormRS485->FontBtn; - FormRS485->Btn5.Focus = 0; - - FormRS485->Btn6.Left = BTN6_X; - FormRS485->Btn6.Top = BTN6_Y; - FormRS485->Btn6.Height = BTN6_H; - FormRS485->Btn6.Width = BTN6_W; - FormRS485->Btn6.pCaption = BTN6_TEXT; - FormRS485->Btn6.Font = &FormRS485->FontBtn; - FormRS485->Btn6.Focus = 0; - - { - uint8_t i; - char *BrightStr[8] = { - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - }; - - for (i = 0; i < 8; i++) - { - FormRS485->BtnBright[i].Left = BTNB_X + (BTNB_W + 10) * i; - FormRS485->BtnBright[i].Top = BTNB_Y; - FormRS485->BtnBright[i].Height = BTNB_H; - FormRS485->BtnBright[i].Width = BTNB_W; - FormRS485->BtnBright[i].pCaption = BrightStr[i]; - FormRS485->BtnBright[i].Font = &FormRS485->FontBtn; - FormRS485->BtnBright[i].Focus = 0; - } - } - - { - FormRS485->Box3.Left = BOX3_X; - FormRS485->Box3.Top = BOX3_Y; - FormRS485->Box3.Height = BOX3_H; - FormRS485->Box3.Width = BOX3_W; - FormRS485->Box3.pCaption = BOX3_TEXT; - FormRS485->Box3.Font = &FormRS485->FontBox; - - FormRS485->LabelOldAddr.Left = LABEL_OLDADDR_X; - FormRS485->LabelOldAddr.Top = LABEL_OLDADDR_Y; - FormRS485->LabelOldAddr.MaxLen = 0; - FormRS485->LabelOldAddr.pCaption = LABEL_OLDADDR_TEXT; - FormRS485->LabelOldAddr.Font = &FormRS485->FontBlack; - - FormRS485->LabelNewAddr.Left = LABEL_NEWADDR_X; - FormRS485->LabelNewAddr.Top = LABEL_NEWADDR_Y; - FormRS485->LabelNewAddr.MaxLen = 0; - FormRS485->LabelNewAddr.pCaption = LABEL_NEWADDR_TEXT; - FormRS485->LabelNewAddr.Font = &FormRS485->FontBlack; - - FormRS485->EditOldAddr.Left = EDIT_OLDADDR_X; - FormRS485->EditOldAddr.Top = EDIT_OLDADDR_Y; - FormRS485->EditOldAddr.Height = EDIT_OLDADDR_H; - FormRS485->EditOldAddr.Width = EDIT_OLDADDR_W; - FormRS485->EditOldAddr.pCaption = FormRS485->EditOldAddr.Text; - FormRS485->EditOldAddr.Font = &FormRS485->FontBtn; - - FormRS485->EditNewAddr.Left = EDIT_NEWADDR_X; - FormRS485->EditNewAddr.Top = EDIT_NEWADDR_Y; - FormRS485->EditNewAddr.Height = EDIT_NEWDDR_H; - FormRS485->EditNewAddr.Width = EDIT_NEWADDR_W; - FormRS485->EditNewAddr.pCaption = FormRS485->EditNewAddr.Text; - FormRS485->EditNewAddr.Font = &FormRS485->FontBtn; - - FormRS485->BtnSetAddr.Left = BTN_SETADDR_X; - FormRS485->BtnSetAddr.Top = BTN_SETADDR_Y; - FormRS485->BtnSetAddr.Height = BTN_SETADDR_H; - FormRS485->BtnSetAddr.Width = BTN_SETADDR_W; - FormRS485->BtnSetAddr.pCaption = BTN_SETADDR_TEXT; - FormRS485->BtnSetAddr.Font = &FormRS485->FontBtn; - FormRS485->BtnSetAddr.Focus = 0; - - FormRS485->EditOldAddr.Text[0] = 0; - FormRS485->EditNewAddr.Text[0] = 0; - - FormRS485->LblInfo1.Left = LBL_INFO1_X; - FormRS485->LblInfo1.Top = LBL_INFO1_Y; - FormRS485->LblInfo1.MaxLen = 0; - FormRS485->LblInfo1.pCaption = LBL_INFO1_TEXT; - FormRS485->LblInfo1.Font = &FormRS485->FontBlack; - - FormRS485->LblInfo2.Left = LBL_INFO2_X; - FormRS485->LblInfo2.Top = LBL_INFO2_Y; - FormRS485->LblInfo2.MaxLen = 0; - FormRS485->LblInfo2.pCaption = LBL_INFO2_TEXT; - FormRS485->LblInfo2.Font = &FormRS485->FontBlack; - } -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormRS485 -* 功能说明: 显示所有的静态控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormRS485(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormRS485->Box1); - LCD_DrawGroupBox(&FormRS485->Box2); - - LCD_DrawLabel(&FormRS485->Label1); - LCD_DrawLabel(&FormRS485->Label3); - LCD_DrawLabel(&FormRS485->Label5); - - LCD_DrawLabel(&FormRS485->Label2); - LCD_DrawLabel(&FormRS485->Label4); - LCD_DrawLabel(&FormRS485->Label6); - - /* 按钮 */ - LCD_DrawButton(&FormRS485->Btn1); - LCD_DrawButton(&FormRS485->Btn2); - LCD_DrawButton(&FormRS485->Btn3); - LCD_DrawButton(&FormRS485->Btn4); - LCD_DrawButton(&FormRS485->Btn5); - LCD_DrawButton(&FormRS485->Btn6); - - { - uint8_t i; - - for (i = 0; i < 8; i++) - { - LCD_DrawButton(&FormRS485->BtnBright[i]); - } - } - - LCD_DrawGroupBox(&FormRS485->Box3); - LCD_DrawLabel(&FormRS485->LabelOldAddr); - LCD_DrawLabel(&FormRS485->LabelNewAddr); - LCD_DrawEdit(&FormRS485->EditOldAddr); - LCD_DrawEdit(&FormRS485->EditNewAddr); - LCD_DrawButton(&FormRS485->BtnSetAddr); - LCD_DrawLabel(&FormRS485->LblInfo1); - LCD_DrawLabel(&FormRS485->LblInfo2); - - LCD_DrawButton(&FormRS485->BtnRet); -} - -/* -********************************************************************************************************* -* 函 数 名: DispLabelAddr -* 功能说明: 显示485地址 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispLabelAddr(uint8_t _addr1, uint8_t _addr2) -{ - char buf[10]; - - sprintf(buf, "%d", _addr1); - - /* 动态标签 */ - FormRS485->Label2.pCaption = buf; - LCD_DrawLabel(&FormRS485->Label2); - - sprintf(FormRS485->EditOldAddr.Text, "%d", _addr1); - LCD_DrawEdit(&FormRS485->EditOldAddr); - - sprintf(FormRS485->EditNewAddr.Text, "%d", _addr2); - LCD_DrawEdit(&FormRS485->EditNewAddr); -} - -/* -********************************************************************************************************* -* 函 数 名: DispLabelTx -* 功能说明: 显示发送的数据 -* 形 参: _Baud 波特率 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispLabelBaud(uint32_t _Baud) -{ - char buf[10]; - - sprintf(buf, "%d", _Baud); - - /* 动态标签 */ - FormRS485->Label4.pCaption = buf; - LCD_DrawLabel(&FormRS485->Label4); -} - -/* -********************************************************************************************************* -* 函 数 名: DispLabelRx -* 功能说明: 显示接收到的数据 -* 形 参: _buf 要发送的数据 -* _ -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispLabelRx(uint8_t *_buf, uint8_t _len) -{ - char buf[16]; - - _buf[_len] = 0; - sprintf(buf, "%d | %s", _len, _buf); - - /* 动态标签 */ - FormRS485->Label6.pCaption = buf; - LCD_DrawLabel(&FormRS485->Label6); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_touch.c b/User/app/src/old/form_touch.c deleted file mode 100755 index 009db6b..0000000 --- a/User/app/src/old/form_touch.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 触摸测试界面。 -* 文件名称 : touch_test.c -* 版 本 : V1.1 -* 说 明 : 测试屏是否有缺陷,触摸是否准确 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-01-01 armfly 正式发布 -* V1.1 2014-09-06 armfly 增加图片显示速度测试功能 -* -* Copyright (C), 2014-2015, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" /* printf函数定向输出到串口,所以必须包含这个文件 */ - -#include "form_main_menu.h" -#include "images.h" -#include "param.h" -#include "ff.h" /* FatFS 文件系统头文件 */ -#include "usbh_usr.h" /* usb host u盘支持 */ -#include "ff_gen_drv.h" -#include "sd_diskio_dma.h" -#include "usbh_diskio.h" -#include "nand_diskio.h" - -//#define PIC_DISK FS_NAND /* 选择缺省读取的磁盘: FS_NAND, FS_SD, FS_USB */ -#define PIC_PATH "/Pic" /* MP3文件存放的缺省文件夹, 根目录下的PIC */ - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - - BUTTON_T Btn1; /* 拨号 */ - BUTTON_T Btn2; /* 挂机 */ - BUTTON_T Btn3; /* 切换音频通道 */ - - BUTTON_T BtnRet; /* 返回 */ - - char strHardInfo[32]; /* 模块硬件信息 */ - uint8_t ucNetStatus; /* 网络状态 */ - uint8_t ucAudioCh; /* 当前音频通道 0, 1 */ - uint8_t ucEarVolume; /* 耳机音量 0 - 5 */ - int16_t ucMicGain; /* MIC音量 -12:最小增益 12:最大增益 13:静音*/ - -} FormGPRS_T; - -/* 返回按钮的坐标(屏幕右下角) */ -#define BUTTON_RET_H 32 -#define BUTTON_RET_W 60 -#define BUTTON_RET_X (g_LcdWidth - BUTTON_RET_W - 4) -#define BUTTON_RET_Y (g_LcdHeight - BUTTON_RET_H - 4) - -static LABEL_T Label1; /* 显示PS2设备状态 */ -static LABEL_T Label2; /* 显示PS2键盘和鼠标发出的键值 */ -static LABEL_T Label3; /* 显示摇杆,红外,按钮事件 */ - -static FONT_T FontLabel; - -/* 图片地址 RA8875图片芯片偏移地址 */ -const uint32_t g_RA8875Addr_480x272[3] = - { - 0x00200000, /* 480x272 沙滩背景 */ - 0x0023FC00, /* 480x272 树叶背景 */ - 0x0027F800, /* 480x272 水珠背景 */ -}; -const uint32_t g_RA8875Addr_800x480[3] = - { - 0x002BF400, /* 800x480 沙滩背景 */ - 0x0037AC00, /* 800x480 树叶背景 */ - 0x00436400 /* 800x480 水珠背景 */ -}; - -/* NOR FLASH中存储的图片地址 */ -const uint32_t g_NorAddr_480x272[3] = - { - (0x64000000 + 0x00200000), /* 480x272 沙滩背景 */ - (0x64000000 + 0x0023FC00), /* 480x272 树叶背景 */ - (0x64000000 + 0x0027F800), /* 480x272 水珠背景 */ -}; -const uint32_t g_NorAddr_800x480[3] = - { - (0x64000000 + 0x002BF400), /* 800x480 沙滩背景 */ - (0x64000000 + 0x0037AC00), /* 800x480 树叶背景 */ - (0x64000000 + 0x00436400) /* 800x480 水珠背景 */ -}; - -/* NOR FLASH, PIC目录下 存储的图片文件名 */ -const char *g_NandFileName_480x272[3] = - { - "480272_1.bin", - "480272_2.bin", - "480272_3.bin", - //"480x272_4.bin", - //"480x272_5.bin", - //"480x272_6.bin" -}; - -const char *g_NandFileName_800x480[3] = - { - "800480_1.bin", - "800480_2.bin", - "800480_3.bin", - //"800x480_4.bin", - //"800x480_5.bin", - //"800x480_6.bin" -}; - -typedef struct -{ - uint32_t code; - char *str; -} KB_STR_T; - -static const KB_STR_T s_KeyNameTab[] = - { - {0xEEEEEEEE, ""}, - - {KB_A, "A"}, - {KB_B, "B"}, - {KB_C, "C"}, - {KB_D, "D"}, - {KB_E, "E"}, - {KB_F, "F"}, - {KB_G, "G"}, - {KB_H, "H"}, - {KB_I, "I"}, - {KB_J, "J"}, - {KB_K, "K"}, - {KB_L, "L"}, - {KB_M, "M"}, - {KB_N, "N"}, - {KB_O, "O"}, - {KB_P, "P"}, - {KB_Q, "Q"}, - {KB_R, "R"}, - {KB_S, "S"}, - {KB_T, "T"}, - {KB_U, "U"}, - {KB_V, "V"}, - {KB_W, "W"}, - {KB_X, "X"}, - {KB_Y, "Y"}, - {KB_Z, "Z"}, - {KB_0, "0"}, - {KB_1, "1"}, - {KB_2, "2"}, - {KB_3, "3"}, - {KB_4, "4"}, - {KB_5, "5"}, - {KB_6, "6"}, - {KB_7, "7"}, - {KB_8, "8"}, - {KB_9, "9"}, - {KB_PIE, "`"}, /* 撇,键盘左上角 */ - {KB_SUB, "-"}, /* 中杠,减号 */ - {KB_EQU, "="}, /* 等号 */ - {KB_FXG, "\\"}, /* 反斜杠 */ - {KB_BKSP, "Backspace"}, - {KB_SPACE, "Space"}, - {KB_TAB, "Tab"}, - {KB_CAPS, "CapsLk"}, - {KB_L_SHFT, "Shift Left"}, - {KB_L_CTRL, "Ctrl Left"}, - {KB_L_GUI, "GUI Left"}, - {KB_L_ALT, "Alt Left"}, - {KB_R_SHFT, "Shift Right"}, - {KB_R_CTRL, "Ctrl Right"}, - {KB_R_GUI, "Gui Right"}, - {KB_R_ALT, "Alt Right"}, - {KB_APPS, "Apps"}, - {KB_ENTER, "Enter"}, - {KB_ESC, "ESC"}, - {KB_F1, "F1"}, - {KB_F2, "F2"}, - {KB_F3, "F3"}, - {KB_F4, "F4"}, - {KB_F5, "F5"}, - {KB_F6, "F6"}, - {KB_F7, "F7"}, - {KB_F8, "F8"}, - {KB_F9, "F9"}, - {KB_F10, "F10"}, - {KB_F11, "F11"}, - {KB_F12, "F12"}, - {KB_PRNT_SCRN, "Print Screen/SysRq"}, - {KB_SCROLL, "Scroll Lock"}, - {KB_PAUSE, "Pause/Break"}, - {KB_ZZKH, "["}, - {KB_INSERT, "Insert"}, - {KB_HOME, "Home"}, - {KB_PGUP, "Page Up"}, - {KB_DELETE, "Delete"}, - {KB_END, "End"}, - {KB_PGDN, "Page Down"}, - {KB_U_ARROW, "Up Arrow"}, - {KB_L_ARROW, "Left Arrow"}, - {KB_D_ARROW, "Down Arrow"}, - {KB_R_ARROW, "Right Arrow"}, - {KB_NUM, "Num Lock"}, - {KB_KP_DIV, "KP /"}, /* 小键盘除号 KP 表示小键盘 */ - {KB_KP_MULT, "KP *"}, /* 小键盘乘号 */ - {KB_KP_SUB, "KP -"}, /* - */ - {KB_KP_ADD, "KP +"}, - {KB_KP_ENTER, "KP Enter"}, - {KB_KP_DOT, "KP ."}, /* 小数点 */ - {KB_KP_0, "KP 0"}, - {KB_KP_1, "KP 0"}, - {KB_KP_2, "KP 0"}, - {KB_KP_3, "KP 0"}, - {KB_KP_4, "KP 0"}, - {KB_KP_5, "KP 0"}, - {KB_KP_6, "KP 0"}, - {KB_KP_7, "KP 0"}, - {KB_KP_8, "KP 0"}, - {KB_KP_9, "KP 0"}, - {KB_YZKH, "]"}, /* ] 右中括号 */ - {KB_SEMICOLON, ";"}, /* ; 分号 */ - {KB_QUOTES, "'"}, /* 单引号 */ - {KB_COMMA, ","}, /* 逗号 */ - {KB_DOT, "."}, /* 小数点 */ - {KB_DIV, "/"}, /* 除号 */ - - {0, ""} /* 查表结束标志 */ -}; - -static void InitFormTouch(void); -static const char *GetNameOfKey(uint32_t _code); -static void DispPic(void); -uint8_t ReadFileDispPic(char *_strFileName, uint16_t _usX, uint16_t _usY, uint16_t usHeight, uint16_t usWidth); - -static uint8_t s_pic = 0; - -/* -********************************************************************************************************* -* 函 数 名: TestTouch -* 功能说明: 触摸测试 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestTouch(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint32_t uiPS2Msg; /* PS2键盘鼠标消息 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ - FONT_T tFont, tFontBtn; /* 定义一个字体结构体变量,用于设置字体参数 */ - char buf[64]; - uint16_t usAdcX, usAdcY; - int16_t tpX, tpY; - uint8_t fQuit = 0; - - BUTTON_T tBtn; - - s_pic = 0; - - LCD_ClrScr(CL_BLUE); /* 清屏,背景蓝色 */ - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - { - tFontBtn.FontCode = FC_ST_16; - tFontBtn.BackColor = CL_MASK; /* 背景透明 */ - tFontBtn.FrontColor = CL_BLACK; - tFontBtn.Space = 0; - } - - LCD_SetBackLight(g_tParam.ucBackLight); /* 设置背光亮度 */ - - InitFormTouch(); - -#if 1 - bsp_InitPS2(); - PS2_StartWork(); - - /* 初始化PS2设备. 键盘可以不配置. 鼠标必须配置后才会输出数据包 */ - { - uint8_t ucDevType; - - ucDevType = PS2_GetDevceType(); - if (ucDevType == PS2_MOUSE) - { - Label1.pCaption = "检测到PS2鼠标"; - LCD_DrawLabel(&Label1); - - PS2_InitMouse(); - } - else if (ucDevType == PS2_KEYBOARD) - { - Label1.pCaption = "检测到PS2键盘"; - LCD_DrawLabel(&Label1); - - PS2_InitKeyboard(); - } - else - { - Label1.pCaption = "未检测到PS2设备"; - LCD_DrawLabel(&Label1); - } - } -#endif - - IRD_StartWork(); /* 开始红外解码 */ - - usbh_OpenMassStorage(); /* 打开USB HOST, 支持U盘 */ - - fRefresh = 1; /* 1表示需要刷新LCD */ - while (fQuit == 0) - { - bsp_Idle(); - - usbh_Poll(); /* 支持U盘 */ - - if (fRefresh) - { - fRefresh = 0; - - /* 实时刷新触摸ADC采样值和转换后的坐标 */ - { - LCD_DispStr(5, 3, "测试触摸屏、按键、摇杆、LED灯、PS/S键盘鼠标 红外遥控器", &tFont); /* 在(8,3)坐标处显示一串汉字 */ - - /* 显示TFT控制器型号和屏幕分辨率 */ - //LCD_GetChipDescribe(buf); /* 读取TFT驱动芯片型号 */ - if (g_TouchType == CT_GT811) - { - strcpy(buf, "STM32H743 + GT811"); - } - else if (g_TouchType == CT_GT911) - { - strcpy(buf, "STM32H743 + GT911"); - } - else if (g_TouchType == CT_FT5X06) - { - strcpy(buf, "STM32H743 + FT5X06"); - } - else if (g_TouchType == CT_STMPE811) - { - strcpy(buf, "STM32H743 + STMPE811"); - } - else - { - strcpy(buf, "STM32H743 + NoTouch"); - } - sprintf(&buf[strlen(buf)], " %d x %d", LCD_GetWidth(), LCD_GetHeight()); - LCD_DispStr(5, 23, buf, &tFont); /* 在(8,3)坐标处显示一串汉字 */ - - /* 读取并显示当前X轴和Y轴的ADC采样值 */ - usAdcX = TOUCH_ReadAdcX(); - usAdcY = TOUCH_ReadAdcY(); - sprintf(buf, "触摸ADC值 X = %4d, Y = %4d ", usAdcX, usAdcY); - LCD_DispStr(5, 60, buf, &tFont); - - /* 读取并显示当前触摸坐标 */ - tpX = TOUCH_GetX(); - tpY = TOUCH_GetY(); - sprintf(buf, "触摸坐标 X = %4d, Y = %4d ", tpX, tpY); - LCD_DispStr(5, 80, buf, &tFont); - - /* 在触笔所在位置显示一个小圈 */ - if ((tpX > 0) && (tpY > 0)) - { - LCD_DrawCircle(tpX, tpY, 2, CL_YELLOW); - } - } - - /* 显示图标阵列 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 失去焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - - /* 在屏幕边沿绘制2个矩形框(用于检测面板边缘像素是否正常) */ - LCD_DrawRect(0, 0, LCD_GetHeight(), LCD_GetWidth(), CL_WHITE); - LCD_DrawRect(2, 2, LCD_GetHeight() - 4, LCD_GetWidth() - 4, CL_YELLOW); - - /* 显示背光值 */ - sprintf(buf, "当前背光亮度: %3d", g_tParam.ucBackLight); - LCD_DispStr(5, 130, buf, &tFont); - - //if (g_ChipID == IC_8875) - { - /* 3.5寸屏不支持 */ - LCD_DispStr(5, LCD_GetHeight() - 20, "按K1 K2 键显示图片", &tFont); - } - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - BEEP_KeyTone(); /* 按键提示音 */ - - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - - /* 在触笔所在位置显示一个小圈 */ - if ((tpX > 0) && (tpY > 0)) - { - LCD_DrawCircle(tpX, tpY, 3, CL_RED); - } - break; - - case TOUCH_MOVE: /* 触笔移动事件 */ - /* 实时刷新触摸ADC采样值和转换后的坐标 */ - { - /* 读取并显示当前X轴和Y轴的ADC采样值 */ - usAdcX = TOUCH_ReadAdcX(); - usAdcY = TOUCH_ReadAdcY(); - sprintf(buf, "触摸ADC值 X = %4d, Y = %4d ", usAdcX, usAdcY); - LCD_DispStr(5, 60, buf, &tFont); - - /* 读取并显示当前触摸坐标 */ - //tpX = TOUCH_GetX(); - //tpY = TOUCH_GetY(); - sprintf(buf, "触摸坐标 X = %4d, Y = %4d ", tpX, tpY); - LCD_DispStr(5, 80, buf, &tFont); - - /* 在触笔所在位置显示一个小圈 */ - if ((tpX > 0) && (tpY > 0)) - { - LCD_DrawCircle(tpX, tpY, 2, CL_YELLOW); - } - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - /* 在触笔所在位置显示一个小圈 */ - if ((tpX > 0) && (tpY > 0)) - { - LCD_DrawCircle(tpX, tpY, 4, CL_WHITE); - } - - if (TOUCH_InRect(tpX, tpY, BUTTON_RET_X, BUTTON_RET_Y, BUTTON_RET_H, BUTTON_RET_W)) - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 1; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - - SaveParam(); /* 保存参数 */ - fQuit = 1; - break; /* 返回 */ - } - else /* 按钮失去焦点 */ - { - tBtn.Font = &tFontBtn; - - tBtn.Left = BUTTON_RET_X; - tBtn.Top = BUTTON_RET_Y; - tBtn.Height = BUTTON_RET_H; - tBtn.Width = BUTTON_RET_W; - tBtn.Focus = 0; /* 焦点 */ - tBtn.pCaption = "返回"; - LCD_DrawButton(&tBtn); - } - } - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 遥控按键发提示音 */ - if (ucKeyCode >= IR_KEY_STRAT) - { - BEEP_KeyTone(); /* 按键提示音 */ - } - - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 */ - bsp_LedOn(1); /* 点亮LED1 */ - { - if (s_pic > 0) - { - s_pic--; - } - DispPic(); /* 显示图片 */ - } - break; - - case KEY_UP_K1: /* K1键松开 */ - bsp_LedOff(1); /* 熄灭LED1 */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - bsp_LedOn(2); /* 点亮LED2 */ - { - if (s_pic < 14) - { - s_pic++; - } - DispPic(); /* 显示上一张图片 */ - } - break; - - case KEY_UP_K2: /* K2键松开 */ - //Label3.pCaption = "K2键松开"; - //LCD_DrawLabel(&Label3); - bsp_LedOff(2); /* 熄灭LED2 */ - break; - - case KEY_DOWN_K3: /* K3键按下 */ - Label3.pCaption = "K3键按下"; - LCD_DrawLabel(&Label3); - bsp_LedOn(3); /* 点亮LED3 */ - break; - - case KEY_UP_K3: /* K3键松开 */ - Label3.pCaption = "K3键松开"; - LCD_DrawLabel(&Label3); - bsp_LedOff(3); /* 熄灭LED3 */ - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - Label3.pCaption = "摇杆上键按下"; - LCD_DrawLabel(&Label3); - - if (g_tParam.ucBackLight < 255) - { - g_tParam.ucBackLight++; - } - LCD_SetBackLight(g_tParam.ucBackLight); /* 设置背光亮度 */ - fRefresh = 1; - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - Label3.pCaption = "摇杆下键按下"; - LCD_DrawLabel(&Label3); - if (g_tParam.ucBackLight > 0) - { - g_tParam.ucBackLight--; - } - LCD_SetBackLight(g_tParam.ucBackLight); /* 设置背光亮度 */ - fRefresh = 1; - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - Label3.pCaption = "摇杆左键按下"; - LCD_DrawLabel(&Label3); - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - Label3.pCaption = "摇杆右键按下"; - LCD_DrawLabel(&Label3); - bsp_DelayMS(500); - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - Label3.pCaption = "摇杆OK键按下"; - LCD_DrawLabel(&Label3); - bsp_LedOn(4); /* 点亮LED4 */ - break; - - case JOY_UP_OK: /* 摇杆OK键松开 */ - Label3.pCaption = "摇杆OK键松开"; - LCD_DrawLabel(&Label3); - bsp_LedOff(4); /* 熄灭LED4 */ - break; - - /* 下面是红外遥控器的事件 */ - case IR_KEY_POWER: - Label3.pCaption = "IR Power"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_MENU: - Label3.pCaption = "IR Menu"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_TEST: - Label3.pCaption = "IR Test"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_UP: - Label3.pCaption = "IR +"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_RETURN: - Label3.pCaption = "IR Return"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_LEFT: - Label3.pCaption = "IR Left"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_OK: - Label3.pCaption = "IR Ok"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_RIGHT: - Label3.pCaption = "IR Right"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_0: - Label3.pCaption = "IR 0"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_DOWN: - Label3.pCaption = "IR -"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_C: - Label3.pCaption = "IR C"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_1: - Label3.pCaption = "IR 1"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_2: - Label3.pCaption = "IR 2"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_3: - Label3.pCaption = "IR 3"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_4: - Label3.pCaption = "IR 4"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_5: - Label3.pCaption = "IR 5"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_6: - Label3.pCaption = "IR 6"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_7: - Label3.pCaption = "IR 7"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_8: - Label3.pCaption = "IR 8"; - LCD_DrawLabel(&Label3); - break; - - case IR_KEY_9: - Label3.pCaption = "IR 9"; - LCD_DrawLabel(&Label3); - break; - - default: - if (ucKeyCode >= IR_KEY_STRAT) - { - sprintf(buf, "IR 无法识别 %02X %02X %02X %02X", g_tIR.RxBuf[0], g_tIR.RxBuf[1], - g_tIR.RxBuf[2], g_tIR.RxBuf[3]); - - Label3.pCaption = buf; - LCD_DrawLabel(&Label3); - } - break; - } - } - - /* PS2按键检测由中断服务程序实现,我们只需要调用PS2_GetMsg读取键值即可。 */ - uiPS2Msg = PS2_GetMsg(); - if (uiPS2Msg != PS2_NONE) - { - //sprintf(buf, "%X\r\n", uiPS2Msg); - //Label1.pCaption = buf; - //LCD_DrawLabel(&Label1); - - if (uiPS2Msg == 0xAA) - { - Label1.pCaption = "检测到PS2键盘"; - LCD_DrawLabel(&Label1); - - PS2_InitKeyboard(); - } - if (uiPS2Msg == 0xAA00) - { - Label1.pCaption = "检测到PS2鼠标"; - LCD_DrawLabel(&Label1); - - PS2_InitMouse(); - } - - /* 打印PS2鼠标数据包解码结果 */ - if (PS2_IsMousePacket(uiPS2Msg)) - { - MOUSE_PACKET_T mouse; - - PS2_DecodeMouse(uiPS2Msg, &mouse); - - sprintf(buf, "X=%4d, Y=%4d, Z=%2d, 左键=%d, 中键=%d, 右键=%d", - mouse.Xmove, mouse.Ymove, mouse.Zmove, - mouse.BtnLeft, mouse.BtnMid, mouse.BtnRight); - - Label2.pCaption = buf; - LCD_DrawLabel(&Label2); - } - else /* 作为PS2键盘数据包处理 */ - { - sprintf(buf, "%s", GetNameOfKey(uiPS2Msg)); - Label2.pCaption = buf; - LCD_DrawLabel(&Label2); - } - } - } - - PS2_StopWork(); /* 停止PS2中断 */ - IRD_StopWork(); /* 停止红外解码 */ - - usbh_CloseMassStorage(); /* 关闭 USB HOST - U盘 */ -} - -/* -********************************************************************************************************* -* 函 数 名: DispPic -* 功能说明: 依次显示NAND Flash图片(3张)、SRAM单色图片(3张)、SD卡图片(3张)、U盘图片(3张)并计算刷屏时间 -* 形 参: 无 -* 返 回 值: 字符串指针 -********************************************************************************************************* -*/ -static void DispPic(void) -{ - char buf[64]; - - int32_t time1, time2; - FONT_T tFont; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - /* K1键切换背景图片 */ - if (s_pic <= 2) /* NAND FLASH 中的图片3张 */ - { - uint16_t color; - - if (s_pic == 0) - { - color = CL_RED; - } - else if (s_pic == 1) - { - color = CL_GREEN; - } - else - { - color = CL_BLUE; - } - - time1 = bsp_GetRunTime(); - - /* - DMA2D填充太快,只有几个ms,因此用示波器测量执行时间。 - 使用 J6排针的第10脚 --- 5.0V扩展输出口最高bit - 开始绘制前设置 Y50_7 = 1; 完毕后设置 Y50_7 = 0. - 2015-11-19 测试结果: (已经将DMA2D库函数就地展开进行优化) - - 480 * 272 屏 : 1.84ms - 800 * 480 屏 : 3.68ms - */ - HC574_SetPin(Y50_7, 1); /* Y50_7 = 1 */ - - if (LCD_GetWidth() == 480) /* 4.3寸屏 480x272 */ - { - LCD_Fill_Rect(0, 0, g_LcdHeight, g_LcdWidth, color); - } - else /* 5寸和7寸 800*480 屏 */ - { - LCD_Fill_Rect(0, 0, g_LcdHeight, g_LcdWidth, color); - } - - HC574_SetPin(Y50_7, 0); /* Y50_7 = 0, */ - - time2 = bsp_GetRunTime(); - sprintf(buf, "图片%d DMA2D单色填充, 显示时间: %4dms", s_pic + 1, time2 - time1); - LCD_DispStrEx(5, 5, buf, &tFont, 300, ALIGN_LEFT); - } - else if (s_pic >= 3 && s_pic <= 5) /* SDRAM 中单色图片3张 */ - { - uint16_t *p1 = (uint16_t *)SDRAM_APP_BUF; - - /* 填充1个单色区域 */ - { - uint32_t i; - uint16_t *p = (uint16_t *)SDRAM_APP_BUF; - uint16_t color; - - if (s_pic == 3) - { - color = CL_RED; - } - else if (s_pic == 4) - { - color = CL_GREEN; - } - else - { - color = CL_BLUE; - } - - for (i = 0; i < g_LcdHeight * g_LcdWidth; i++) - { - *p++ = color; - } - } - - time1 = bsp_GetRunTime(); - if (LCD_GetWidth() == 480) /* 4.3寸屏 480x272 */ - { - LCD_DrawBMP(0, 0, g_LcdHeight, g_LcdWidth, p1); - } - else /* 5寸和7寸 800*480 屏 */ - { - LCD_DrawBMP(0, 0, g_LcdHeight, g_LcdWidth, p1); - } - time2 = bsp_GetRunTime(); - sprintf(buf, "图片%d SDRAM, 显示时间: %4dms", s_pic + 1, time2 - time1); - LCD_DispStrEx(5, 5, buf, &tFont, 300, ALIGN_LEFT); - } - else if (s_pic >= 6 && s_pic <= 8) /* SD卡中的图片3张 */ - { - /* 访问Fatfs用到的全局变量 */ - FATFS fs; - char FileName[64]; - uint8_t err = 0; - char DiskPath[4]; /* 保存FatFS 磁盘路径 */ - - /* 每次读1行 */ - FATFS_LinkDriver(&SD_Driver, DiskPath); - - if (f_mount(&fs, DiskPath, 0) == FR_OK) - { - time1 = bsp_GetRunTime(); - - if (LCD_GetWidth() == 480) /* 4.3寸屏 480x272 */ - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_480x272[s_pic - 6]); - } - else - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_800x480[s_pic - 6]); - } - if (ReadFileDispPic(FileName, 0, 0, g_LcdHeight, g_LcdWidth) == 0) - { - err = 1; - } - - time2 = bsp_GetRunTime(); - } - else - { - err = 1; - } - - if (err == 1) - { - LCD_ClrScr(CL_BLUE); - sprintf(buf, "图片%d SD卡文件错误: %s", s_pic + 1, FileName); - } - else - { - sprintf(buf, "图片%d SD卡, 显示时间: %dms", s_pic + 1, time2 - time1); - } - LCD_DispStrEx(5, 5, buf, &tFont, 300, ALIGN_LEFT); - - /* 卸载文件系统 */ - f_mount(NULL, DiskPath, 0); - - FATFS_UnLinkDriver(DiskPath); - } - else if (s_pic >= 9 && s_pic <= 11) /* U盘中的图片3张 */ - { - /* 访问Fatfs用到的全局变量 */ - FATFS fs; - char FileName[64]; - uint8_t err = 0; - char DiskPath[4]; /* 保存FatFS 磁盘路径 */ - - /* 每次读1行 */ - FATFS_LinkDriver(&USBH_Driver, DiskPath); - - /* 每次读1行 */ - if (f_mount(&fs, DiskPath, 0) == FR_OK) - { - time1 = bsp_GetRunTime(); - - if (LCD_GetWidth() == 480) /* 4.3寸屏 480x272 */ - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_480x272[s_pic - 9]); - } - else - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_800x480[s_pic - 9]); - } - if (ReadFileDispPic(FileName, 0, 0, g_LcdHeight, g_LcdWidth) == 0) - { - err = 1; - } - - time2 = bsp_GetRunTime(); - } - else - { - printf("f_mount文件系统失败"); - err = 1; - } - - if (err == 1) - { - LCD_ClrScr(CL_BLUE); - sprintf(buf, "图片%d U盘文件错误:%s", s_pic + 1, FileName); - } - else - { - sprintf(buf, "图片%d U盘, 显示时间: %dms", s_pic + 1, time2 - time1); - } - LCD_DispStrEx(5, 5, buf, &tFont, 300, ALIGN_LEFT); - - /* 卸载文件系统 */ - f_mount(NULL, DiskPath, 0); - - FATFS_UnLinkDriver(DiskPath); - } - else if (s_pic >= 12 && s_pic <= 14) /* NAND FALSH的图片3张 */ - { - /* 访问Fatfs用到的全局变量 */ - FATFS fs; - char FileName[64]; - uint8_t err = 0; - char DiskPath[4]; /* 保存FatFS 磁盘路径 */ - - /* 每次读1行 */ - FATFS_LinkDriver(&nand_Driver, DiskPath); - - /* 每次读1行 */ - if (f_mount(&fs, DiskPath, 0) == FR_OK) - { - time1 = bsp_GetRunTime(); - - if (LCD_GetWidth() == 480) /* 4.3寸屏 480x272 */ - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_480x272[s_pic - 12]); - } - else - { - sprintf(FileName, "%sPic/%s", DiskPath, g_NandFileName_800x480[s_pic - 12]); - } - if (ReadFileDispPic(FileName, 0, 0, g_LcdHeight, g_LcdWidth) == 0) - { - err = 1; - } - - time2 = bsp_GetRunTime(); - } - else - { - printf("f_mount文件系统失败"); - err = 1; - } - - if (err == 1) - { - LCD_ClrScr(CL_BLUE); - sprintf(buf, "图片%d NAND Flash文件错误:%s", s_pic + 1, FileName); - } - else - { - sprintf(buf, "图片%d NAND Flash, 显示时间: %dms", s_pic + 1, time2 - time1); - } - LCD_DispStrEx(5, 5, buf, &tFont, 300, ALIGN_LEFT); - - /* 卸载文件系统 */ - f_mount(NULL, DiskPath, 0); - - FATFS_UnLinkDriver(DiskPath); - } -} - -/* -********************************************************************************************************* -* 函 数 名: ReadFileDispPic -* 功能说明: 读图片文件,并显示。 在调用本函数前,请确保 磁盘已经执行 f_mount -* 形 参: _strFileName : 文件全名,含磁盘号和全路径 -* 返 回 值: 0 表示错误, 1表示成功 -********************************************************************************************************* -*/ -uint8_t ReadFileDispPic(char *_strFileName, uint16_t _usX, uint16_t _usY, uint16_t usHeight, uint16_t usWidth) -{ - /* 访问Fatfs用到的全局变量 */ - // FATFS fs; - FIL file; - uint32_t bw; - // uint16_t data[800]; - uint16_t *pSDRAM = (uint16_t *)SDRAM_APP_BUF; - - if (usWidth > 800) - { - return 0; - } - -#if 1 - /* 打开文件 */ - { - FRESULT result; - - // uint16_t *p = (uint16_t *)(SDRAM_APP_BUF + g_LcdHeight * g_LcdWidth * 2); - - result = f_open(&file, _strFileName, FA_OPEN_EXISTING | FA_READ); - if (result != FR_OK) - { - printf("Open file Error, %s\r\n", _strFileName); - goto err_ret; - } - - memset((uint8_t *)pSDRAM, 0x51, usWidth * usHeight * 2); - - f_lseek(&file, 0); /* 修改文件当前指针到文件头, 从头开始读。 可以不做,缺省就是0 */ - f_read(&file, pSDRAM, usWidth * usHeight * 2, &bw); - - if (bw != usWidth * usHeight * 2) - { - printf("Open file Error, %s\r\n", _strFileName); - goto err_ret; - } - - /* 关闭文件*/ - f_close(&file); - - LCD_DrawBMP(_usX, _usY, usHeight, usWidth, pSDRAM); - } - -#else - /* 打开文件 */ - { - FRESULT result; - uint16_t i; - - result = f_open(&file, _strFileName, FA_OPEN_EXISTING | FA_READ); - if (result != FR_OK) - { - printf("Open file Error, %s\r\n", _strFileName); - goto err_ret; - } - - // f_lseek(&file, 0); /* 修改文件当前指针到文件头, 从头开始读。 可以不做,缺省就是0 */ - - for (i = 0; i < usHeight; i++) - { - f_read(&file, &data, usWidth * 2, &bw); - if (bw <= 0) - { - goto err_ret; - } - - LCD_DrawBMP(_usX, _usY + i, 1, usWidth, data); - } - } -#endif - - /* 关闭文件*/ - f_close(&file); - return 1; /* 返回OK */ - -err_ret: - /* 关闭文件*/ - f_close(&file); - return 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispKeyBoard -* 功能说明: 显示按键键名字 -* 形 参: 无 -* 返 回 值: 字符串指针 -********************************************************************************************************* -*/ -static const char *GetNameOfKey(uint32_t _code) -{ - uint16_t i = 0; - - while (1) - { - if (s_KeyNameTab[i].code == 0) - { - break; - } - - if (_code == s_KeyNameTab[i].code) - { - return s_KeyNameTab[i].str; - } - i++; - } - - return ""; -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormTouch -* 功能说明: 显示按键键名字 -* 形 参: 无 -* 返 回 值: 字符串指针 -********************************************************************************************************* -*/ -static void InitFormTouch(void) -{ - FontLabel.FontCode = FC_ST_16; - FontLabel.BackColor = CL_BLUE; - FontLabel.FrontColor = CL_WHITE; - FontLabel.Space = 0; - - Label3.Left = 5; - Label3.Top = 110; - Label3.MaxLen = 0; - Label3.pCaption = ""; - Label3.Font = &FontLabel; - - Label1.Left = 5; - Label1.Top = 150; - Label1.MaxLen = 0; - Label1.pCaption = ""; - Label1.Font = &FontLabel; - - Label2.Left = 5; - Label2.Top = 170; - Label2.MaxLen = 0; - Label2.pCaption = ""; - Label2.Font = &FontLabel; -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_usbd_msc.c b/User/app/src/old/form_usbd_msc.c deleted file mode 100755 index 8dfe270..0000000 --- a/User/app/src/old/form_usbd_msc.c +++ /dev/null @@ -1,577 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : SD卡和NAND Flash模拟U盘程序。 -* 文件名称 : usbd_msc_test.c -* 版 本 : V1.1 -* 说 明 : 使用USB Device接口,在PC上虚拟出2个U盘设备:SD卡 和 NAND Flash -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2013-02-01 armfly 首发 -* V1.1 2015-10-13 armfly K3键启动NAND坏块重新标记, 之前先关闭USB,避免PC和STM32同时访问NAND。 -* -* Copyright (C), 2015-2020, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "usbd_usr.h" /* usb底层驱动 */ - -#include "form_usbd_msc.h" - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 蓝色 */ - FONT_T FontRed; /* 变化的文字字体 红色 */ - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; /* SD卡状态 */ - LABEL_T Label3; - LABEL_T Label4; /* NAND状态 */ - LABEL_T Label5; - LABEL_T Label6; /* USBD状态 */ - - BUTTON_T Btn1; - BUTTON_T Btn2; - BUTTON_T Btn3; - BUTTON_T Btn4; - - BUTTON_T BtnRet; - -} FormUSB_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 4个框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "SD卡和NAND Flash模拟U盘" - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define BTN1_H 32 -#define BTN1_W 100 -#define BTN1_X (BOX1_X + 5) -#define BTN1_Y (BOX1_Y + 100) -#define BTN1_TEXT "打开模拟U盘" - -#define BTN2_H 32 -#define BTN2_W 100 -#define BTN2_X (BTN1_X + BTN1_W + 10) -#define BTN2_Y BTN1_Y -#define BTN2_TEXT "关闭模拟U盘" - -#define BTN3_H 32 -#define BTN3_W 100 -#define BTN3_X BTN1_X -#define BTN3_Y (BTN1_Y + BTN1_H + 10) -#define BTN3_TEXT "低格NAND" - -#define BTN4_H 32 -#define BTN4_W 100 -#define BTN4_X (BTN1_X + BTN1_W + 10) -#define BTN4_Y (BTN1_Y + BTN1_H + 10) -#define BTN4_TEXT "扫描坏块" - -/* 标签 */ -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (BOX1_Y + 20) -#define LABEL1_TEXT "SD卡状态 : " - -#define LABEL2_X (LABEL1_X + 100) -#define LABEL2_Y LABEL1_Y -#define LABEL2_TEXT "--" - -#define LABEL3_X (LABEL1_X) -#define LABEL3_Y (LABEL1_Y + 20) -#define LABEL3_TEXT "NAND状态 : " - -#define LABEL4_X (LABEL3_X + 100) -#define LABEL4_Y (LABEL3_Y) -#define LABEL4_TEXT "--" - -#define LABEL5_X (LABEL1_X) -#define LABEL5_Y (LABEL1_Y + 20 * 2) -#define LABEL5_TEXT "USBD状态 : " - -#define LABEL6_X (LABEL5_X + 100) -#define LABEL6_Y (LABEL5_Y) -#define LABEL6_TEXT "--" - -static void InitFormUSB(void); -static void DispUSBInitFace(void); - -FormUSB_T *FormUSB; - -/* -********************************************************************************************************* -* 函 数 名: TestUsbdMsc -* 功能说明: 虚拟U盘程序入口 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestUsbdMsc(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - uint8_t ucNandOk; - uint8_t ucCardOk; - uint8_t ucUsbOk; - FormUSB_T form; - uint8_t fRefresh; - - char buf[64]; - - FormUSB = &form; - - InitFormUSB(); - DispUSBInitFace(); - - { -#if 1 - NAND_DispBadBlockInfo(); /* 向串口1打印NAND Flash坏块信息 (此函数开头初始FSMC) */ - - /* 配置FSMC用于NAND Flash, 复位NAND Flash,重建LUT表 */ - if (NAND_Init() == NAND_OK) - { - printf("NAND_Init() Ok\r\n"); - ucNandOk = 1; - } - else - { - /* 建议在正式的产品中采用人为干预的方式启动低级格式化 */ - /* 自动检测nand flash是否进行了低级格式化,如果没有则执行格式化(2秒) */ - printf("NAND_Init() Error! \r\n"); - printf("Start Format(Low Level) NAND Flash......\r\n"); - if (NAND_Format() == NAND_OK) - { - printf("NAND Flash Format Ok\r\n"); - } - else - { - printf("NAND Flash Format Error\r\n"); - } - - ucNandOk = 1; - } - - if (NAND_GetBlockInfo(&nand) == 1) - { - ucNandOk = 1; - -#if 0 - NAND_DispParamPage(); /* 显示NAND 芯片版本信息 */ -#endif - } - else - { - ucNandOk = 0; - } -#endif - if (BSP_SD_Init() == MSD_OK) - { - ucCardOk = 1; - } - else - { - ucCardOk = 0; - } - } - - ucUsbOk = 1; - usbd_OpenMassStorage(); /* 初始化USB Device,配置为Mass Storage */ - - fRefresh = 1; - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (fRefresh) - { - fRefresh = 0; - - if (ucCardOk) - { - FormUSB->Label2.Font = &FormUSB->FontBlue; - FormUSB->Label2.pCaption = "Ok "; - } - else - { - FormUSB->Label2.Font = &FormUSB->FontRed; - FormUSB->Label2.pCaption = "Err"; - } - LCD_DrawLabel(&FormUSB->Label2); - - if (ucNandOk) - { - FormUSB->Label4.pCaption = buf; - sprintf(buf, "OK, %s, Bad=%d, Used=%d, Free=%d", nand.ChipName, nand.Bad, nand.Used, nand.Free); - - if (nand.Bad > 30) - { - /* 如果坏块个数大于30个,则显示红色 */ - FormUSB->Label4.Font = &FormUSB->FontRed; - } - else - { - /* 坏块数量在正常范围内,显示蓝色 */ - FormUSB->Label4.Font = &FormUSB->FontBlue; - } - } - else - { - FormUSB->Label4.Font = &FormUSB->FontRed; - FormUSB->Label4.pCaption = "Err"; - } - LCD_DrawLabel(&FormUSB->Label4); - - if (ucUsbOk) - { - FormUSB->Label6.Font = &FormUSB->FontBlue; - FormUSB->Label6.pCaption = "已打开 "; - } - else - { - FormUSB->Label6.Font = &FormUSB->FontRed; - FormUSB->Label6.pCaption = "已关闭"; - } - LCD_DrawLabel(&FormUSB->Label6); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - LCD_ButtonTouchDown(&FormUSB->BtnRet, tpX, tpY); - LCD_ButtonTouchDown(&FormUSB->Btn1, tpX, tpY); - LCD_ButtonTouchDown(&FormUSB->Btn2, tpX, tpY); - LCD_ButtonTouchDown(&FormUSB->Btn3, tpX, tpY); - LCD_ButtonTouchDown(&FormUSB->Btn4, tpX, tpY); - break; - - case TOUCH_MOVE: /* 触笔移动事件 */ - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormUSB->BtnRet, tpX, tpY)) - { - FormUSB->BtnRet.Focus = 0; - LCD_DrawButton(&FormUSB->BtnRet); - fQuit = 1; /* 返回 */ - } - else if (LCD_ButtonTouchRelease(&FormUSB->Btn1, tpX, tpY)) - { - FormUSB->Btn1.Focus = 0; - LCD_DrawButton(&FormUSB->Btn1); - - if (BSP_SD_Init() == MSD_OK) - { - ucCardOk = 1; - } - else - { - ucCardOk = 0; - } - usbd_OpenMassStorage(); /* 打开U盘 */ - ucUsbOk = 1; - fRefresh = 1; - } - else if (LCD_ButtonTouchRelease(&FormUSB->Btn2, tpX, tpY)) - { - usbd_CloseMassStorage(); /* 关闭U盘 */ - ucUsbOk = 0; - fRefresh = 1; - } - else if (LCD_ButtonTouchRelease(&FormUSB->Btn3, tpX, tpY)) - { - if (NAND_Format() == NAND_OK) - { - FormUSB->Label4.pCaption = "低级格式化成功"; - } - else - { - FormUSB->Label4.pCaption = "低级格式化失败"; - } - LCD_DrawLabel(&FormUSB->Label4); - } - else if (LCD_ButtonTouchRelease(&FormUSB->Btn4, tpX, tpY)) - { - if (ucUsbOk == 0) /* 关闭USB连接时才能访问NAND,否则USB中断程序会干扰扫描过程 */ - { - /* 重新扫描测试坏块,执行时间很长。 用于NAND 磁盘修复 */ - uint32_t i; - - FormUSB->Label4.pCaption = buf; - FormUSB->Label4.Font = &FormUSB->FontRed; - for (i = 0; i < NAND_BLOCK_COUNT; i++) - { - sprintf(buf, "扫描坏块... %d (%d%%) --- K1键终止", i, (i + 1) * 100 / NAND_BLOCK_COUNT); - LCD_DrawLabel(&FormUSB->Label4); - - if (NAND_ScanBlock(i) == NAND_OK) - { - ; - } - else - { - NAND_MarkBadBlock(i); /* 标记坏块 */ - } - - /* 如果有任意键按下,则退出 */ - if (bsp_GetKey() == KEY_DOWN_K1) - { - sprintf(buf, "扫描终止"); - LCD_DrawLabel(&FormUSB->Label4); - break; - } - } - } - - else - { - FormUSB->Label4.Font = &FormUSB->FontRed; - FormUSB->Label4.pCaption = buf; - sprintf(buf, "请先关闭模拟U盘功能"); - LCD_DrawLabel(&FormUSB->Label4); - } - } - else /* 按钮失去焦点 */ - { - LCD_ButtonTouchRelease(&FormUSB->BtnRet, tpX, tpY); - LCD_ButtonTouchRelease(&FormUSB->Btn1, tpX, tpY); - LCD_ButtonTouchRelease(&FormUSB->Btn2, tpX, tpY); - LCD_ButtonTouchRelease(&FormUSB->Btn3, tpX, tpY); - LCD_ButtonTouchRelease(&FormUSB->Btn4, tpX, tpY); - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键 */ - //printf("【1 - 移除U盘】\r\n"); - //usbd_CloseMassStorage(); - break; - - case KEY_DOWN_K2: /* K2键按下 */ - /* 使能U盘,软件模拟U盘插入 */ - //printf("【2 - 使能U盘】\r\n"); - //usbd_OpenMassStorage(); - break; - - case KEY_DOWN_K3: /* K3键按下 */ - ; - break; - - case JOY_DOWN_U: /* 摇杆UP键按下 */ - break; - - case JOY_DOWN_D: /* 摇杆DOWN键按下 */ - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 */ - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 */ - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - break; - - default: - break; - } - } - } - - usbd_CloseMassStorage(); /* 移除U盘 */ -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormUSB -* 功能说明: 初始化GPS初始界面控件 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormUSB(void) -{ - /* 分组框标题字体 */ - FormUSB->FontBox.FontCode = FC_ST_16; - FormUSB->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormUSB->FontBox.FrontColor = CL_BLACK; - FormUSB->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormUSB->FontBlack.FontCode = FC_ST_16; - FormUSB->FontBlack.BackColor = CL_MASK; /* 透明色 */ - FormUSB->FontBlack.FrontColor = CL_BLACK; - FormUSB->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormUSB->FontBlue.FontCode = FC_ST_16; - FormUSB->FontBlue.BackColor = CL_BTN_FACE; - FormUSB->FontBlue.FrontColor = CL_BLUE; - FormUSB->FontBlue.Space = 0; - - /* 字体3 用于变化的文字 */ - FormUSB->FontRed.FontCode = FC_ST_16; - FormUSB->FontRed.BackColor = CL_BTN_FACE; - FormUSB->FontRed.FrontColor = CL_RED; - FormUSB->FontRed.Space = 0; - - /* 按钮字体 */ - FormUSB->FontBtn.FontCode = FC_ST_16; - FormUSB->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormUSB->FontBtn.FrontColor = CL_BLACK; - FormUSB->FontBtn.Space = 0; - - /* 分组框 */ - FormUSB->Box1.Left = BOX1_X; - FormUSB->Box1.Top = BOX1_Y; - FormUSB->Box1.Height = BOX1_H; - FormUSB->Box1.Width = BOX1_W; - FormUSB->Box1.pCaption = BOX1_TEXT; - FormUSB->Box1.Font = &FormUSB->FontBox; - - /* 静态标签 */ - FormUSB->Label1.Left = LABEL1_X; - FormUSB->Label1.Top = LABEL1_Y; - FormUSB->Label1.MaxLen = 0; - FormUSB->Label1.pCaption = LABEL1_TEXT; - FormUSB->Label1.Font = &FormUSB->FontBlack; - - FormUSB->Label3.Left = LABEL3_X; - FormUSB->Label3.Top = LABEL3_Y; - FormUSB->Label3.MaxLen = 0; - FormUSB->Label3.pCaption = LABEL3_TEXT; - FormUSB->Label3.Font = &FormUSB->FontBlack; - - FormUSB->Label5.Left = LABEL5_X; - FormUSB->Label5.Top = LABEL5_Y; - FormUSB->Label5.MaxLen = 0; - FormUSB->Label5.pCaption = LABEL5_TEXT; - FormUSB->Label5.Font = &FormUSB->FontBlack; - - /* 动态标签 */ - FormUSB->Label2.Left = LABEL2_X; - FormUSB->Label2.Top = LABEL2_Y; - FormUSB->Label2.MaxLen = 0; - FormUSB->Label2.pCaption = LABEL2_TEXT; - FormUSB->Label2.Font = &FormUSB->FontBlue; - - FormUSB->Label4.Left = LABEL4_X; - FormUSB->Label4.Top = LABEL4_Y; - FormUSB->Label4.MaxLen = 0; - FormUSB->Label4.pCaption = LABEL4_TEXT; - FormUSB->Label4.Font = &FormUSB->FontBlue; - - FormUSB->Label6.Left = LABEL6_X; - FormUSB->Label6.Top = LABEL6_Y; - FormUSB->Label6.MaxLen = 0; - FormUSB->Label6.pCaption = LABEL6_TEXT; - FormUSB->Label6.Font = &FormUSB->FontBlue; - - /* 按钮 */ - FormUSB->BtnRet.Left = BTN_RET_X; - FormUSB->BtnRet.Top = BTN_RET_Y; - FormUSB->BtnRet.Height = BTN_RET_H; - FormUSB->BtnRet.Width = BTN_RET_W; - FormUSB->BtnRet.pCaption = BTN_RET_TEXT; - FormUSB->BtnRet.Font = &FormUSB->FontBtn; - FormUSB->BtnRet.Focus = 0; - - FormUSB->Btn1.Left = BTN1_X; - FormUSB->Btn1.Top = BTN1_Y; - FormUSB->Btn1.Height = BTN1_H; - FormUSB->Btn1.Width = BTN1_W; - FormUSB->Btn1.pCaption = BTN1_TEXT; - FormUSB->Btn1.Font = &FormUSB->FontBtn; - FormUSB->Btn1.Focus = 0; - - FormUSB->Btn2.Left = BTN2_X; - FormUSB->Btn2.Top = BTN2_Y; - FormUSB->Btn2.Height = BTN2_H; - FormUSB->Btn2.Width = BTN2_W; - FormUSB->Btn2.pCaption = BTN2_TEXT; - FormUSB->Btn2.Font = &FormUSB->FontBtn; - FormUSB->Btn2.Focus = 0; - - FormUSB->Btn3.Left = BTN3_X; - FormUSB->Btn3.Top = BTN3_Y; - FormUSB->Btn3.Height = BTN3_H; - FormUSB->Btn3.Width = BTN3_W; - FormUSB->Btn3.pCaption = BTN3_TEXT; - FormUSB->Btn3.Font = &FormUSB->FontBtn; - FormUSB->Btn3.Focus = 0; - - FormUSB->Btn4.Left = BTN4_X; - FormUSB->Btn4.Top = BTN4_Y; - FormUSB->Btn4.Height = BTN4_H; - FormUSB->Btn4.Width = BTN4_W; - FormUSB->Btn4.pCaption = BTN4_TEXT; - FormUSB->Btn4.Font = &FormUSB->FontBtn; - FormUSB->Btn4.Focus = 0; -} - -/* -********************************************************************************************************* -* 函 数 名: DispUSBInitFace -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispUSBInitFace(void) -{ - LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormUSB->Box1); - - /* 标签 */ - LCD_DrawLabel(&FormUSB->Label1); - LCD_DrawLabel(&FormUSB->Label2); - LCD_DrawLabel(&FormUSB->Label3); - LCD_DrawLabel(&FormUSB->Label4); - LCD_DrawLabel(&FormUSB->Label5); - LCD_DrawLabel(&FormUSB->Label6); - - /* 按钮 */ - LCD_DrawButton(&FormUSB->BtnRet); - LCD_DrawButton(&FormUSB->Btn1); - LCD_DrawButton(&FormUSB->Btn2); - LCD_DrawButton(&FormUSB->Btn3); - LCD_DrawButton(&FormUSB->Btn4); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/form_wifi.c b/User/app/src/old/form_wifi.c deleted file mode 100755 index 31abaff..0000000 --- a/User/app/src/old/form_wifi.c +++ /dev/null @@ -1,713 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 测试WIFI模块 -* 文件名称 : wifi_test.c -* 版 本 : V1.0 -* 说 明 : 测试串口WiFi模块. 使用串口超级终端工具可以操作本例子。为了测试AT指令 -* SecureCRT ,需要配置为: 菜单选项 -> 会话选项 -> 左侧栏终端 -> 仿真 -> 模式 -* 右侧窗口,当前模式中勾选"新行模式" -* 修改记录 : -* 版本号 日期 作者 说明 -* v1.0 2015-07-16 armfly 首发 -* -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ - -#include "bsp.h" -#include "form_wifi.h" -#include "num_pad.h" - -#define AP_MAX_NUM 30 - -/* 定义界面结构 */ -typedef struct -{ - FONT_T FontBlack; /* 静态的文字 */ - FONT_T FontBlue; /* 变化的文字字体 */ - FONT_T FontRed; - FONT_T FontBtn; /* 按钮的字体 */ - FONT_T FontBox; /* 分组框标题字体 */ - - GROUP_T Box1; - - LABEL_T Label1; - LABEL_T Label2; - LABEL_T Label3; - LABEL_T Label4; - LABEL_T Label5; - LABEL_T Label6; - LABEL_T Label7; - LABEL_T Label8; - - LABEL_T Label9; - - EDIT_T Edit1; /* WIFI密码 */ - - BUTTON_T Btn1; /* 列举AP */ - BUTTON_T Btn2; /* 加入AP */ - BUTTON_T Btn3; /* */ - BUTTON_T Btn4; /* */ - - BUTTON_T BtnRet; /* 返回 */ - - WIFI_AP_T APList[AP_MAX_NUM]; /* AP 列表 */ - -} FormWIFI_T; - -/* 窗体背景色 */ -#define FORM_BACK_COLOR CL_BTN_FACE - -/* 框的坐标和大小 */ -#define BOX1_X 5 -#define BOX1_Y 8 -#define BOX1_H (g_LcdHeight - BOX1_Y - 10) -#define BOX1_W (g_LcdWidth - 2 * BOX1_X) -#define BOX1_TEXT "ESP8266 WiFi模块测试程序." - -/* 返回按钮的坐标(屏幕右下角) */ -#define BTN_RET_H 32 -#define BTN_RET_W 60 -#define BTN_RET_X ((BOX1_X + BOX1_W) - BTN_RET_W - 4) -#define BTN_RET_Y ((BOX1_Y + BOX1_H) - BTN_RET_H - 4) -#define BTN_RET_TEXT "返回" - -#define LABEL1_X (BOX1_X + 6) -#define LABEL1_Y (g_LcdHeight - 28) -#define LABEL1_TEXT "--- " - -/* 按钮 */ -#define BTN1_H 32 -#define BTN1_W 120 -#define BTN1_X (g_LcdWidth - BTN1_W - 10) -#define BTN1_Y 20 -#define BTN1_TEXT "列举AP" - -/* Edit */ -#define EDIT1_X BTN1_X -#define EDIT1_Y (BTN1_Y + (BTN1_H + 2)) -#define EDIT1_H BTN1_H -#define EDIT1_W BTN1_W - -#define LABEL2_X EDIT1_X - 45 -#define LABEL2_Y EDIT1_Y + 4 -#define LABEL2_TEXT "密码:" - -#define BTN2_H BTN1_H -#define BTN2_W BTN1_W -#define BTN2_X BTN1_X -#define BTN2_Y (BTN1_Y + (BTN1_H + 2) * 2) -#define BTN2_TEXT "加入AP" - -#define BTN3_H BTN1_H -#define BTN3_W BTN1_W -#define BTN3_X BTN1_X -#define BTN3_Y (BTN1_Y + (BTN1_H + 2) * 3) -#define BTN3_TEXT "查看本机IP" - -#define BTN4_H BTN1_H -#define BTN4_W BTN1_W -#define BTN4_X BTN1_X -#define BTN4_Y (BTN1_Y + (BTN1_H + 2) * 4) -#define BTN4_TEXT "创建TCP服务" - -static void InitFormWIFI(void); -static void DispFormWIFI(void); -static void DispInfoWiFi(char *_str); - -FormWIFI_T *FormWIFI; - -int16_t g_APCount = 0; -uint8_t g_TCPServerOk = 0; - -static void ScanAP(void); -static void DispAP(void); -void AnlyzeHostCmd(void); - -/* -********************************************************************************************************* -* 函 数 名: TestWIFI -* 功能说明: 测试串口WiFi模块 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void TestWIFI(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t ucTouch; /* 触摸事件 */ - uint8_t fQuit = 0; - int16_t tpX, tpY; - uint8_t ucValue; - uint8_t fRefresh = 0; - FormWIFI_T form; - - FormWIFI = &form; - - LCD_ClrScr(CL_BTN_FACE); - - InitFormWIFI(); - DispFormWIFI(); - - bsp_InitESP8266(); - - //WiFiDispHelp(); - - DispInfoWiFi("【1】正在给ESP8266模块上电...(波特率: 74880bsp)"); - printf("\r\n【1】正在给ESP8266模块上电...(波特率: 74880bsp)\r\n"); - - ESP8266_PowerOn(); - - DispInfoWiFi("【2】上电完成。波特率: 115200bsp"); - printf("\r\n【2】上电完成。波特率: 115200bsp\r\n"); - - // - DispInfoWiFi("【3】测试AT指令"); - ESP8266_SendAT("AT"); - if (ESP8266_WaitResponse("OK", 50) == 1) - { - DispInfoWiFi("【3】模块应答AT成功"); - bsp_DelayMS(1000); - } - else - { - DispInfoWiFi("【3】模块无应答, 请按K3键修改模块的波特率为115200"); - bsp_DelayMS(1000); - } - - g_TCPServerOk = 0; - - /* 进入主程序循环体 */ - while (fQuit == 0) - { - bsp_Idle(); - - if (g_TCPServerOk == 1) - { - AnlyzeHostCmd(); - } - else - { - /* 从WIFI收到的数据发送到串口1 */ - if (comGetChar(COM_ESP8266, &ucValue)) - { - comSendChar(COM1, ucValue); - continue; - } - /* 将串口1的数据发送到MG323模块 */ - if (comGetChar(COM1, &ucValue)) - { - comSendChar(COM_ESP8266, ucValue); - continue; - } - } - - if (fRefresh) - { - fRefresh = 0; - - LCD_ClrScr(CL_BTN_FACE); - DispFormWIFI(); /* 刷新所有控件 */ - DispAP(); - } - - ucTouch = TOUCH_GetKey(&tpX, &tpY); /* 读取触摸事件 */ - if (ucTouch != TOUCH_NONE) - { - switch (ucTouch) - { - case TOUCH_DOWN: /* 触笔按下事件 */ - LCD_ButtonTouchDown(&FormWIFI->BtnRet, tpX, tpY); - LCD_ButtonTouchDown(&FormWIFI->Btn1, tpX, tpY); - LCD_ButtonTouchDown(&FormWIFI->Btn2, tpX, tpY); - LCD_ButtonTouchDown(&FormWIFI->Btn3, tpX, tpY); - LCD_ButtonTouchDown(&FormWIFI->Btn4, tpX, tpY); - - /* 编辑框 */ - if (TOUCH_InRect(tpX, tpY, EDIT1_X, EDIT1_Y, EDIT1_H, EDIT1_W)) - { - { - uint8_t len = 30; - - if (InputNumber(NUMPAD_STR, "输入WiFi密码", &len, (void *)FormWIFI->Edit1.Text)) - { - ; - } - fRefresh = 1; - } - } - break; - - case TOUCH_RELEASE: /* 触笔释放事件 */ - if (LCD_ButtonTouchRelease(&FormWIFI->BtnRet, tpX, tpY)) - { - fQuit = 1; /* 返回 */ - } - else if (LCD_ButtonTouchRelease(&FormWIFI->Btn1, tpX, tpY)) - { - ScanAP(); /* 扫描AP */ - DispAP(); - } - else if (LCD_ButtonTouchRelease(&FormWIFI->Btn2, tpX, tpY)) - { - int32_t sn = 0; - char buf[64]; - - if (InputInt("选择AP序号", 0, 20, &sn)) - { - LCD_ClrScr(CL_BTN_FACE); - DispFormWIFI(); /* 刷新所有控件 */ - DispAP(); - - if (sn > 1) - { - sn--; - } - - sprintf(buf, "正在加入AP... 请等待 %s", FormWIFI->APList[sn].ssid); - DispInfoWiFi(buf); - /* 加入AP 超时时间 10000ms,10秒 */ - if (ESP8266_JoinAP(FormWIFI->APList[sn].ssid, FormWIFI->Edit1.Text, 15000)) - { - DispInfoWiFi("接入AP成功"); - } - else - { - DispInfoWiFi("接入AP失败"); - } - } - else - { - LCD_ClrScr(CL_BTN_FACE); - DispFormWIFI(); /* 刷新所有控件 */ - DispAP(); - } - } - else if (LCD_ButtonTouchRelease(&FormWIFI->Btn3, tpX, tpY)) /* 查看本机IP */ - { - char ip[20]; - char mac[32]; - char buf[128]; - - if (ESP8266_GetLocalIP(ip, mac) == 1) - { - sprintf(buf, "%s, %s", ip, mac); - DispInfoWiFi(buf); - } - else - { - DispInfoWiFi("查询IP失败"); - } - } - else if (LCD_ButtonTouchRelease(&FormWIFI->Btn4, tpX, tpY)) /* 拨打10086 */ - { - if (g_TCPServerOk == 0) - { - if (ESP8266_CreateTCPServer(1000) == 1) - { - DispInfoWiFi("正在监听1000端口..."); - g_TCPServerOk = 1; - } - else - { - DispInfoWiFi("创建TCP服务失败!"); - } - } - else - { - ESP8266_CloseTcpUdp(0); - g_TCPServerOk = 0; - DispInfoWiFi("关闭当前TCP连接!"); - } - } - break; - } - } - - /* 处理按键事件 */ - ucKeyCode = bsp_GetKey(); - if (ucKeyCode > 0) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_DOWN_K1: /* K1键按下 */ - //ESP8266_SendAT("AT+CWLAP"); /* 列举AP */ - break; - - case KEY_DOWN_K2: /* K2键按下 */ - //ESP8266_SendAT("AT+CWJAP=\"Tenda_5BD8A8\",\"123456887af\""); /* 加入某个WIFI 网络 */ - //ESP8266_JoinAP("Tenda_5BD8A8", "123456887af"); - break; - - case KEY_DOWN_K3: /* K3键-9600波特率切换到115200 */ - comSetBaud(COM_ESP8266, 9600); /* 模块缺省是9600bps */ - ESP8266_SendAT("AT+CIOBAUD=115200"); /* 按 9600bps 发送指令切换为 115200 */ - ESP8266_WaitResponse("OK", 2000); /* 这个 OK 是模块按 9600 应答的 */ - comSetBaud(COM_ESP8266, 115200); /* 切换STM32的波特率为 115200 */ - - /* 切换为 Station模式 */ - bsp_DelayMS(100); - ESP8266_SendAT("AT+CWMODE=1"); - ESP8266_WaitResponse("OK", 2000); - bsp_DelayMS(1500); - ESP8266_SendAT("AT+RST"); - break; - - case JOY_DOWN_U: /* 摇杆上键, AT+CIFSR获取本地IP地址 */ - ESP8266_SendAT("AT+CIFSR"); - break; - - case JOY_DOWN_D: /* 摇杆DOWN键 AT+CIPSTATUS获得IP连接状态 */ - ESP8266_SendAT("AT+CIPSTATUS"); - break; - - case JOY_DOWN_L: /* 摇杆LEFT键按下 AT+CIPSTART 建立TCP连接. 访问www,armfly.com http服务端口 */ - ESP8266_SendAT("AT+CIPSTART=\"TCP\",\"WWW.ARMFLY.COM\",80"); - break; - - case JOY_DOWN_R: /* 摇杆RIGHT键按下 AT+CIPCLOSE关闭当前的TCP或UDP连接 */ - ESP8266_SendAT("AT+CIPCLOSE"); - break; - - case JOY_DOWN_OK: /* 摇杆OK键按下 */ - //printf("\r\n进入固件升级模式\r\n"); - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: AnlyzeHostCmd -* 功能说明: 分析TCP客户端发来的数据 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ - -void AnlyzeHostCmd(void) -{ - uint8_t cmd_buf[2048]; - //uint8_t *cmd_buf; - uint8_t cmd_len; - static uint8_t s_test = 0; - - //cmd_buf = (uint8_t *)EXT_SRAM_ADDR; /* 指向外部SRAM */ - cmd_len = ESP8266_RxNew(cmd_buf); - if (cmd_len == 0) - { - return; - } - - if (s_test == 1) - { - if ((cmd_len == 1) && (memcmp(cmd_buf, "A", 1)) == 0) - { - ESP8266_SendTcpUdp(cmd_buf, 1300); - } - } - else if (s_test == 2) - { - ESP8266_SendTcpUdp("OK", 2); - } - - if ((cmd_len == 6) && (memcmp(cmd_buf, "txtest", 6)) == 0) - { - s_test = 1; - ESP8266_SendTcpUdp(cmd_buf, 1300); - } - else if ((cmd_len == 6) && (memcmp(cmd_buf, "rxtest", 6)) == 0) - { - ESP8266_SendTcpUdp("OK", 2); - s_test = 2; - } - else if ((cmd_len == 4) && (memcmp(cmd_buf, "stop", 4)) == 0) - { - s_test = 0; - } - else - { - if (cmd_len == 7) - { - if (memcmp(cmd_buf, "ledon 1 ", 7) == 0) - { - bsp_LedOn(1); - ESP8266_SendTcpUdp("led1 on", 7); - } - else if (memcmp(cmd_buf, "ledon 2 ", 7) == 0) - { - bsp_LedOn(2); - ESP8266_SendTcpUdp("led2 on", 7); - } - else if (memcmp(cmd_buf, "ledon 3 ", 7) == 0) - { - bsp_LedOn(3); - ESP8266_SendTcpUdp("led3 on", 7); - } - else if (memcmp(cmd_buf, "ledon 4 ", 7) == 0) - { - bsp_LedOn(4); - ESP8266_SendTcpUdp("led4 on", 7); - } - } - else if (cmd_len == 8) - { - if (memcmp(cmd_buf, "ledoff 1", 8) == 0) - { - bsp_LedOff(1); - ESP8266_SendTcpUdp("led1 off", 8); - } - else if (memcmp(cmd_buf, "ledoff 2", 8) == 0) - { - bsp_LedOff(2); - ESP8266_SendTcpUdp("led2 off", 8); - } - else if (memcmp(cmd_buf, "ledoff 3", 8) == 0) - { - bsp_LedOff(3); - ESP8266_SendTcpUdp("led3 off", 8); - } - else if (memcmp(cmd_buf, "ledoff 4", 8) == 0) - { - bsp_LedOff(4); - ESP8266_SendTcpUdp("led4 off", 8); - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: ScanAP -* 功能说明: 扫描AP,并显示出来. -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void ScanAP(void) -{ - /* 扫描 AP列表, 返回AP个数 */ - g_APCount = ESP8266_ScanAP(FormWIFI->APList, AP_MAX_NUM); -} - -/* -********************************************************************************************************* -* 函 数 名: DispAP -* 功能说明: 显示扫描到的AP -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispAP(void) -{ - char buf[48]; - FONT_T tFont; - uint16_t x, y; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_GREY; /* 字体颜色 */ - tFont.BackColor = CL_BTN_FACE; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - } - - x = 10; - y = 25; - - LCD_Fill_Rect(x, y, 234, 280, CL_BTN_FACE); - - sprintf(buf, "共扫描到%d个WiFi AP", g_APCount); - DispInfoWiFi(buf); - - { - uint8_t i; - uint8_t m; - //const char *ecn_name[5] = - //{ - // "OPEN", "WEP", "WPA_PSK", "WPA2_PSK", "WPA_WPA2_PSK" - //}; - m = g_APCount; - if (m > 13) - { - m = 13; - } - for (i = 0; i < m; i++) - { - //sprintf(buf, " %02d=%s, rssi=%d, [%s]\r\n", i+1, g_APList[i].ssid, g_APList[i].rssi, - // ecn_name[g_APList[i].ecn]); - - sprintf(buf, "%02d=%s, %ddBm", i + 1, FormWIFI->APList[i].ssid, FormWIFI->APList[i].rssi); - - LCD_DispStr(x, y, buf, &tFont); - y += 17; - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: InitFormWIFI -* 功能说明: 初始化控件属性 -* 形 参:无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void InitFormWIFI(void) -{ - /* 分组框标题字体 */ - FormWIFI->FontBox.FontCode = FC_ST_16; - FormWIFI->FontBox.BackColor = CL_BTN_FACE; /* 和背景色相同 */ - FormWIFI->FontBox.FrontColor = CL_BLACK; - FormWIFI->FontBox.Space = 0; - - /* 字体1 用于静止标签 */ - FormWIFI->FontBlack.FontCode = FC_ST_16; - FormWIFI->FontBlack.BackColor = CL_BTN_FACE; /* 透明色 */ - FormWIFI->FontBlack.FrontColor = CL_BLACK; - FormWIFI->FontBlack.Space = 0; - - /* 字体2 用于变化的文字 */ - FormWIFI->FontBlue.FontCode = FC_ST_16; - FormWIFI->FontBlue.BackColor = CL_BTN_FACE; - FormWIFI->FontBlue.FrontColor = CL_BLUE; - FormWIFI->FontBlue.Space = 0; - - FormWIFI->FontRed.FontCode = FC_ST_16; - FormWIFI->FontRed.BackColor = CL_BTN_FACE; - FormWIFI->FontRed.FrontColor = CL_RED; - FormWIFI->FontRed.Space = 0; - - /* 按钮字体 */ - FormWIFI->FontBtn.FontCode = FC_ST_16; - FormWIFI->FontBtn.BackColor = CL_MASK; /* 透明背景 */ - FormWIFI->FontBtn.FrontColor = CL_BLACK; - FormWIFI->FontBtn.Space = 0; - - /* 分组框 */ - FormWIFI->Box1.Left = BOX1_X; - FormWIFI->Box1.Top = BOX1_Y; - FormWIFI->Box1.Height = BOX1_H; - FormWIFI->Box1.Width = BOX1_W; - FormWIFI->Box1.pCaption = BOX1_TEXT; - FormWIFI->Box1.Font = &FormWIFI->FontBox; - - /* 静态标签 */ - FormWIFI->Label1.Left = LABEL1_X; - FormWIFI->Label1.Top = LABEL1_Y; - FormWIFI->Label1.MaxLen = 0; - FormWIFI->Label1.pCaption = LABEL1_TEXT; - FormWIFI->Label1.Font = &FormWIFI->FontBlack; - - FormWIFI->Label2.Left = LABEL2_X; - FormWIFI->Label2.Top = LABEL2_Y; - FormWIFI->Label2.MaxLen = 0; - FormWIFI->Label2.pCaption = LABEL2_TEXT; - FormWIFI->Label2.Font = &FormWIFI->FontBlack; - - /* 按钮 */ - FormWIFI->BtnRet.Left = BTN_RET_X; - FormWIFI->BtnRet.Top = BTN_RET_Y; - FormWIFI->BtnRet.Height = BTN_RET_H; - FormWIFI->BtnRet.Width = BTN_RET_W; - FormWIFI->BtnRet.pCaption = BTN_RET_TEXT; - FormWIFI->BtnRet.Font = &FormWIFI->FontBtn; - FormWIFI->BtnRet.Focus = 0; - - FormWIFI->Btn1.Left = BTN1_X; - FormWIFI->Btn1.Top = BTN1_Y; - FormWIFI->Btn1.Height = BTN1_H; - FormWIFI->Btn1.Width = BTN1_W; - FormWIFI->Btn1.pCaption = BTN1_TEXT; - FormWIFI->Btn1.Font = &FormWIFI->FontBtn; - FormWIFI->Btn1.Focus = 0; - - FormWIFI->Btn2.Left = BTN2_X; - FormWIFI->Btn2.Top = BTN2_Y; - FormWIFI->Btn2.Height = BTN2_H; - FormWIFI->Btn2.Width = BTN2_W; - FormWIFI->Btn2.pCaption = BTN2_TEXT; - FormWIFI->Btn2.Font = &FormWIFI->FontBtn; - FormWIFI->Btn2.Focus = 0; - - FormWIFI->Btn3.Left = BTN3_X; - FormWIFI->Btn3.Top = BTN3_Y; - FormWIFI->Btn3.Height = BTN3_H; - FormWIFI->Btn3.Width = BTN3_W; - FormWIFI->Btn3.pCaption = BTN3_TEXT; - FormWIFI->Btn3.Font = &FormWIFI->FontBtn; - FormWIFI->Btn3.Focus = 0; - - FormWIFI->Btn4.Left = BTN4_X; - FormWIFI->Btn4.Top = BTN4_Y; - FormWIFI->Btn4.Height = BTN4_H; - FormWIFI->Btn4.Width = BTN4_W; - FormWIFI->Btn4.pCaption = BTN4_TEXT; - FormWIFI->Btn4.Font = &FormWIFI->FontBtn; - FormWIFI->Btn4.Focus = 0; - - /* 编辑框 */ - FormWIFI->Edit1.Left = EDIT1_X; - FormWIFI->Edit1.Top = EDIT1_Y; - FormWIFI->Edit1.Height = EDIT1_H; - FormWIFI->Edit1.Width = EDIT1_W; - sprintf(FormWIFI->Edit1.Text, "123456887af"); - FormWIFI->Edit1.pCaption = FormWIFI->Edit1.Text; - FormWIFI->Edit1.Font = &FormWIFI->FontBtn; -} - -/* -********************************************************************************************************* -* 函 数 名: DispInfoWiFi -* 功能说明: 显示信息 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispInfoWiFi(char *_str) -{ - FormWIFI->Label1.pCaption = _str; - LCD_DrawLabel(&FormWIFI->Label1); -} - -/* -********************************************************************************************************* -* 函 数 名: DispFormWIFI -* 功能说明: 显示所有的控件 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -static void DispFormWIFI(void) -{ - //LCD_ClrScr(CL_BTN_FACE); - - /* 分组框 */ - LCD_DrawGroupBox(&FormWIFI->Box1); - - /* 标签 */ - LCD_DrawLabel(&FormWIFI->Label1); - LCD_DrawLabel(&FormWIFI->Label2); - - /* 按钮 */ - LCD_DrawButton(&FormWIFI->BtnRet); - LCD_DrawButton(&FormWIFI->Btn1); - LCD_DrawButton(&FormWIFI->Btn2); - LCD_DrawButton(&FormWIFI->Btn3); - LCD_DrawButton(&FormWIFI->Btn4); - - /* 编辑框 */ - LCD_DrawEdit(&FormWIFI->Edit1); - - /* 动态标签 */ - LCD_DrawLabel(&FormWIFI->Label2); -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/old/status_menu.c b/User/app/src/old/status_menu.c deleted file mode 100755 index cb0c91f..0000000 --- a/User/app/src/old/status_menu.c +++ /dev/null @@ -1,390 +0,0 @@ -/* -********************************************************************************************************* -* -* 模块名称 : 程序功能选择 -* 文件名称 : status_MenuMain.c -* 版 本 : V1.0 -* 说 明 : -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2018-12-06 armfly 正式发布 -* -* Copyright (C), 2018-2030, 安富莱电子 www.armfly.com -* -********************************************************************************************************* -*/ -#include "bsp.h" -#include "param.h" -#include "main.h" -#include "images.h" /* 图标文件 */ -#include "status_menu.h" -#include "modbus_reg_addr.h" - -#define FORM_BACK_COLOR CL_BLUE - -#define ICON_HEIGHT 48 /* 矩形图标高度 */ -#define ICON_WIDTH 48 /* 矩形图标宽度 */ - -#define ICON_STEP_X 80 /* 图标之间的间隔 */ -#define ICON_STEP_Y 70 /* 图标之间的间隔 */ - -#define MENU_COUNT 5 -static const ICON_T s_tMainIcons[MENU_COUNT] = - { - {ID_ICON, 40, 20, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acchujiao, "1.联机模式"}, - {ID_ICON, 40, 20, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acLCD, "2.电压表"}, - {ID_ICON, 40, 20, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acRadio, "3.NTC测温"}, - {ID_ICON, 40, 20, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acRecorder, "4.电阻表"}, - {ID_ICON, 40, 20, ICON_HEIGHT, ICON_WIDTH, (uint16_t *)acchujiao, "5.负载电流"}, -}; - -/* -********************************************************************************************************* -* 函 数 名: status_MenuMain -* 功能说明: 功能菜单 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void status_MenuMain(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t fRefresh; - FONT_T tFont; /* 定义字体结构体变量 */ - FONT_T tIconFont; /* 定义一个字体结构体变量,用于图标文本 */ - static uint8_t s_menu_idx = 0; - uint8_t ucIgnoreKey = 0; - - /* 设置字体参数 */ - { - uint16_t x; - uint16_t y; - char buf[64]; - - tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_YELLOW; /* 字体颜色 */ - tFont.BackColor = FORM_BACK_COLOR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - LCD_ClrScr(FORM_BACK_COLOR); /* 清屏,背景蓝色 */ - - x = 5; - - y = 3; - LCD_DispStr(x, y, "选择功能", &tFont); - - y = y + 20; - sprintf(buf, "MAC:%02X-%02X-%02X-%02X-%02X-%02X", - g_tVar.MACaddr[0], g_tVar.MACaddr[1], g_tVar.MACaddr[2], - g_tVar.MACaddr[3], g_tVar.MACaddr[4], g_tVar.MACaddr[5]); - LCD_DispStr(x, y, buf, &tFont); - - y = y + 20; - sprintf(buf, "IP:%d.%d.%d.%d", - g_tVar.MACaddr[0], g_tVar.MACaddr[1], g_tVar.MACaddr[2], - g_tVar.MACaddr[3], g_tVar.MACaddr[4], g_tVar.MACaddr[5]); - LCD_DispStr(x, y, buf, &tFont); - - LCD_SetBackLight(BRIGHT_DEFAULT); /* 打开背光,设置为缺省亮度 */ - - /* 设置字体参数 */ - { - tIconFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ - tIconFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tIconFont.BackColor = CL_BLUE; /* 文字背景颜色 */ - tIconFont.Space = 1; /* 文字间距,单位 = 像素 */ - } - } - - bsp_ClearKey(); /* 清缓存的按键 */ - - /* 从其他界面返回后需要忽略第1个C键弹起事件 */ - if (bsp_GetKeyState(KID_S) || bsp_GetKeyState(KID_C)) - { - ucIgnoreKey = 1; - } - - fRefresh = 1; - while (g_MainStatus == MS_MAIN_MENU) - { - bsp_Idle(); - - if (fRefresh) /* 刷新整个界面 */ - { - fRefresh = 0; - LCD_DrawIcon32(&s_tMainIcons[s_menu_idx], &tIconFont, 0); - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_UP_S: /* S键 */ - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - if (++s_menu_idx >= MENU_COUNT) - { - s_menu_idx = 0; - } - fRefresh = 1; - break; - - case KEY_UP_C: /* C键 */ - if (ucIgnoreKey == 1) - { - ucIgnoreKey = 0; /* 丢弃第1个按键弹起事件 */ - break; - } - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - if (s_menu_idx > 0) - { - s_menu_idx--; - } - else - { - s_menu_idx = MENU_COUNT - 1; - } - fRefresh = 1; - break; - - case KEY_LONG_S: /* S键 */ - BEEP_KeyTone(); - g_MainStatus = MS_SYSTEM_SET; - break; - - case KEY_LONG_C: /* C键 */ - BEEP_KeyTone(); - if (++g_tParam.DispDir > 3) - { - g_tParam.DispDir = 0; - } - LCD_SetDirection(g_tParam.DispDir); - SaveParam(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - ucIgnoreKey = 1; - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: status_LinkMode -* 功能说明: 联机模式(功能由上位机控制) -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void status_LinkMode(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t fRefresh; - FONT_T tFont; /* 定义字体结构体变量 */ - FONT_T tIconFont; /* 定义一个字体结构体变量,用于图标文本 */ - static uint8_t s_menu_idx = 0; - uint8_t ucIgnoreKey = 0; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_24; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = FORM_BACK_COLOR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - LCD_ClrScr(FORM_BACK_COLOR); /* 清屏,背景蓝色 */ - - LCD_DispStr(5, 3, "直流电压表", &tFont); - } - - bsp_ClearKey(); /* 清缓存的按键 */ - - /* 从其他界面返回后需要忽略第1个C键弹起事件 */ - if (bsp_GetKeyState(KID_S) || bsp_GetKeyState(KID_C)) - { - ucIgnoreKey = 1; - } - - /* 初始化DSO硬件电路 */ - { - DSO_InitHard(); - DSO_SetDC(1, 1); /* CH1 选DC耦合 */ - DSO_SetDC(2, 1); /* CH2 选DC耦合 */ - DSO_SetGain(1, 0); /* CH1 增益选择最小(量程最大) */ - DSO_SetGain(2, 0); /* CH2 增益选择最小(量程最大) */ - } - - fRefresh = 1; - bsp_StartAutoTimer(0, 100); /* 100ms 刷新 */ - while (g_MainStatus == MS_VOLT_METER) - { - bsp_Idle(); - - if (fRefresh) /* 刷新整个界面 */ - { - fRefresh = 0; - ; - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_UP_S: /* S键 */ - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - break; - - case KEY_UP_C: /* C键 */ - if (ucIgnoreKey == 1) - { - ucIgnoreKey = 0; /* 丢弃第1个按键弹起事件 */ - break; - } - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - break; - - case KEY_LONG_S: /* S键 */ - BEEP_KeyTone(); - g_MainStatus = MS_SYSTEM_SET; - break; - - case KEY_LONG_C: /* C键 */ - BEEP_KeyTone(); - if (++g_tParam.DispDir > 3) - { - g_tParam.DispDir = 0; - } - LCD_SetDirection(g_tParam.DispDir); - SaveParam(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - ucIgnoreKey = 1; - break; - - default: - break; - } - } - } -} - -/* -********************************************************************************************************* -* 函 数 名: status_VoltMeter -* 功能说明: 电压表 -* 形 参: 无 -* 返 回 值: 无 -********************************************************************************************************* -*/ -void status_VoltMeter(void) -{ - uint8_t ucKeyCode; /* 按键代码 */ - uint8_t fRefresh; - FONT_T tFont; /* 定义字体结构体变量 */ - FONT_T tIconFont; /* 定义一个字体结构体变量,用于图标文本 */ - static uint8_t s_menu_idx = 0; - uint8_t ucIgnoreKey = 0; - - /* 设置字体参数 */ - { - tFont.FontCode = FC_ST_24; /* 字体代码 16点阵 */ - tFont.FrontColor = CL_WHITE; /* 字体颜色 */ - tFont.BackColor = FORM_BACK_COLOR; /* 文字背景颜色 */ - tFont.Space = 0; /* 文字间距,单位 = 像素 */ - - LCD_ClrScr(FORM_BACK_COLOR); /* 清屏,背景蓝色 */ - - LCD_DispStr(5, 3, "直流电压表", &tFont); - } - - bsp_ClearKey(); /* 清缓存的按键 */ - - /* 从其他界面返回后需要忽略第1个C键弹起事件 */ - if (bsp_GetKeyState(KID_S) || bsp_GetKeyState(KID_C)) - { - ucIgnoreKey = 1; - } - - /* 初始化DSO硬件电路 */ - { - DSO_InitHard(); - DSO_SetDC(1, 1); /* CH1 选DC耦合 */ - DSO_SetDC(2, 1); /* CH2 选DC耦合 */ - DSO_SetGain(1, 0); /* CH1 增益选择最小(量程最大) */ - DSO_SetGain(2, 0); /* CH2 增益选择最小(量程最大) */ - } - - fRefresh = 1; - bsp_StartAutoTimer(0, 100); /* 100ms 刷新 */ - while (g_MainStatus == MS_VOLT_METER) - { - bsp_Idle(); - - if (fRefresh) /* 刷新整个界面 */ - { - fRefresh = 0; - ; - } - - ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ - if (ucKeyCode != KEY_NONE) - { - /* 有键按下 */ - switch (ucKeyCode) - { - case KEY_UP_S: /* S键 */ - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - break; - - case KEY_UP_C: /* C键 */ - if (ucIgnoreKey == 1) - { - ucIgnoreKey = 0; /* 丢弃第1个按键弹起事件 */ - break; - } - BEEP_KeyTone(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - break; - - case KEY_LONG_S: /* S键 */ - BEEP_KeyTone(); - g_MainStatus = MS_SYSTEM_SET; - break; - - case KEY_LONG_C: /* C键 */ - BEEP_KeyTone(); - if (++g_tParam.DispDir > 3) - { - g_tParam.DispDir = 0; - } - LCD_SetDirection(g_tParam.DispDir); - SaveParam(); - LCD_ClrScr(CL_BLUE); - fRefresh = 1; - ucIgnoreKey = 1; - break; - - default: - break; - } - } - } -} - -/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/status_current_meter.c b/User/app/src/status_current_meter.c index ccfd1a0..3a2535c 100755 --- a/User/app/src/status_current_meter.c +++ b/User/app/src/status_current_meter.c @@ -24,7 +24,7 @@ static void DispHelpCurrentMeter(void); /* ********************************************************************************************************* * 函 数 名: status_CurrentMeter -* 功能说明: 高侧电压电流表态. +* 功能说明: 高侧电压电流表状态. * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* diff --git a/User/app/src/status_link_mode.c b/User/app/src/status_link_mode.c index 72b5999..471d12e 100755 --- a/User/app/src/status_link_mode.c +++ b/User/app/src/status_link_mode.c @@ -142,6 +142,8 @@ void status_LinkMode(void) usbd_CloseCDC(); usbd_OpenCDC(1); /* 启用USB虚拟串口1, 用于虚拟串口,RS232 RS485 TTL-UART */ } + + DSO_StartMode2(); /* 示波器启动模式2-低速多通道扫描 */ } /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/status_tvcc_power.c b/User/app/src/status_tvcc_power.c new file mode 100644 index 0000000..c800725 --- /dev/null +++ b/User/app/src/status_tvcc_power.c @@ -0,0 +1,214 @@ +/* +********************************************************************************************************* +* +* 模块名称 : 微型数控电源 +* 文件名称 : status_TVccPower.c +* 版 本 : V1.0 +* 说 明 : 通过TVCC输出可调电压。电压范围1.2-5.0V,电流限制400mA +* 修改记录 : +* 版本号 日期 作者 说明 +* V1.0 2019-11-04 armfly 正式发布1 +* +* Copyright (C), 2018-2030, 安富莱电子 www.armfly.com +* +********************************************************************************************************* +*/ +#include "bsp.h" +#include "main.h" + +static void DispTVccVoltCurr(void); +static void DispHelpTVCCPower(void); +static void DispTVccSetting(uint16_t _volt); + +/* +********************************************************************************************************* +* 函 数 名: status_TVCCPower +* 功能说明: 微型电源状态。TVCC引脚输出电压可调,电流可以监视。400mA限流。 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void status_TVCCPower(void) +{ + uint8_t ucKeyCode; /* 按键代码 */ + uint8_t fRefresh; + uint8_t ucIgnoreKey = 0; + uint8_t ucAdjustMode = 0; + uint16_t NowVolt; /* 当前设置电压 mV */ + + DispHeader("微型数控电源"); + DispHelpTVCCPower(); + + fRefresh = 1; + + NowVolt = 3300; + DispTVccSetting(NowVolt); + bsp_StartAutoTimer(0, 300); + while (g_MainStatus == MS_TVCC_POWER) + { + bsp_Idle(); + + if (fRefresh) /* 刷新整个界面 */ + { + fRefresh = 0; + + bsp_SetTVCC(NowVolt); + DispTVccVoltCurr(); + } + + if (bsp_CheckTimer(0)) + { + fRefresh = 1; + } + + ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */ + if (ucKeyCode != KEY_NONE) + { + /* 有键按下 */ + switch (ucKeyCode) + { + case KEY_DOWN_S: /* S键按下 */ + break; + + case KEY_UP_S: /* S键释放 */ + if (ucAdjustMode == 0) + { + g_MainStatus = NextStatus(MS_TVCC_POWER); + } + else + { + if (NowVolt < 5000) + { + NowVolt += 100; + DispTVccSetting(NowVolt); + } + else + { + BEEP_Start(5, 5, 3); /* 叫50ms,停50ms,循环3次 */ + } + } + break; + + case KEY_LONG_S: /* S键长按 */ + ucAdjustMode = 1; + BEEP_KeyTone(); + break; + + case KEY_DOWN_C: /* C键按下 */ + break; + + case KEY_UP_C: /* C键释放 */ + if (ucAdjustMode == 0 && ucIgnoreKey == 0) + { + g_MainStatus = LastStatus(MS_TVCC_POWER); + } + else + { + if (NowVolt > 1200) + { + NowVolt -= 100; + DispTVccSetting(NowVolt); + } + else + { + BEEP_Start(5,5,3); /* 叫50ms,停50ms,循环3次 */ + } + } + ucIgnoreKey = 0; + break; + + case KEY_LONG_C: /* C键长按 */ + ucAdjustMode = 0; + ucIgnoreKey = 1; /* 需要丢弃即将到来的C键弹起事件 */ + BEEP_KeyTone(); + break; + + default: + break; + } + } + } + bsp_StopTimer(0); + + bsp_SetTVCC(3300); /* 退出时还原为3.3V */ +} + +/* +********************************************************************************************************* +* 函 数 名: DispHelpTVCCPower +* 功能说明: 显示操作提示 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +static void DispHelpTVCCPower(void) +{ + FONT_T tFont; /* 定义字体结构体变量 */ + + tFont.FontCode = FC_ST_16; /* 字体代码 16点阵 */ + tFont.FrontColor = CL_YELLOW; /* 字体颜色 */ + tFont.BackColor = FORM_BACK_COLOR; /* 文字背景颜色 */ + tFont.Space = 0; /* 文字间距,单位 = 像素 */ + tFont.FrontColor = CL_BLACK; /* 黑字 */ + + LCD_DispStr(5, 240 - 40, "TVCC输出1.2-5.0V, 限流400mA", &tFont); + LCD_DispStr(5, 240 - 20, "长按S进入调节状态", &tFont); +} + +/* +********************************************************************************************************* +* 函 数 名: DispTVccVoltCurr +* 功能说明: 显示电压电流 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +static void DispTVccVoltCurr(void) +{ + FONT_T tFont; + char buf[64]; + + /* 设置字体参数 */ + { + tFont.FontCode = FC_ST_24; /* 字体代码 16点阵 */ + tFont.FrontColor = CL_WHITE; /* 字体颜色 */ + tFont.BackColor = HEAD_BAR_COLOR; /* 文字背景颜色 */ + tFont.Space = 0; /* 文字间距,单位 = 像素 */ + } + + sprintf(buf, "电压: %8.3fV", g_tVar.TVCCVolt ); + LCD_DispStrEx(10, 50 + 32 * 0, buf, &tFont, 220, ALIGN_CENTER); + + sprintf(buf, "电流: %8.2fmA", g_tVar.TVCCCurr); + LCD_DispStrEx(10, 50 + 32 * 1, buf, &tFont, 220, ALIGN_CENTER); + + sprintf(buf, "功率: %8.3fW", g_tVar.TVCCVolt * g_tVar.TVCCCurr / 1000); + LCD_DispStrEx(10, 50 + 32 * 2, buf, &tFont, 220, ALIGN_CENTER); +} + +/* +********************************************************************************************************* +* 函 数 名: DispTVccSetting +* 功能说明: 显示设置电压 +* 形 参: _volt : mV (1200 - 5000) +* 返 回 值: 无 +********************************************************************************************************* +*/ +static void DispTVccSetting(uint16_t _volt) +{ + FONT_T tFont; + char buf[64]; + + /* 设置字体参数 */ + { + tFont.FontCode = FC_ST_24; /* 字体代码 16点阵 */ + tFont.FrontColor = CL_YELLOW; /* 字体颜色 */ + tFont.BackColor = HEAD_BAR_COLOR; /* 文字背景颜色 */ + tFont.Space = 0; /* 文字间距,单位 = 像素 */ + } + + sprintf(buf, "设置电压: %d.%dV", _volt / 1000, (_volt % 1000) / 100); + LCD_DispStrEx(10, 70 + 32 * 3, buf, &tFont, 220, ALIGN_CENTER); +} + +/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/ diff --git a/User/app/src/status_voltage_meter.c b/User/app/src/status_voltage_meter.c index 2da52ff..b6b3c8b 100755 --- a/User/app/src/status_voltage_meter.c +++ b/User/app/src/status_voltage_meter.c @@ -34,8 +34,6 @@ void status_VoltageMeter(void) DispHeader("电压表"); - DSO_StartMode2(); /* 示波器启动模式2-低速多通道扫描 */ - fRefresh = 1; bsp_StartAutoTimer(0, 300); diff --git a/User/bsp/bsp.c b/User/bsp/bsp.c index 77825f9..d743338 100755 --- a/User/bsp/bsp.c +++ b/User/bsp/bsp.c @@ -125,8 +125,8 @@ void bsp_Init(void) */ static void SystemClock_Config(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; HAL_StatusTypeDef ret = HAL_OK; diff --git a/User/bsp/inc/bsp_timer.h b/User/bsp/inc/bsp_timer.h index b997508..f02fd8c 100755 --- a/User/bsp/inc/bsp_timer.h +++ b/User/bsp/inc/bsp_timer.h @@ -23,7 +23,7 @@ /* 定时器结构体,成员变量必须是 volatile, 否则C编译器优化时可能有问题 */ typedef enum { - TMR_ONCE_MODE = 0, /* 一次工作模式 */ + TMR_ONCE_MODE = 0, /* 一次工作模式 */ TMR_AUTO_MODE = 1 /* 自动定时工作模式 */ } TMR_MODE_E; @@ -32,8 +32,8 @@ typedef struct { volatile uint8_t Mode; /* 计数器模式,1次性 */ volatile uint8_t Flag; /* 定时到达标志 */ - volatile uint32_t Count; /* 计数器 */ - volatile uint32_t PreLoad; /* 计数器预装值 */ + volatile uint32_t Count; /* 计数器 */ + volatile uint32_t PreLoad; /* 计数器预装值 */ } SOFT_TMR; /* 提供给其他C文件调用的函数 */ diff --git a/User/bsp/src/bsp_fmc_io.c b/User/bsp/src/bsp_fmc_io.c index 670e6d9..2a8bf2d 100755 --- a/User/bsp/src/bsp_fmc_io.c +++ b/User/bsp/src/bsp_fmc_io.c @@ -41,11 +41,11 @@ gpio_init.Pin = pin; \ HAL_GPIO_Init(gpio, &gpio_init); -#define GPIO_DIR_SET_OUT(gpio, pin) gpio->BSRRL = pin /* DIR = 1 输出 */ +#define GPIO_DIR_SET_OUT(gpio, pin) gpio->BSRRL = pin /* DIR = 1 输出 */ #define GPIO_DIR_SET_IN(gpio, pin) gpio->BSRRH = pin /* DIR = 0 输入 */ -#define GPIO_SET_HIGH(gpio, pin) gpio->BSRRL = pin /* pin = 1 */ -#define GPIO_SET_LOW(gpio, pin) gpio->BSRRH = pin /* pin = 0 */ +#define GPIO_SET_HIGH(gpio, pin) gpio->BSRRL = pin /* pin = 1 */ +#define GPIO_SET_LOW(gpio, pin) gpio->BSRRH = pin /* pin = 0 */ #define GPIO_IN_IS_HIGH(gpio, pin) (gpio->IDR & pin) #define GPIO_OUT_IS_HIGH(gpio, pin) (gpio->ODR & pin) diff --git a/User/bsp/src/bsp_qspi_w25q256.c b/User/bsp/src/bsp_qspi_w25q256.c index 14a0835..fed02de 100755 --- a/User/bsp/src/bsp_qspi_w25q256.c +++ b/User/bsp/src/bsp_qspi_w25q256.c @@ -43,79 +43,79 @@ /* QSPI引脚和时钟相关配置宏定义 */ #if 1 -#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() -#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() -#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() -#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() -#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() -#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() -#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() +#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() +#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() -#define QSPI_MDMA_CLK_ENABLE() __HAL_RCC_MDMA_CLK_ENABLE() -#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() -#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() +#define QSPI_MDMA_CLK_ENABLE() __HAL_RCC_MDMA_CLK_ENABLE() +#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() +#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() -#define QSPI_CS_PIN GPIO_PIN_6 -#define QSPI_CS_GPIO_PORT GPIOG -#define QSPI_CS_GPIO_AF GPIO_AF10_QUADSPI +#define QSPI_CS_PIN GPIO_PIN_6 +#define QSPI_CS_GPIO_PORT GPIOG +#define QSPI_CS_GPIO_AF GPIO_AF10_QUADSPI -#define QSPI_CLK_PIN GPIO_PIN_2 -#define QSPI_CLK_GPIO_PORT GPIOB -#define QSPI_CLK_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_CLK_PIN GPIO_PIN_2 +#define QSPI_CLK_GPIO_PORT GPIOB +#define QSPI_CLK_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D0_PIN GPIO_PIN_11 -#define QSPI_BK1_D0_GPIO_PORT GPIOD -#define QSPI_BK1_D0_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D0_PIN GPIO_PIN_11 +#define QSPI_BK1_D0_GPIO_PORT GPIOD +#define QSPI_BK1_D0_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D1_PIN GPIO_PIN_12 -#define QSPI_BK1_D1_GPIO_PORT GPIOD -#define QSPI_BK1_D1_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D1_PIN GPIO_PIN_12 +#define QSPI_BK1_D1_GPIO_PORT GPIOD +#define QSPI_BK1_D1_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D2_PIN GPIO_PIN_7 -#define QSPI_BK1_D2_GPIO_PORT GPIOF -#define QSPI_BK1_D2_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D2_PIN GPIO_PIN_7 +#define QSPI_BK1_D2_GPIO_PORT GPIOF +#define QSPI_BK1_D2_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D3_PIN GPIO_PIN_13 -#define QSPI_BK1_D3_GPIO_PORT GPIOD -#define QSPI_BK1_D3_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D3_PIN GPIO_PIN_13 +#define QSPI_BK1_D3_GPIO_PORT GPIOD +#define QSPI_BK1_D3_GPIO_AF GPIO_AF9_QUADSPI #else -#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() -#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() -#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() -#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() +#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() +#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() -#define QSPI_MDMA_CLK_ENABLE() __HAL_RCC_MDMA_CLK_ENABLE() -#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() -#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() +#define QSPI_MDMA_CLK_ENABLE() __HAL_RCC_MDMA_CLK_ENABLE() +#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() +#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() -#define QSPI_CS_PIN GPIO_PIN_6 -#define QSPI_CS_GPIO_PORT GPIOG -#define QSPI_CS_GPIO_AF GPIO_AF10_QUADSPI +#define QSPI_CS_PIN GPIO_PIN_6 +#define QSPI_CS_GPIO_PORT GPIOG +#define QSPI_CS_GPIO_AF GPIO_AF10_QUADSPI -#define QSPI_CLK_PIN GPIO_PIN_10 -#define QSPI_CLK_GPIO_PORT GPIOF -#define QSPI_CLK_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_CLK_PIN GPIO_PIN_10 +#define QSPI_CLK_GPIO_PORT GPIOF +#define QSPI_CLK_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D0_PIN GPIO_PIN_8 -#define QSPI_BK1_D0_GPIO_PORT GPIOF -#define QSPI_BK1_D0_GPIO_AF GPIO_AF10_QUADSPI +#define QSPI_BK1_D0_PIN GPIO_PIN_8 +#define QSPI_BK1_D0_GPIO_PORT GPIOF +#define QSPI_BK1_D0_GPIO_AF GPIO_AF10_QUADSPI -#define QSPI_BK1_D1_PIN GPIO_PIN_9 -#define QSPI_BK1_D1_GPIO_PORT GPIOF -#define QSPI_BK1_D1_GPIO_AF GPIO_AF10_QUADSPI +#define QSPI_BK1_D1_PIN GPIO_PIN_9 +#define QSPI_BK1_D1_GPIO_PORT GPIOF +#define QSPI_BK1_D1_GPIO_AF GPIO_AF10_QUADSPI -#define QSPI_BK1_D2_PIN GPIO_PIN_7 -#define QSPI_BK1_D2_GPIO_PORT GPIOF -#define QSPI_BK1_D2_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D2_PIN GPIO_PIN_7 +#define QSPI_BK1_D2_GPIO_PORT GPIOF +#define QSPI_BK1_D2_GPIO_AF GPIO_AF9_QUADSPI -#define QSPI_BK1_D3_PIN GPIO_PIN_6 -#define QSPI_BK1_D3_GPIO_PORT GPIOF -#define QSPI_BK1_D3_GPIO_AF GPIO_AF9_QUADSPI +#define QSPI_BK1_D3_PIN GPIO_PIN_6 +#define QSPI_BK1_D3_GPIO_PORT GPIOF +#define QSPI_BK1_D3_GPIO_AF GPIO_AF9_QUADSPI #endif /* 供本文件调用的全局变量 */ diff --git a/User/bsp/src/bsp_tim_pwm.c b/User/bsp/src/bsp_tim_pwm.c index eb3d31e..3e66c3d 100755 --- a/User/bsp/src/bsp_tim_pwm.c +++ b/User/bsp/src/bsp_tim_pwm.c @@ -1,22 +1,22 @@ /* ********************************************************************************************************* * -* 模块名称 : TIM基本定时中断和PWM驱动模块 -* 文件名称 : bsp_tim_pwm.c -* 版 本 : V1.6 -* 说 明 : 利用STM32F4内部TIM输出PWM信号, 并实现基本的定时中断 -* 修改记录 : -* 版本号 日期 作者 说明 -* V1.0 2013-08-16 armfly 正式发布 -* V1.1 2014-06-15 armfly 完善 bsp_SetTIMOutPWM,当占空比=0和100%时,关闭定时器,GPIO配置为输出 -* V1.2 2015-05-08 armfly 解决TIM8不能输出PWM的问题。 -* V1.3 2015-07-23 armfly 初始化定时器,必须设置 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0x0000; -* TIM1 和 TIM8 必须设置。否则蜂鸣器的控制不正常。 -* V1.4 2015-07-30 armfly 增加反相引脚输出PWM函数 bsp_SetTIMOutPWM_N(); -* V1.5 2016-02-01 armfly 去掉 TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable); -* V1.6 2016-02-27 armfly 解决TIM14无法中断的BUG, TIM8_TRG_COM_TIM14_IRQn +* 模块名称 : TIM基本定时中断和PWM驱动模块 +* 文件名称 : bsp_tim_pwm.c +* 版 本 : V1.6 +* 说 明 : 利用STM32H7内部TIM输出PWM信号, 并实现基本的定时中断 +* 修改记录 : +* 版本号 日期 作者 说明 +* V1.0 2013-08-16 armfly 正式发布 +* V1.1 2014-06-15 armfly 完善 bsp_SetTIMOutPWM,当占空比=0和100%时,关闭定时器,GPIO配置为输出 +* V1.2 2015-05-08 armfly 解决TIM8不能输出PWM的问题。 +* V1.3 2015-07-23 armfly 初始化定时器,必须设置 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0x0000; +* TIM1 和 TIM8 必须设置。否则蜂鸣器的控制不正常。 +* V1.4 2015-07-30 armfly 增加反相引脚输出PWM函数 bsp_SetTIMOutPWM_N(); +* V1.5 2016-02-01 armfly 去掉 TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable); +* V1.6 2016-02-27 armfly 解决TIM14无法中断的BUG, TIM8_TRG_COM_TIM14_IRQn * -* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com +* Copyright (C), 2018-2030, 安富莱电子 www.armfly.com * ********************************************************************************************************* */ @@ -24,52 +24,52 @@ #include "bsp.h" /* + 注意,STM32H7有TIM1 – TIM17(没有TIM9,TIM10和TIM11)共计14个定时器。 可以输出到GPIO的TIM通道: - TIM1_CH1, PA8, PE9, - TIM1_CH2, PA9, PE11 - TIM1_CH3, PA10, PE13 - TIM1_CH4, PA11, PE14 + TIM1_CH1, PA8 PE9 PK1 + TIM1_CH2, PA9 PE11 + TIM1_CH3, PA10 PE13 PJ9 + TIM1_CH4, PA11 PE14 PJ11 - TIM2_CH1, PA15 (仅限429,439) 407没有此脚 - TIM2_CH2, PA1, PB3 - TIM2_CH3, PA2, PB10 - TIM2_CH4, PA3, PB11 + TIM2_CH1, PA0 PA5 PA15 + TIM2_CH2, PA1 PB3 + TIM2_CH3, PA2 + TIM2_CH4, PA3 PB11 - TIM3_CH1, PA6, PB4, PC6 - TIM3_CH2, PA7, PB5, PC7 - TIM3_CH3, PB0, PC8 - TIM3_CH4, PB1, PC9 + TIM3_CH1, PA6 PC6 PB4 + TIM3_CH2, PA7 PC7 PB5 + TIM3_CH3, PB0 PC8 + TIM3_CH4, PB1 PC9 - TIM4_CH1, PB6, PD12 - TIM4_CH2, PB7, PD13 - TIM4_CH3, PB8, PD14 - TIM4_CH4, PB9, PD15 + TIM4_CH1, PB6 PD12 + TIM4_CH2, PB7 PD13 + TIM4_CH3, PB8 PD14 + TIM4_CH4, PB9 PD15 - TIM5_CH1, PA0, PH10 - TIM5_CH2, PA1, PH11 - TIM5_CH3, PA2, PH12 - TIM5_CH4, PA3, PI10 + TIM5_CH1, PA0 PH10 + TIM5_CH2, PA1 PH11 + TIM5_CH3, PA2 PH12 + TIM5_CH4, PA3 PI0 - TIM8_CH1, PC6, PI5 - TIM8_CH2, PC7, PI6 - TIM8_CH3, PC8, PI7 - TIM8_CH4, PC9, PI2 + TIM8_CH1, PC6 PI5 PJ8 + TIM8_CH2, PC7 PI6 PJ10 + TIM8_CH3, PC8 PI7 PK0 + TIM8_CH4, PC9 - TIM9_CH1, PA2, PE5 - TIM9_CH2, PA3, PE6 + TIM12_CH1, PB14 PH6 + TIM12_CH2, PB15 PH9 - TIM10_CH1, PB8, PF6 + TIM13_CH1, PF8 - TIM11_CH1, PB9, PF7 + TIM14_CH1, PF9 - TIM12_CH1, PB14, PH6 - TIM12_CH2, PB15, PH9 + TIM15_CH1, PE5 + TIM15_CH2, PE6 - TIM13_CH1, PA6, PF8 - TIM14_CH1, PA7, PF9 + TIM16_CH1, PB8 PF6 + TIM16_CH2, PF7 - APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14 - APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11 + TIM17_CH1, PB9 */ /* @@ -80,30 +80,19 @@ * 返 回 值: 无 ********************************************************************************************************* */ -void bsp_RCC_GPIO_Enable(GPIO_TypeDef *GPIOx) +void bsp_RCC_GPIO_Enable(GPIO_TypeDef* GPIOx) { - if (GPIOx == GPIOA) - __HAL_RCC_GPIOA_CLK_ENABLE(); - else if (GPIOx == GPIOB) - __HAL_RCC_GPIOB_CLK_ENABLE(); - else if (GPIOx == GPIOC) - __HAL_RCC_GPIOC_CLK_ENABLE(); - else if (GPIOx == GPIOD) - __HAL_RCC_GPIOD_CLK_ENABLE(); - else if (GPIOx == GPIOE) - __HAL_RCC_GPIOE_CLK_ENABLE(); - else if (GPIOx == GPIOF) - __HAL_RCC_GPIOF_CLK_ENABLE(); - else if (GPIOx == GPIOG) - __HAL_RCC_GPIOG_CLK_ENABLE(); - else if (GPIOx == GPIOH) - __HAL_RCC_GPIOH_CLK_ENABLE(); - else if (GPIOx == GPIOI) - __HAL_RCC_GPIOI_CLK_ENABLE(); - else if (GPIOx == GPIOJ) - __HAL_RCC_GPIOJ_CLK_ENABLE(); - else if (GPIOx == GPIOK) - __HAL_RCC_GPIOK_CLK_ENABLE(); + if (GPIOx == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE(); + else if (GPIOx == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); + else if (GPIOx == GPIOC) __HAL_RCC_GPIOC_CLK_ENABLE(); + else if (GPIOx == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); + else if (GPIOx == GPIOE) __HAL_RCC_GPIOE_CLK_ENABLE(); + else if (GPIOx == GPIOF) __HAL_RCC_GPIOF_CLK_ENABLE(); + else if (GPIOx == GPIOG) __HAL_RCC_GPIOG_CLK_ENABLE(); + else if (GPIOx == GPIOH) __HAL_RCC_GPIOH_CLK_ENABLE(); + else if (GPIOx == GPIOI) __HAL_RCC_GPIOI_CLK_ENABLE(); + else if (GPIOx == GPIOJ) __HAL_RCC_GPIOJ_CLK_ENABLE(); + else if (GPIOx == GPIOK) __HAL_RCC_GPIOK_CLK_ENABLE(); } /* @@ -114,90 +103,62 @@ void bsp_RCC_GPIO_Enable(GPIO_TypeDef *GPIOx) * 返 回 值: 无 ********************************************************************************************************* */ -void bsp_RCC_TIM_Enable(TIM_TypeDef *TIMx) +void bsp_RCC_TIM_Enable(TIM_TypeDef* TIMx) { - if (TIMx == TIM1) - __HAL_RCC_TIM1_CLK_ENABLE(); - else if (TIMx == TIM2) - __HAL_RCC_TIM2_CLK_ENABLE(); - else if (TIMx == TIM3) - __HAL_RCC_TIM3_CLK_ENABLE(); - else if (TIMx == TIM4) - __HAL_RCC_TIM4_CLK_ENABLE(); - else if (TIMx == TIM5) - __HAL_RCC_TIM5_CLK_ENABLE(); - else if (TIMx == TIM6) - __HAL_RCC_TIM6_CLK_ENABLE(); - else if (TIMx == TIM7) - __HAL_RCC_TIM7_CLK_ENABLE(); - else if (TIMx == TIM8) - __HAL_RCC_TIM8_CLK_ENABLE(); - // else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_ENABLE(); - // else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_ENABLE(); - // else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_ENABLE(); - else if (TIMx == TIM12) - __HAL_RCC_TIM12_CLK_ENABLE(); - else if (TIMx == TIM13) - __HAL_RCC_TIM13_CLK_ENABLE(); - else if (TIMx == TIM14) - __HAL_RCC_TIM14_CLK_ENABLE(); - else if (TIMx == TIM15) - __HAL_RCC_TIM15_CLK_ENABLE(); - else if (TIMx == TIM16) - __HAL_RCC_TIM16_CLK_ENABLE(); - else if (TIMx == TIM17) - __HAL_RCC_TIM17_CLK_ENABLE(); + if (TIMx == TIM1) __HAL_RCC_TIM1_CLK_ENABLE(); + else if (TIMx == TIM2) __HAL_RCC_TIM2_CLK_ENABLE(); + else if (TIMx == TIM3) __HAL_RCC_TIM3_CLK_ENABLE(); + else if (TIMx == TIM4) __HAL_RCC_TIM4_CLK_ENABLE(); + else if (TIMx == TIM5) __HAL_RCC_TIM5_CLK_ENABLE(); + else if (TIMx == TIM6) __HAL_RCC_TIM6_CLK_ENABLE(); + else if (TIMx == TIM7) __HAL_RCC_TIM7_CLK_ENABLE(); + else if (TIMx == TIM8) __HAL_RCC_TIM8_CLK_ENABLE(); +// else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_ENABLE(); +// else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_ENABLE(); +// else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_ENABLE(); + else if (TIMx == TIM12) __HAL_RCC_TIM12_CLK_ENABLE(); + else if (TIMx == TIM13) __HAL_RCC_TIM13_CLK_ENABLE(); + else if (TIMx == TIM14) __HAL_RCC_TIM14_CLK_ENABLE(); + else if (TIMx == TIM15) __HAL_RCC_TIM15_CLK_ENABLE(); + else if (TIMx == TIM16) __HAL_RCC_TIM16_CLK_ENABLE(); + else if (TIMx == TIM17) __HAL_RCC_TIM17_CLK_ENABLE(); else { Error_Handler(__FILE__, __LINE__); - } + } } /* ********************************************************************************************************* -* 函 数 名: bsp_RCC_TIM_Disable -* 功能说明: 关闭TIM RCC 时钟 -* 形 参: 无 -* 返 回 值: TIM外设时钟名 +* 函 数 名: bsp_RCC_TIM_Disable +* 功能说明: 关闭TIM RCC 时钟 +* 形 参: TIMx TIM1 - TIM17 +* 返 回 值: TIM外设时钟名 ********************************************************************************************************* */ -void bsp_RCC_TIM_Disable(TIM_TypeDef *TIMx) +void bsp_RCC_TIM_Disable(TIM_TypeDef* TIMx) { /* APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14 - APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11 + APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17 */ - if (TIMx == TIM1) - __HAL_RCC_TIM3_CLK_DISABLE(); - else if (TIMx == TIM2) - __HAL_RCC_TIM2_CLK_DISABLE(); - else if (TIMx == TIM3) - __HAL_RCC_TIM3_CLK_DISABLE(); - else if (TIMx == TIM4) - __HAL_RCC_TIM4_CLK_DISABLE(); - else if (TIMx == TIM5) - __HAL_RCC_TIM5_CLK_DISABLE(); - else if (TIMx == TIM6) - __HAL_RCC_TIM6_CLK_DISABLE(); - else if (TIMx == TIM7) - __HAL_RCC_TIM7_CLK_DISABLE(); - else if (TIMx == TIM8) - __HAL_RCC_TIM8_CLK_DISABLE(); - // else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_DISABLE(); - // else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_DISABLE(); - // else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_DISABLE(); - else if (TIMx == TIM12) - __HAL_RCC_TIM12_CLK_DISABLE(); - else if (TIMx == TIM13) - __HAL_RCC_TIM13_CLK_DISABLE(); - else if (TIMx == TIM14) - __HAL_RCC_TIM14_CLK_DISABLE(); - else if (TIMx == TIM15) - __HAL_RCC_TIM15_CLK_DISABLE(); - else if (TIMx == TIM16) - __HAL_RCC_TIM16_CLK_DISABLE(); - else if (TIMx == TIM17) - __HAL_RCC_TIM17_CLK_DISABLE(); + if (TIMx == TIM1) __HAL_RCC_TIM3_CLK_DISABLE(); + else if (TIMx == TIM2) __HAL_RCC_TIM2_CLK_DISABLE(); + else if (TIMx == TIM3) __HAL_RCC_TIM3_CLK_DISABLE(); + else if (TIMx == TIM4) __HAL_RCC_TIM4_CLK_DISABLE(); + else if (TIMx == TIM5) __HAL_RCC_TIM5_CLK_DISABLE(); + else if (TIMx == TIM6) __HAL_RCC_TIM6_CLK_DISABLE(); + else if (TIMx == TIM7) __HAL_RCC_TIM7_CLK_DISABLE(); + else if (TIMx == TIM8) __HAL_RCC_TIM8_CLK_DISABLE(); +// else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_DISABLE(); +// else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_DISABLE(); +// else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_DISABLE(); + else if (TIMx == TIM12) __HAL_RCC_TIM12_CLK_DISABLE(); + else if (TIMx == TIM13) __HAL_RCC_TIM13_CLK_DISABLE(); + else if (TIMx == TIM14) __HAL_RCC_TIM14_CLK_DISABLE(); + else if (TIMx == TIM15) __HAL_RCC_TIM15_CLK_DISABLE(); + else if (TIMx == TIM16) __HAL_RCC_TIM16_CLK_DISABLE(); + else if (TIMx == TIM17) __HAL_RCC_TIM17_CLK_DISABLE(); else { Error_Handler(__FILE__, __LINE__); @@ -206,61 +167,49 @@ void bsp_RCC_TIM_Disable(TIM_TypeDef *TIMx) /* ********************************************************************************************************* -* 函 数 名: bsp_GetAFofTIM -* 功能说明: 根据TIM 得到AF寄存器配置 -* 形 参: 无 -* 返 回 值: AF寄存器配置 +* 函 数 名: bsp_GetAFofTIM +* 功能说明: 根据TIM 得到AF寄存器配置 +* 形 参: TIMx TIM1 - TIM17 +* 返 回 值: AF寄存器配置 ********************************************************************************************************* */ -uint8_t bsp_GetAFofTIM(TIM_TypeDef *TIMx) +uint8_t bsp_GetAFofTIM(TIM_TypeDef* TIMx) { uint8_t ret = 0; - if (TIMx == TIM1) - ret = GPIO_AF1_TIM1; - else if (TIMx == TIM2) - ret = GPIO_AF1_TIM2; - else if (TIMx == TIM3) - ret = GPIO_AF2_TIM3; - else if (TIMx == TIM4) - ret = GPIO_AF2_TIM4; - else if (TIMx == TIM5) - ret = GPIO_AF2_TIM5; - else if (TIMx == TIM8) - ret = GPIO_AF3_TIM8; - else if (TIMx == TIM12) - ret = GPIO_AF2_TIM12; - else if (TIMx == TIM13) - ret = GPIO_AF9_TIM13; - else if (TIMx == TIM14) - ret = GPIO_AF9_TIM14; - else if (TIMx == TIM15) - ret = GPIO_AF4_TIM15; - else if (TIMx == TIM16) - ret = GPIO_AF1_TIM16; - else if (TIMx == TIM17) - ret = GPIO_AF1_TIM17; + if (TIMx == TIM1) ret = GPIO_AF1_TIM1; + else if (TIMx == TIM2) ret = GPIO_AF1_TIM2; + else if (TIMx == TIM3) ret = GPIO_AF2_TIM3; + else if (TIMx == TIM4) ret = GPIO_AF2_TIM4; + else if (TIMx == TIM5) ret = GPIO_AF2_TIM5; + else if (TIMx == TIM8) ret = GPIO_AF3_TIM8; + else if (TIMx == TIM12) ret = GPIO_AF2_TIM12; + else if (TIMx == TIM13) ret = GPIO_AF9_TIM13; + else if (TIMx == TIM14) ret = GPIO_AF9_TIM14; + else if (TIMx == TIM15) ret = GPIO_AF4_TIM15; + else if (TIMx == TIM16) ret = GPIO_AF1_TIM16; + else if (TIMx == TIM17) ret = GPIO_AF1_TIM17; else { Error_Handler(__FILE__, __LINE__); } - + return ret; } /* ********************************************************************************************************* -* 函 数 名: bsp_ConfigTimGpio -* 功能说明: 配置GPIO和TIM时钟, GPIO连接到TIM输出通道 -* 形 参: GPIOx -* GPIO_PinX -* TIMx -* 返 回 值: 无 +* 函 数 名: bsp_ConfigTimGpio +* 功能说明: 配置GPIO和TIM时钟, GPIO连接到TIM输出通道 +* 形 参: GPIOx : GPIOA - GPIOK +* GPIO_PinX : GPIO_PIN_0 - GPIO__PIN_15 +* TIMx : TIM1 - TIM17 +* 返 回 值: 无 ********************************************************************************************************* */ -void bsp_ConfigTimGpio(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX, TIM_TypeDef *TIMx) +void bsp_ConfigTimGpio(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinX, TIM_TypeDef* TIMx) { - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef GPIO_InitStruct; /* 使能GPIO时钟 */ bsp_RCC_GPIO_Enable(GPIOx); @@ -278,18 +227,18 @@ void bsp_ConfigTimGpio(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX, TIM_TypeDef *TIM /* ********************************************************************************************************* -* 函 数 名: bsp_ConfigGpioOut -* 功能说明: 配置GPIO为推挽输出。主要用于PWM输出,占空比为0和100的情况。 -* 形 参: GPIOx -* GPIO_PinX -* 返 回 值: 无 +* 函 数 名: bsp_ConfigGpioOut +* 功能说明: 配置GPIO为推挽输出。主要用于PWM输出,占空比为0和100的情况。 +* 形 参: GPIOx : GPIOA - GPIOK +* GPIO_PinX : GPIO_PIN_0 - GPIO__PIN_15 +* 返 回 值: 无 ********************************************************************************************************* */ -void bsp_ConfigGpioOut(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX) +void bsp_ConfigGpioOut(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinX) { - GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitTypeDef GPIO_InitStruct; - bsp_RCC_GPIO_Enable(GPIOx); /* 使能GPIO时钟 */ + bsp_RCC_GPIO_Enable(GPIOx); /* 使能GPIO时钟 */ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; @@ -300,65 +249,73 @@ void bsp_ConfigGpioOut(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinX) /* ********************************************************************************************************* -* 函 数 名: bsp_SetTIMOutPWM -* 功能说明: 设置引脚输出的PWM信号的频率和占空比. 当频率为0,并且占空为0时,关闭定时器,GPIO输出0; -* 当频率为0,占空比为100%时,GPIO输出1. -* 形 参: -* GPIOx : GPIOA- GPIOK -* GPIO_Pin : GPIO_PIN_1 - GPIO__PIN_15 -* TIMx : TIM1 - TIM14 -* _ulFreq : PWM信号频率,单位Hz (实际测试,最大输出频率为 168M / 4 = 42M). 0 表示禁止输出 -* _ulDutyCycle : PWM信号占空比,单位: 万分之一。如5000,表示50.00%的占空比 -* 返 回 值: 无 +* 函 数 名: bsp_SetTIMOutPWM +* 功能说明: 设置引脚输出的PWM信号的频率和占空比. 当频率为0,并且占空为0时,关闭定时器,GPIO输出0; +* 当频率为0,占空比为100%时,GPIO输出1. +* 形 参: GPIOx : GPIOA - GPIOK +* GPIO_Pin : GPIO_PIN_0 - GPIO__PIN_15 +* TIMx : TIM1 - TIM17 +* _ucChannel:使用的定时器通道,范围1 - 4 +* _ulFreq : PWM信号频率,单位Hz (实际测试,可以输出100MHz),0 表示禁止输出 +* _ulDutyCycle : PWM信号占空比,单位: 万分之一。如5000,表示50.00%的占空比 +* 返 回 值: 无 ********************************************************************************************************* */ -void bsp_SetTIMOutPWM(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, uint8_t _ucChannel, - uint32_t _ulFreq, uint32_t _ulDutyCycle) +void bsp_SetTIMOutPWM(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TIM_TypeDef* TIMx, uint8_t _ucChannel, + uint32_t _ulFreq, uint32_t _ulDutyCycle) { - TIM_HandleTypeDef TimHandle = {0}; - TIM_OC_InitTypeDef sConfig = {0}; + TIM_HandleTypeDef TimHandle = {0}; + TIM_OC_InitTypeDef sConfig = {0}; uint16_t usPeriod; uint16_t usPrescaler; uint32_t pulse; uint32_t uiTIMxCLK; - const uint16_t TimChannel[6 + 1] = {0, TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4, TIM_CHANNEL_5, TIM_CHANNEL_6}; + const uint16_t TimChannel[6+1] = {0, TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4, TIM_CHANNEL_5, TIM_CHANNEL_6}; if (_ucChannel > 6) { Error_Handler(__FILE__, __LINE__); } - + if (_ulDutyCycle == 0) - { - //bsp_RCC_TIM_Disable(TIMx); /* 关闭TIM时钟, 可能影响其他通道 */ - bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */ - GPIOx->BSRRH = GPIO_Pin; /* PWM = 0 */ + { + //bsp_RCC_TIM_Disable(TIMx); /* 关闭TIM时钟, 可能影响其他通道 */ + bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */ + GPIOx->BSRRH = GPIO_Pin; /* PWM = 0 */ return; } else if (_ulDutyCycle == 10000) { //bsp_RCC_TIM_Disable(TIMx); /* 关闭TIM时钟, 可能影响其他通道 */ - bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */ - GPIOx->BSRRL = GPIO_Pin; /* PWM = 1*/ + bsp_ConfigGpioOut(GPIOx, GPIO_Pin); /* 配置GPIO为推挽输出 */ + GPIOx->BSRRL = GPIO_Pin; /* PWM = 1*/ return; } - + /* 下面是PWM输出 */ - - bsp_ConfigTimGpio(GPIOx, GPIO_Pin, TIMx); /* 使能GPIO和TIM时钟,并连接TIM通道到GPIO */ - + + bsp_ConfigTimGpio(GPIOx, GPIO_Pin, TIMx); /* 使能GPIO和TIM时钟,并连接TIM通道到GPIO */ + /*----------------------------------------------------------------------- - system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下: + bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下: - HCLK = SYSCLK / 1 (AHB1Periph) - PCLK2 = HCLK / 2 (APB2Periph) - PCLK1 = HCLK / 4 (APB1Periph) + System Clock source = PLL (HSE) + SYSCLK(Hz) = 400000000 (CPU Clock) + HCLK(Hz) = 200000000 (AXI and AHBs Clock) + AHB Prescaler = 2 + D1 APB3 Prescaler = 2 (APB3 Clock 100MHz) + D2 APB1 Prescaler = 2 (APB1 Clock 100MHz) + D2 APB2 Prescaler = 2 (APB2 Clock 100MHz) + D3 APB4 Prescaler = 2 (APB4 Clock 100MHz) - 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2; - 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock; + 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz; + 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz; + APB4上面的TIMxCLK没有分频,所以就是100MHz; - APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14 - APB2 定时器有 TIM1, TIM8 ,TIM15, TIM16, TIM17 + APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1 + APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17 + + APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5 ----------------------------------------------------------------------- */ if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM15) || (TIMx == TIM16) || (TIMx == TIM17)) @@ -366,7 +323,7 @@ void bsp_SetTIMOutPWM(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, /* APB2 定时器时钟 = 200M */ uiTIMxCLK = SystemCoreClock / 2; } - else + else { /* APB1 定时器 = 200M */ uiTIMxCLK = SystemCoreClock / 2; @@ -374,33 +331,30 @@ void bsp_SetTIMOutPWM(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, if (_ulFreq < 100) { - usPrescaler = 10000 - 1; /* 分频比 = 10000 */ - usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */ + usPrescaler = 10000 - 1; /* 分频比 = 10000 */ + usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */ } else if (_ulFreq < 3000) { - usPrescaler = 100 - 1; /* 分频比 = 100 */ - usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */ + usPrescaler = 100 - 1; /* 分频比 = 100 */ + usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */ } - else /* 大于4K的频率,无需分频 */ + else /* 大于4K的频率,无需分频 */ { - usPrescaler = 0; /* 分频比 = 1 */ + usPrescaler = 0; /* 分频比 = 1 */ usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */ } pulse = (_ulDutyCycle * usPeriod) / 10000; + HAL_TIM_PWM_DeInit(&TimHandle); - /* Initialize TIMx peripheral as follows: - + Prescaler = (SystemCoreClock / (2*20000000)) - 1 - + Period = (1000 - 1) - + ClockDivision = 0 - + Counter direction = Up - */ + + /* PWM频率 = TIMxCLK / usPrescaler + 1)/usPeriod + 1)*/ TimHandle.Instance = TIMx; - TimHandle.Init.Prescaler = usPrescaler; - TimHandle.Init.Period = usPeriod; - TimHandle.Init.ClockDivision = 0; - TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + TimHandle.Init.Prescaler = usPrescaler; + TimHandle.Init.Period = usPeriod; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; TimHandle.Init.AutoReloadPreload = 0; if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) @@ -408,23 +362,22 @@ void bsp_SetTIMOutPWM(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, Error_Handler(__FILE__, __LINE__); } - /*##-2- Configure the PWM channels #########################################*/ - /* Common configuration for all channels */ - sConfig.OCMode = TIM_OCMODE_PWM1; - sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; - sConfig.OCFastMode = TIM_OCFAST_DISABLE; - sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; + /* 配置定时器PWM输出通道 */ + sConfig.OCMode = TIM_OCMODE_PWM1; + sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfig.OCFastMode = TIM_OCFAST_DISABLE; + sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; - sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; - /* Set the pulse value for channel */ + /* 占空比 */ sConfig.Pulse = pulse; if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TimChannel[_ucChannel]) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } - - /* Start channel */ + + /* 启动PWM输出 */ if (HAL_TIM_PWM_Start(&TimHandle, TimChannel[_ucChannel]) != HAL_OK) { Error_Handler(__FILE__, __LINE__); @@ -433,54 +386,63 @@ void bsp_SetTIMOutPWM(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, TIM_TypeDef *TIMx, /* ********************************************************************************************************* -* 函 数 名: bsp_SetTIMforInt -* 功能说明: 配置TIM和NVIC,用于简单的定时中断. 开启定时中断。 中断服务程序由应用程序实现。 -* 形 参: TIMx : 定时器 -* _ulFreq : 定时频率 (Hz)。 0 表示关闭。 -* _PreemptionPriority : 中断优先级分组 -* _SubPriority : 子优先级 -* 返 回 值: 无 +* 函 数 名: bsp_SetTIMforInt +* 功能说明: 配置TIM和NVIC,用于简单的定时中断,开启定时中断。另外注意中断服务程序需要由用户应用程序实现。 +* 形 参: TIMx : 定时器 +* _ulFreq : 定时频率 (Hz)。 0 表示关闭。 +* _PreemptionPriority : 抢占优先级 +* _SubPriority : 子优先级 +* 返 回 值: 无 ********************************************************************************************************* */ - -/* TIM定时中断服务程序范例,必须清中断标志 -void TIM3_IRQHandler(void) +/* +TIM定时中断服务程序范例,必须清中断标志 +void TIM6_DAC_IRQHandler(void) { - TIM3->SR = ~ (uint32_t)TIM_IT_UPDATE; - - HC574_TogglePin(GPIO_PIN_23); + if((TIM6->SR & TIM_FLAG_UPDATE) != RESET) + { + TIM6->SR = ~ TIM_FLAG_UPDATE; + //添加用户代码 + } } */ -void bsp_SetTIMforInt(TIM_TypeDef *TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority) +void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, uint8_t _SubPriority) { - TIM_HandleTypeDef TimHandle; + TIM_HandleTypeDef TimHandle = {0}; uint16_t usPeriod; uint16_t usPrescaler; uint32_t uiTIMxCLK; - + /* 使能TIM时钟 */ bsp_RCC_TIM_Enable(TIMx); - + /*----------------------------------------------------------------------- - system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下: + bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下: - HCLK = SYSCLK / 1 (AHB1Periph) - PCLK2 = HCLK / 2 (APB2Periph) - PCLK1 = HCLK / 4 (APB1Periph) + System Clock source = PLL (HSE) + SYSCLK(Hz) = 400000000 (CPU Clock) + HCLK(Hz) = 200000000 (AXI and AHBs Clock) + AHB Prescaler = 2 + D1 APB3 Prescaler = 2 (APB3 Clock 100MHz) + D2 APB1 Prescaler = 2 (APB1 Clock 100MHz) + D2 APB2 Prescaler = 2 (APB2 Clock 100MHz) + D3 APB4 Prescaler = 2 (APB4 Clock 100MHz) - 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2; - 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock; + 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz; + 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz; + APB4上面的TIMxCLK没有分频,所以就是100MHz; - APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14 - APB2 定时器有 TIM1, TIM8 ,TIM15, TIM16, TIM17 + APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1 + APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17 + APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5 ----------------------------------------------------------------------- */ if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM15) || (TIMx == TIM16) || (TIMx == TIM17)) { /* APB2 定时器时钟 = 200M */ uiTIMxCLK = SystemCoreClock / 2; } - else + else { /* APB1 定时器 = 200M */ uiTIMxCLK = SystemCoreClock / 2; @@ -488,31 +450,28 @@ void bsp_SetTIMforInt(TIM_TypeDef *TIMx, uint32_t _ulFreq, uint8_t _PreemptionPr if (_ulFreq < 100) { - usPrescaler = 10000 - 1; /* 分频比 = 10000 */ - usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */ + usPrescaler = 10000 - 1; /* 分频比 = 10000 */ + usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */ } else if (_ulFreq < 3000) { - usPrescaler = 100 - 1; /* 分频比 = 100 */ - usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */ + usPrescaler = 100 - 1; /* 分频比 = 100 */ + usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */ } - else /* 大于4K的频率,无需分频 */ + else /* 大于4K的频率,无需分频 */ { - usPrescaler = 0; /* 分频比 = 1 */ + usPrescaler = 0; /* 分频比 = 1 */ usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */ } - /* Initialize TIMx peripheral as follows: - + Prescaler = (SystemCoreClock / (2*20000000)) - 1 - + Period = (1000 - 1) - + ClockDivision = 0 - + Counter direction = Up + /* + 定时器中断更新周期 = TIMxCLK / usPrescaler + 1)/usPeriod + 1) */ TimHandle.Instance = TIMx; - TimHandle.Init.Prescaler = usPrescaler; - TimHandle.Init.Period = usPeriod / 2; /* 除以2才是正确频率 */ - TimHandle.Init.ClockDivision = 0; - TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + TimHandle.Init.Prescaler = usPrescaler; + TimHandle.Init.Period = usPeriod; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK) @@ -520,49 +479,36 @@ void bsp_SetTIMforInt(TIM_TypeDef *TIMx, uint32_t _ulFreq, uint8_t _PreemptionPr Error_Handler(__FILE__, __LINE__); } - /* TIM Interrupts enable */ + /* 使能定时器中断 */ __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE); + /* 配置TIM定时更新中断 (Update) */ { - uint8_t irq = 0; /* 中断号, 定义在 stm32f4xx.h */ + uint8_t irq = 0; /* 中断号, 定义在 stm32h7xx.h */ - if (TIMx == TIM1) - irq = TIM1_UP_IRQn; - else if (TIMx == TIM2) - irq = TIM2_IRQn; - else if (TIMx == TIM3) - irq = TIM3_IRQn; - else if (TIMx == TIM4) - irq = TIM4_IRQn; - else if (TIMx == TIM5) - irq = TIM5_IRQn; - else if (TIMx == TIM6) - irq = TIM6_DAC_IRQn; - else if (TIMx == TIM7) - irq = TIM7_IRQn; - else if (TIMx == TIM8) - irq = TIM8_UP_TIM13_IRQn; - else if (TIMx == TIM12) - irq = TIM8_BRK_TIM12_IRQn; - else if (TIMx == TIM13) - irq = TIM8_UP_TIM13_IRQn; - else if (TIMx == TIM14) - irq = TIM8_TRG_COM_TIM14_IRQn; - else if (TIMx == TIM15) - irq = TIM15_IRQn; - else if (TIMx == TIM16) - irq = TIM16_IRQn; - else if (TIMx == TIM16) - irq = TIM17_IRQn; + if (TIMx == TIM1) irq = TIM1_UP_IRQn; + else if (TIMx == TIM2) irq = TIM2_IRQn; + else if (TIMx == TIM3) irq = TIM3_IRQn; + else if (TIMx == TIM4) irq = TIM4_IRQn; + else if (TIMx == TIM5) irq = TIM5_IRQn; + else if (TIMx == TIM6) irq = TIM6_DAC_IRQn; + else if (TIMx == TIM7) irq = TIM7_IRQn; + else if (TIMx == TIM8) irq = TIM8_UP_TIM13_IRQn; + else if (TIMx == TIM12) irq = TIM8_BRK_TIM12_IRQn; + else if (TIMx == TIM13) irq = TIM8_UP_TIM13_IRQn; + else if (TIMx == TIM14) irq = TIM8_TRG_COM_TIM14_IRQn; + else if (TIMx == TIM15) irq = TIM15_IRQn; + else if (TIMx == TIM16) irq = TIM16_IRQn; + else if (TIMx == TIM17) irq = TIM17_IRQn; else { Error_Handler(__FILE__, __LINE__); - } + } HAL_NVIC_SetPriority((IRQn_Type)irq, _PreemptionPriority, _SubPriority); - HAL_NVIC_EnableIRQ((IRQn_Type)irq); + HAL_NVIC_EnableIRQ((IRQn_Type)irq); } - + HAL_TIM_Base_Start(&TimHandle); } diff --git a/User/bsp/src/bsp_timer.c b/User/bsp/src/bsp_timer.c index 3b24d26..bb9f29b 100755 --- a/User/bsp/src/bsp_timer.c +++ b/User/bsp/src/bsp_timer.c @@ -89,7 +89,7 @@ static void bsp_SoftTimerDec(SOFT_TMR *_tmr); ********************************************************************************************************* * 函 数 名: bsp_InitTimer * 功能说明: 配置systick中断,并初始化软件定时器变量 -* 形 参: 无 +* 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ @@ -109,7 +109,7 @@ void bsp_InitTimer(void) /* 配置systic中断周期为1ms,并启动systick中断。 - SystemCoreClock 是固件中定义的系统内核时钟,对于STM32F4XX,一般为 168MHz + SystemCoreClock 是固件中定义的系统内核时钟,对于STM32H7,一般为 400MHz SysTick_Config() 函数的形参表示内核时钟多少个周期后触发一次Systick定时中断. -- SystemCoreClock / 1000 表示定时频率为 1000Hz, 也就是定时周期为 1ms @@ -180,7 +180,7 @@ void SysTick_ISR(void) ********************************************************************************************************* * 函 数 名: bsp_SoftTimerDec * 功能说明: 每隔1ms对所有定时器变量减1。必须被SysTick_ISR周期性调用。 -* 形 参: _tmr : 定时器变量指针 +* 形 参: _tmr : 定时器变量指针 * 返 回 值: 无 ********************************************************************************************************* */ @@ -247,7 +247,7 @@ void bsp_DelayMS(uint32_t n) ********************************************************************************************************* * 函 数 名: bsp_DelayUS * 功能说明: us级延迟。 必须在systick定时器启动后才能调用此函数。 -* 形 参: n : 延迟长度,单位1 us +* 形 参: n : 延迟长度,单位1 us * 返 回 值: 无 ********************************************************************************************************* */ @@ -295,8 +295,8 @@ void bsp_DelayUS(uint32_t n) ********************************************************************************************************* * 函 数 名: bsp_StartTimer * 功能说明: 启动一个定时器,并设置定时周期。 -* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 -* _period : 定时周期,单位1ms +* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 +* _period : 定时周期,单位1ms * 返 回 值: 无 ********************************************************************************************************* */ @@ -306,8 +306,7 @@ void bsp_StartTimer(uint8_t _id, uint32_t _period) { /* 打印出错的源代码文件名、函数名称 */ BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__); - while (1) - ; /* 参数异常,死机等待看门狗复位 */ + while (1); /* 参数异常,死机等待看门狗复位 */ } DISABLE_INT(); /* 关中断 */ @@ -324,8 +323,8 @@ void bsp_StartTimer(uint8_t _id, uint32_t _period) ********************************************************************************************************* * 函 数 名: bsp_StartAutoTimer * 功能说明: 启动一个自动定时器,并设置定时周期。 -* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 -* _period : 定时周期,单位10ms +* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 +* _period : 定时周期,单位10ms * 返 回 值: 无 ********************************************************************************************************* */ @@ -363,8 +362,7 @@ void bsp_StopTimer(uint8_t _id) { /* 打印出错的源代码文件名、函数名称 */ BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__); - while (1) - ; /* 参数异常,死机等待看门狗复位 */ + while (1); /* 参数异常,死机等待看门狗复位 */ } DISABLE_INT(); /* 关中断 */ @@ -380,8 +378,8 @@ void bsp_StopTimer(uint8_t _id) ********************************************************************************************************* * 函 数 名: bsp_CheckTimer * 功能说明: 检测定时器是否超时 -* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 -* _period : 定时周期,单位1ms +* 形 参: _id : 定时器ID,值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID,以避免定时器ID冲突。 +* _period : 定时周期,单位1ms * 返 回 值: 返回 0 表示定时未到, 1表示定时到 ********************************************************************************************************* */ @@ -438,8 +436,8 @@ int32_t bsp_CheckRunTime(int32_t _LastTime) int32_t time_diff; DISABLE_INT(); /* 关中断 */ - now_time = g_iRunTime; /* 这个变量在Systick中断中被改写,因此需要关中断进行保护 */ - ENABLE_INT(); /* 开中断 */ + now_time = g_iRunTime; /* 这个变量在Systick中断中被改写,因此需要关中断进行保护 */ + ENABLE_INT(); /* 开中断 */ if (now_time >= _LastTime) { @@ -457,7 +455,7 @@ int32_t bsp_CheckRunTime(int32_t _LastTime) ********************************************************************************************************* * 函 数 名: bsp_DelayNS * 功能说明: us级延迟。 必须在systick定时器启动后才能调用此函数。 -* 形 参: n : 延迟长度,单位NS +* 形 参: n : 延迟长度,单位NS * 返 回 值: 无 ********************************************************************************************************* */ @@ -541,26 +539,34 @@ void SysTick_Handler(void) */ void bsp_InitHardTimer(void) { - TIM_HandleTypeDef TimHandle; + TIM_HandleTypeDef TimHandle = {0}; uint32_t usPeriod; uint16_t usPrescaler; uint32_t uiTIMxCLK; - TIM_TypeDef *TIMx = TIM_HARD; - - RCC_TIM_HARD_CLK_ENABLE(); /* 使能TIM时钟 */ - + TIM_TypeDef* TIMx = TIM_HARD; + + RCC_TIM_HARD_CLK_ENABLE(); /* 使能TIM时钟 */ + /*----------------------------------------------------------------------- - system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下: + bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下: - HCLK = SYSCLK / 1 (AHB1Periph) - PCLK2 = HCLK / 2 (APB2Periph) - PCLK1 = HCLK / 4 (APB1Periph) + System Clock source = PLL (HSE) + SYSCLK(Hz) = 400000000 (CPU Clock) + HCLK(Hz) = 200000000 (AXI and AHBs Clock) + AHB Prescaler = 2 + D1 APB3 Prescaler = 2 (APB3 Clock 100MHz) + D2 APB1 Prescaler = 2 (APB1 Clock 100MHz) + D2 APB2 Prescaler = 2 (APB2 Clock 100MHz) + D3 APB4 Prescaler = 2 (APB4 Clock 100MHz) - 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2; - 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock; + 因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz; + 因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz; + APB4上面的TIMxCLK没有分频,所以就是100MHz; - APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13,TIM14 - APB2 定时器有 TIM1, TIM8 ,TIM15, TIM16, TIM17 + APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1 + APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17 + + APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5 ----------------------------------------------------------------------- */ if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM15) || (TIMx == TIM16) || (TIMx == TIM17)) @@ -568,116 +574,106 @@ void bsp_InitHardTimer(void) /* APB2 定时器时钟 = 200M */ uiTIMxCLK = SystemCoreClock / 2; } - else + else { /* APB1 定时器 = 200M */ uiTIMxCLK = SystemCoreClock / 2; } - usPrescaler = uiTIMxCLK / 1000000 - 1; /* 分频比 = 1 */ - - // if (TIMx == TIM2 || TIMx == TIM5) H743 无需特殊处理 - // { - // usPeriod = 0xFFFFFFFF; - // } - // else + usPrescaler = uiTIMxCLK / 1000000 - 1; /* 分频比 = 1 */ + + if (TIMx == TIM2 || TIMx == TIM5) + { + usPeriod = 0xFFFFFFFF; + } + else { usPeriod = 0xFFFF; } - /* Initialize TIMx peripheral as follows: - + Prescaler = (SystemCoreClock / (2*20000000)) - 1 - + Period = (1000 - 1) - + ClockDivision = 0 - + Counter direction = Up + /* + 设置分频为usPrescaler后,那么定时器计数器计1次就是1us + 而参数usPeriod的值是决定了最大计数: + usPeriod = 0xFFFF 表示最大0xFFFF微秒。 + usPeriod = 0xFFFFFFFF 表示最大0xFFFFFFFF微秒。 */ TimHandle.Instance = TIMx; - TimHandle.Init.Prescaler = usPrescaler; - TimHandle.Init.Period = usPeriod; - TimHandle.Init.ClockDivision = 0; - TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + TimHandle.Init.Prescaler = usPrescaler; + TimHandle.Init.Period = usPeriod; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.RepetitionCounter = 0; - TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - + TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK) { Error_Handler(__FILE__, __LINE__); } - /* 配置TIM定时更新中断 (Update) */ + /* 配置定时器中断,给CC捕获比较中断使用 */ { HAL_NVIC_SetPriority(TIM_HARD_IRQn, 0, 2); - HAL_NVIC_EnableIRQ(TIM_HARD_IRQn); + HAL_NVIC_EnableIRQ(TIM_HARD_IRQn); } + + /* 启动定时器 */ HAL_TIM_Base_Start(&TimHandle); } /* ********************************************************************************************************* -* 函 数 名: bsp_StartHardTimer -* 功能说明: 使用TIM2-5做单次定时器使用, 定时时间到后执行回调函数。可以同时启动4个定时器,互不干扰。 -* 定时精度正负1us (主要耗费在调用本函数的执行时间,函数内部进行了补偿减小误差) +* 函 数 名: bsp_StartHardTimer +* 功能说明: 使用TIM2-5做单次定时器使用, 定时时间到后执行回调函数。可以同时启动4个定时器通道,互不干扰。 +* 定时精度正负1us (主要耗费在调用本函数的执行时间) * TIM2和TIM5 是32位定时器。定时范围很大 * TIM3和TIM4 是16位定时器。 -* 形 参: _CC : 捕获通道几,1,2,3, 4 -* _uiTimeOut : 超时时间, 单位 1us. 对于16位定时器,最大 65.5ms; 对于32位定时器,最大 4294秒 +* 形 参: _CC : 捕获比较通道几,1,2,3, 4 +* _uiTimeOut : 超时时间, 单位 1us. 对于16位定时器,最大 65.5ms; 对于32位定时器,最大 4294秒 * _pCallBack : 定时时间到后,被执行的函数 -* 返 回 值: 无 +* 返 回 值: 无 ********************************************************************************************************* */ void bsp_StartHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void *_pCallBack) { - uint16_t cnt_now; - uint16_t cnt_tar; - TIM_TypeDef *TIMx = TIM_HARD; - - /* - H743速度太快,无需补偿延迟,实测精度正负1us - 407执行下面这个语句,时长 = 18us (通过逻辑分析仪测量IO翻转) - bsp_StartTimer2(3, 500, (void *)test1); - */ - // if (_uiTimeOut < 1) - // { - // ; - // } - // else - // { - // _uiTimeOut -= 5; 5 for F407 - // } - - cnt_now = (uint16_t)TIMx->CNT; /* 读取当前的计数器值 CNT实际只有16bit */ - cnt_tar = cnt_now + _uiTimeOut; /* 计算捕获的计数器值 */ + uint32_t cnt_now; + uint32_t cnt_tar; + TIM_TypeDef* TIMx = TIM_HARD; + + /* H743速度较快,无需补偿延迟,实测精度正负1us */ + + cnt_now = TIMx->CNT; + cnt_tar = cnt_now + _uiTimeOut; /* 计算捕获的计数器值 */ if (_CC == 1) { s_TIM_CallBack1 = (void (*)(void))_pCallBack; - TIMx->CCR1 = cnt_tar; //TIM_SetCompare1(TIM_HARD, cnt_tar); /* 设置捕获比较计数器CC1 */ - TIMx->SR = (uint16_t)~TIM_IT_CC1; //TIM_ClearITPendingBit(TIM_HARD, TIM_IT_CC1); - TIMx->DIER |= TIM_IT_CC1; //TIM_ITConfig(TIM_HARD, TIM_IT_CC1, ENABLE); /* 使能CC1中断 */ + TIMx->CCR1 = cnt_tar; /* 设置捕获比较计数器CC1 */ + TIMx->SR = (uint16_t)~TIM_IT_CC1; /* 清除CC1中断标志 */ + TIMx->DIER |= TIM_IT_CC1; /* 使能CC1中断 */ } else if (_CC == 2) { s_TIM_CallBack2 = (void (*)(void))_pCallBack; - TIMx->CCR2 = cnt_tar; /* 设置捕获比较计数器CC2 */ - TIMx->SR = (uint16_t)~TIM_IT_CC2; - TIMx->DIER |= TIM_IT_CC2; /* 使能CC2中断 */ + TIMx->CCR2 = cnt_tar; /* 设置捕获比较计数器CC2 */ + TIMx->SR = (uint16_t)~TIM_IT_CC2; /* 清除CC2中断标志 */ + TIMx->DIER |= TIM_IT_CC2; /* 使能CC2中断 */ } else if (_CC == 3) { s_TIM_CallBack3 = (void (*)(void))_pCallBack; - TIMx->CCR3 = cnt_tar; /* 设置捕获比较计数器CC3 */ - TIMx->SR = (uint16_t)~TIM_IT_CC3; - TIMx->DIER |= TIM_IT_CC3; /* 使能CC3中断 */ + TIMx->CCR3 = cnt_tar; /* 设置捕获比较计数器CC3 */ + TIMx->SR = (uint16_t)~TIM_IT_CC3; /* 清除CC3中断标志 */ + TIMx->DIER |= TIM_IT_CC3; /* 使能CC3中断 */ } else if (_CC == 4) { s_TIM_CallBack4 = (void (*)(void))_pCallBack; - TIMx->CCR4 = cnt_tar; /* 设置捕获比较计数器CC3 */ - TIMx->SR = (uint16_t)~TIM_IT_CC4; - TIMx->DIER |= TIM_IT_CC4; /* 使能CC4中断 */ + TIMx->CCR4 = cnt_tar; /* 设置捕获比较计数器CC4 */ + TIMx->SR = (uint16_t)~TIM_IT_CC4; /* 清除CC4中断标志 */ + TIMx->DIER |= TIM_IT_CC4; /* 使能CC4中断 */ } else { @@ -689,7 +685,7 @@ void bsp_StartHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void *_pCallBack) ********************************************************************************************************* * 函 数 名: TIMx_IRQHandler * 功能说明: TIM 中断服务程序 -* 形 参:无 +* 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ diff --git a/User/bsp/src/bsp_uart_fifo.c b/User/bsp/src/bsp_uart_fifo.c index d888a17..1c330c5 100755 --- a/User/bsp/src/bsp_uart_fifo.c +++ b/User/bsp/src/bsp_uart_fifo.c @@ -26,108 +26,108 @@ #include "bsp.h" /* 串口1的GPIO PA9, PA10 RS323 DB9接口 */ -#define USART1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE() +#define USART1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE() -#define USART1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART1_TX_GPIO_PORT GPIOA -#define USART1_TX_PIN GPIO_PIN_9 -#define USART1_TX_AF GPIO_AF7_USART1 +#define USART1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define USART1_TX_GPIO_PORT GPIOA +#define USART1_TX_PIN GPIO_PIN_9 +#define USART1_TX_AF GPIO_AF7_USART1 -#define USART1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART1_RX_GPIO_PORT GPIOA -#define USART1_RX_PIN GPIO_PIN_10 -#define USART1_RX_AF GPIO_AF7_USART1 +#define USART1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define USART1_RX_GPIO_PORT GPIOA +#define USART1_RX_PIN GPIO_PIN_10 +#define USART1_RX_AF GPIO_AF7_USART1 /* 串口2的GPIO --- PA2 PA3 GPS (只用RX。 TX被以太网占用) */ -#define USART2_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +#define USART2_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() -#define USART2_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART2_TX_GPIO_PORT GPIOA -#define USART2_TX_PIN GPIO_PIN_2 -#define USART2_TX_AF GPIO_AF7_USART2 +#define USART2_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define USART2_TX_GPIO_PORT GPIOA +#define USART2_TX_PIN GPIO_PIN_2 +#define USART2_TX_AF GPIO_AF7_USART2 -#define USART2_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define USART2_RX_GPIO_PORT GPIOA -#define USART2_RX_PIN GPIO_PIN_3 -#define USART2_RX_AF GPIO_AF7_USART2 +#define USART2_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define USART2_RX_GPIO_PORT GPIOA +#define USART2_RX_PIN GPIO_PIN_3 +#define USART2_RX_AF GPIO_AF7_USART2 /* 串口3的GPIO --- PB10 PB11 RS485 */ -#define USART3_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE() +#define USART3_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE() -#define USART3_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() -#define USART3_TX_GPIO_PORT GPIOB -#define USART3_TX_PIN GPIO_PIN_10 -#define USART3_TX_AF GPIO_AF7_USART3 +#define USART3_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define USART3_TX_GPIO_PORT GPIOB +#define USART3_TX_PIN GPIO_PIN_10 +#define USART3_TX_AF GPIO_AF7_USART3 -#define USART3_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() -#define USART3_RX_GPIO_PORT GPIOB -#define USART3_RX_PIN GPIO_PIN_11 -#define USART3_RX_AF GPIO_AF7_USART3 +#define USART3_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define USART3_RX_GPIO_PORT GPIOB +#define USART3_RX_PIN GPIO_PIN_11 +#define USART3_RX_AF GPIO_AF7_USART3 /* 串口4的GPIO --- PH13 PH14 */ -#define UART4_CLK_ENABLE() __HAL_RCC_UART4_CLK_ENABLE() +#define UART4_CLK_ENABLE() __HAL_RCC_UART4_CLK_ENABLE() -#define UART4_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() -#define UART4_TX_GPIO_PORT GPIOH -#define UART4_TX_PIN GPIO_PIN_13 -#define UART4_TX_AF GPIO_AF8_UART4 +#define UART4_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define UART4_TX_GPIO_PORT GPIOH +#define UART4_TX_PIN GPIO_PIN_13 +#define UART4_TX_AF GPIO_AF8_UART4 -#define UART4_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() -#define UART4_RX_GPIO_PORT GPIOH -#define UART4_RX_PIN GPIO_PIN_14 -#define UART4_RX_AF GPIO_AF8_UART4 +#define UART4_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define UART4_RX_GPIO_PORT GPIOH +#define UART4_RX_PIN GPIO_PIN_14 +#define UART4_RX_AF GPIO_AF8_UART4 /* 串口5的GPIO --- PC12/UART5_TX PD2/UART5_RX (被SD卡占用) */ -#define UART5_CLK_ENABLE() __HAL_RCC_UART5_CLK_ENABLE() +#define UART5_CLK_ENABLE() __HAL_RCC_UART5_CLK_ENABLE() -#define UART5_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() -#define UART5_TX_GPIO_PORT GPIOC -#define UART5_TX_PIN GPIO_PIN_12 -#define UART5_TX_AF GPIO_AF8_UART5 +#define UART5_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define UART5_TX_GPIO_PORT GPIOC +#define UART5_TX_PIN GPIO_PIN_12 +#define UART5_TX_AF GPIO_AF8_UART5 -#define UART5_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() -#define UART5_RX_GPIO_PORT GPIOD -#define UART5_RX_PIN GPIO_PIN_2 -#define UART5_RX_AF GPIO_AF8_UART5 +#define UART5_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define UART5_RX_GPIO_PORT GPIOD +#define UART5_RX_PIN GPIO_PIN_2 +#define UART5_RX_AF GPIO_AF8_UART5 /* 串口6的GPIO --- PG14 PC7 GPRS */ -#define USART6_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE() +#define USART6_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE() -#define USART6_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() -#define USART6_TX_GPIO_PORT GPIOG -#define USART6_TX_PIN GPIO_PIN_14 -#define USART6_TX_AF GPIO_AF7_USART6 +#define USART6_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define USART6_TX_GPIO_PORT GPIOG +#define USART6_TX_PIN GPIO_PIN_14 +#define USART6_TX_AF GPIO_AF7_USART6 -#define USART6_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() -#define USART6_RX_GPIO_PORT GPIOC -#define USART6_RX_PIN GPIO_PIN_7 -#define USART6_RX_AF GPIO_AF7_USART6 +#define USART6_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define USART6_RX_GPIO_PORT GPIOC +#define USART6_RX_PIN GPIO_PIN_7 +#define USART6_RX_AF GPIO_AF7_USART6 /* 串口7的GPIO --- PA15 PA8 */ -#define UART7_CLK_ENABLE() __HAL_RCC_UART7_CLK_ENABLE() +#define UART7_CLK_ENABLE() __HAL_RCC_UART7_CLK_ENABLE() -#define UART7_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define UART7_TX_GPIO_PORT GPIOA -#define UART7_TX_PIN GPIO_PIN_15 -#define UART7_TX_AF GPIO_AF11_UART7 +#define UART7_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define UART7_TX_GPIO_PORT GPIOA +#define UART7_TX_PIN GPIO_PIN_15 +#define UART7_TX_AF GPIO_AF11_UART7 -#define UART7_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define UART7_RX_GPIO_PORT GPIOA -#define UART7_RX_PIN GPIO_PIN_8 -#define UART7_RX_AF GPIO_AF11_UART7 +#define UART7_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define UART7_RX_GPIO_PORT GPIOA +#define UART7_RX_PIN GPIO_PIN_8 +#define UART7_RX_AF GPIO_AF11_UART7 /* 串口8的GPIO --- PB4/UART7_TX, PB3/UART7_RX (被SPI3 占用) */ -#define UART8_CLK_ENABLE() __HAL_RCC_UART8_CLK_ENABLE() +#define UART8_CLK_ENABLE() __HAL_RCC_UART8_CLK_ENABLE() -#define UART8_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE() -#define UART8_TX_GPIO_PORT GPIOJ -#define UART8_TX_PIN GPIO_PIN_8 -#define UART8_TX_AF GPIO_AF8_UART8 +#define UART8_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE() +#define UART8_TX_GPIO_PORT GPIOJ +#define UART8_TX_PIN GPIO_PIN_8 +#define UART8_TX_AF GPIO_AF8_UART8 -#define UART8_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE() -#define UART8_RX_GPIO_PORT GPIOJ -#define UART8_RX_PIN GPIO_PIN_9 -#define UART8_RX_AF GPIO_AF8_UART8 +#define UART8_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE() +#define UART8_RX_GPIO_PORT GPIOJ +#define UART8_RX_PIN GPIO_PIN_9 +#define UART8_RX_AF GPIO_AF8_UART8 /* 定义每个串口结构体变量 */ #if UART1_FIFO_EN == 1 @@ -803,7 +803,7 @@ static void UartVarInit(void) */ void bsp_SetUartParam(USART_TypeDef *Instance, uint32_t BaudRate, uint32_t Parity, uint32_t Mode) { - UART_HandleTypeDef UartHandle; + UART_HandleTypeDef UartHandle = {0}; /* 第2步: 配置串口硬件参数 */ /*##-1- Configure the UART peripheral ######################################*/ diff --git a/User/fonts/hz16.c b/User/fonts/hz16.c index 942a2a3..fb1a4ac 100755 --- a/User/fonts/hz16.c +++ b/User/fonts/hz16.c @@ -1246,6 +1246,12 @@ unsigned char const g_Hz16[] = { 0xC8,0xDD, 0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x88,0x24,0x11,0x10,0x22,0x88,0x04,0x40,// 容 // 0x08,0x20,0x30,0x18,0xDF,0xF6,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10, +0xBD,0xC5, 0x01,0x00,0x79,0x00,0x49,0x1E,0x4B,0x92,0x49,0x12,0x79,0x12,0x49,0x12,0x4F,0xD2,// 脚 // + 0x49,0x12,0x79,0x12,0x4A,0x1A,0x4A,0x94,0x4F,0xD0,0x4A,0x50,0x48,0x10,0x98,0x10, + +0xCF,0xDE, 0x00,0x00,0x7B,0xF8,0x4A,0x08,0x52,0x08,0x53,0xF8,0x62,0x08,0x52,0x08,0x4B,0xF8,// 限 // + 0x4A,0x44,0x4A,0x48,0x6A,0x30,0x52,0x20,0x42,0x10,0x42,0x88,0x43,0x06,0x42,0x00, + /* 最后一行必须用0xFF,0xFF结束,这是字库数组结束标志 */ 0xFF,0xFF diff --git a/User/fonts/hz24.c b/User/fonts/hz24.c index e2f8048..0924606 100755 --- a/User/fonts/hz24.c +++ b/User/fonts/hz24.c @@ -431,6 +431,31 @@ unsigned char const g_Hz24[] = { 0x8C,0x61,0x80,0x0C,0x61,0x80,0x0C,0x43,0xC0,0x0C,0xC6,0x60,0x0C,0x8C,0x38,0x0D, 0x30,0x1F,0x0E,0x40,0x0C,0x08,0x00,0x00, +0xBF,0xD8, 0x08,0x06,0x00,0x0E,0x03,0x00,0x0C,0x01,0x80,0x0C,0x21,0x0C,0x0C,0x3F,0xFE,0x0D,// 控 // + 0x60,0x0C,0x7F,0x60,0x10,0x0C,0x48,0x40,0x0C,0x0E,0x30,0x0C,0x98,0x18,0x0D,0x30, + 0x0C,0x0E,0x20,0x06,0x1C,0x40,0x04,0x7C,0x80,0x30,0x2C,0x7F,0xF8,0x0C,0x03,0x00, + 0x0C,0x03,0x00,0x0C,0x03,0x00,0x0C,0x03,0x00,0x0C,0x03,0x00,0x0C,0x03,0x0C,0x7C, + 0xFF,0xFE,0x18,0x00,0x00,0x10,0x00,0x00, + +0xCE,0xA2, 0x04,0x20,0x40,0x06,0x38,0x70,0x0C,0x30,0x60,0x0D,0x32,0x60,0x19,0xB2,0xC0,0x11,// 微 // + 0x32,0xC0,0x21,0x32,0x84,0x49,0x32,0xFE,0x0D,0xFF,0x98,0x0C,0x01,0x18,0x18,0x04, + 0x98,0x19,0xFE,0x98,0x38,0x00,0x98,0x38,0x8C,0x90,0x58,0xFE,0xB0,0x98,0xCC,0x70, + 0x18,0xCC,0x60,0x18,0xCC,0x60,0x18,0xCD,0xE0,0x19,0x8E,0xF0,0x19,0x9D,0x98,0x1B, + 0x09,0x1C,0x1A,0x02,0x0F,0x14,0x04,0x04, + +0xD0,0xCD, 0x00,0x00,0x10,0x00,0x30,0x1C,0x3F,0xF9,0x18,0x0C,0x61,0xD8,0x0C,0x61,0x98,0x0C,// 型 // + 0x61,0x98,0x0C,0x61,0x98,0x0C,0x69,0x98,0x7F,0xFD,0x98,0x0C,0x61,0x98,0x0C,0x61, + 0x98,0x0C,0x61,0x18,0x18,0x60,0x18,0x18,0x60,0xF8,0x30,0x50,0x30,0x40,0x1C,0x00, + 0x00,0x18,0x30,0x1F,0xFF,0xF8,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x0C,0x7F, + 0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, + +0xD4,0xB4, 0x00,0x00,0x00,0x30,0x80,0x0C,0x18,0xFF,0xFE,0x0C,0xC1,0x00,0x08,0xC1,0x80,0x00,// 源 // + 0xC9,0x18,0x00,0xCF,0xFC,0x60,0xCC,0x18,0x32,0xCC,0x18,0x1A,0xCF,0xF8,0x12,0xCC, + 0x18,0x04,0xCC,0x18,0x04,0xCF,0xF8,0x08,0xC9,0x90,0x18,0xC1,0x80,0x78,0xC9,0xA0, + 0x19,0x8D,0x98,0x19,0x99,0x8C,0x19,0x99,0x8E,0x1B,0x31,0x86,0x1B,0x61,0x84,0x1A, + 0x8F,0x80,0x0C,0x03,0x00,0x00,0x02,0x00, + + /* 最后一行必须用0xFF,0xFF结束,这是字库数组结束标志 */ 0xFF,0xFF diff --git a/User/lua/if/lua_if_gpio.c b/User/lua/if/lua_if_gpio.c index 3c30b53..fcac44c 100755 --- a/User/lua/if/lua_if_gpio.c +++ b/User/lua/if/lua_if_gpio.c @@ -130,7 +130,6 @@ static int lua_GpioWrite(lua_State* L) static int lua_GpioRead(lua_State* L) { uint8_t _no; - uint8_t _value; if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */ { diff --git a/User/lua/if/lua_if_tim.c b/User/lua/if/lua_if_tim.c index 61fe3b1..1cae9de 100755 --- a/User/lua/if/lua_if_tim.c +++ b/User/lua/if/lua_if_tim.c @@ -6,8 +6,6 @@ #include "lua_if.h" #include "bsp.h" -static int lua_udp_print(lua_State* L); - void lua_tim_RegisterFun(void) { //将指定的函数注册为Lua的全局函数变量,其中第一个字符串参数为Lua代码