From 9fd4c2f933e9469f04c9c1588bf70bf618aef5a0 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Thu, 15 Apr 2021 21:07:13 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .svn/entries | 1 + .svn/format | 1 + ...63c491127ce3638df803692169c7b2fe9.svn-base | 523 ++ ...f8f1a3b08357c9714aaf2e312d6eddb70.svn-base | 7 + ...633ed6d314da30c9e118696eec16e0932.svn-base | 4785 +++++++++++++ ...630a3031de2e5e002c6dca24892a28619.svn-base | 364 + ...eb77e355bd41c5f9c7bda8adea56270e1.svn-base | 22 + ...7cbf504c49130f659d5962dddccac528e.svn-base | 2798 ++++++++ ...a69edd2709d47cc1ad07666411e99b021.svn-base | 851 +++ ...19ceb5d4b7a310ad34d0e94155614e71c.svn-base | 121 + ...40e2cec13d2d24563b3b98728580c4d2e.svn-base | 141 + ...e0d267f5db15e4e56af114d31cdbdb033.svn-base | 1248 ++++ ...32f93dcfe52f4f18b844a1fb2774b9e7a.svn-base | 12 + ...482529a79be97c290f7d58b5422901fae.svn-base | 63 + ...3d7a5eb37ac67326ed339f3ee942e6ba8.svn-base | 5810 ++++++++++++++++ ...f1bce930da764fa85f332effaec9b7490.svn-base | 18 + ...7cc3db72ec9889c4f8811b613f5cb00ce.svn-base | 57 + ...f3e7937e0b7f9c175b6509f3e5a1f4c2a.svn-base | 225 + ...a903829daf058ea00ef58cab1e4e84512.svn-base | 54 + ...a7516d130841f66ccccb602ed4ea70c9e.svn-base | 577 ++ ...3e0df2c0627998cd03ee60d1e0fa832f5.svn-base | 20 + ...dad193a24e77c8b808d59b35c080186ad.svn-base | 50 + ...943aa76cbc45136183c34e432ce24f25c.svn-base | 654 ++ ...7b27fcd9ed088a2d416b5e61515861a76.svn-base | 5894 +++++++++++++++++ ...9ce9bacdbb5b912cc79d345d86b30cf70.svn-base | 74 + ...039f14543a5d348513a31ac5bfa2ba4ff.svn-base | 37 + ...11fe9bab6f021b6eedb23767250ad93e8.svn-base | 170 + ...654c8aed207f60be1bdde303c686c0b8f.svn-base | 15 + ...42619ee3e46ea3426fdb10ec6ff9aebc2.svn-base | 462 ++ ...f2382fa41e5a93791c4fd331e8c0f3699.svn-base | 186 + ...960aaca49802c9be390d450cfc6990a28.svn-base | 1799 +++++ ...2be22d31ad62ac290e2e98cce5fe5e77a.svn-base | 161 + ...a463526c028407e3b454f9ce2bc4d3565.svn-base | 279 + ...f538764c56f4c0cccc558ea67aa10c855.svn-base | 11 + ...ea373bb259539f233f42aebd4d1d435cf.svn-base | 179 + ...a3603da0dee16dec1a34f9dfe3e564a84.svn-base | 328 + ...2c76ed36a098618123bf8d6d9877a6a51.svn-base | 1239 ++++ ...10a834238832f14e0db4d77eb1416efbe.svn-base | 615 ++ ...534b455bdac2379c7c856bd152e928fed.svn-base | 1320 ++++ ...0d26773cb5379183240262b1ffdc6ab53.svn-base | 5 + ...7c57a99aa8cc27a2a378e57c29807ce55.svn-base | 270 + ...be3351cf386222111c3cb4dd510abbac1.svn-base | 372 ++ ...664a90b2ef14758e7b9cf2a31e20d02ac.svn-base | 229 + ...5af79d0210118506b98770e65c99237e9.svn-base | 268 + ...e439040bc2e7c7390c57595ce9f80350c.svn-base | 30 + ...d914026c0cf635cc18ad73e615b8d93d2.svn-base | 7 + ...b8210b598b7533626af5f844900a3a406.svn-base | 322 + ...eb0c01aaa11f2155ca9a3ddfb49824262.svn-base | 720 ++ ...9e86a4c69729ee53d7085bfa1fd9f1201.svn-base | 141 + ...02848c671305abb87fdf70346ff457c13.svn-base | 616 ++ ...d43c6c1fa2ee18af53264a130881aef8d.svn-base | 1632 +++++ ...eb06711602e0a204cffd8a595ed186056.svn-base | 77 + ...b3b4390988467031c0b94eefa83975877.svn-base | 711 ++ ...b93f1416966fb123053dd67eac6acb7d5.svn-base | 38 + ...015cad3f8f755534e03a7302161e929d0.svn-base | 28 + ...c30ec4334a07778a66890842b4f2901f0.svn-base | 18 + ...c7c08e9f6c9c94651c41f8141cd49c6c9.svn-base | 78 + ...b32f5cf8bb087808d270a7143a1a91f3c.svn-base | 982 +++ ...491d1bb3749ae899151e4250bf9d9c1fe.svn-base | 1077 +++ ...7af540a61bdc917b0945aec010fa1195a.svn-base | 132 + ...079725d35e4bcf79e7d2e292c42d5f227.svn-base | 99 + ...2a0d0c294d26b0e83ddf9416f8e7431d0.svn-base | 935 +++ ...862d301a6b22bca1a8083a07295b4dbed.svn-base | 1814 +++++ ...96386a0726157a5d113fe824650c50814.svn-base | 99 + ...d0e66aad88377898fa1b4c6724f62a30e.svn-base | 71 + ...63ac3993e8f8ac947fe5fac773a99adc6.svn-base | 15 + ...6c830b0bd105faa1f39e727b4ec7a1f88.svn-base | 1116 ++++ ...850b7881438dfcf3ff39157a0133f7a26.svn-base | 725 ++ ...6d41c121e94a58358851f8d21d7bd5f23.svn-base | 42 + ...897cd8289e711375bb5c0d9e70e4df40c.svn-base | 4 + ...2f4128cb819448a0a9ba83a36b6cc5474.svn-base | 23 + ...10fdf269e25f14bd37cdbd5dd34080e6f.svn-base | Bin 0 -> 14336 bytes ...d548d8a1d4efc0c644fe34d45642780b7.svn-base | 44 + ...c48af8d299f2bb8623cb0db9911e086e4.svn-base | 61 + ...f7885927f9ec2af434c61d604058c30ee.svn-base | 10 + ...d8faa056b85845c66c50c38468fffb7fd.svn-base | 133 + ...bf88b2baace4100423a73fb773fe6651b.svn-base | 63 + ...10391ced7ab58fdff5e119d4b0d3ef96a.svn-base | 24 + ...a15fbdb127f8087f8a67c2a2516409754.svn-base | 62 + ...9d76cb6c10b7ec3d4a4c4ff6d76cc8348.svn-base | 802 +++ ...62bec67c4c3fe939fd4e8330a4a47fed1.svn-base | 395 ++ ...6a34c0714d8b47143eaa15b1153fdf7fa.svn-base | 56 + ...afe0a4d81761b531104a0499abc2b60c7.svn-base | 292 + ...4413d9765a67e97dfa4e9b3bfe5e2f105.svn-base | 228 + ...bc2031853e38b58bd7465417fc3ffaa53.svn-base | Bin 0 -> 12800 bytes ...8f6e28fb33bf78b775a2137aaa9507e26.svn-base | 89 + ...c51d7aeb30e7c9cbd130d6534e0cc9a75.svn-base | 1174 ++++ ...d78d4f529057b8b4771ef12aa6949d4ce.svn-base | 17 + ...4af0bf4b33ab59a4b20f5e5fe037df6de.svn-base | 2748 ++++++++ ...021e0d873107658ec2166d2ba27606fc0.svn-base | 460 ++ ...2304cd967c6f09f434b3df719afe8692d.svn-base | 434 ++ ...1f75133d8f7e24d3e2f3f3580908d9fc4.svn-base | 1315 ++++ ...f1bd663d2e2513d763834516c0a8616d3.svn-base | 160 + ...72ebc90e94d6dee8f5c2f2913801e17bb.svn-base | 187 + ...69469213541991ccf2bdebe991b120469.svn-base | 333 + ...8a6aab19207d286c6671850857e05c271.svn-base | 626 ++ ...932415327da777405536bfe94b57f9a32.svn-base | 189 + ...a51d660b28eeda8c0fe14e0c0afa74c7a.svn-base | 94 + ...45189b48d5cd436cc977bab84ff94f1f6.svn-base | 357 + ...ced3e22c8591906a098ebb4039c299326.svn-base | 20 + ...5ae10f93200cddb6618457ea06e3f0768.svn-base | 1070 +++ ...90c7fe7025041acbb23d64c7d16602222.svn-base | 52 + ...be08cd7d495fd5d977d7e4d44b30852e4.svn-base | 93 + ...607794fab47efe22fa6804994cf933c82.svn-base | 106 + ...92f8c7c7dc1e0d421c2727fbb4454eb46.svn-base | 77 + ...737a1e6b5b9f785b60123083c4670a8e7.svn-base | 1186 ++++ ...357b521cb8389144fd91326d3f56fe2ad.svn-base | 15 + ...c201bc607b3dc244356f9c2a75e5d610a.svn-base | 23 + ...bab98e7279aeaf199e55da2d7e233dad4.svn-base | 1902 ++++++ ...c0298d04b4b1d81f3beb32fa90a26425a.svn-base | 629 ++ ...b528b7eddc67fa3bb7a217de0588c4c1c.svn-base | 888 +++ ...0a567ff88eda97034935e973cf37314aa.svn-base | 220 + ...4f8c6613811c65114b7263919a56b15eb.svn-base | 865 +++ ...4398aedabecc6f32d9094d6610fe3aba0.svn-base | 141 + .svn/wc.db | Bin 0 -> 204800 bytes .svn/wc.db-journal | 0 DRIVERS/ccnet/CCRSProtocol.c | 725 ++ DRIVERS/ccnet/CCRSProtocol.h | 364 + DRIVERS/ccnet/VMCConst.h | 5 + DRIVERS/ccnet/uart1.c | 106 + DRIVERS/ccnet/uart1.h | 11 + DRIVERS/fiscal/fiscal.c | 802 +++ DRIVERS/fiscal/fiscal.h | 395 ++ DRIVERS/fiscal/uart0.c | 270 + DRIVERS/fiscal/uart0.h | 15 + DRIVERS/fram/fram.c | 161 + DRIVERS/fram/fram.h | 23 + DRIVERS/fram/spi.c | 94 + DRIVERS/fram/spi.h | 15 + DRIVERS/keyboard/keyboard.c | 225 + DRIVERS/keyboard/keyboard.h | 37 + DRIVERS/lcd/lcd.c | 333 + DRIVERS/lcd/lcd.h | 50 + DRIVERS/modem/modem.c | 935 +++ DRIVERS/modem/modem.h | 63 + DRIVERS/modem/uart2.c | 228 + DRIVERS/modem/uart2.h | 18 + Flash/Exe/solarium.hex | 5894 +++++++++++++++++ Flash/Exe/solarium.out | Bin 0 -> 974341 bytes Flash/Obj/CCRSProtocol.o | Bin 0 -> 53080 bytes Flash/Obj/CCRSProtocol.pbi | 63 + Flash/Obj/app.o | Bin 0 -> 8916 bytes Flash/Obj/app.pbi | 63 + Flash/Obj/app_serv.o | Bin 0 -> 96896 bytes Flash/Obj/app_serv.pbi | 63 + Flash/Obj/bsp.o | Bin 0 -> 135044 bytes Flash/Obj/bsp.pbi | 63 + Flash/Obj/coin.o | Bin 0 -> 34664 bytes Flash/Obj/coin.pbi | 63 + Flash/Obj/control.o | Bin 0 -> 36328 bytes Flash/Obj/control.pbi | 63 + Flash/Obj/cpu_a.o | Bin 0 -> 1536 bytes Flash/Obj/crc16.o | Bin 0 -> 6780 bytes Flash/Obj/crc16.pbi | 63 + Flash/Obj/cstartup.o | Bin 0 -> 3680 bytes Flash/Obj/data.o | Bin 0 -> 35548 bytes Flash/Obj/data.pbi | 63 + Flash/Obj/datadesc.o | Bin 0 -> 254736 bytes Flash/Obj/datadesc.pbi | 63 + Flash/Obj/fiscal.o | Bin 0 -> 83868 bytes Flash/Obj/fiscal.pbi | 63 + Flash/Obj/fr.o | Bin 0 -> 50320 bytes Flash/Obj/fr.pbi | 63 + Flash/Obj/fram.o | Bin 0 -> 21692 bytes Flash/Obj/fram.pbi | 63 + Flash/Obj/journal.o | Bin 0 -> 60292 bytes Flash/Obj/journal.pbi | 63 + Flash/Obj/keyboard.o | Bin 0 -> 42996 bytes Flash/Obj/keyboard.pbi | 63 + Flash/Obj/lcd.o | Bin 0 -> 45164 bytes Flash/Obj/lcd.pbi | 63 + Flash/Obj/lib_mem.o | Bin 0 -> 12972 bytes Flash/Obj/lib_mem.pbi | 63 + Flash/Obj/lib_str.o | Bin 0 -> 26112 bytes Flash/Obj/lib_str.pbi | 63 + Flash/Obj/menu.o | Bin 0 -> 68204 bytes Flash/Obj/menu.pbi | 63 + Flash/Obj/menudesc.o | Bin 0 -> 236000 bytes Flash/Obj/menudesc.pbi | 63 + Flash/Obj/mode.o | Bin 0 -> 16400 bytes Flash/Obj/mode.pbi | 63 + Flash/Obj/modem.o | Bin 0 -> 80996 bytes Flash/Obj/modem.pbi | 63 + Flash/Obj/modem_task.o | Bin 0 -> 55216 bytes Flash/Obj/modem_task.pbi | 63 + Flash/Obj/os_core.o | Bin 0 -> 68924 bytes Flash/Obj/os_core.pbi | 63 + Flash/Obj/os_cpu_a.o | Bin 0 -> 4408 bytes Flash/Obj/os_cpu_c.o | Bin 0 -> 20260 bytes Flash/Obj/os_cpu_c.pbi | 63 + Flash/Obj/os_dbg.o | Bin 0 -> 33576 bytes Flash/Obj/os_dbg.pbi | 63 + Flash/Obj/os_dcc.o | Bin 0 -> 2536 bytes Flash/Obj/os_dcc.pbi | 63 + Flash/Obj/os_flag.o | Bin 0 -> 31608 bytes Flash/Obj/os_flag.pbi | 63 + Flash/Obj/os_mbox.o | Bin 0 -> 21460 bytes Flash/Obj/os_mbox.pbi | 63 + Flash/Obj/os_mem.o | Bin 0 -> 12896 bytes Flash/Obj/os_mem.pbi | 63 + Flash/Obj/os_mutex.o | Bin 0 -> 23204 bytes Flash/Obj/os_mutex.pbi | 63 + Flash/Obj/os_q.o | Bin 0 -> 28424 bytes Flash/Obj/os_q.pbi | 63 + Flash/Obj/os_sem.o | Bin 0 -> 22632 bytes Flash/Obj/os_sem.pbi | 63 + Flash/Obj/os_task.o | Bin 0 -> 29992 bytes Flash/Obj/os_task.pbi | 63 + Flash/Obj/os_time.o | Bin 0 -> 13848 bytes Flash/Obj/os_time.pbi | 63 + Flash/Obj/os_tmr.o | Bin 0 -> 35660 bytes Flash/Obj/os_tmr.pbi | 63 + Flash/Obj/solarium.pbd | 43 + Flash/Obj/spi.o | Bin 0 -> 28080 bytes Flash/Obj/spi.pbi | 63 + Flash/Obj/time.o | Bin 0 -> 65900 bytes Flash/Obj/time.pbi | 63 + Flash/Obj/uart0.o | Bin 0 -> 42420 bytes Flash/Obj/uart0.pbi | 63 + Flash/Obj/uart1.o | Bin 0 -> 26500 bytes Flash/Obj/uart1.pbi | 63 + Flash/Obj/uart2.o | Bin 0 -> 35884 bytes Flash/Obj/uart2.pbi | 63 + Flash/Obj/validator.o | Bin 0 -> 34784 bytes Flash/Obj/validator.pbi | 63 + OS/app/app.c | 78 + OS/app/app_cfg.h | 52 + OS/app/includes.h | 22 + OS/app/os_cfg.h | 141 + OS/bsp/LPC2368_Flash.icf | 56 + OS/bsp/LPC2368_Flash.mac | 4 + OS/bsp/bsp.c | 851 +++ OS/bsp/bsp.h | 99 + OS/bsp/cstartup.s | 132 + OS/bsp/iolpc2368.h | 4785 +++++++++++++ OS/uc/cpu/cpu.h | 328 + OS/uc/cpu/cpu_a.s | 121 + OS/uc/cpu/cpu_def.h | 133 + OS/uc/lib/lib_def.h | 616 ++ OS/uc/lib/lib_mem.c | 462 ++ OS/uc/lib/lib_mem.h | 615 ++ OS/uc/lib/lib_str.c | 1248 ++++ OS/uc/lib/lib_str.h | 279 + OS/uc/os_ii/port/os_cpu.h | 229 + OS/uc/os_ii/port/os_cpu_a.asm | 577 ++ OS/uc/os_ii/port/os_cpu_c.c | 523 ++ OS/uc/os_ii/port/os_dbg.c | 292 + OS/uc/os_ii/port/os_dcc.c | 220 + OS/uc/os_ii/source/os_core.c | 1632 +++++ OS/uc/os_ii/source/os_flag.c | 1174 ++++ OS/uc/os_ii/source/os_mbox.c | 626 ++ OS/uc/os_ii/source/os_mem.c | 434 ++ OS/uc/os_ii/source/os_mutex.c | 711 ++ OS/uc/os_ii/source/os_q.c | 865 +++ OS/uc/os_ii/source/os_sem.c | 629 ++ OS/uc/os_ii/source/os_task.c | 1070 +++ OS/uc/os_ii/source/os_time.c | 268 + OS/uc/os_ii/source/os_tmr.c | 1116 ++++ OS/uc/os_ii/source/ucos_ii.h | 1902 ++++++ PROJECT/app/app_serv.c | 1186 ++++ PROJECT/app/app_serv.h | 71 + PROJECT/app/control.c | 187 + PROJECT/app/control.h | 24 + PROJECT/app/journal.c | 460 ++ PROJECT/app/journal.h | 179 + PROJECT/app/modem_task.c | 720 ++ PROJECT/app/modem_task.h | 28 + PROJECT/data/data.c | 357 + PROJECT/data/data.h | 141 + PROJECT/data/datadesc.c | 2798 ++++++++ PROJECT/data/datadesc.h | 189 + PROJECT/data/fram_map.h | 42 + PROJECT/menu/menu.c | 654 ++ PROJECT/menu/menu.h | 99 + PROJECT/menu/menudesc.c | 1814 +++++ PROJECT/menu/menudesc.h | 62 + PROJECT/service/coin.c | 160 + PROJECT/service/coin.h | 18 + PROJECT/service/fr.c | 982 +++ PROJECT/service/fr.h | 30 + PROJECT/service/mode.c | 57 + PROJECT/service/mode.h | 17 + PROJECT/service/time.c | 322 + PROJECT/service/time.h | 44 + PROJECT/service/validator.c | 372 ++ PROJECT/service/validator.h | 20 + PROJECT/tools/crc16.c | 89 + PROJECT/tools/crc16.h | 20 + PROJECT/version.h | 7 + settings/solarium.cspy.bat | 15 + settings/solarium.dbgdt | 74 + settings/solarium.dni | 93 + settings/solarium.wsdt | 77 + settings/solarium_Flash.jlink | 12 + solarium.dep | 1316 ++++ solarium.ewd | 888 +++ solarium.ewp | 1239 ++++ solarium.eww | 10 + todo.txt | 54 + параметры.txt | 63 + список выводов.xls | Bin 0 -> 14336 bytes 301 files changed, 112182 insertions(+) create mode 100644 .svn/entries create mode 100644 .svn/format create mode 100644 .svn/pristine/02/022515663c491127ce3638df803692169c7b2fe9.svn-base create mode 100644 .svn/pristine/04/0486bfef8f1a3b08357c9714aaf2e312d6eddb70.svn-base create mode 100644 .svn/pristine/05/054a010633ed6d314da30c9e118696eec16e0932.svn-base create mode 100644 .svn/pristine/06/064e186630a3031de2e5e002c6dca24892a28619.svn-base create mode 100644 .svn/pristine/06/066b62aeb77e355bd41c5f9c7bda8adea56270e1.svn-base create mode 100644 .svn/pristine/09/0962d2e7cbf504c49130f659d5962dddccac528e.svn-base create mode 100644 .svn/pristine/09/0986d6aa69edd2709d47cc1ad07666411e99b021.svn-base create mode 100644 .svn/pristine/09/09b5f4319ceb5d4b7a310ad34d0e94155614e71c.svn-base create mode 100644 .svn/pristine/0d/0df01c140e2cec13d2d24563b3b98728580c4d2e.svn-base create mode 100644 .svn/pristine/0e/0ef7114e0d267f5db15e4e56af114d31cdbdb033.svn-base create mode 100644 .svn/pristine/11/114bc6032f93dcfe52f4f18b844a1fb2774b9e7a.svn-base create mode 100644 .svn/pristine/13/13d341d482529a79be97c290f7d58b5422901fae.svn-base create mode 100644 .svn/pristine/14/14d13e43d7a5eb37ac67326ed339f3ee942e6ba8.svn-base create mode 100644 .svn/pristine/17/1727e06f1bce930da764fa85f332effaec9b7490.svn-base create mode 100644 .svn/pristine/19/194f3897cc3db72ec9889c4f8811b613f5cb00ce.svn-base create mode 100644 .svn/pristine/1a/1aed176f3e7937e0b7f9c175b6509f3e5a1f4c2a.svn-base create mode 100644 .svn/pristine/23/236e5d2a903829daf058ea00ef58cab1e4e84512.svn-base create mode 100644 .svn/pristine/28/289d5caa7516d130841f66ccccb602ed4ea70c9e.svn-base create mode 100644 .svn/pristine/29/29f8c8b3e0df2c0627998cd03ee60d1e0fa832f5.svn-base create mode 100644 .svn/pristine/2a/2ad7ea9dad193a24e77c8b808d59b35c080186ad.svn-base create mode 100644 .svn/pristine/2e/2e6563f943aa76cbc45136183c34e432ce24f25c.svn-base create mode 100644 .svn/pristine/30/30b68ba7b27fcd9ed088a2d416b5e61515861a76.svn-base create mode 100644 .svn/pristine/32/32be97f9ce9bacdbb5b912cc79d345d86b30cf70.svn-base create mode 100644 .svn/pristine/35/350b1d7039f14543a5d348513a31ac5bfa2ba4ff.svn-base create mode 100644 .svn/pristine/35/354359d11fe9bab6f021b6eedb23767250ad93e8.svn-base create mode 100644 .svn/pristine/36/3689fb4654c8aed207f60be1bdde303c686c0b8f.svn-base create mode 100644 .svn/pristine/36/36d8a1b42619ee3e46ea3426fdb10ec6ff9aebc2.svn-base create mode 100644 .svn/pristine/37/37e0d0cf2382fa41e5a93791c4fd331e8c0f3699.svn-base create mode 100644 .svn/pristine/38/389d894960aaca49802c9be390d450cfc6990a28.svn-base create mode 100644 .svn/pristine/3e/3eec29b2be22d31ad62ac290e2e98cce5fe5e77a.svn-base create mode 100644 .svn/pristine/41/415518ca463526c028407e3b454f9ce2bc4d3565.svn-base create mode 100644 .svn/pristine/42/422692cf538764c56f4c0cccc558ea67aa10c855.svn-base create mode 100644 .svn/pristine/48/4835c4fea373bb259539f233f42aebd4d1d435cf.svn-base create mode 100644 .svn/pristine/4d/4d13467a3603da0dee16dec1a34f9dfe3e564a84.svn-base create mode 100644 .svn/pristine/4d/4d53cd22c76ed36a098618123bf8d6d9877a6a51.svn-base create mode 100644 .svn/pristine/4d/4d7f94f10a834238832f14e0db4d77eb1416efbe.svn-base create mode 100644 .svn/pristine/51/51d60af534b455bdac2379c7c856bd152e928fed.svn-base create mode 100644 .svn/pristine/54/5499a160d26773cb5379183240262b1ffdc6ab53.svn-base create mode 100644 .svn/pristine/55/55cd02b7c57a99aa8cc27a2a378e57c29807ce55.svn-base create mode 100644 .svn/pristine/56/5687b4ebe3351cf386222111c3cb4dd510abbac1.svn-base create mode 100644 .svn/pristine/5e/5eab627664a90b2ef14758e7b9cf2a31e20d02ac.svn-base create mode 100644 .svn/pristine/5f/5fb79265af79d0210118506b98770e65c99237e9.svn-base create mode 100644 .svn/pristine/61/61df778e439040bc2e7c7390c57595ce9f80350c.svn-base create mode 100644 .svn/pristine/62/628409cd914026c0cf635cc18ad73e615b8d93d2.svn-base create mode 100644 .svn/pristine/63/63437cfb8210b598b7533626af5f844900a3a406.svn-base create mode 100644 .svn/pristine/67/671d6f8eb0c01aaa11f2155ca9a3ddfb49824262.svn-base create mode 100644 .svn/pristine/6d/6d1c24d9e86a4c69729ee53d7085bfa1fd9f1201.svn-base create mode 100644 .svn/pristine/71/7160dac02848c671305abb87fdf70346ff457c13.svn-base create mode 100644 .svn/pristine/75/7522885d43c6c1fa2ee18af53264a130881aef8d.svn-base create mode 100644 .svn/pristine/76/764880feb06711602e0a204cffd8a595ed186056.svn-base create mode 100644 .svn/pristine/79/796635eb3b4390988467031c0b94eefa83975877.svn-base create mode 100644 .svn/pristine/7a/7ac514db93f1416966fb123053dd67eac6acb7d5.svn-base create mode 100644 .svn/pristine/7b/7b0e8b7015cad3f8f755534e03a7302161e929d0.svn-base create mode 100644 .svn/pristine/7c/7ce900fc30ec4334a07778a66890842b4f2901f0.svn-base create mode 100644 .svn/pristine/7d/7d0688ac7c08e9f6c9c94651c41f8141cd49c6c9.svn-base create mode 100644 .svn/pristine/7e/7ea2debb32f5cf8bb087808d270a7143a1a91f3c.svn-base create mode 100644 .svn/pristine/83/83c5faa491d1bb3749ae899151e4250bf9d9c1fe.svn-base create mode 100644 .svn/pristine/84/84b86297af540a61bdc917b0945aec010fa1195a.svn-base create mode 100644 .svn/pristine/85/850ec0e079725d35e4bcf79e7d2e292c42d5f227.svn-base create mode 100644 .svn/pristine/8b/8bef40d2a0d0c294d26b0e83ddf9416f8e7431d0.svn-base create mode 100644 .svn/pristine/90/9099a53862d301a6b22bca1a8083a07295b4dbed.svn-base create mode 100644 .svn/pristine/95/95c51dd96386a0726157a5d113fe824650c50814.svn-base create mode 100644 .svn/pristine/97/9797818d0e66aad88377898fa1b4c6724f62a30e.svn-base create mode 100644 .svn/pristine/98/98c384363ac3993e8f8ac947fe5fac773a99adc6.svn-base create mode 100644 .svn/pristine/9d/9dafea76c830b0bd105faa1f39e727b4ec7a1f88.svn-base create mode 100644 .svn/pristine/9e/9e83995850b7881438dfcf3ff39157a0133f7a26.svn-base create mode 100644 .svn/pristine/9f/9f4ca976d41c121e94a58358851f8d21d7bd5f23.svn-base create mode 100644 .svn/pristine/a0/a00279d897cd8289e711375bb5c0d9e70e4df40c.svn-base create mode 100644 .svn/pristine/a2/a2246f12f4128cb819448a0a9ba83a36b6cc5474.svn-base create mode 100644 .svn/pristine/a2/a22abde10fdf269e25f14bd37cdbd5dd34080e6f.svn-base create mode 100644 .svn/pristine/a6/a63ea37d548d8a1d4efc0c644fe34d45642780b7.svn-base create mode 100644 .svn/pristine/ac/acbbf9ac48af8d299f2bb8623cb0db9911e086e4.svn-base create mode 100644 .svn/pristine/ad/adfa546f7885927f9ec2af434c61d604058c30ee.svn-base create mode 100644 .svn/pristine/ae/ae4148ad8faa056b85845c66c50c38468fffb7fd.svn-base create mode 100644 .svn/pristine/b0/b06d17bbf88b2baace4100423a73fb773fe6651b.svn-base create mode 100644 .svn/pristine/b1/b1cd9dd10391ced7ab58fdff5e119d4b0d3ef96a.svn-base create mode 100644 .svn/pristine/b2/b2b77ada15fbdb127f8087f8a67c2a2516409754.svn-base create mode 100644 .svn/pristine/b3/b3e6d069d76cb6c10b7ec3d4a4c4ff6d76cc8348.svn-base create mode 100644 .svn/pristine/b7/b71983062bec67c4c3fe939fd4e8330a4a47fed1.svn-base create mode 100644 .svn/pristine/b7/b7dcedd6a34c0714d8b47143eaa15b1153fdf7fa.svn-base create mode 100644 .svn/pristine/b8/b81093eafe0a4d81761b531104a0499abc2b60c7.svn-base create mode 100644 .svn/pristine/bb/bbd54324413d9765a67e97dfa4e9b3bfe5e2f105.svn-base create mode 100644 .svn/pristine/bd/bdce684bc2031853e38b58bd7465417fc3ffaa53.svn-base create mode 100644 .svn/pristine/c1/c1d58908f6e28fb33bf78b775a2137aaa9507e26.svn-base create mode 100644 .svn/pristine/c3/c35ce57c51d7aeb30e7c9cbd130d6534e0cc9a75.svn-base create mode 100644 .svn/pristine/c3/c361b81d78d4f529057b8b4771ef12aa6949d4ce.svn-base create mode 100644 .svn/pristine/c5/c5693094af0bf4b33ab59a4b20f5e5fe037df6de.svn-base create mode 100644 .svn/pristine/c6/c609119021e0d873107658ec2166d2ba27606fc0.svn-base create mode 100644 .svn/pristine/c7/c7a8f2a2304cd967c6f09f434b3df719afe8692d.svn-base create mode 100644 .svn/pristine/c8/c8224411f75133d8f7e24d3e2f3f3580908d9fc4.svn-base create mode 100644 .svn/pristine/c9/c9639f2f1bd663d2e2513d763834516c0a8616d3.svn-base create mode 100644 .svn/pristine/cd/cd2b95272ebc90e94d6dee8f5c2f2913801e17bb.svn-base create mode 100644 .svn/pristine/cd/cd652f769469213541991ccf2bdebe991b120469.svn-base create mode 100644 .svn/pristine/d1/d1fb2da8a6aab19207d286c6671850857e05c271.svn-base create mode 100644 .svn/pristine/d3/d39b196932415327da777405536bfe94b57f9a32.svn-base create mode 100644 .svn/pristine/d4/d4ed29ba51d660b28eeda8c0fe14e0c0afa74c7a.svn-base create mode 100644 .svn/pristine/d7/d74b48545189b48d5cd436cc977bab84ff94f1f6.svn-base create mode 100644 .svn/pristine/db/db30e0aced3e22c8591906a098ebb4039c299326.svn-base create mode 100644 .svn/pristine/db/db318d95ae10f93200cddb6618457ea06e3f0768.svn-base create mode 100644 .svn/pristine/dc/dc4804b90c7fe7025041acbb23d64c7d16602222.svn-base create mode 100644 .svn/pristine/dd/dd7db2bbe08cd7d495fd5d977d7e4d44b30852e4.svn-base create mode 100644 .svn/pristine/de/deb2b62607794fab47efe22fa6804994cf933c82.svn-base create mode 100644 .svn/pristine/e0/e08eaa492f8c7c7dc1e0d421c2727fbb4454eb46.svn-base create mode 100644 .svn/pristine/e3/e391c6b737a1e6b5b9f785b60123083c4670a8e7.svn-base create mode 100644 .svn/pristine/e4/e4c1d1a357b521cb8389144fd91326d3f56fe2ad.svn-base create mode 100644 .svn/pristine/e7/e7c424ac201bc607b3dc244356f9c2a75e5d610a.svn-base create mode 100644 .svn/pristine/ea/ea27b8cbab98e7279aeaf199e55da2d7e233dad4.svn-base create mode 100644 .svn/pristine/f2/f24bce3c0298d04b4b1d81f3beb32fa90a26425a.svn-base create mode 100644 .svn/pristine/f3/f314655b528b7eddc67fa3bb7a217de0588c4c1c.svn-base create mode 100644 .svn/pristine/f3/f39a6f70a567ff88eda97034935e973cf37314aa.svn-base create mode 100644 .svn/pristine/f7/f79bb474f8c6613811c65114b7263919a56b15eb.svn-base create mode 100644 .svn/pristine/f8/f8307ce4398aedabecc6f32d9094d6610fe3aba0.svn-base create mode 100644 .svn/wc.db create mode 100644 .svn/wc.db-journal create mode 100644 DRIVERS/ccnet/CCRSProtocol.c create mode 100644 DRIVERS/ccnet/CCRSProtocol.h create mode 100644 DRIVERS/ccnet/VMCConst.h create mode 100644 DRIVERS/ccnet/uart1.c create mode 100644 DRIVERS/ccnet/uart1.h create mode 100644 DRIVERS/fiscal/fiscal.c create mode 100644 DRIVERS/fiscal/fiscal.h create mode 100644 DRIVERS/fiscal/uart0.c create mode 100644 DRIVERS/fiscal/uart0.h create mode 100644 DRIVERS/fram/fram.c create mode 100644 DRIVERS/fram/fram.h create mode 100644 DRIVERS/fram/spi.c create mode 100644 DRIVERS/fram/spi.h create mode 100644 DRIVERS/keyboard/keyboard.c create mode 100644 DRIVERS/keyboard/keyboard.h create mode 100644 DRIVERS/lcd/lcd.c create mode 100644 DRIVERS/lcd/lcd.h create mode 100644 DRIVERS/modem/modem.c create mode 100644 DRIVERS/modem/modem.h create mode 100644 DRIVERS/modem/uart2.c create mode 100644 DRIVERS/modem/uart2.h create mode 100644 Flash/Exe/solarium.hex create mode 100644 Flash/Exe/solarium.out create mode 100644 Flash/Obj/CCRSProtocol.o create mode 100644 Flash/Obj/CCRSProtocol.pbi create mode 100644 Flash/Obj/app.o create mode 100644 Flash/Obj/app.pbi create mode 100644 Flash/Obj/app_serv.o create mode 100644 Flash/Obj/app_serv.pbi create mode 100644 Flash/Obj/bsp.o create mode 100644 Flash/Obj/bsp.pbi create mode 100644 Flash/Obj/coin.o create mode 100644 Flash/Obj/coin.pbi create mode 100644 Flash/Obj/control.o create mode 100644 Flash/Obj/control.pbi create mode 100644 Flash/Obj/cpu_a.o create mode 100644 Flash/Obj/crc16.o create mode 100644 Flash/Obj/crc16.pbi create mode 100644 Flash/Obj/cstartup.o create mode 100644 Flash/Obj/data.o create mode 100644 Flash/Obj/data.pbi create mode 100644 Flash/Obj/datadesc.o create mode 100644 Flash/Obj/datadesc.pbi create mode 100644 Flash/Obj/fiscal.o create mode 100644 Flash/Obj/fiscal.pbi create mode 100644 Flash/Obj/fr.o create mode 100644 Flash/Obj/fr.pbi create mode 100644 Flash/Obj/fram.o create mode 100644 Flash/Obj/fram.pbi create mode 100644 Flash/Obj/journal.o create mode 100644 Flash/Obj/journal.pbi create mode 100644 Flash/Obj/keyboard.o create mode 100644 Flash/Obj/keyboard.pbi create mode 100644 Flash/Obj/lcd.o create mode 100644 Flash/Obj/lcd.pbi create mode 100644 Flash/Obj/lib_mem.o create mode 100644 Flash/Obj/lib_mem.pbi create mode 100644 Flash/Obj/lib_str.o create mode 100644 Flash/Obj/lib_str.pbi create mode 100644 Flash/Obj/menu.o create mode 100644 Flash/Obj/menu.pbi create mode 100644 Flash/Obj/menudesc.o create mode 100644 Flash/Obj/menudesc.pbi create mode 100644 Flash/Obj/mode.o create mode 100644 Flash/Obj/mode.pbi create mode 100644 Flash/Obj/modem.o create mode 100644 Flash/Obj/modem.pbi create mode 100644 Flash/Obj/modem_task.o create mode 100644 Flash/Obj/modem_task.pbi create mode 100644 Flash/Obj/os_core.o create mode 100644 Flash/Obj/os_core.pbi create mode 100644 Flash/Obj/os_cpu_a.o create mode 100644 Flash/Obj/os_cpu_c.o create mode 100644 Flash/Obj/os_cpu_c.pbi create mode 100644 Flash/Obj/os_dbg.o create mode 100644 Flash/Obj/os_dbg.pbi create mode 100644 Flash/Obj/os_dcc.o create mode 100644 Flash/Obj/os_dcc.pbi create mode 100644 Flash/Obj/os_flag.o create mode 100644 Flash/Obj/os_flag.pbi create mode 100644 Flash/Obj/os_mbox.o create mode 100644 Flash/Obj/os_mbox.pbi create mode 100644 Flash/Obj/os_mem.o create mode 100644 Flash/Obj/os_mem.pbi create mode 100644 Flash/Obj/os_mutex.o create mode 100644 Flash/Obj/os_mutex.pbi create mode 100644 Flash/Obj/os_q.o create mode 100644 Flash/Obj/os_q.pbi create mode 100644 Flash/Obj/os_sem.o create mode 100644 Flash/Obj/os_sem.pbi create mode 100644 Flash/Obj/os_task.o create mode 100644 Flash/Obj/os_task.pbi create mode 100644 Flash/Obj/os_time.o create mode 100644 Flash/Obj/os_time.pbi create mode 100644 Flash/Obj/os_tmr.o create mode 100644 Flash/Obj/os_tmr.pbi create mode 100644 Flash/Obj/solarium.pbd create mode 100644 Flash/Obj/spi.o create mode 100644 Flash/Obj/spi.pbi create mode 100644 Flash/Obj/time.o create mode 100644 Flash/Obj/time.pbi create mode 100644 Flash/Obj/uart0.o create mode 100644 Flash/Obj/uart0.pbi create mode 100644 Flash/Obj/uart1.o create mode 100644 Flash/Obj/uart1.pbi create mode 100644 Flash/Obj/uart2.o create mode 100644 Flash/Obj/uart2.pbi create mode 100644 Flash/Obj/validator.o create mode 100644 Flash/Obj/validator.pbi create mode 100644 OS/app/app.c create mode 100644 OS/app/app_cfg.h create mode 100644 OS/app/includes.h create mode 100644 OS/app/os_cfg.h create mode 100644 OS/bsp/LPC2368_Flash.icf create mode 100644 OS/bsp/LPC2368_Flash.mac create mode 100644 OS/bsp/bsp.c create mode 100644 OS/bsp/bsp.h create mode 100644 OS/bsp/cstartup.s create mode 100644 OS/bsp/iolpc2368.h create mode 100644 OS/uc/cpu/cpu.h create mode 100644 OS/uc/cpu/cpu_a.s create mode 100644 OS/uc/cpu/cpu_def.h create mode 100644 OS/uc/lib/lib_def.h create mode 100644 OS/uc/lib/lib_mem.c create mode 100644 OS/uc/lib/lib_mem.h create mode 100644 OS/uc/lib/lib_str.c create mode 100644 OS/uc/lib/lib_str.h create mode 100644 OS/uc/os_ii/port/os_cpu.h create mode 100644 OS/uc/os_ii/port/os_cpu_a.asm create mode 100644 OS/uc/os_ii/port/os_cpu_c.c create mode 100644 OS/uc/os_ii/port/os_dbg.c create mode 100644 OS/uc/os_ii/port/os_dcc.c create mode 100644 OS/uc/os_ii/source/os_core.c create mode 100644 OS/uc/os_ii/source/os_flag.c create mode 100644 OS/uc/os_ii/source/os_mbox.c create mode 100644 OS/uc/os_ii/source/os_mem.c create mode 100644 OS/uc/os_ii/source/os_mutex.c create mode 100644 OS/uc/os_ii/source/os_q.c create mode 100644 OS/uc/os_ii/source/os_sem.c create mode 100644 OS/uc/os_ii/source/os_task.c create mode 100644 OS/uc/os_ii/source/os_time.c create mode 100644 OS/uc/os_ii/source/os_tmr.c create mode 100644 OS/uc/os_ii/source/ucos_ii.h create mode 100644 PROJECT/app/app_serv.c create mode 100644 PROJECT/app/app_serv.h create mode 100644 PROJECT/app/control.c create mode 100644 PROJECT/app/control.h create mode 100644 PROJECT/app/journal.c create mode 100644 PROJECT/app/journal.h create mode 100644 PROJECT/app/modem_task.c create mode 100644 PROJECT/app/modem_task.h create mode 100644 PROJECT/data/data.c create mode 100644 PROJECT/data/data.h create mode 100644 PROJECT/data/datadesc.c create mode 100644 PROJECT/data/datadesc.h create mode 100644 PROJECT/data/fram_map.h create mode 100644 PROJECT/menu/menu.c create mode 100644 PROJECT/menu/menu.h create mode 100644 PROJECT/menu/menudesc.c create mode 100644 PROJECT/menu/menudesc.h create mode 100644 PROJECT/service/coin.c create mode 100644 PROJECT/service/coin.h create mode 100644 PROJECT/service/fr.c create mode 100644 PROJECT/service/fr.h create mode 100644 PROJECT/service/mode.c create mode 100644 PROJECT/service/mode.h create mode 100644 PROJECT/service/time.c create mode 100644 PROJECT/service/time.h create mode 100644 PROJECT/service/validator.c create mode 100644 PROJECT/service/validator.h create mode 100644 PROJECT/tools/crc16.c create mode 100644 PROJECT/tools/crc16.h create mode 100644 PROJECT/version.h create mode 100644 settings/solarium.cspy.bat create mode 100644 settings/solarium.dbgdt create mode 100644 settings/solarium.dni create mode 100644 settings/solarium.wsdt create mode 100644 settings/solarium_Flash.jlink create mode 100644 solarium.dep create mode 100644 solarium.ewd create mode 100644 solarium.ewp create mode 100644 solarium.eww create mode 100644 todo.txt create mode 100644 параметры.txt create mode 100644 список выводов.xls diff --git a/.svn/entries b/.svn/entries new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/.svn/entries @@ -0,0 +1 @@ +12 diff --git a/.svn/format b/.svn/format new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/.svn/format @@ -0,0 +1 @@ +12 diff --git a/.svn/pristine/02/022515663c491127ce3638df803692169c7b2fe9.svn-base b/.svn/pristine/02/022515663c491127ce3638df803692169c7b2fe9.svn-base new file mode 100644 index 0000000..ae07b00 --- /dev/null +++ b/.svn/pristine/02/022515663c491127ce3638df803692169c7b2fe9.svn-base @@ -0,0 +1,523 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_CPU_C.C +* Version : V1.82 +* By : Jean J. Labrosse +* Jean-Denis Hatier +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#define OS_CPU_GLOBALS +#include + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL CONSTANTS +* +* Note(s) : 1) ARM_MODE_ARM is the CPSR bit mask for ARM Mode +* 2) ARM_MODE_THUMB is the CPSR bit mask for THUMB Mode +* 3) ARM_SVC_MODE_THUMB is the CPSR bit mask for SVC MODE + THUMB Mode +* 4) ARM_SVC_MODE_ARM is the CPSR bit mask for SVC MODE + ARM Mode + 5) OS_NTASKS_FP establishes the number of tasks capable of supporting floating-point. One +* task is removed for the idle task because it doesn't do floating-point at all. +* 6) OS_FP_STORAGE_SIZE currently allocates 1024 bytes of storage in order to accomodate +* thirty-two, single precision 32 bit, or sixteen double precision 64 bit VFP registers. +********************************************************************************************************* +*/ + +#define ARM_MODE_ARM 0x00000000 +#define ARM_MODE_THUMB 0x00000020 + +#define ARM_SVC_MODE_THUMB (0x00000013L + ARM_MODE_THUMB) +#define ARM_SVC_MODE_ARM (0x00000013L + ARM_MODE_ARM) + +#define OS_NTASKS_FP (OS_MAX_TASKS + OS_N_SYS_TASKS - 1) +#define OS_FP_STORAGE_SIZE 128L + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +#if OS_TMR_EN > 0 +static INT16U OSTmrCtr; +#endif + +#if OS_CPU_FPU_EN > 0 +static OS_MEM *OSFPPartPtr; /* Pointer to memory partition for storing FPU registers */ +static INT32U OSFPPart[OS_NTASKS_FP][OS_FP_STORAGE_SIZE / sizeof(INT32U)]; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE FP SUPPORT +* +* Description: This function initializes the memory partition used to save FPU registers +* during a context switch. This function MUST be called AFTER calling +* OSInit(). OS_CPU_FPU_EN must be defined > 0 in order to compile FPU support into the +* build. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) Tasks that are to use FP support MUST be created with OSTaskCreateExt(). +* 2) For the ARM VFP, 1024 bytes are required to save the VFP context. +* The INT32U data type is used to ensure that storage is aligned on a 32-bit boundary. +* 3) If you need to perform floating point operations from within the OSStatTaskHook(), +* then you must change the 'Options' attribute for OSTaskCreatExt() when creating +* the statistics task. This only applies if OS_TaskStat() was created with OSTaskCreateExt(). +********************************************************************************************************* +*/ + +#if OS_CPU_FPU_EN > 0 +void OS_CPU_FP_Init (void) +{ + INT8U err; +#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN + OS_TCB *ptcb; + void *pblk; +#endif + + + OSFPPartPtr = OSMemCreate(&OSFPPart[0][0], OS_NTASKS_FP, OS_FP_STORAGE_SIZE, &err); + +#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN /* CHANGE 'OPTIONS' for OS_TaskStat() */ + ptcb = OSTCBPrioTbl[OS_TASK_STAT_PRIO]; + ptcb->OSTCBOpt |= OS_TASK_OPT_SAVE_FP; /* Allow floating-point support for Statistic task */ + pblk = OSMemGet(OSFPPartPtr, &err); /* Get storage for VFP registers */ + if (pblk != (void *)0) { /* Did we get a memory block? */ + ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } +#endif +} +#endif + +/* +********************************************************************************************************* +* OS INITIALIZATION HOOK +* (BEGINNING) +* +* Description: This function is called by OSInit() at the beginning of OSInit(). +* +* Arguments : none +* +* Note(s) : 1) Interrupts should be disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSInitHookBegin (void) +{ +#if OS_TMR_EN > 0 + OSTmrCtr = 0; +#endif +} +#endif + +/* +********************************************************************************************************* +* OS INITIALIZATION HOOK +* (END) +* +* Description: This function is called by OSInit() at the end of OSInit(). +* +* Arguments : none +* +* Note(s) : 1) Interrupts should be disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSInitHookEnd (void) +{ +#if OS_CPU_INT_DIS_MEAS_EN > 0 + OS_CPU_IntDisMeasInit(); +#endif + +#if OS_CPU_FPU_EN > 0 + OS_CPU_FP_Init(); /* Initialize support for VFP register save / restore */ +#endif +} +#endif + +/* +********************************************************************************************************* +* TASK CREATION HOOK +* +* Description: This function is called when a task is created. +* +* Arguments : ptcb is a pointer to the task control block of the task being created. +* +* Note(s) : 1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 +void OSTaskCreateHook (OS_TCB *ptcb) +{ +#if OS_CPU_FPU_EN > 0 + INT8U err; + void *pblk; +#endif + + +#if OS_CPU_FPU_EN > 0 + if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task needs FP support */ + pblk = OSMemGet(OSFPPartPtr, &err); /* Yes, Get storage for VFP registers */ + if (pblk != (void *)0) { /* Did we get a memory block? */ + ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskCreateHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + + +/* +********************************************************************************************************* +* TASK DELETION HOOK +* +* Description: This function is called when a task is deleted. +* +* Arguments : ptcb is a pointer to the task control block of the task being deleted. +* +* Note(s) : 1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 +void OSTaskDelHook (OS_TCB *ptcb) +{ +#if OS_CPU_FPU_EN > 0 + if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task had FP support */ + if (ptcb->OSTCBExtPtr != (void *)0) { /* Yes, OSTCBExtPtr must not be NULL */ + OSMemPut(OSFPPartPtr, ptcb->OSTCBExtPtr); /* Return memory block to free pool */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskDelHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + +/* +********************************************************************************************************* +* IDLE TASK HOOK +* +* Description: This function is called by the idle task. This hook has been added to allow you to do +* such things as STOP the CPU to conserve power. +* +* Arguments : none +* +* Note(s) : 1) Interrupts are enabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251 +void OSTaskIdleHook (void) +{ +#if OS_CPU_ARM_DCC_EN > 0 + OSDCC_Handler(); +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskIdleHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* STATISTIC TASK HOOK +* +* Description: This function is called every second by uC/OS-II's statistics task. This allows your +* application to add functionality to the statistics task. +* +* Arguments : none +********************************************************************************************************* +*/ + +#if OS_CPU_HOOKS_EN > 0 +void OSTaskStatHook (void) +{ +#if OS_APP_HOOKS_EN > 0 + App_TaskStatHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* INITIALIZE A TASK'S STACK +* +* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the +* stack frame of the task being created. This function is highly processor specific. +* +* Arguments : task is a pointer to the task code +* +* p_arg is a pointer to a user supplied data area that will be passed to the task +* when the task first executes. +* +* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to +* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then +* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if +* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address +* of the stack. +* +* opt specifies options that can be used to alter the behavior of OSTaskStkInit(). +* (see uCOS_II.H for OS_TASK_OPT_xxx). +* +* Returns : Always returns the location of the new top-of-stack' once the processor registers have +* been placed on the stack in the proper order. +* +* Note(s) : 1) Interrupts are enabled when your task starts executing. +* 2) All tasks run in SVC mode. +********************************************************************************************************* +*/ + +OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) +{ + OS_STK *stk; + INT32U task_addr; + + + opt = opt; /* 'opt' is not used, prevent warning */ + stk = ptos; /* Load stack pointer */ + task_addr = (INT32U)task & ~1; /* Mask off lower bit in case task is thumb mode */ + *(stk) = (INT32U)task_addr; /* Entry Point */ + *(--stk) = (INT32U)0x14141414L; /* R14 (LR) */ + *(--stk) = (INT32U)0x12121212L; /* R12 */ + *(--stk) = (INT32U)0x11111111L; /* R11 */ + *(--stk) = (INT32U)0x10101010L; /* R10 */ + *(--stk) = (INT32U)0x09090909L; /* R9 */ + *(--stk) = (INT32U)0x08080808L; /* R8 */ + *(--stk) = (INT32U)0x07070707L; /* R7 */ + *(--stk) = (INT32U)0x06060606L; /* R6 */ + *(--stk) = (INT32U)0x05050505L; /* R5 */ + *(--stk) = (INT32U)0x04040404L; /* R4 */ + *(--stk) = (INT32U)0x03030303L; /* R3 */ + *(--stk) = (INT32U)0x02020202L; /* R2 */ + *(--stk) = (INT32U)0x01010101L; /* R1 */ + *(--stk) = (INT32U)p_arg; /* R0 : argument */ + if ((INT32U)task & 0x01) { /* See if task runs in Thumb or ARM mode */ + *(--stk) = (INT32U)ARM_SVC_MODE_THUMB; /* CPSR (Enable both IRQ and FIQ interrupts, THUMB-mode) */ + } else { + *(--stk) = (INT32U)ARM_SVC_MODE_ARM; /* CPSR (Enable both IRQ and FIQ interrupts, ARM-mode) */ + } + + return (stk); +} + +/* +********************************************************************************************************* +* TASK SWITCH HOOK +* +* Description: This function is called when a task switch is performed. This allows you to perform other +* operations during a context switch. +* +* Arguments : none +* +* Note(s) : 1) Interrupts are disabled during this call. +* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that +* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the +* task being switched out (i.e. the preempted task). +********************************************************************************************************* +*/ +#if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0) +void OSTaskSwHook (void) +{ +#if OS_CPU_FPU_EN > 0 + void *pblk; +#endif + +#if OS_CPU_FPU_EN > 0 /* Save VFP context of preempted task */ + if (OSRunning == OS_TRUE) { /* Don't save on OSStart()! */ + if (OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task used FP */ + pblk = OSTCBCur->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */ + if (pblk != (void *)0) { /* Make sure we have storage */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } + } + } + /* Restore VFP context of new task */ + if (OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if new task uses FP */ + pblk = OSTCBHighRdy->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */ + if (pblk != (void *)0) { /* Make sure we have storage */ + OS_CPU_FP_Restore(pblk); /* Get contents of VFP registers */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskSwHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* OS_TCBInit() HOOK +* +* Description: This function is called by OS_TCBInit() after setting up most of the TCB. +* +* Arguments : ptcb is a pointer to the TCB of the task being created. +* +* Note(s) : 1) Interrupts may or may not be ENABLED during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSTCBInitHook (OS_TCB *ptcb) +{ +#if OS_APP_HOOKS_EN > 0 + App_TCBInitHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + + +/* +********************************************************************************************************* +* TICK HOOK +* +* Description: This function is called every tick. +* +* Arguments : none +* +* Note(s) : 1) Interrupts may or may not be ENABLED during this call. +********************************************************************************************************* +*/ +#if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0) +void OSTimeTickHook (void) +{ +#if OS_APP_HOOKS_EN > 0 + App_TimeTickHook(); +#endif + +#if OS_TMR_EN > 0 + OSTmrCtr++; + if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) { + OSTmrCtr = 0; + OSTmrSignal(); + } +#endif + +#if OS_CPU_ARM_DCC_EN > 0 + OSDCC_Handler(); +#endif +} +#endif + + +/* +********************************************************************************************************* +* INTERRUPT DISABLE TIME MEASUREMENT, START +********************************************************************************************************* +*/ + +#if OS_CPU_INT_DIS_MEAS_EN > 0 +void OS_CPU_IntDisMeasInit (void) +{ + OS_CPU_IntDisMeasNestingCtr = 0; + OS_CPU_IntDisMeasCntsEnter = 0; + OS_CPU_IntDisMeasCntsExit = 0; + OS_CPU_IntDisMeasCntsMax = 0; + OS_CPU_IntDisMeasCntsDelta = 0; + OS_CPU_IntDisMeasCntsOvrhd = 0; + OS_CPU_IntDisMeasStart(); /* Measure the overhead of the functions */ + OS_CPU_IntDisMeasStop(); + OS_CPU_IntDisMeasCntsOvrhd = OS_CPU_IntDisMeasCntsDelta; +} + + +void OS_CPU_IntDisMeasStart (void) +{ + OS_CPU_IntDisMeasNestingCtr++; + if (OS_CPU_IntDisMeasNestingCtr == 1) { /* Only measure at the first nested level */ + OS_CPU_IntDisMeasCntsEnter = OS_CPU_IntDisMeasTmrRd(); + } +} + + +void OS_CPU_IntDisMeasStop (void) +{ + OS_CPU_IntDisMeasNestingCtr--; /* Decrement nesting ctr */ + if (OS_CPU_IntDisMeasNestingCtr == 0) { + OS_CPU_IntDisMeasCntsExit = OS_CPU_IntDisMeasTmrRd(); + OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsExit - OS_CPU_IntDisMeasCntsEnter; + if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsOvrhd) { /* Ensure overhead < delta */ + OS_CPU_IntDisMeasCntsDelta -= OS_CPU_IntDisMeasCntsOvrhd; + } else { + OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsOvrhd; + } + if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsMax) { /* Track MAXIMUM */ + OS_CPU_IntDisMeasCntsMax = OS_CPU_IntDisMeasCntsDelta; + } + } +} +#endif + + +/* +********************************************************************************************************* +* INITIALIZE EXCEPTION VECTORS +* +* Description : This function initialize exception vectors to the default handlers. +* +* Arguments : None. +********************************************************************************************************* +*/ + +void OS_CPU_InitExceptVect (void) +{ +/* + (*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptResetHndlr; +*/ + + (*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptUndefInstrHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptSwiHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptPrefetchAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptDataAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptAddrAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptIrqHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptFiqHndlr; +} diff --git a/.svn/pristine/04/0486bfef8f1a3b08357c9714aaf2e312d6eddb70.svn-base b/.svn/pristine/04/0486bfef8f1a3b08357c9714aaf2e312d6eddb70.svn-base new file mode 100644 index 0000000..665d2e5 --- /dev/null +++ b/.svn/pristine/04/0486bfef8f1a3b08357c9714aaf2e312d6eddb70.svn-base @@ -0,0 +1,7 @@ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define DEVICE_FW_VERSION "03.19" + + +#endif // #ifndef _VERSION_H_ \ No newline at end of file diff --git a/.svn/pristine/05/054a010633ed6d314da30c9e118696eec16e0932.svn-base b/.svn/pristine/05/054a010633ed6d314da30c9e118696eec16e0932.svn-base new file mode 100644 index 0000000..3848281 --- /dev/null +++ b/.svn/pristine/05/054a010633ed6d314da30c9e118696eec16e0932.svn-base @@ -0,0 +1,4785 @@ +/*************************************************************************** + ** + ** This file defines the Special Function Registers for + ** NXP LPC2368 + ** + ** Used with ARM IAR C/C++ Compiler and Assembler. + ** + ** (c) Copyright IAR Systems 2006 + ** + ** $Revision: 24053 $ + ** + ** Note: Only little endian addressing of 8 bit registers. + ***************************************************************************/ + +#ifndef __IOLPC2368_H +#define __IOLPC2368_H + +#if (((__TID__ >> 8) & 0x7F) != 0x4F) /* 0x4F = 79 dec */ +#error This file should only be compiled by ARM IAR compiler and assembler +#endif + +#include "io_macros.h" + +/*************************************************************************** + *************************************************************************** + ** + ** LPC2368 SPECIAL FUNCTION REGISTERS + ** + *************************************************************************** + *************************************************************************** + ***************************************************************************/ + +/* C-compiler specific declarations ***************************************/ +#ifdef __IAR_SYSTEMS_ICC__ + +#ifndef _SYSTEM_BUILD +#pragma system_include +#endif + +#if __LITTLE_ENDIAN__ == 0 +#error This file should only be compiled in little endian mode +#endif + +/* Memory mapping control register */ +typedef struct{ +__REG32 MAP : 2; +__REG32 :30; +} __memmap_bits; + +/* Reset Source Identification Register */ +typedef struct{ +__REG32 POR : 1; +__REG32 EXTR : 1; +__REG32 WDTR : 1; +__REG32 BODR : 1; +__REG32 :28; +} __rsir_bits; + +/* External interrupt register */ +typedef struct{ +__REG32 EINT0 : 1; +__REG32 EINT1 : 1; +__REG32 EINT2 : 1; +__REG32 EINT3 : 1; +__REG32 :28; +} __extint_bits; + +/* External Interrupt Mode Register */ +typedef struct{ +__REG32 EXTMODE0 : 1; +__REG32 EXTMODE1 : 1; +__REG32 EXTMODE2 : 1; +__REG32 EXTMODE3 : 1; +__REG32 :28; +} __extmode_bits; + +/* External Interrupt Polarity Register */ +typedef struct{ +__REG32 EXTPOLAR0 : 1; +__REG32 EXTPOLAR1 : 1; +__REG32 EXTPOLAR2 : 1; +__REG32 EXTPOLAR3 : 1; +__REG32 :28; +} __extpolar_bits; + +/* System Controls and Status register */ +typedef struct{ +__REG32 GPIOM : 1; +__REG32 : 2; +__REG32 MCIPWR : 1; +__REG32 OSCRANGE : 1; +__REG32 OSCEN : 1; +__REG32 OSCSTAT : 1; +__REG32 :25; +} __scs_bits; + +/* AHB Arbiter Configuration Register*/ +typedef struct{ +__REG32 SHDL : 1; +__REG32 BB : 2; +__REG32 QT : 1; +__REG32 QS : 4; +__REG32 DM : 4; +__REG32 EP1 : 4; +__REG32 EP2 : 4; +__REG32 EP3 : 4; +__REG32 EP4 : 4; +__REG32 : 4; +} __ahbcfg1_bits; + +typedef struct{ +__REG32 SHDL : 1; +__REG32 BB : 2; +__REG32 QT : 1; +__REG32 QS : 4; +__REG32 DM : 4; +__REG32 EP1 : 4; +__REG32 EP2 : 4; +__REG32 :12; +} __ahbcfg2_bits; + +/* Clock Soucre Select register */ +typedef struct{ +__REG32 CLKSRC : 2; +__REG32 :30; +} __clksrcsel_bits; + +/* IRC Trim Register (IRCTRIM - 0xE01FC1A4) */ +typedef struct{ +__REG32 IRCTRIM : 8; +__REG32 :24; +} __irctrim_bits; + +/* CPU Clock Configuration register */ +typedef struct{ +__REG32 CCLKSEL : 8; +__REG32 :24; +} __cclkcfg_bits; + +/* USB Clock Configuration register */ +typedef struct{ +__REG32 USBSEL : 4; +__REG32 :28; +} __usbclkcfg_bits; + +/* Peripheral Clock Selection registers 0 */ +typedef struct{ +__REG32 PCLK_WDT : 2; +__REG32 PCLK_TIMER0 : 2; +__REG32 PCLK_TIMER1 : 2; +__REG32 PCLK_UART0 : 2; +__REG32 PCLK_UART1 : 2; +__REG32 : 2; +__REG32 PCLK_PWM1 : 2; +__REG32 PCLK_I2C0 : 2; +__REG32 PCLK_SPI : 2; +__REG32 PCLK_RTC : 2; +__REG32 PCLK_SSP1 : 2; +__REG32 PCLK_DAC : 2; +__REG32 PCLK_ADC : 2; +__REG32 PCLK_CAN1 : 2; +__REG32 PCLK_CAN2 : 2; +__REG32 PCLK_ACF : 2; +} __pclksel0_bits; + +/* Peripheral Clock Selection registers 1 */ +typedef struct{ +__REG32 PCLK_BAT_RAM: 2; +__REG32 PCLK_GPIO : 2; +__REG32 PCLK_PCB : 2; +__REG32 PCLK_I2C1 : 2; +__REG32 : 2; +__REG32 PCLK_SSP0 : 2; +__REG32 PCLK_TIMER2 : 2; +__REG32 PCLK_TIMER3 : 2; +__REG32 PCLK_UART2 : 2; +__REG32 PCLK_UART3 : 2; +__REG32 PCLK_I2C2 : 2; +__REG32 PCLK_I2S : 2; +__REG32 PCLK_MCI : 2; +__REG32 : 2; +__REG32 PCLK_SYSCON : 2; +__REG32 : 2; +} __pclksel1_bits; + +/* PLL control register */ +typedef struct{ +__REG32 PLLE : 1; +__REG32 PLLC : 1; +__REG32 :30; +} __pllcon_bits; + +/* PLL config register */ +typedef struct{ +__REG32 MSEL :15; +__REG32 : 1; +__REG32 NSEL : 8; +__REG32 : 8; +} __pllcfg_bits; + +/* PLL status register */ +typedef struct{ +__REG32 MSEL :15; +__REG32 : 1; +__REG32 NSEL : 8; +__REG32 PLLE : 1; +__REG32 PLLC : 1; +__REG32 PLOCK : 1; +__REG32 : 5; +} __pllstat_bits; + +/* PLL feed register */ +typedef struct{ +__REG32 FEED : 8; +__REG32 :24; +} __pllfeed_bits; + +/* Power control register */ +typedef struct{ +__REG32 IDL : 1; +__REG32 PD : 1; +__REG32 BODPDM : 1; +__REG32 BOGD : 1; +__REG32 BORD : 1; +__REG32 : 2; +__REG32 PM2 : 1; +__REG32 :24; +}__pcon_bits; + +/* Interrupt Wakeup Register */ +typedef struct{ +__REG32 EXTWAKE0 : 1; +__REG32 EXTWAKE1 : 1; +__REG32 EXTWAKE2 : 1; +__REG32 EXTWAKE3 : 1; +__REG32 ETHWAK : 1; +__REG32 USBWAKE : 1; +__REG32 CANWAKE : 1; +__REG32 GPIO0WAKE : 1; +__REG32 GPIO2WAKE : 1; +__REG32 : 5; +__REG32 BODWAKE : 1; +__REG32 RTCWAKE : 1; +__REG32 :16; +}__intwake_bits; + +/* Power control for peripherals register */ +typedef struct{ +__REG32 : 1; +__REG32 PCTIM0 : 1; +__REG32 PCTIM1 : 1; +__REG32 PCUART0 : 1; +__REG32 PCUART1 : 1; +__REG32 : 1; +__REG32 PCPWM1 : 1; +__REG32 PCI2C0 : 1; +__REG32 PCSPI : 1; +__REG32 PCRTC : 1; +__REG32 PCSSP1 : 1; +__REG32 : 1; +__REG32 PCAD : 1; +__REG32 PCAN1 : 1; +__REG32 PCAN2 : 1; +__REG32 : 4; +__REG32 PCI2C1 : 1; +__REG32 : 1; +__REG32 PCSSP0 : 1; +__REG32 PCTIM2 : 1; +__REG32 PCTIM3 : 1; +__REG32 PCUART2 : 1; +__REG32 PCUART3 : 1; +__REG32 PCI2C2 : 1; +__REG32 PCI2S : 1; +__REG32 PCSDC : 1; +__REG32 PCGPDMA : 1; +__REG32 PCENET : 1; +__REG32 PCUSB : 1; +} __pconp_bits; + +/* Memory accelerator module control register */ +typedef struct { + __REG32 MODECTRL : 2; + __REG32 :30; +} __mamcr_bits; + +/* Memory accelerator module timing register */ +typedef struct { + __REG32 CYCLES : 3; + __REG32 :29; +} __mamtim_bits; + +/* VIC Interrupt registers */ +typedef struct{ +__REG32 WDT : 1; +__REG32 : 1; +__REG32 ARMCORE0 : 1; +__REG32 ARMCORE1 : 1; +__REG32 TIMER0 : 1; +__REG32 TIMER1 : 1; +__REG32 UART0 : 1; +__REG32 UART1 : 1; +__REG32 PWM1 : 1; +__REG32 I2C0 : 1; +__REG32 SPI : 1; +__REG32 SSP1 : 1; +__REG32 PLL : 1; +__REG32 RTC : 1; +__REG32 EINT0 : 1; +__REG32 EINT1 : 1; +__REG32 EINT2 : 1; +__REG32 EINT3 : 1; +__REG32 AD0 : 1; +__REG32 I2C1 : 1; +__REG32 BOD : 1; +__REG32 ETHERNET : 1; +__REG32 USB : 1; +__REG32 CAN12 : 1; +__REG32 SDMMC : 1; +__REG32 GPDMA : 1; +__REG32 TIMER2 : 1; +__REG32 TIMER3 : 1; +__REG32 UART2 : 1; +__REG32 UART3 : 1; +__REG32 I2C2 : 1; +__REG32 I2S : 1; +} __vicint_bits; + +/* VIC Vector control registers */ +typedef struct{ +__REG32 PRIORITY : 4; +__REG32 :28; +} __vicvectpr_bits; + +/* VIC Software Priority register */ +typedef struct{ +__REG32 SWPRIORITY:16; +__REG32 :16; +} __vicswprmask_bits; + +/* VIC protection enable register */ +typedef struct{ +__REG32 VIC_ACCESS : 1; +__REG32 :31; +} __vicprotection_bits; + +/* Pin function select register 0 */ +typedef struct{ +__REG32 P0_0 : 2; +__REG32 P0_1 : 2; +__REG32 P0_2 : 2; +__REG32 P0_3 : 2; +__REG32 P0_4 : 2; +__REG32 P0_5 : 2; +__REG32 P0_6 : 2; +__REG32 P0_7 : 2; +__REG32 P0_8 : 2; +__REG32 P0_9 : 2; +__REG32 P0_10 : 2; +__REG32 P0_11 : 2; +__REG32 P0_12 : 2; +__REG32 P0_13 : 2; +__REG32 P0_14 : 2; +__REG32 P0_15 : 2; +} __pinsel0_bits; + +/* Pin function select register 1 */ +typedef struct{ +__REG32 P0_16 : 2; +__REG32 P0_17 : 2; +__REG32 P0_18 : 2; +__REG32 P0_19 : 2; +__REG32 P0_20 : 2; +__REG32 P0_21 : 2; +__REG32 P0_22 : 2; +__REG32 P0_23 : 2; +__REG32 P0_24 : 2; +__REG32 P0_25 : 2; +__REG32 P0_26 : 2; +__REG32 P0_27 : 2; +__REG32 P0_28 : 2; +__REG32 P0_29 : 2; +__REG32 P0_30 : 2; +__REG32 P0_31 : 2; +} __pinsel1_bits; + +/* Pin function select register 2 */ +typedef struct{ +__REG32 P1_0 : 2; +__REG32 P1_1 : 2; +__REG32 P1_2 : 2; +__REG32 P1_3 : 2; +__REG32 P1_4 : 2; +__REG32 P1_5 : 2; +__REG32 P1_6 : 2; +__REG32 P1_7 : 2; +__REG32 P1_8 : 2; +__REG32 P1_9 : 2; +__REG32 P1_10 : 2; +__REG32 P1_11 : 2; +__REG32 P1_12 : 2; +__REG32 P1_13 : 2; +__REG32 P1_14 : 2; +__REG32 P1_15 : 2; +} __pinsel2_bits; + +/* Pin function select register 3 */ +typedef struct{ +__REG32 P1_16 : 2; +__REG32 P1_17 : 2; +__REG32 P1_18 : 2; +__REG32 P1_19 : 2; +__REG32 P1_20 : 2; +__REG32 P1_21 : 2; +__REG32 P1_22 : 2; +__REG32 P1_23 : 2; +__REG32 P1_24 : 2; +__REG32 P1_25 : 2; +__REG32 P1_26 : 2; +__REG32 P1_27 : 2; +__REG32 P1_28 : 2; +__REG32 P1_29 : 2; +__REG32 P1_30 : 2; +__REG32 P1_31 : 2; +} __pinsel3_bits; + +/* Pin function select register 4 */ +typedef struct{ +__REG32 P2_0 : 2; +__REG32 P2_1 : 2; +__REG32 P2_2 : 2; +__REG32 P2_3 : 2; +__REG32 P2_4 : 2; +__REG32 P2_5 : 2; +__REG32 P2_6 : 2; +__REG32 P2_7 : 2; +__REG32 P2_8 : 2; +__REG32 P2_9 : 2; +__REG32 P2_10 : 2; +__REG32 P2_11 : 2; +__REG32 P2_12 : 2; +__REG32 P2_13 : 2; +__REG32 P2_14 : 2; +__REG32 P2_15 : 2; +} __pinsel4_bits; + +/* Pin function select register 5 */ +typedef struct{ +__REG32 P2_16 : 2; +__REG32 P2_17 : 2; +__REG32 P2_18 : 2; +__REG32 P2_19 : 2; +__REG32 P2_20 : 2; +__REG32 P2_21 : 2; +__REG32 P2_22 : 2; +__REG32 P2_23 : 2; +__REG32 P2_24 : 2; +__REG32 P2_25 : 2; +__REG32 P2_26 : 2; +__REG32 P2_27 : 2; +__REG32 P2_28 : 2; +__REG32 P2_29 : 2; +__REG32 P2_30 : 2; +__REG32 P2_31 : 2; +} __pinsel5_bits; + +/* Pin function select register 6 */ +typedef struct{ +__REG32 P3_0 : 2; +__REG32 P3_1 : 2; +__REG32 P3_2 : 2; +__REG32 P3_3 : 2; +__REG32 P3_4 : 2; +__REG32 P3_5 : 2; +__REG32 P3_6 : 2; +__REG32 P3_7 : 2; +__REG32 P3_8 : 2; +__REG32 P3_9 : 2; +__REG32 P3_10 : 2; +__REG32 P3_11 : 2; +__REG32 P3_12 : 2; +__REG32 P3_13 : 2; +__REG32 P3_14 : 2; +__REG32 P3_15 : 2; +} __pinsel6_bits; + +/* Pin function select register 7 */ +typedef struct{ +__REG32 P3_16 : 2; +__REG32 P3_17 : 2; +__REG32 P3_18 : 2; +__REG32 P3_19 : 2; +__REG32 P3_20 : 2; +__REG32 P3_21 : 2; +__REG32 P3_22 : 2; +__REG32 P3_23 : 2; +__REG32 P3_24 : 2; +__REG32 P3_25 : 2; +__REG32 P3_26 : 2; +__REG32 P3_27 : 2; +__REG32 P3_28 : 2; +__REG32 P3_29 : 2; +__REG32 P3_30 : 2; +__REG32 P3_31 : 2; +} __pinsel7_bits; + +/* Pin function select register 8 */ +typedef struct{ +__REG32 P4_0 : 2; +__REG32 P4_1 : 2; +__REG32 P4_2 : 2; +__REG32 P4_3 : 2; +__REG32 P4_4 : 2; +__REG32 P4_5 : 2; +__REG32 P4_6 : 2; +__REG32 P4_7 : 2; +__REG32 P4_8 : 2; +__REG32 P4_9 : 2; +__REG32 P4_10 : 2; +__REG32 P4_11 : 2; +__REG32 P4_12 : 2; +__REG32 P4_13 : 2; +__REG32 P4_14 : 2; +__REG32 P4_15 : 2; +} __pinsel8_bits; + +/* Pin function select register 9 */ +typedef struct{ +__REG32 P4_16 : 2; +__REG32 P4_17 : 2; +__REG32 P4_18 : 2; +__REG32 P4_19 : 2; +__REG32 P4_20 : 2; +__REG32 P4_21 : 2; +__REG32 P4_22 : 2; +__REG32 P4_23 : 2; +__REG32 P4_24 : 2; +__REG32 P4_25 : 2; +__REG32 P4_26 : 2; +__REG32 P4_27 : 2; +__REG32 P4_28 : 2; +__REG32 P4_29 : 2; +__REG32 P4_30 : 2; +__REG32 P4_31 : 2; +} __pinsel9_bits; + +/* Pin function select register 10 */ +typedef struct{ +__REG32 : 3; +__REG32 GPIO_TRACE : 1; +__REG32 :28; +} __pinsel10_bits; + +/* GPIO 0 Registers */ +typedef struct { +__REG32 P0_0 : 1; +__REG32 P0_1 : 1; +__REG32 P0_2 : 1; +__REG32 P0_3 : 1; +__REG32 P0_4 : 1; +__REG32 P0_5 : 1; +__REG32 P0_6 : 1; +__REG32 P0_7 : 1; +__REG32 P0_8 : 1; +__REG32 P0_9 : 1; +__REG32 P0_10 : 1; +__REG32 P0_11 : 1; +__REG32 P0_12 : 1; +__REG32 P0_13 : 1; +__REG32 P0_14 : 1; +__REG32 P0_15 : 1; +__REG32 P0_16 : 1; +__REG32 P0_17 : 1; +__REG32 P0_18 : 1; +__REG32 P0_19 : 1; +__REG32 P0_20 : 1; +__REG32 P0_21 : 1; +__REG32 P0_22 : 1; +__REG32 P0_23 : 1; +__REG32 P0_24 : 1; +__REG32 P0_25 : 1; +__REG32 P0_26 : 1; +__REG32 P0_27 : 1; +__REG32 P0_28 : 1; +__REG32 P0_29 : 1; +__REG32 P0_30 : 1; +__REG32 P0_31 : 1; +} __gpio0_bits; + +/* FGPIO 0 Registers*/ +typedef union{ + //FIO0DIR + //FIO0MASK + //FIO0PIN + //FIO0SET + //FIO0CLR + struct { + __REG32 P0_0 : 1; + __REG32 P0_1 : 1; + __REG32 P0_2 : 1; + __REG32 P0_3 : 1; + __REG32 P0_4 : 1; + __REG32 P0_5 : 1; + __REG32 P0_6 : 1; + __REG32 P0_7 : 1; + __REG32 P0_8 : 1; + __REG32 P0_9 : 1; + __REG32 P0_10 : 1; + __REG32 P0_11 : 1; + __REG32 P0_12 : 1; + __REG32 P0_13 : 1; + __REG32 P0_14 : 1; + __REG32 P0_15 : 1; + __REG32 P0_16 : 1; + __REG32 P0_17 : 1; + __REG32 P0_18 : 1; + __REG32 P0_19 : 1; + __REG32 P0_20 : 1; + __REG32 P0_21 : 1; + __REG32 P0_22 : 1; + __REG32 P0_23 : 1; + __REG32 P0_24 : 1; + __REG32 P0_25 : 1; + __REG32 P0_26 : 1; + __REG32 P0_27 : 1; + __REG32 P0_28 : 1; + __REG32 P0_29 : 1; + __REG32 P0_30 : 1; + __REG32 P0_31 : 1; + }; + + struct + { + union + { + //FIO0DIR0 + //FIO0MASK0 + //FIO0PIN0 + //FIO0SET0 + //FIO0CLR0 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO0DIR1 + //FIO0MASK1 + //FIO0PIN1 + //FIO0SET1 + //FIO0CLR1 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO0DIR2 + //FIO0MASK2 + //FIO0PIN2 + //FIO0SET2 + //FIO0CLR2 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO0DIR3 + //FIO0MASK3 + //FIO0PIN3 + //FIO0SET3 + //FIO0CLR3 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO0DIRL + //FIO0MASKL + //FIO0PINL + //FIO0SETL + //FIO0CLRL + struct{ + __REG16 P0_0 : 1; + __REG16 P0_1 : 1; + __REG16 P0_2 : 1; + __REG16 P0_3 : 1; + __REG16 P0_4 : 1; + __REG16 P0_5 : 1; + __REG16 P0_6 : 1; + __REG16 P0_7 : 1; + __REG16 P0_8 : 1; + __REG16 P0_9 : 1; + __REG16 P0_10 : 1; + __REG16 P0_11 : 1; + __REG16 P0_12 : 1; + __REG16 P0_13 : 1; + __REG16 P0_14 : 1; + __REG16 P0_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO0DIRU + //FIO0MASKU + //FIO0PINU + //FIO0SETU + //FIO0CLRU + struct{ + __REG16 P0_0 : 1; + __REG16 P0_1 : 1; + __REG16 P0_2 : 1; + __REG16 P0_3 : 1; + __REG16 P0_4 : 1; + __REG16 P0_5 : 1; + __REG16 P0_6 : 1; + __REG16 P0_7 : 1; + __REG16 P0_8 : 1; + __REG16 P0_9 : 1; + __REG16 P0_10 : 1; + __REG16 P0_11 : 1; + __REG16 P0_12 : 1; + __REG16 P0_13 : 1; + __REG16 P0_14 : 1; + __REG16 P0_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio0_bits; + +/* GPIO 1 Registers */ +typedef struct { +__REG32 P1_0 : 1; +__REG32 P1_1 : 1; +__REG32 P1_2 : 1; +__REG32 P1_3 : 1; +__REG32 P1_4 : 1; +__REG32 P1_5 : 1; +__REG32 P1_6 : 1; +__REG32 P1_7 : 1; +__REG32 P1_8 : 1; +__REG32 P1_9 : 1; +__REG32 P1_10 : 1; +__REG32 P1_11 : 1; +__REG32 P1_12 : 1; +__REG32 P1_13 : 1; +__REG32 P1_14 : 1; +__REG32 P1_15 : 1; +__REG32 P1_16 : 1; +__REG32 P1_17 : 1; +__REG32 P1_18 : 1; +__REG32 P1_19 : 1; +__REG32 P1_20 : 1; +__REG32 P1_21 : 1; +__REG32 P1_22 : 1; +__REG32 P1_23 : 1; +__REG32 P1_24 : 1; +__REG32 P1_25 : 1; +__REG32 P1_26 : 1; +__REG32 P1_27 : 1; +__REG32 P1_28 : 1; +__REG32 P1_29 : 1; +__REG32 P1_30 : 1; +__REG32 P1_31 : 1; +} __gpio1_bits; + +/* FGPIO 1 Registers*/ +typedef union{ + //FIO1DIR + //FIO1MASK + //FIO1PIN + //FIO1SET + //FIO1CLR + struct { + __REG32 P1_0 : 1; + __REG32 P1_1 : 1; + __REG32 P1_2 : 1; + __REG32 P1_3 : 1; + __REG32 P1_4 : 1; + __REG32 P1_5 : 1; + __REG32 P1_6 : 1; + __REG32 P1_7 : 1; + __REG32 P1_8 : 1; + __REG32 P1_9 : 1; + __REG32 P1_10 : 1; + __REG32 P1_11 : 1; + __REG32 P1_12 : 1; + __REG32 P1_13 : 1; + __REG32 P1_14 : 1; + __REG32 P1_15 : 1; + __REG32 P1_16 : 1; + __REG32 P1_17 : 1; + __REG32 P1_18 : 1; + __REG32 P1_19 : 1; + __REG32 P1_20 : 1; + __REG32 P1_21 : 1; + __REG32 P1_22 : 1; + __REG32 P1_23 : 1; + __REG32 P1_24 : 1; + __REG32 P1_25 : 1; + __REG32 P1_26 : 1; + __REG32 P1_27 : 1; + __REG32 P1_28 : 1; + __REG32 P1_29 : 1; + __REG32 P1_30 : 1; + __REG32 P1_31 : 1; + }; + + struct + { + union + { + //FIO1DIR0 + //FIO1MASK0 + //FIO1PIN0 + //FIO1SET0 + //FIO1CLR0 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO1DIR1 + //FIO1MASK1 + //FIO1PIN1 + //FIO1SET1 + //FIO1CLR1 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO1DIR2 + //FIO1MASK2 + //FIO1PIN2 + //FIO1SET2 + //FIO1CLR2 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO1DIR3 + //FIO1MASK3 + //FIO1PIN3 + //FIO1SET3 + //FIO1CLR3 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO1DIRL + //FIO1MASKL + //FIO1PINL + //FIO1SETL + //FIO1CLRL + struct{ + __REG16 P1_0 : 1; + __REG16 P1_1 : 1; + __REG16 P1_2 : 1; + __REG16 P1_3 : 1; + __REG16 P1_4 : 1; + __REG16 P1_5 : 1; + __REG16 P1_6 : 1; + __REG16 P1_7 : 1; + __REG16 P1_8 : 1; + __REG16 P1_9 : 1; + __REG16 P1_10 : 1; + __REG16 P1_11 : 1; + __REG16 P1_12 : 1; + __REG16 P1_13 : 1; + __REG16 P1_14 : 1; + __REG16 P1_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO1DIRU + //FIO1MASKU + //FIO1PINU + //FIO1SETU + //FIO1CLRU + struct{ + __REG16 P1_0 : 1; + __REG16 P1_1 : 1; + __REG16 P1_2 : 1; + __REG16 P1_3 : 1; + __REG16 P1_4 : 1; + __REG16 P1_5 : 1; + __REG16 P1_6 : 1; + __REG16 P1_7 : 1; + __REG16 P1_8 : 1; + __REG16 P1_9 : 1; + __REG16 P1_10 : 1; + __REG16 P1_11 : 1; + __REG16 P1_12 : 1; + __REG16 P1_13 : 1; + __REG16 P1_14 : 1; + __REG16 P1_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio1_bits; + +/* GPIO 2 Registers */ +typedef struct { +__REG32 P2_0 : 1; +__REG32 P2_1 : 1; +__REG32 P2_2 : 1; +__REG32 P2_3 : 1; +__REG32 P2_4 : 1; +__REG32 P2_5 : 1; +__REG32 P2_6 : 1; +__REG32 P2_7 : 1; +__REG32 P2_8 : 1; +__REG32 P2_9 : 1; +__REG32 P2_10 : 1; +__REG32 P2_11 : 1; +__REG32 P2_12 : 1; +__REG32 P2_13 : 1; +__REG32 P2_14 : 1; +__REG32 P2_15 : 1; +__REG32 P2_16 : 1; +__REG32 P2_17 : 1; +__REG32 P2_18 : 1; +__REG32 P2_19 : 1; +__REG32 P2_20 : 1; +__REG32 P2_21 : 1; +__REG32 P2_22 : 1; +__REG32 P2_23 : 1; +__REG32 P2_24 : 1; +__REG32 P2_25 : 1; +__REG32 P2_26 : 1; +__REG32 P2_27 : 1; +__REG32 P2_28 : 1; +__REG32 P2_29 : 1; +__REG32 P2_30 : 1; +__REG32 P2_31 : 1; +} __gpio2_bits; + +/* FGPIO 2 Registers*/ +typedef union{ + //FIO2DIR + //FIO2MASK + //FIO2PIN + //FIO2SET + //FIO2CLR + struct { + __REG32 P2_0 : 1; + __REG32 P2_1 : 1; + __REG32 P2_2 : 1; + __REG32 P2_3 : 1; + __REG32 P2_4 : 1; + __REG32 P2_5 : 1; + __REG32 P2_6 : 1; + __REG32 P2_7 : 1; + __REG32 P2_8 : 1; + __REG32 P2_9 : 1; + __REG32 P2_10 : 1; + __REG32 P2_11 : 1; + __REG32 P2_12 : 1; + __REG32 P2_13 : 1; + __REG32 P2_14 : 1; + __REG32 P2_15 : 1; + __REG32 P2_16 : 1; + __REG32 P2_17 : 1; + __REG32 P2_18 : 1; + __REG32 P2_19 : 1; + __REG32 P2_20 : 1; + __REG32 P2_21 : 1; + __REG32 P2_22 : 1; + __REG32 P2_23 : 1; + __REG32 P2_24 : 1; + __REG32 P2_25 : 1; + __REG32 P2_26 : 1; + __REG32 P2_27 : 1; + __REG32 P2_28 : 1; + __REG32 P2_29 : 1; + __REG32 P2_30 : 1; + __REG32 P2_31 : 1; + }; + + struct + { + union + { + //FIO2DIR0 + //FIO2MASK0 + //FIO2PIN0 + //FIO2SET0 + //FIO2CLR0 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO2DIR1 + //FIO2MASK1 + //FIO2PIN1 + //FIO2SET1 + //FIO2CLR1 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO2DIR2 + //FIO2MASK2 + //FIO2PIN2 + //FIO2SET2 + //FIO2CLR2 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO2DIR3 + //FIO2MASK3 + //FIO2PIN3 + //FIO2SET3 + //FIO2CLR3 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO2DIRL + //FIO2MASKL + //FIO2PINL + //FIO2SETL + //FIO2CLRL + struct{ + __REG16 P2_0 : 1; + __REG16 P2_1 : 1; + __REG16 P2_2 : 1; + __REG16 P2_3 : 1; + __REG16 P2_4 : 1; + __REG16 P2_5 : 1; + __REG16 P2_6 : 1; + __REG16 P2_7 : 1; + __REG16 P2_8 : 1; + __REG16 P2_9 : 1; + __REG16 P2_10 : 1; + __REG16 P2_11 : 1; + __REG16 P2_12 : 1; + __REG16 P2_13 : 1; + __REG16 P2_14 : 1; + __REG16 P2_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO2DIRU + //FIO2MASKU + //FIO2PINU + //FIO2SETU + //FIO2CLRU + struct{ + __REG16 P2_0 : 1; + __REG16 P2_1 : 1; + __REG16 P2_2 : 1; + __REG16 P2_3 : 1; + __REG16 P2_4 : 1; + __REG16 P2_5 : 1; + __REG16 P2_6 : 1; + __REG16 P2_7 : 1; + __REG16 P2_8 : 1; + __REG16 P2_9 : 1; + __REG16 P2_10 : 1; + __REG16 P2_11 : 1; + __REG16 P2_12 : 1; + __REG16 P2_13 : 1; + __REG16 P2_14 : 1; + __REG16 P2_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio2_bits; + +/* FGPIO 3 Registers*/ +typedef union{ + //FIO3DIR + //FIO3MASK + //FIO3PIN + //FIO3SET + //FIO3CLR + struct { + __REG32 P3_0 : 1; + __REG32 P3_1 : 1; + __REG32 P3_2 : 1; + __REG32 P3_3 : 1; + __REG32 P3_4 : 1; + __REG32 P3_5 : 1; + __REG32 P3_6 : 1; + __REG32 P3_7 : 1; + __REG32 P3_8 : 1; + __REG32 P3_9 : 1; + __REG32 P3_10 : 1; + __REG32 P3_11 : 1; + __REG32 P3_12 : 1; + __REG32 P3_13 : 1; + __REG32 P3_14 : 1; + __REG32 P3_15 : 1; + __REG32 P3_16 : 1; + __REG32 P3_17 : 1; + __REG32 P3_18 : 1; + __REG32 P3_19 : 1; + __REG32 P3_20 : 1; + __REG32 P3_21 : 1; + __REG32 P3_22 : 1; + __REG32 P3_23 : 1; + __REG32 P3_24 : 1; + __REG32 P3_25 : 1; + __REG32 P3_26 : 1; + __REG32 P3_27 : 1; + __REG32 P3_28 : 1; + __REG32 P3_29 : 1; + __REG32 P3_30 : 1; + __REG32 P3_31 : 1; + }; + + struct + { + union + { + //FIO3DIR0 + //FIO3MASK0 + //FIO3PIN0 + //FIO3SET0 + //FIO3CLR0 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO3DIR1 + //FIO3MASK1 + //FIO3PIN1 + //FIO3SET1 + //FIO3CLR1 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO3DIR2 + //FIO3MASK2 + //FIO3PIN2 + //FIO3SET2 + //FIO3CLR2 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO3DIR3 + //FIO3MASK3 + //FIO3PIN3 + //FIO3SET3 + //FIO3CLR3 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO3DIRL + //FIO3MASKL + //FIO3PINL + //FIO3SETL + //FIO3CLRL + struct{ + __REG16 P3_0 : 1; + __REG16 P3_1 : 1; + __REG16 P3_2 : 1; + __REG16 P3_3 : 1; + __REG16 P3_4 : 1; + __REG16 P3_5 : 1; + __REG16 P3_6 : 1; + __REG16 P3_7 : 1; + __REG16 P3_8 : 1; + __REG16 P3_9 : 1; + __REG16 P3_10 : 1; + __REG16 P3_11 : 1; + __REG16 P3_12 : 1; + __REG16 P3_13 : 1; + __REG16 P3_14 : 1; + __REG16 P3_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO3DIRU + //FIO3MASKU + //FIO3PINU + //FIO3SETU + //FIO3CLRU + struct{ + __REG16 P3_0 : 1; + __REG16 P3_1 : 1; + __REG16 P3_2 : 1; + __REG16 P3_3 : 1; + __REG16 P3_4 : 1; + __REG16 P3_5 : 1; + __REG16 P3_6 : 1; + __REG16 P3_7 : 1; + __REG16 P3_8 : 1; + __REG16 P3_9 : 1; + __REG16 P3_10 : 1; + __REG16 P3_11 : 1; + __REG16 P3_12 : 1; + __REG16 P3_13 : 1; + __REG16 P3_14 : 1; + __REG16 P3_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio3_bits; + +/* FGPIO 4 Registers*/ +typedef union{ + //FIO4DIR + //FIO4MASK + //FIO4PIN + //FIO4SET + //FIO4CLR + struct { + __REG32 P4_0 : 1; + __REG32 P4_1 : 1; + __REG32 P4_2 : 1; + __REG32 P4_3 : 1; + __REG32 P4_4 : 1; + __REG32 P4_5 : 1; + __REG32 P4_6 : 1; + __REG32 P4_7 : 1; + __REG32 P4_8 : 1; + __REG32 P4_9 : 1; + __REG32 P4_10 : 1; + __REG32 P4_11 : 1; + __REG32 P4_12 : 1; + __REG32 P4_13 : 1; + __REG32 P4_14 : 1; + __REG32 P4_15 : 1; + __REG32 P4_16 : 1; + __REG32 P4_17 : 1; + __REG32 P4_18 : 1; + __REG32 P4_19 : 1; + __REG32 P4_20 : 1; + __REG32 P4_21 : 1; + __REG32 P4_22 : 1; + __REG32 P4_23 : 1; + __REG32 P4_24 : 1; + __REG32 P4_25 : 1; + __REG32 P4_26 : 1; + __REG32 P4_27 : 1; + __REG32 P4_28 : 1; + __REG32 P4_29 : 1; + __REG32 P4_30 : 1; + __REG32 P4_31 : 1; + }; + + struct + { + union + { + //FIO4DIR0 + //FIO4MASK0 + //FIO4PIN0 + //FIO4SET0 + //FIO4CLR0 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO4DIR1 + //FIO4MASK1 + //FIO4PIN1 + //FIO4SET1 + //FIO4CLR1 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO4DIR2 + //FIO4MASK2 + //FIO4PIN2 + //FIO4SET2 + //FIO4CLR2 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO4DIR3 + //FIO4MASK3 + //FIO4PIN3 + //FIO4SET3 + //FIO4CLR3 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO4DIRL + //FIO4MASKL + //FIO4PINL + //FIO4SETL + //FIO4CLRL + struct{ + __REG16 P4_0 : 1; + __REG16 P4_1 : 1; + __REG16 P4_2 : 1; + __REG16 P4_3 : 1; + __REG16 P4_4 : 1; + __REG16 P4_5 : 1; + __REG16 P4_6 : 1; + __REG16 P4_7 : 1; + __REG16 P4_8 : 1; + __REG16 P4_9 : 1; + __REG16 P4_10 : 1; + __REG16 P4_11 : 1; + __REG16 P4_12 : 1; + __REG16 P4_13 : 1; + __REG16 P4_14 : 1; + __REG16 P4_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO4DIRU + //FIO4MASKU + //FIO4PINU + //FIO4SETU + //FIO4CLRU + struct{ + __REG16 P4_0 : 1; + __REG16 P4_1 : 1; + __REG16 P4_2 : 1; + __REG16 P4_3 : 1; + __REG16 P4_4 : 1; + __REG16 P4_5 : 1; + __REG16 P4_6 : 1; + __REG16 P4_7 : 1; + __REG16 P4_8 : 1; + __REG16 P4_9 : 1; + __REG16 P4_10 : 1; + __REG16 P4_11 : 1; + __REG16 P4_12 : 1; + __REG16 P4_13 : 1; + __REG16 P4_14 : 1; + __REG16 P4_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio4_bits; + +/* GPIO overall Interrupt Status register */ +typedef struct{ +__REG32 P0INT : 1; +__REG32 : 1; +__REG32 P2INT : 1; +__REG32 :29; +}__iointst_bits; + +/* MAC Configuration Register 1 */ +typedef struct{ +__REG32 RE : 1; +__REG32 PARF : 1; +__REG32 RXFC : 1; +__REG32 TXFC : 1; +__REG32 LB : 1; +__REG32 : 3; +__REG32 RSTTX : 1; +__REG32 RSTMCSTX : 1; +__REG32 RSTRX : 1; +__REG32 RSTMCSRX : 1; +__REG32 : 2; +__REG32 SIMRST : 1; +__REG32 SOFTRST : 1; +__REG32 :16; +}__mac1_bits; + +/* MAC Configuration Register 2 */ +typedef struct{ +__REG32 FD : 1; +__REG32 FLC : 1; +__REG32 HFE : 1; +__REG32 DLYCRC : 1; +__REG32 CRCEN : 1; +__REG32 PADCRCEN : 1; +__REG32 VLANCRCEN : 1; +__REG32 ADPE : 1; +__REG32 PPE : 1; +__REG32 LPE : 1; +__REG32 : 2; +__REG32 NB : 1; +__REG32 BP : 1; +__REG32 ED : 1; +__REG32 :17; +}__mac2_bits; + +/* Back-to-Back Inter-Packet-Gap Register */ +typedef struct{ +__REG32 IPG : 7; +__REG32 :25; +}__ipgt_bits; + +/* Non Back-to-Back Inter-Packet-Gap Register */ +typedef struct{ +__REG32 IPGR2 : 7; +__REG32 : 1; +__REG32 IPGR1 : 7; +__REG32 :17; +}__ipgr_bits; + +/*Collision Window / Retry Register */ +typedef struct{ +__REG32 RM : 4; +__REG32 : 4; +__REG32 CW : 6; +__REG32 :18; +}__clrt_bits; + +/* Maximum Frame Register */ +typedef struct{ +__REG32 MAXF :16; +__REG32 :16; +}__maxf_bits; + +/* PHY Support Register */ +typedef struct{ +__REG32 : 8; +__REG32 SPEED : 1; +__REG32 :23; +}__supp_bits; + +/* Test Register */ +typedef struct{ +__REG32 SPQ : 1; +__REG32 TP : 1; +__REG32 TB : 1; +__REG32 :29; +}__test_bits; + +/* MII Mgmt Configuration Register */ +typedef struct{ +__REG32 SI : 1; +__REG32 SP : 1; +__REG32 CS : 3; +__REG32 :10; +__REG32 RSTMIIMGMT : 1; +__REG32 :16; +}__mcfg_bits; + +/* MII Mgmt Command Register */ +typedef struct{ +__REG32 READ : 1; +__REG32 SCAN : 1; +__REG32 :30; +}__mcmd_bits; + +/* MII Mgmt Address Register */ +typedef struct{ +__REG32 REGADDR : 5; +__REG32 : 3; +__REG32 PHY_ADDR : 5; +__REG32 :19; +}__madr_bits; + +/* MII Mgmt Write Data Register */ +typedef struct{ +__REG32 WRITEDATA :16; +__REG32 :16; +}__mwtd_bits; + +/* MII Mgmt Read Data Register */ +typedef struct{ +__REG32 READDATA :16; +__REG32 :16; +}__mrdd_bits; + +/* MII Mgmt Indicators Register */ +typedef struct{ +__REG32 BUSY : 1; +__REG32 SCANNING : 1; +__REG32 NOT_VALID : 1; +__REG32 MII_LINK_FAIL : 1; +__REG32 :28; +}__mind_bits; + +/* Station Address 0 Register */ +typedef struct{ +__REG32 STATION_ADDR_2 : 8; +__REG32 STATION_ADDR_1 : 8; +__REG32 :16; +}__sa0_bits; + +/* Station Address 1 Register */ +typedef struct{ +__REG32 STATION_ADDR_4 : 8; +__REG32 STATION_ADDR_3 : 8; +__REG32 :16; +}__sa1_bits; + +/* Station Address 2 Register */ +typedef struct{ +__REG32 STATION_ADDR_6 : 8; +__REG32 STATION_ADDR_5 : 8; +__REG32 :16; +}__sa2_bits; + +/* Command Register */ +typedef struct{ +__REG32 RXENABLE : 1; +__REG32 TXENABLE : 1; +__REG32 : 1; +__REG32 REGRESET : 1; +__REG32 TXRESET : 1; +__REG32 RXRESET : 1; +__REG32 PASSRUNTFRAME : 1; +__REG32 PASSRXFILTER : 1; +__REG32 TXFLOWCONTROL : 1; +__REG32 RMII : 1; +__REG32 FULLDUPLEX : 1; +__REG32 :21; +}__command_bits; + +/* Status Register */ +typedef struct{ +__REG32 RXSTATUS : 1; +__REG32 TXSTATUS : 1; +__REG32 :30; +}__status_bits; + +/* Receive Number of Descriptors Register */ +typedef struct{ +__REG32 RXDESCRIPTORNUMBER :16; +__REG32 :16; +}__rxdescrn_bits; + +/* Receive Produce Index Register */ +typedef struct{ +__REG32 RXPRODUCDINDEX :16; +__REG32 :16; +}__rxprodind_bits; + +/* Receive Consume Index Register */ +typedef struct{ +__REG32 RXCONSUMEINDEX :16; +__REG32 :16; +}__rxcomind_bits; + +/* Transmit Number of Descriptors Register */ +typedef struct{ +__REG32 TXDESCRIPTORNUMBER :16; +__REG32 :16; +}__txdescrn_bits; + +/* Transmit Produce Index Register */ +typedef struct{ +__REG32 TXPRODUCDINDEX :16; +__REG32 :16; +}__txprodind_bits; + +/* Transmit Consume Index Register */ +typedef struct{ +__REG32 TXCONSUMEINDEX :16; +__REG32 :16; +}__txcomind_bits; + +/* Transmit Status Vector 0 Register */ +typedef struct{ +__REG32 CCR_ERR : 1; +__REG32 LCERR : 1; +__REG32 LOOR : 1; +__REG32 DONE : 1; +__REG32 MULTICAST : 1; +__REG32 BROADCAST : 1; +__REG32 PD : 1; +__REG32 ED : 1; +__REG32 EC : 1; +__REG32 LC : 1; +__REG32 GIANT : 1; +__REG32 UNDERRUN : 1; +__REG32 TB :16; +__REG32 CF : 1; +__REG32 PAUSE : 1; +__REG32 BACKPRESSURE : 1; +__REG32 VLAN : 1; +}__tsv0_bits; + +/* Transmit Status Vector 1 Register */ +typedef struct{ +__REG32 TBC :16; +__REG32 TCC : 4; +__REG32 :12; +}__tsv1_bits; + +/* Receive Status Vector Register */ +typedef struct{ +__REG32 RBC :16; +__REG32 PPI : 1; +__REG32 RXDVEPS : 1; +__REG32 CEPS : 1; +__REG32 RCV : 1; +__REG32 CRC_ERR : 1; +__REG32 LCE : 1; +__REG32 LOOR : 1; +__REG32 R_OK : 1; +__REG32 MULTICAST : 1; +__REG32 BROADCAST : 1; +__REG32 DN : 1; +__REG32 CF : 1; +__REG32 PAUSE : 1; +__REG32 UO : 1; +__REG32 VLAN : 1; +__REG32 : 1; +}__rsv_bits; + +/* Flow Control Counter Register */ +typedef struct{ +__REG32 MC :16; +__REG32 PT :16; +}__fwctrlcnt_bits; + +/* Flow Control Status Register */ +typedef struct{ +__REG32 MCC :16; +__REG32 :16; +}__fwctrlstat_bits; + +/* Receive Filter Control Register */ +typedef struct{ +__REG32 AUE : 1; +__REG32 ABE : 1; +__REG32 AME : 1; +__REG32 AUHE : 1; +__REG32 AMHE : 1; +__REG32 APE : 1; +__REG32 : 6; +__REG32 MPEWOL : 1; +__REG32 RXFEWOL : 1; +__REG32 :18; +}__rxflctrl_bits; + +/* Receive Filter WoL Status Register */ +typedef struct{ +__REG32 AUWOL : 1; +__REG32 ABWOL : 1; +__REG32 AMWOL : 1; +__REG32 AUHWOL : 1; +__REG32 AMHWOL : 1; +__REG32 APWOL : 1; +__REG32 : 1; +__REG32 RXFWOL : 1; +__REG32 MPWOL : 1; +__REG32 :23; +}__rxflwolstat_bits; + +/* Receive Filter WoL Clear Register */ +typedef struct{ +__REG32 AUWOLC : 1; +__REG32 ABWOLC : 1; +__REG32 AMWOLC : 1; +__REG32 AUHWOLC : 1; +__REG32 AMHWOLC : 1; +__REG32 APWOLC : 1; +__REG32 : 1; +__REG32 RXFWOLC : 1; +__REG32 MPWOLC : 1; +__REG32 :23; +}__rxflwolclr_bits; + +/* Interrupt Status Register */ +typedef struct{ +__REG32 RXOVERRUNINT : 1; +__REG32 RXERRORINT : 1; +__REG32 RXFINISHEDINT : 1; +__REG32 RXDONEINT : 1; +__REG32 TXUNDERRUNINT : 1; +__REG32 TXERRORINT : 1; +__REG32 TXFINISHEDINT : 1; +__REG32 TXDONEINT : 1; +__REG32 : 4; +__REG32 SOFTINT : 1; +__REG32 WAKEUPINT : 1; +__REG32 :18; +}__intstat_bits; + +/* Interrupt Enable Register */ +typedef struct{ +__REG32 RXOVERRUNINTEN : 1; +__REG32 RXERRORINTEN : 1; +__REG32 RXFINISHEDINTEN : 1; +__REG32 RXDONEINTEN : 1; +__REG32 TXUNDERRUNINTEN : 1; +__REG32 TXERRORINTEN : 1; +__REG32 TXFINISHEDINTEN : 1; +__REG32 TXDONEINTEN : 1; +__REG32 : 4; +__REG32 SOFTINTEN : 1; +__REG32 WAKEUPINTEN : 1; +__REG32 :18; +}__intena_bits; + +/* Interrupt Clear Register */ +typedef struct{ +__REG32 RXOVERRUNINTCLR : 1; +__REG32 RXERRORINTCLR : 1; +__REG32 RXFINISHEDINTCLR: 1; +__REG32 RXDONEINTCLR : 1; +__REG32 TXUNDERRUNINTCLR: 1; +__REG32 TXERRORINTCLR : 1; +__REG32 TXFINISHEDINTCLR: 1; +__REG32 TXDONEINTCLR : 1; +__REG32 : 4; +__REG32 SOFTINTCLR : 1; +__REG32 WAKEUPINTCLR : 1; +__REG32 :18; +}__intclr_bits; + +/* Interrupt Set Register */ +typedef struct{ +__REG32 RXOVERRUNINTSET : 1; +__REG32 RXERRORINTSET : 1; +__REG32 RXFINISHEDINTSET: 1; +__REG32 RXDONEINTSET : 1; +__REG32 TXUNDERRUNINTSET: 1; +__REG32 TXERRORINTSET : 1; +__REG32 TXFINISHEDINTSET: 1; +__REG32 TXDONEINTSET : 1; +__REG32 : 4; +__REG32 SOFTINTSET : 1; +__REG32 WAKEUPINTSET : 1; +__REG32 :18; +}__intset_bits; + +/* Power Down Register */ +typedef struct{ +__REG32 :31; +__REG32 POWERDOWN : 1; +}__pwrdn_bits; + +/* CAN acceptance filter mode register */ +typedef struct { + __REG32 ACCOFF :1; + __REG32 ACCBP :1; + __REG32 EFCAN :1; + __REG32 :29; +} __afmr_bits; + +/* CAN LUT Error Register */ +typedef struct { + __REG32 LUTERR :1; + __REG32 :31; +} __luterr_bits; + +/* Global FullCANInterrupt Enable register */ +typedef struct { + __REG32 FCANIE :1; + __REG32 :31; +} __fcanie_bits; + +/* FullCAN Interrupt and Capture registers 0 */ +typedef struct { + __REG32 INTPND0 :1; + __REG32 INTPND1 :1; + __REG32 INTPND2 :1; + __REG32 INTPND3 :1; + __REG32 INTPND4 :1; + __REG32 INTPND5 :1; + __REG32 INTPND6 :1; + __REG32 INTPND7 :1; + __REG32 INTPND8 :1; + __REG32 INTPND9 :1; + __REG32 INTPND10 :1; + __REG32 INTPND11 :1; + __REG32 INTPND12 :1; + __REG32 INTPND13 :1; + __REG32 INTPND14 :1; + __REG32 INTPND15 :1; + __REG32 INTPND16 :1; + __REG32 INTPND17 :1; + __REG32 INTPND18 :1; + __REG32 INTPND19 :1; + __REG32 INTPND20 :1; + __REG32 INTPND21 :1; + __REG32 INTPND22 :1; + __REG32 INTPND23 :1; + __REG32 INTPND24 :1; + __REG32 INTPND25 :1; + __REG32 INTPND26 :1; + __REG32 INTPND27 :1; + __REG32 INTPND28 :1; + __REG32 INTPND29 :1; + __REG32 INTPND30 :1; + __REG32 INTPND31 :1; +} __fcanic0_bits; + +/* FullCAN Interrupt and Capture registers 1 */ +typedef struct { + __REG32 INTPND32 :1; + __REG32 INTPND33 :1; + __REG32 INTPND34 :1; + __REG32 INTPND35 :1; + __REG32 INTPND36 :1; + __REG32 INTPND37 :1; + __REG32 INTPND38 :1; + __REG32 INTPND39 :1; + __REG32 INTPND40 :1; + __REG32 INTPND41 :1; + __REG32 INTPND42 :1; + __REG32 INTPND43 :1; + __REG32 INTPND44 :1; + __REG32 INTPND45 :1; + __REG32 INTPND46 :1; + __REG32 INTPND47 :1; + __REG32 INTPND48 :1; + __REG32 INTPND49 :1; + __REG32 INTPND50 :1; + __REG32 INTPND51 :1; + __REG32 INTPND52 :1; + __REG32 INTPND53 :1; + __REG32 INTPND54 :1; + __REG32 INTPND55 :1; + __REG32 INTPND56 :1; + __REG32 INTPND57 :1; + __REG32 INTPND58 :1; + __REG32 INTPND59 :1; + __REG32 INTPND60 :1; + __REG32 INTPND61 :1; + __REG32 INTPND62 :1; + __REG32 INTPND63 :1; +} __fcanic1_bits; + +/* CAN central transmit status register */ +typedef struct { + __REG32 TS1 : 1; + __REG32 TS2 : 1; + __REG32 : 6; + __REG32 TBS1 : 1; + __REG32 TBS2 : 1; + __REG32 : 6; + __REG32 TCS1 : 1; + __REG32 TCS2 : 1; + __REG32 :14; +} __cantxsr_bits; + +/* CAN central receive status register */ +typedef struct { + __REG32 RS1 : 1; + __REG32 RS2 : 1; + __REG32 : 6; + __REG32 RBS1 : 1; + __REG32 RBS2 : 1; + __REG32 : 6; + __REG32 DOS1 : 1; + __REG32 DOS2 : 1; + __REG32 :14; +} __canrxsr_bits; + +/* CAN miscellaneous status register */ +typedef struct { + __REG32 E1 : 1; + __REG32 E2 : 1; + __REG32 : 6; + __REG32 BS1 : 1; + __REG32 BS2 : 1; + __REG32 :22; +} __canmsr_bits; + +/* CAN mode register */ +typedef struct { + __REG32 RM :1; + __REG32 LOM :1; + __REG32 STM :1; + __REG32 TPM :1; + __REG32 SM :1; + __REG32 RPM :1; + __REG32 :1; + __REG32 TM :1; + __REG32 :24; +} __canmod_bits; + +/* CAN command register */ +typedef struct { + __REG32 TR :1; + __REG32 AT :1; + __REG32 RRB :1; + __REG32 CDO :1; + __REG32 SRR :1; + __REG32 STB1 :1; + __REG32 STB2 :1; + __REG32 STB3 :1; + __REG32 :24; +} __cancmr_bits; + +/* CAN global status register */ +typedef struct { + __REG32 RBS :1; + __REG32 DOS :1; + __REG32 TBS :1; + __REG32 TCS :1; + __REG32 RS :1; + __REG32 TS :1; + __REG32 ES :1; + __REG32 BS :1; + __REG32 :8; + __REG32 RXERR :8; + __REG32 TXERR :8; +} __cangsr_bits; + +/* CAN interrupt capture register */ +typedef struct { + __REG32 RI :1; + __REG32 TI1 :1; + __REG32 EI :1; + __REG32 DOI :1; + __REG32 WUI :1; + __REG32 EPI :1; + __REG32 ALI :1; + __REG32 BEI :1; + __REG32 IDI :1; + __REG32 TI2 :1; + __REG32 TI3 :1; + __REG32 :5; + __REG32 ERRBIT :5; + __REG32 ERRDIR :1; + __REG32 ERRC :2; + __REG32 ALCBIT :8; +} __canicr_bits; + +/* CAN interrupt enable register */ +typedef struct { + __REG32 RIE :1; + __REG32 TIE1 :1; + __REG32 EIE :1; + __REG32 DOIE :1; + __REG32 WUIE :1; + __REG32 EPIE :1; + __REG32 ALIE :1; + __REG32 BEIE :1; + __REG32 IDIE :1; + __REG32 TIE2 :1; + __REG32 TIE3 :1; + __REG32 :21; +} __canier_bits; + +/* CAN bus timing register */ +typedef struct { + __REG32 BRP :10; + __REG32 :4; + __REG32 SJW :2; + __REG32 TSEG1 :4; + __REG32 TSEG2 :3; + __REG32 SAM :1; + __REG32 :8; +} __canbtr_bits; + +/* CAN error warning limit register */ +typedef struct { + __REG32 EWL :8; + __REG32 :24; +} __canewl_bits; + +/* CAN status register */ +typedef struct { + __REG32 RBS :1; + __REG32 DOS :1; + __REG32 TBS1 :1; + __REG32 TCS1 :1; + __REG32 RS :1; + __REG32 TS1 :1; + __REG32 ES :1; + __REG32 BS :1; + __REG32 /*RBS*/ :1; + __REG32 /*DOS*/ :1; + __REG32 TBS2 :1; + __REG32 TCS2 :1; + __REG32 /*RS*/ :1; + __REG32 TS2 :1; + __REG32 /*ES*/ :1; + __REG32 /*BS*/ :1; + __REG32 /*RBS*/ :1; + __REG32 /*DOS*/ :1; + __REG32 TBS3 :1; + __REG32 TCS3 :1; + __REG32 /*RS*/ :1; + __REG32 TS3 :1; + __REG32 /*ES*/ :1; + __REG32 /*BS*/ :1; + __REG32 :8; +} __cansr_bits; + +/* CAN rx frame status register */ +typedef struct { + __REG32 IDINDEX :10; + __REG32 BP :1; + __REG32 :5; + __REG32 DLC :4; + __REG32 :10; + __REG32 RTR :1; + __REG32 FF :1; +} __canrfs_bits; + +/* CAN rx identifier register */ +typedef union { + //CANxRID + struct { + __REG32 ID10_0 :11; + __REG32 :21; + }; + //CANxRID + struct { + __REG32 ID29_18 :11; + __REG32 :21; + }; + //CANxRID + struct { + __REG32 ID29_0 :29; + __REG32 :3; + }; +} __canrid_bits; + +/* CAN rx data register A */ +typedef struct { + __REG32 DATA1 :8; + __REG32 DATA2 :8; + __REG32 DATA3 :8; + __REG32 DATA4 :8; +} __canrda_bits; + +/* CAN rx data register B */ +typedef struct { + __REG32 DATA5 :8; + __REG32 DATA6 :8; + __REG32 DATA7 :8; + __REG32 DATA8 :8; +} __canrdb_bits; + +/* CAN tx frame information register */ +typedef struct { + __REG32 PRIO :8; + __REG32 :8; + __REG32 DLC :4; + __REG32 :10; + __REG32 RTR :1; + __REG32 FF :1; +} __cantfi_bits; + +/* CAN tx identifier register */ +typedef union { + //CANxTIDy + struct { + __REG32 ID10_0 :11; + __REG32 :21; + }; + //CANxTIDy + struct { + __REG32 ID29_18 :11; + __REG32 :21; + }; + //CANxTIDy + struct { + __REG32 ID29_0 :29; + __REG32 :3; + }; +} __cantid_bits; + +/* CAN tx data register A */ +typedef struct { + __REG32 DATA1 :8; + __REG32 DATA2 :8; + __REG32 DATA3 :8; + __REG32 DATA4 :8; +} __cantda_bits; + +/* CAN tx data register B */ +typedef struct { + __REG32 DATA5 :8; + __REG32 DATA6 :8; + __REG32 DATA7 :8; + __REG32 DATA8 :8; +} __cantdb_bits; + +/* USB - Device Interrupt Status Register */ +typedef struct { + __REG32 PORTSEL : 2; + __REG32 :30; +} __usbportsel_bits; + +/* USB Clock Control register (USBClkCtrl - 0xFFE0 CFF4) */ +typedef struct{ +__REG32 : 1; +__REG32 DEV_CLK_EN : 1; +__REG32 : 1; +__REG32 PORTSEL_CLK_EN : 1; +__REG32 AHB_CLK_EN : 1; +__REG32 :27; +} __usbclkctrl_bits; + +/* USB Clock Status register (USBClkSt - 0xFFE0 CFF8) */ +typedef struct{ +__REG32 : 1; +__REG32 DEV_CLK_ON : 1; +__REG32 : 1; +__REG32 PORTSEL_CLK_ON : 1; +__REG32 AHB_CLK_ON : 1; +__REG32 :27; +} __usbclkst_bits; + +/* USB - Device Interrupt Status Register */ +typedef struct { + __REG32 USB_INT_REQ_LP : 1; + __REG32 USB_INT_REQ_HP : 1; + __REG32 USB_INT_REQ_DMA : 1; + __REG32 : 5; + __REG32 USB_NEED_CLOCK : 1; + __REG32 :22; + __REG32 EN_USB_INTS : 1; +} __usbints_bits; + +/* USB - Device Interrupt Status Register */ +/* USB - Device Interrupt Enable Register */ +/* USB - Device Interrupt Clear Register */ +/* USB - Device Interrupt Set Register */ +typedef struct { + __REG32 FRAME : 1; + __REG32 EP_FAST : 1; + __REG32 EP_SLOW : 1; + __REG32 DEV_STAT : 1; + __REG32 CCEMTY : 1; + __REG32 CDFULL : 1; + __REG32 RXENDPKT : 1; + __REG32 TXENDPKT : 1; + __REG32 EP_RLZED : 1; + __REG32 ERR_INT : 1; + __REG32 :22; +} __usbdevintst_bits; + +/* USB - Device Interrupt Priority Register */ +typedef struct { + __REG8 FRAME : 1; + __REG8 EP_FAST : 1; + __REG8 : 6; +} __usbdevintpri_bits; + +/* USB - Endpoint Interrupt Status Register */ +/* USB - Endpoint Interrupt Enable Register */ +/* USB - Endpoint Interrupt Clear Register */ +/* USB - Endpoint Interrupt Set Register */ +/* USB - Endpoint Interrupt Priority Register */ +typedef struct { + __REG32 EP_0RX : 1; + __REG32 EP_0TX : 1; + __REG32 EP_1RX : 1; + __REG32 EP_1TX : 1; + __REG32 EP_2RX : 1; + __REG32 EP_2TX : 1; + __REG32 EP_3RX : 1; + __REG32 EP_3TX : 1; + __REG32 EP_4RX : 1; + __REG32 EP_4TX : 1; + __REG32 EP_5RX : 1; + __REG32 EP_5TX : 1; + __REG32 EP_6RX : 1; + __REG32 EP_6TX : 1; + __REG32 EP_7RX : 1; + __REG32 EP_7TX : 1; + __REG32 EP_8RX : 1; + __REG32 EP_8TX : 1; + __REG32 EP_9RX : 1; + __REG32 EP_9TX : 1; + __REG32 EP_10RX : 1; + __REG32 EP_10TX : 1; + __REG32 EP_11RX : 1; + __REG32 EP_11TX : 1; + __REG32 EP_12RX : 1; + __REG32 EP_12TX : 1; + __REG32 EP_13RX : 1; + __REG32 EP_13TX : 1; + __REG32 EP_14RX : 1; + __REG32 EP_14TX : 1; + __REG32 EP_15RX : 1; + __REG32 EP_15TX : 1; +} __usbepintst_bits; + +/* USB - Realize Enpoint Register */ +/* USB - DMA Request Status Register */ +/* USB - DMA Request Clear Register */ +/* USB - DMA Request Set Regiser */ +/* USB - EP DMA Status Register */ +/* USB - EP DMA Enable Register */ +/* USB - EP DMA Disable Register */ +/* USB - New DD Request Interrupt Status Register */ +/* USB - New DD Request Interrupt Clear Register */ +/* USB - New DD Request Interrupt Set Register */ +/* USB - End Of Transfer Interrupt Status Register */ +/* USB - End Of Transfer Interrupt Clear Register */ +/* USB - End Of Transfer Interrupt Set Register */ +/* USB - System Error Interrupt Status Register */ +/* USB - System Error Interrupt Clear Register */ +/* USB - System Error Interrupt Set Register */ +typedef struct { + __REG32 EP0 : 1; + __REG32 EP1 : 1; + __REG32 EP2 : 1; + __REG32 EP3 : 1; + __REG32 EP4 : 1; + __REG32 EP5 : 1; + __REG32 EP6 : 1; + __REG32 EP7 : 1; + __REG32 EP8 : 1; + __REG32 EP9 : 1; + __REG32 EP10 : 1; + __REG32 EP11 : 1; + __REG32 EP12 : 1; + __REG32 EP13 : 1; + __REG32 EP14 : 1; + __REG32 EP15 : 1; + __REG32 EP16 : 1; + __REG32 EP17 : 1; + __REG32 EP18 : 1; + __REG32 EP19 : 1; + __REG32 EP20 : 1; + __REG32 EP21 : 1; + __REG32 EP22 : 1; + __REG32 EP23 : 1; + __REG32 EP24 : 1; + __REG32 EP25 : 1; + __REG32 EP26 : 1; + __REG32 EP27 : 1; + __REG32 EP28 : 1; + __REG32 EP29 : 1; + __REG32 EP30 : 1; + __REG32 EP31 : 1; +} __usbreep_bits; + +/* USB - Endpoint Index Register */ +typedef struct { + __REG32 PHY_ENDP : 5; + __REG32 :27; +} __usbepin_bits; + +/* USB - MaxPacketSize Register */ +typedef struct { + __REG32 MPS :10; + __REG32 :22; +} __usbmaxpsize_bits; + +/* USB - Receive Packet Length Register */ +typedef struct { + __REG32 PKT_LNGTH :10; + __REG32 DV : 1; + __REG32 PKT_RDY : 1; + __REG32 :20; +} __usbrxplen_bits; + +/* USB - Transmit Packet Length Register */ +typedef struct { + __REG32 PKT_LNGHT :10; + __REG32 :22; +} __usbtxplen_bits; + +/* USB - Control Register */ +typedef struct { + __REG32 RD_EN : 1; + __REG32 WR_EN : 1; + __REG32 LOG_ENDPOINT : 4; + __REG32 :26; +} __usbctrl_bits; + +/* USB - Command Code Register */ +typedef struct { + __REG32 : 8; + __REG32 CMD_PHASE : 8; + __REG32 CMD_CODE : 8; + __REG32 : 8; +} __usbcmdcode_bits; + +/* USB - Command Data Register */ +typedef struct { + __REG32 CMD_DATA : 8; + __REG32 :24; +} __usbcmddata_bits; + +/* USB - DMA Interrupt Status Register */ +/* USB - DMA Interrupt Enable Register */ +typedef struct { + __REG32 EOT : 1; + __REG32 NDDR : 1; + __REG32 ERR : 1; + __REG32 :29; +} __usbdmaintst_bits; + +/* UART interrupt enable register */ +typedef struct{ +__REG32 RDAIE : 1; +__REG32 THREIE : 1; +__REG32 RXLSIE : 1; +__REG32 : 5; +__REG32 ABTOINTEN : 1; +__REG32 ABEOINTEN : 1; +__REG32 :22; +} __uartier0_bits; + +/* UART1 interrupt enable register */ +typedef struct{ +__REG32 RDAIE : 1; +__REG32 THREIE : 1; +__REG32 RXLSIE : 1; +__REG32 RXMSIE : 1; +__REG32 : 3; +__REG32 CTSIE : 1; +__REG32 ABTOINTEN : 1; +__REG32 ABEOINTEN : 1; +__REG32 :22; +} __uartier1_bits; + +/* UART Transmit Enable Register */ +typedef struct{ +__REG8 : 7; +__REG8 TXEN : 1; +} __uartter_bits; + +/* UART line status register */ +typedef struct{ +__REG8 DR : 1; +__REG8 OE : 1; +__REG8 PE : 1; +__REG8 FE : 1; +__REG8 BI : 1; +__REG8 THRE : 1; +__REG8 TEMT : 1; +__REG8 RXFE : 1; +} __uartlsr_bits; + +/* UART line control register */ +typedef struct{ +__REG8 WLS : 2; +__REG8 SBS : 1; +__REG8 PE : 1; +__REG8 PS : 2; +__REG8 BC : 1; +__REG8 DLAB : 1; +} __uartlcr_bits; + +/* UART interrupt identification register and fifo control register */ +typedef union { + //UxIIR + struct { +__REG32 IP : 1; +__REG32 IID : 3; +__REG32 : 2; +__REG32 IIRFE : 2; +__REG32 ABEOINT: 1; +__REG32 ABTOINT: 1; +__REG32 :22; + }; + //UxFCR + struct { +__REG32 FCRFE : 1; +__REG32 RFR : 1; +__REG32 TFR : 1; +__REG32 : 3; +__REG32 RTLS : 2; +__REG32 :24; + }; +} __uartfcriir_bits; + +/* UART modem control register */ +typedef struct{ +__REG8 DTR : 1; +__REG8 RTS : 1; +__REG8 : 2; +__REG8 LMS : 1; +__REG8 : 1; +__REG8 RTSEN : 1; +__REG8 CTSEN : 1; +} __uartmcr_bits; + +/* UART modem status register */ +typedef union{ + //UxMSR + struct { +__REG8 DCTS : 1; +__REG8 DDSR : 1; +__REG8 TERI : 1; +__REG8 DDCD : 1; +__REG8 CTS : 1; +__REG8 DSR : 1; +__REG8 RI : 1; +__REG8 DCD : 1; + }; + //UxMSR + struct { +__REG8 MSR0 : 1; +__REG8 MSR1 : 1; +__REG8 MSR2 : 1; +__REG8 MSR3 : 1; +__REG8 MSR4 : 1; +__REG8 MSR5 : 1; +__REG8 MSR6 : 1; +__REG8 MSR7 : 1; + }; +} __uartmsr_bits; + +/* UART Auto-baud Control Register */ +typedef struct{ +__REG32 START : 1; +__REG32 MODE : 1; +__REG32 AUTORESTART : 1; +__REG32 : 5; +__REG32 ABEOINTCLR : 1; +__REG32 ABTOINTCLR : 1; +__REG32 :22; +} __uartacr_bits; + +/* IrDA Control Register for UART3 Only */ +typedef struct{ +__REG32 IRDAEN : 1; +__REG32 IRDAINV : 1; +__REG32 FIXPULSEEN : 1; +__REG32 PULSEDIV : 3; +__REG32 :26; +} __uarticr_bits; + +/* UART Fractional Divider Register */ +typedef struct{ +__REG32 DIVADDVAL : 4; +__REG32 MULVAL : 4; +__REG32 :24; +} __uartfdr_bits; + +/* SPI control register */ +typedef struct{ +__REG32 : 2; +__REG32 BITENABLE : 1; +__REG32 CPHA : 1; +__REG32 CPOL : 1; +__REG32 MSTR : 1; +__REG32 LSBF : 1; +__REG32 SPIE : 1; +__REG32 BITS : 4; +__REG32 :20; +} __spcr_bits; + +/* SPI status register */ +typedef struct{ +__REG32 : 3; +__REG32 ABRT : 1; +__REG32 MODF : 1; +__REG32 ROVR : 1; +__REG32 WCOL : 1; +__REG32 SPIF : 1; +__REG32 :24; +} __spsr_bits; + +/* SPI clock counter register */ +typedef struct{ +__REG32 COUNTER : 8; +__REG32 :24; +} __spccr_bits; + +/* SPI interrupt register */ +typedef struct{ +__REG32 SPIINT : 1; +__REG32 :31; +} __spint_bits; + +/* SPI Test control register */ +typedef struct{ +__REG8 : 1; +__REG8 TEST : 7; +} __sptcr_bits; + +/* SPI Test Status Register */ +typedef struct{ +__REG8 : 3; +__REG8 ABRT : 1; +__REG8 MODF : 1; +__REG8 ROVR : 1; +__REG8 WCOL : 1; +__REG8 SPIF : 1; +} __sptsr_bits; + +/* SSP Control Register 0 */ +typedef struct{ +__REG32 DSS : 4; +__REG32 FRF : 2; +__REG32 SPO : 1; +__REG32 SPH : 1; +__REG32 SCR : 8; +__REG32 :16; +} __sspcr0_bits; + +/* SSP Control Register 1 */ +typedef struct{ +__REG32 LBM : 1; +__REG32 SSE : 1; +__REG32 MS : 1; +__REG32 SOD : 1; +__REG32 :28; +} __sspcr1_bits; + +/* SSP Data Register */ +typedef struct{ +__REG32 DATA :16; +__REG32 :16; +} __sspdr_bits; + +/* SSP Status Register */ +typedef struct{ +__REG32 TFE : 1; +__REG32 TNF : 1; +__REG32 RNE : 1; +__REG32 RFF : 1; +__REG32 BSY : 1; +__REG32 :27; +} __sspsr_bits; + +/* SSP Clock Prescale Register */ +typedef struct{ +__REG32 CPSDVSR : 8; +__REG32 :24; +} __sspcpsr_bits; + +/* SSP Interrupt Mask Set/Clear Register */ +typedef struct{ +__REG32 RORIM : 1; +__REG32 RTIM : 1; +__REG32 RXIM : 1; +__REG32 TXIM : 1; +__REG32 :28; +} __sspimsc_bits; + +/* SSP Raw Interrupt Status Register */ +typedef struct{ +__REG32 RORRIS : 1; +__REG32 RTRIS : 1; +__REG32 RXRIS : 1; +__REG32 TXRIS : 1; +__REG32 :28; +} __sspris_bits; + +/* SSP Masked Interrupt Status Register */ +typedef struct{ +__REG32 RORMIS : 1; +__REG32 RTMIS : 1; +__REG32 RXMIS : 1; +__REG32 TXMIS : 1; +__REG32 :28; +} __sspmis_bits; + +/* SSP Interrupt Clear Register */ +typedef struct{ +__REG32 RORIC : 1; +__REG32 RTIC : 1; +__REG32 :30; +} __sspicr_bits; + +/* SSP DMA Control Register */ +typedef struct{ +__REG32 RXDMAE : 1; +__REG32 TXDMAE : 1; +__REG32 :30; +} __sspdmacr_bits; + +/* SD/MMC Power control register */ +typedef struct{ +__REG32 CTRL : 2; +__REG32 : 4; +__REG32 OPENDRAIN : 1; +__REG32 ROD : 1; +__REG32 :24; +} __mcipower_bits; + +/* SD/MMC Clock control register */ +typedef struct{ +__REG32 CLKDIV : 8; +__REG32 ENABLE : 1; +__REG32 PWRSAVE : 1; +__REG32 BYPASS : 1; +__REG32 WIDEBUS : 1; +__REG32 :20; +} __mciclock_bits; + +/* SD/MMC Command register */ +typedef struct{ +__REG32 CMDINDEX : 6; +__REG32 RESPONSE : 1; +__REG32 LONGRSP : 1; +__REG32 INTERRUPT : 1; +__REG32 PENDING : 1; +__REG32 ENABLE : 1; +__REG32 :21; +} __mcicommand_bits; + +/* SD/MMC Command response register */ +typedef struct{ +__REG32 RESPCMD : 6; +__REG32 :26; +} __mcirespcmd_bits; + +/* SD/MMC Data control register */ +typedef struct{ +__REG32 ENABLE : 1; +__REG32 DIRECTION : 1; +__REG32 MODE : 1; +__REG32 DMAENABLE : 1; +__REG32 BLOCKSIZE : 4; +__REG32 :24; +} __mcidatactrl_bits; + +/* SD/MMC Status register */ +typedef struct{ +__REG32 CMDCRCFAIL : 1; +__REG32 DATACRCFAIL : 1; +__REG32 CMDTIMEOUT : 1; +__REG32 DATATIMEOUT : 1; +__REG32 TXUNDERRUN : 1; +__REG32 RXOVERRUN : 1; +__REG32 CMDRESPEND : 1; +__REG32 CMDSENT : 1; +__REG32 DATAEND : 1; +__REG32 STARTBITERR : 1; +__REG32 DATABLOCKEND : 1; +__REG32 CMDACTIVE : 1; +__REG32 TXACTIVE : 1; +__REG32 RXACTIVE : 1; +__REG32 TXFIFOHALFEMPTY : 1; +__REG32 RXFIFOHALFFULL : 1; +__REG32 TXFIFOFULL : 1; +__REG32 RXFIFOFULL : 1; +__REG32 TXFIFOEMPTY : 1; +__REG32 RXFIFOEMPTY : 1; +__REG32 TXDATAAVLBL : 1; +__REG32 RXDATAAVLBL : 1; +__REG32 :10; +} __mcistatus_bits; + +/* SD/MMC Clear register */ +typedef struct{ +__REG32 CMDCRCFAILCLR : 1; +__REG32 DATACRCFAILCLR : 1; +__REG32 CMDTIMEOUTCLR : 1; +__REG32 DATATIMEOUTCLR : 1; +__REG32 TXUNDERRUNCLR : 1; +__REG32 RXOVERRUNCLR : 1; +__REG32 CMDRESPENDCLR : 1; +__REG32 CMDSENTCLR : 1; +__REG32 DATAENDCLR : 1; +__REG32 STARTBITERRCLR : 1; +__REG32 DATABLOCKENDCLR : 1; +__REG32 :21; +} __mciclear_bits; + +/* SD/MMC FIFO counter register */ +typedef struct{ +__REG32 DATACOUNT :15; +__REG32 :17; +} __mcififocnt_bits; + +/* I2C control set register */ +typedef struct{ +__REG32 : 2; +__REG32 AA : 1; +__REG32 SI : 1; +__REG32 STO : 1; +__REG32 STA : 1; +__REG32 I2EN : 1; +__REG32 :25; +} __i2conset_bits; + +/* I2C control clear register */ +typedef struct{ +__REG32 : 2; +__REG32 AAC : 1; +__REG32 SIC : 1; +__REG32 : 1; +__REG32 STAC : 1; +__REG32 I2ENC : 1; +__REG32 :25; +} __i2conclr_bits; + +/* I2C status register */ +typedef struct{ +__REG32 STATUS : 8; +__REG32 :24; +} __i2stat_bits; + +/* I2C data register */ +typedef struct{ +__REG32 DATA : 8; +__REG32 :24; +} __i2dat_bits; + +/* I2C slave address register */ +typedef struct{ +__REG32 GC : 1; +__REG32 ADDR : 7; +__REG32 :24; +} __i2adr_bits; + +/* I2C SCL High Duty Cycle register */ +typedef struct{ +__REG32 SCLH :16; +__REG32 :16; +} __i2sch_bits; + +/* I2C scl duty cycle register */ +typedef struct{ +__REG32 SCLL :16; +__REG32 :16; +} __i2scl_bits; + +/* I2S Digital Audio Output Registes */ +typedef struct{ +__REG32 WORS_WIDTH : 2; +__REG32 MONO : 1; +__REG32 STOP : 1; +__REG32 RESET : 1; +__REG32 WS_SEL : 1; +__REG32 WS_HALFPERIOD : 9; +__REG32 MUTE : 1; +__REG32 :16; +} __i2sdao_bits; + +/* I2S Digital Audio Input Register */ +typedef struct{ +__REG32 WORS_WIDTH : 2; +__REG32 MONO : 1; +__REG32 STOP : 1; +__REG32 RESET : 1; +__REG32 WS_SEL : 1; +__REG32 WS_HALFPERIOD : 9; +__REG32 :17; +} __i2sdai_bits; + +/* I2S Status Feedback Register */ +typedef struct{ +__REG32 IRQ : 1; +__REG32 DMAREQ1 : 1; +__REG32 DMAREQ2 : 1; +__REG32 : 5; +__REG32 RX_LEVEL : 8; +__REG32 TX_LEVEL : 8; +__REG32 : 8; +} __i2sstate_bits; + +/* I2S DMA Configuration Register */ +typedef struct{ +__REG32 RX_DMA_EN : 1; +__REG32 TX_DMA_EN : 1; +__REG32 : 6; +__REG32 RX_DEPTH_DMA : 8; +__REG32 TX_DEPTH_DMA : 8; +__REG32 : 8; +} __i2sdma_bits; + +/* I2S Interrupt Request Control register */ +typedef struct{ +__REG32 RX_IRQ_EN : 1; +__REG32 TX_IRQ_EN : 1; +__REG32 : 6; +__REG32 RX_DEPTH_IRQ : 8; +__REG32 TX_DEPTH_IRQ : 8; +__REG32 : 8; +} __i2sirq_bits; + +/* I2S Transmit Clock Rate Register */ +typedef struct{ +__REG32 TX_RATE :10; +__REG32 :22; +} __i2stxrate_bits; + +/* I2S Receive Clock Rate Register */ +typedef struct{ +__REG32 RX_RATE :10; +__REG32 :22; +} __i2srxrate_bits; + +/* TIMER interrupt register */ +typedef struct{ +__REG32 MR0INT : 1; +__REG32 MR1INT : 1; +__REG32 MR2INT : 1; +__REG32 MR3INT : 1; +__REG32 CR0INT : 1; +__REG32 CR1INT : 1; +__REG32 CR2INT : 1; +__REG32 CR3INT : 1; +__REG32 :24; +} __ir_bits; + +/* TIMER control register */ +typedef struct{ +__REG32 CE : 1; +__REG32 CR : 1; +__REG32 :30; +} __tcr_bits; + +/* TIMER count control register */ +typedef struct{ +__REG32 CTM : 2; //Counter/Timer Mode +__REG32 CIS : 2; //Count Input Select +__REG32 :28; +} __ctcr_bits; + +/* TIMER match control register */ +typedef struct{ +__REG32 MR0I : 1; +__REG32 MR0R : 1; +__REG32 MR0S : 1; +__REG32 MR1I : 1; +__REG32 MR1R : 1; +__REG32 MR1S : 1; +__REG32 MR2I : 1; +__REG32 MR2R : 1; +__REG32 MR2S : 1; +__REG32 MR3I : 1; +__REG32 MR3R : 1; +__REG32 MR3S : 1; +__REG32 :20; +} __mcr_bits; + +/* TIMER capture control register */ +typedef struct{ +__REG32 CAP0RE : 1; +__REG32 CAP0FE : 1; +__REG32 CAP0I : 1; +__REG32 CAP1RE : 1; +__REG32 CAP1FE : 1; +__REG32 CAP1I : 1; +__REG32 CAP2RE : 1; +__REG32 CAP2FE : 1; +__REG32 CAP2I : 1; +__REG32 CAP3RE : 1; +__REG32 CAP3FE : 1; +__REG32 CAP3I : 1; +__REG32 :20; +} __ccr_bits; + +/* TIMER external match register */ +typedef struct{ +__REG32 EM0 : 1; +__REG32 EM1 : 1; +__REG32 EM2 : 1; +__REG32 EM3 : 1; +__REG32 EMC0 : 2; +__REG32 EMC1 : 2; +__REG32 EMC2 : 2; +__REG32 EMC3 : 2; +__REG32 :20; +} __emr_bits; + +/* Watchdog mode register */ +typedef struct{ +__REG32 WDEN : 1; +__REG32 WDRESET : 1; +__REG32 WDTOF : 1; +__REG32 WDINT : 1; +__REG32 :28; +} __wdmod_bits; + +/* Watchdog feed register */ +typedef struct{ +__REG32 FEED : 8; +__REG32 :24; +} __wdfeed_bits; + +/* Watchdog feed register */ +typedef struct{ +__REG32 WDSEL : 2; +__REG32 :30; +} __wdclksel_bits; + +/* A/D Control Register */ +typedef struct{ +__REG32 SEL : 8; +__REG32 CLKDIV : 8; +__REG32 BURST : 1; +__REG32 CLKS : 3; +__REG32 : 1; +__REG32 PDN : 1; +__REG32 : 2; +__REG32 START : 3; +__REG32 EDGE : 1; +__REG32 : 4; +} __adcr_bits; + +/* A/D Global Data Register */ +typedef struct{ +__REG32 : 6; +__REG32 RESULT :10; +__REG32 : 8; +__REG32 CHN : 3; +__REG32 : 3; +__REG32 OVERUN : 1; +__REG32 DONE : 1; +} __adgdr_bits; + +/* A/D Status Register */ +typedef struct{ +__REG32 DONE0 : 1; +__REG32 DONE1 : 1; +__REG32 DONE2 : 1; +__REG32 DONE3 : 1; +__REG32 DONE4 : 1; +__REG32 DONE5 : 1; +__REG32 : 2; +__REG32 OVERRUN0 : 1; +__REG32 OVERRUN1 : 1; +__REG32 OVERRUN2 : 1; +__REG32 OVERRUN3 : 1; +__REG32 OVERRUN4 : 1; +__REG32 OVERRUN5 : 1; +__REG32 : 2; +__REG32 ADINT : 1; +__REG32 :15; +} __adstat_bits; + +/* A/D Intrrupt Enable Register */ +typedef struct{ +__REG32 ADINTEN0 : 1; +__REG32 ADINTEN1 : 1; +__REG32 ADINTEN2 : 1; +__REG32 ADINTEN3 : 1; +__REG32 ADINTEN4 : 1; +__REG32 ADINTEN5 : 1; +__REG32 : 2; +__REG32 ADGINTEN : 1; +__REG32 :23; +} __adinten_bits; + +/* A/D Data Register */ +typedef struct{ +__REG32 : 6; +__REG32 RESULT :10; +__REG32 :14; +__REG32 OVERUN : 1; +__REG32 DONE : 1; +} __addr_bits; + +/* D/A Converter Register */ +typedef struct{ +__REG32 : 6; +__REG32 VALUE :10; +__REG32 BIAS : 1; +__REG32 :15; +} __dacr_bits; + +/* PWM interrupt register */ +typedef struct{ +__REG32 PWMMR0I : 1; +__REG32 PWMMR1I : 1; +__REG32 PWMMR2I : 1; +__REG32 PWMMR3I : 1; +__REG32 : 4; +__REG32 PWMMR4I : 1; +__REG32 PWMMR5I : 1; +__REG32 PWMMR6I : 1; +__REG32 :21; +} __pwmir_bits; + +/* PWM1 timer control register */ +typedef struct{ +__REG32 CE : 1; +__REG32 CR : 1; +__REG32 : 1; +__REG32 PWMEN : 1; +__REG32 :28; +} __pwmtcr1_bits; + +/* PWM Count Control Register */ +typedef struct{ +__REG32 CM : 2; +__REG32 CIS : 2; +__REG32 :28; +} __pwmctcr_bits; + +/* PWM match control register */ +typedef struct{ +__REG32 PWMMR0I : 1; +__REG32 PWMMR0R : 1; +__REG32 PWMMR0S : 1; +__REG32 PWMMR1I : 1; +__REG32 PWMMR1R : 1; +__REG32 PWMMR1S : 1; +__REG32 PWMMR2I : 1; +__REG32 PWMMR2R : 1; +__REG32 PWMMR2S : 1; +__REG32 PWMMR3I : 1; +__REG32 PWMMR3R : 1; +__REG32 PWMMR3S : 1; +__REG32 PWMMR4I : 1; +__REG32 PWMMR4R : 1; +__REG32 PWMMR4S : 1; +__REG32 PWMMR5I : 1; +__REG32 PWMMR5R : 1; +__REG32 PWMMR5S : 1; +__REG32 PWMMR6I : 1; +__REG32 PWMMR6R : 1; +__REG32 PWMMR6S : 1; +__REG32 :11; +} __pwmmcr_bits; + +/* PWM Capture Control Register */ +typedef struct{ +__REG32 CAP0RE : 1; +__REG32 CAP0FE : 1; +__REG32 CAP0INT : 1; +__REG32 CAP1RE : 1; +__REG32 CAP1FE : 1; +__REG32 CAP1INT : 1; +__REG32 CAP2RE : 1; +__REG32 CAP2FE : 1; +__REG32 CAP2INT : 1; +__REG32 CAP3RE : 1; +__REG32 CAP3FE : 1; +__REG32 CAP3INT : 1; +__REG32 :20; +} __pwmccr_bits; + +/* PWM control register */ +typedef struct{ +__REG32 : 2; +__REG32 PWMSEL2 : 1; +__REG32 PWMSEL3 : 1; +__REG32 PWMSEL4 : 1; +__REG32 PWMSEL5 : 1; +__REG32 PWMSEL6 : 1; +__REG32 : 2; +__REG32 PWMENA1 : 1; +__REG32 PWMENA2 : 1; +__REG32 PWMENA3 : 1; +__REG32 PWMENA4 : 1; +__REG32 PWMENA5 : 1; +__REG32 PWMENA6 : 1; +__REG32 :17; +} __pwmpcr_bits; + +/* PWM latch enable register */ +typedef struct{ +__REG32 EM0L : 1; +__REG32 EM1L : 1; +__REG32 EM2L : 1; +__REG32 EM3L : 1; +__REG32 EM4L : 1; +__REG32 EM5L : 1; +__REG32 EM6L : 1; +__REG32 :25; +} __pwmler_bits; + +/* RTC interrupt location register */ +typedef struct{ +__REG32 RTCCIF : 1; +__REG32 RTCALF : 1; +__REG32 RTSSF : 1; +__REG32 :29; +} __ilr_bits; + +/* RTC clock tick counter register */ +typedef struct{ +__REG32 COUNTER :15; +__REG32 :17; +} __ctc_bits; + +/* RTC clock control register */ +typedef struct{ +__REG32 CLKEN : 1; +__REG32 CTCRST : 1; +__REG32 CTTEST : 2; +__REG32 CLKSRC : 1; +__REG32 :27; +} __rtcccr_bits; + +/* RTC counter increment interrupt register */ +typedef struct{ +__REG32 IMSEC : 1; +__REG32 IMMIN : 1; +__REG32 IMHOUR : 1; +__REG32 IMDOM : 1; +__REG32 IMDOW : 1; +__REG32 IMDOY : 1; +__REG32 IMMON : 1; +__REG32 IMYEAR : 1; +__REG32 :24; +} __ciir_bits; + +/* RTC Counter Increment Select Mask Register */ +typedef struct{ +__REG32 SUBSECSEL : 3; +__REG32 : 4; +__REG32 SUBSECENA : 1; +__REG32 :24; +} __ciss_bits; + +/* RTC alarm mask register */ +typedef struct{ +__REG32 AMRSEC : 1; +__REG32 AMRMIN : 1; +__REG32 AMRHOUR : 1; +__REG32 AMRDOM : 1; +__REG32 AMRDOW : 1; +__REG32 AMRDOY : 1; +__REG32 AMRMON : 1; +__REG32 AMRYEAR : 1; +__REG32 :24; +} __amr_bits; + +/* RTC consolidated time register 0 */ +typedef struct{ +__REG32 SEC : 6; +__REG32 : 2; +__REG32 MIN : 6; +__REG32 : 2; +__REG32 HOUR : 5; +__REG32 : 3; +__REG32 DOW : 3; +__REG32 : 5; +} __ctime0_bits; + +/* RTC consolidated time register 1 */ +typedef struct{ +__REG32 DOM : 5; +__REG32 : 3; +__REG32 MON : 4; +__REG32 : 4; +__REG32 YEAR :12; +__REG32 : 4; +} __ctime1_bits; + +/* RTC consolidated time register 2 */ +typedef struct{ +__REG32 DOY :12; +__REG32 :20; +} __ctime2_bits; + +/* RTC second register */ +typedef struct{ +__REG32 SEC : 6; +__REG32 :26; +} __sec_bits; + +/* RTC minute register */ +typedef struct{ +__REG32 MIN : 6; +__REG32 :26; +} __min_bits; + +/* RTC hour register */ +typedef struct{ +__REG32 HOUR : 5; +__REG32 :27; +} __hour_bits; + +/* RTC day of month register */ +typedef struct{ +__REG32 DOM : 5; +__REG32 :27; +} __dom_bits; + +/* RTC day of week register */ +typedef struct{ +__REG32 DOW : 3; +__REG32 :29; +} __dow_bits; + +/* RTC day of year register */ +typedef struct{ +__REG32 DOY : 9; +__REG32 :23; +} __doy_bits; + +/* RTC month register */ +typedef struct{ +__REG32 MON : 4; +__REG32 :28; +} __month_bits; + +/* RTC year register */ +typedef struct{ +__REG32 YEAR :12; +__REG32 :20; +} __year_bits; + +/* RTC prescaler value, integer portion register */ +typedef struct{ +__REG32 VALUE :13; +__REG32 :19; +} __preint_bits; + +/* RTC prescaler value, fractional portion register */ +typedef struct{ +__REG32 VALUE :15; +__REG32 :17; +} __prefrac_bits; + +/* DMA Interrupt Status Register */ +typedef struct{ +__REG32 INTSTATUS0 : 1; +__REG32 INTSTATUS1 : 1; +__REG32 :30; +} __dmacintstatus_bits; + +/* DMA Interrupt Terminal Count Request Status Register */ +typedef struct{ +__REG32 INTTCSTATUS0 : 1; +__REG32 INTTCSTATUS1 : 1; +__REG32 :30; +} __dmacinttcstatus_bits; + +/* DMA Interrupt Terminal Count Request Clear Register */ +typedef struct{ +__REG32 INTTCCLEAR0 : 1; +__REG32 INTTCCLEAR1 : 1; +__REG32 :30; +} __dmacinttcclear_bits; + +/* DMA Interrupt Error Status Register */ +typedef struct{ +__REG32 INTERRORSTATUS0 : 1; +__REG32 INTERRORSTATUS1 : 1; +__REG32 :30; +} __dmacinterrstat_bits; + +/* DMA Interrupt Error Clear Register */ +typedef struct{ +__REG32 INTERRCLR0 : 1; +__REG32 INTERRCLR1 : 1; +__REG32 :30; +} __dmacinterrclr_bits; + +/* DMA Raw Interrupt Terminal Count Status Register */ +typedef struct{ +__REG32 RAWINTTCSTATUS0 : 1; +__REG32 RAWINTTCSTATUS1 : 1; +__REG32 :30; +} __dmacrawinttcstatus_bits; + +/* DMA Raw Error Interrupt Status Register */ +typedef struct{ +__REG32 RAWINTERRORSTATUS0 : 1; +__REG32 RAWINTERRORSTATUS1 : 1; +__REG32 :30; +} __dmacrawinterrorstatus_bits; + +/* DMA Enabled Channel Register */ +typedef struct{ +__REG32 ENABLEDCHANNELS0 : 1; +__REG32 ENABLEDCHANNELS1 : 1; +__REG32 :30; +} __dmacenbldchns_bits; + +/* DMA Software Burst Request Register */ +typedef struct{ +__REG32 SOFTBREQSSP0TX : 1; +__REG32 SOFTBREQSSP0RX : 1; +__REG32 SOFTBREQSSP1TX : 1; +__REG32 SOFTBREQSSP1RX : 1; +__REG32 SOFTBREQSDMMC : 1; +__REG32 :27; +} __dmacsoftbreq_bits; + +/* DMA Software Single Request Register */ +typedef struct{ +__REG32 SOFTREQSSP0TX : 1; +__REG32 SOFTREQSSP0RX : 1; +__REG32 SOFTREQSSP1TX : 1; +__REG32 SOFTREQSSP1RX : 1; +__REG32 SOFTREQSDMMC : 1; +__REG32 SOFTSREQI2S0 : 1; +__REG32 SOFTSREQI2S1 : 1; +__REG32 :25; +} __dmacsoftsreq_bits; + +/* DMA Software Last Burst Request Register */ +typedef struct{ +__REG32 : 4; +__REG32 SOFTLBREQSDMMC : 1; +__REG32 :27; +} __dmacsoftlbreq_bits; + +/* DMA Software Last Single Request Register */ +typedef struct{ +__REG32 : 4; +__REG32 SOFTLSREQSDMMC : 1; +__REG32 :27; +} __dmacsoftlsreq_bits; + +/* DMA Synchronization Register */ +typedef struct{ +__REG32 DMACSYNC :16; +__REG32 :16; +} __dmacsync_bits; + +/* DMA Configuration Register */ +typedef struct{ +__REG32 E : 1; +__REG32 M : 1; +__REG32 :30; +} __dmacconfig_bits; + +/* DMA Software Burst Request Register */ +typedef struct{ +__REG32 : 2; +__REG32 LLI :30; +} __dma_lli_bits; + +/* DMA Channel Control Registers */ +typedef struct{ +__REG32 TRANSFERSIZE :12; +__REG32 SBSIZE : 3; +__REG32 DBSIZE : 3; +__REG32 SWIDTH : 3; +__REG32 DWIDTH : 3; +__REG32 : 2; +__REG32 SI : 1; +__REG32 DI : 1; +__REG32 PROT1 : 1; +__REG32 PROT2 : 1; +__REG32 PROT3 : 1; +__REG32 I : 1; +} __dma_ctrl_bits; + +/* DMA Channel Configuration Registers */ +typedef struct{ +__REG32 E : 1; +__REG32 SRCPERIPHERAL : 4; +__REG32 : 1; +__REG32 DESTPERIPHERAL : 4; +__REG32 : 1; +__REG32 FLOWCNTRL : 3; +__REG32 IE : 1; +__REG32 ITC : 1; +__REG32 L : 1; +__REG32 A : 1; +__REG32 H : 1; +__REG32 :13; +} __dma_cfg_bits; + +#endif /* __IAR_SYSTEMS_ICC__ */ + +/* Declarations common to compiler and assembler **************************/ + +/*************************************************************************** + ** + ** System control block + ** + ***************************************************************************/ +__IO_REG32_BIT(MEMMAP, 0xE01FC040,__READ_WRITE ,__memmap_bits); +__IO_REG32_BIT(RSIR, 0xE01FC180,__READ_WRITE ,__rsir_bits); +#define RSID RSIR +#define RSID_bit RSIR_bit +__IO_REG32_BIT(EXTINT, 0xE01FC140,__READ_WRITE ,__extint_bits); +__IO_REG32_BIT(EXTMODE, 0xE01FC148,__READ_WRITE ,__extmode_bits); +__IO_REG32_BIT(EXTPOLAR, 0xE01FC14C,__READ_WRITE ,__extpolar_bits); +__IO_REG32_BIT(SCS, 0xE01FC1A0,__READ_WRITE ,__scs_bits); +__IO_REG32( CSPR, 0xE01FC184,__WRITE); +__IO_REG32_BIT(PLLCON, 0xE01FC080,__READ_WRITE ,__pllcon_bits); +__IO_REG32_BIT(PLLCFG, 0xE01FC084,__READ_WRITE ,__pllcfg_bits); +__IO_REG32_BIT(PLLSTAT, 0xE01FC088,__READ ,__pllstat_bits); +__IO_REG32_BIT(PLLFEED, 0xE01FC08C,__WRITE ,__pllfeed_bits); +__IO_REG32_BIT(CCLKCFG, 0xE01FC104,__READ_WRITE ,__cclkcfg_bits); +__IO_REG32_BIT(USBCLKCFG, 0xE01FC108,__READ_WRITE ,__usbclkcfg_bits); +__IO_REG32_BIT(CLKSRCSEL, 0xE01FC10C,__READ_WRITE ,__clksrcsel_bits); +__IO_REG32_BIT(IRCTRIM, 0xE01FC1A4,__READ_WRITE ,__irctrim_bits); +__IO_REG32_BIT(PCLKSEL0, 0xE01FC1A8,__READ_WRITE ,__pclksel0_bits); +__IO_REG32_BIT(PCLKSEL1, 0xE01FC1AC,__READ_WRITE ,__pclksel1_bits); +__IO_REG32_BIT(PCON, 0xE01FC0C0,__READ_WRITE ,__pcon_bits); +__IO_REG32_BIT(PCONP, 0xE01FC0C4,__READ_WRITE ,__pconp_bits); +__IO_REG32_BIT(INTWAKE, 0xE01FC144,__READ_WRITE ,__intwake_bits); + +/*************************************************************************** + ** + ** AHB + ** + ***************************************************************************/ +__IO_REG32_BIT(AHBCFG1, 0xE01FC188,__READ_WRITE ,__ahbcfg1_bits); +__IO_REG32_BIT(AHBCFG2, 0xE01FC18C,__READ_WRITE ,__ahbcfg2_bits); + +/*************************************************************************** + ** + ** MAM + ** + ***************************************************************************/ +__IO_REG32_BIT(MAMCR, 0xE01FC000,__READ_WRITE ,__mamcr_bits); +__IO_REG32_BIT(MAMTIM, 0xE01FC004,__READ_WRITE ,__mamtim_bits); + +/*************************************************************************** + ** + ** VIC + ** + ***************************************************************************/ +__IO_REG32_BIT(VICIRQSTATUS, 0xFFFFF000,__READ ,__vicint_bits); +__IO_REG32_BIT(VICFIQSTATUS, 0xFFFFF004,__READ ,__vicint_bits); +__IO_REG32_BIT(VICRAWINTR, 0xFFFFF008,__READ ,__vicint_bits); +__IO_REG32_BIT(VICINTSELECT, 0xFFFFF00C,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICINTENABLE, 0xFFFFF010,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICINTENCLEAR, 0xFFFFF014,__WRITE ,__vicint_bits); +__IO_REG32_BIT(VICSOFTINT, 0xFFFFF018,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICSOFTINTCLEAR, 0xFFFFF01C,__WRITE ,__vicint_bits); +__IO_REG32_BIT(VICPROTECTION, 0xFFFFF020,__READ_WRITE ,__vicprotection_bits); +__IO_REG32_BIT(VICSWPRIORITYMASK, 0xFFFFF024,__READ_WRITE ,__vicswprmask_bits); +__IO_REG32( VICVECTADDR0, 0xFFFFF100,__READ_WRITE); +__IO_REG32( VICVECTADDR1, 0xFFFFF104,__READ_WRITE); +__IO_REG32( VICVECTADDR2, 0xFFFFF108,__READ_WRITE); +__IO_REG32( VICVECTADDR3, 0xFFFFF10C,__READ_WRITE); +__IO_REG32( VICVECTADDR4, 0xFFFFF110,__READ_WRITE); +__IO_REG32( VICVECTADDR5, 0xFFFFF114,__READ_WRITE); +__IO_REG32( VICVECTADDR6, 0xFFFFF118,__READ_WRITE); +__IO_REG32( VICVECTADDR7, 0xFFFFF11C,__READ_WRITE); +__IO_REG32( VICVECTADDR8, 0xFFFFF120,__READ_WRITE); +__IO_REG32( VICVECTADDR9, 0xFFFFF124,__READ_WRITE); +__IO_REG32( VICVECTADDR10, 0xFFFFF128,__READ_WRITE); +__IO_REG32( VICVECTADDR11, 0xFFFFF12C,__READ_WRITE); +__IO_REG32( VICVECTADDR12, 0xFFFFF130,__READ_WRITE); +__IO_REG32( VICVECTADDR13, 0xFFFFF134,__READ_WRITE); +__IO_REG32( VICVECTADDR14, 0xFFFFF138,__READ_WRITE); +__IO_REG32( VICVECTADDR15, 0xFFFFF13C,__READ_WRITE); +__IO_REG32( VICVECTADDR16, 0xFFFFF140,__READ_WRITE); +__IO_REG32( VICVECTADDR17, 0xFFFFF144,__READ_WRITE); +__IO_REG32( VICVECTADDR18, 0xFFFFF148,__READ_WRITE); +__IO_REG32( VICVECTADDR19, 0xFFFFF14C,__READ_WRITE); +__IO_REG32( VICVECTADDR20, 0xFFFFF150,__READ_WRITE); +__IO_REG32( VICVECTADDR21, 0xFFFFF154,__READ_WRITE); +__IO_REG32( VICVECTADDR22, 0xFFFFF158,__READ_WRITE); +__IO_REG32( VICVECTADDR23, 0xFFFFF15C,__READ_WRITE); +__IO_REG32( VICVECTADDR24, 0xFFFFF160,__READ_WRITE); +__IO_REG32( VICVECTADDR25, 0xFFFFF164,__READ_WRITE); +__IO_REG32( VICVECTADDR26, 0xFFFFF168,__READ_WRITE); +__IO_REG32( VICVECTADDR27, 0xFFFFF16C,__READ_WRITE); +__IO_REG32( VICVECTADDR28, 0xFFFFF170,__READ_WRITE); +__IO_REG32( VICVECTADDR29, 0xFFFFF174,__READ_WRITE); +__IO_REG32( VICVECTADDR30, 0xFFFFF178,__READ_WRITE); +__IO_REG32( VICVECTADDR31, 0xFFFFF17C,__READ_WRITE); +__IO_REG32_BIT(VICVECTPRIORITY0, 0xFFFFF200,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY1, 0xFFFFF204,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY2, 0xFFFFF208,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY3, 0xFFFFF20C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY4, 0xFFFFF210,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY5, 0xFFFFF214,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY6, 0xFFFFF218,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY7, 0xFFFFF21C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY8, 0xFFFFF220,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY9, 0xFFFFF224,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY10, 0xFFFFF228,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY11, 0xFFFFF22C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY12, 0xFFFFF230,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY13, 0xFFFFF234,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY14, 0xFFFFF238,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY15, 0xFFFFF23C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY16, 0xFFFFF240,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY17, 0xFFFFF244,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY18, 0xFFFFF248,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY19, 0xFFFFF24C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY20, 0xFFFFF250,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY21, 0xFFFFF254,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY22, 0xFFFFF258,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY23, 0xFFFFF25C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY24, 0xFFFFF260,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY25, 0xFFFFF264,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY26, 0xFFFFF268,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY27, 0xFFFFF26C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY28, 0xFFFFF270,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY29, 0xFFFFF274,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY30, 0xFFFFF278,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY31, 0xFFFFF27C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32( VICADDRESS, 0xFFFFFF00,__READ_WRITE); + +/*************************************************************************** + ** + ** Pin connect block + ** + ***************************************************************************/ +__IO_REG32_BIT(PINSEL0, 0xE002C000,__READ_WRITE ,__pinsel0_bits); +__IO_REG32_BIT(PINSEL1, 0xE002C004,__READ_WRITE ,__pinsel1_bits); +__IO_REG32_BIT(PINSEL2, 0xE002C008,__READ_WRITE ,__pinsel2_bits); +__IO_REG32_BIT(PINSEL3, 0xE002C00C,__READ_WRITE ,__pinsel3_bits); +__IO_REG32_BIT(PINSEL4, 0xE002C010,__READ_WRITE ,__pinsel4_bits); +__IO_REG32_BIT(PINSEL5, 0xE002C014,__READ_WRITE ,__pinsel5_bits); +__IO_REG32_BIT(PINSEL6, 0xE002C018,__READ_WRITE ,__pinsel6_bits); +__IO_REG32_BIT(PINSEL7, 0xE002C01C,__READ_WRITE ,__pinsel7_bits); +__IO_REG32_BIT(PINSEL8, 0xE002C020,__READ_WRITE ,__pinsel8_bits); +__IO_REG32_BIT(PINSEL9, 0xE002C024,__READ_WRITE ,__pinsel9_bits); +__IO_REG32_BIT(PINSEL10, 0xE002C028,__READ_WRITE ,__pinsel10_bits); +__IO_REG32_BIT(PINMODE0, 0xE002C040,__READ_WRITE ,__pinsel0_bits); +__IO_REG32_BIT(PINMODE1, 0xE002C044,__READ_WRITE ,__pinsel1_bits); +__IO_REG32_BIT(PINMODE2, 0xE002C048,__READ_WRITE ,__pinsel2_bits); +__IO_REG32_BIT(PINMODE3, 0xE002C04C,__READ_WRITE ,__pinsel3_bits); +__IO_REG32_BIT(PINMODE4, 0xE002C050,__READ_WRITE ,__pinsel4_bits); +__IO_REG32_BIT(PINMODE5, 0xE002C054,__READ_WRITE ,__pinsel5_bits); +__IO_REG32_BIT(PINMODE6, 0xE002C058,__READ_WRITE ,__pinsel6_bits); +__IO_REG32_BIT(PINMODE7, 0xE002C05C,__READ_WRITE ,__pinsel7_bits); +__IO_REG32_BIT(PINMODE8, 0xE002C060,__READ_WRITE ,__pinsel8_bits); +__IO_REG32_BIT(PINMODE9, 0xE002C064,__READ_WRITE ,__pinsel9_bits); + +/*************************************************************************** + ** + ** GPIO + ** + ***************************************************************************/ +__IO_REG32_BIT(IO0PIN, 0xE0028000,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0SET, 0xE0028004,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0DIR, 0xE0028008,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0CLR, 0xE002800C,__WRITE ,__gpio0_bits); +__IO_REG32_BIT(FIO0DIR, 0x3FFFC000,__READ_WRITE,__fgpio0_bits); +#define FIO0DIR0 FIO0DIR_bit.__byte0 +#define FIO0DIR0_bit FIO0DIR_bit.__byte0_bit +#define FIO0DIR1 FIO0DIR_bit.__byte1 +#define FIO0DIR1_bit FIO0DIR_bit.__byte1_bit +#define FIO0DIR2 FIO0DIR_bit.__byte2 +#define FIO0DIR2_bit FIO0DIR_bit.__byte2_bit +#define FIO0DIR3 FIO0DIR_bit.__byte3 +#define FIO0DIR3_bit FIO0DIR_bit.__byte3_bit +#define FIO0DIRL FIO0DIR_bit.__shortl +#define FIO0DIRL_bit FIO0DIR_bit.__shortl_bit +#define FIO0DIRU FIO0DIR_bit.__shortu +#define FIO0DIRU_bit FIO0DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO0MASK, 0x3FFFC010,__READ_WRITE,__fgpio0_bits); +#define FIO0MASK0 FIO0MASK_bit.__byte0 +#define FIO0MASK0_bit FIO0MASK_bit.__byte0_bit +#define FIO0MASK1 FIO0MASK_bit.__byte1 +#define FIO0MASK1_bit FIO0MASK_bit.__byte1_bit +#define FIO0MASK2 FIO0MASK_bit.__byte2 +#define FIO0MASK2_bit FIO0MASK_bit.__byte2_bit +#define FIO0MASK3 FIO0MASK_bit.__byte3 +#define FIO0MASK3_bit FIO0MASK_bit.__byte3_bit +#define FIO0MASKL FIO0MASK_bit.__shortl +#define FIO0MASKL_bit FIO0MASK_bit.__shortl_bit +#define FIO0MASKU FIO0MASK_bit.__shortu +#define FIO0MASKU_bit FIO0MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO0PIN, 0x3FFFC014,__READ_WRITE,__fgpio0_bits); +#define FIO0PIN0 FIO0PIN_bit.__byte0 +#define FIO0PIN0_bit FIO0PIN_bit.__byte0_bit +#define FIO0PIN1 FIO0PIN_bit.__byte1 +#define FIO0PIN1_bit FIO0PIN_bit.__byte1_bit +#define FIO0PIN2 FIO0PIN_bit.__byte2 +#define FIO0PIN2_bit FIO0PIN_bit.__byte2_bit +#define FIO0PIN3 FIO0PIN_bit.__byte3 +#define FIO0PIN3_bit FIO0PIN_bit.__byte3_bit +#define FIO0PINL FIO0PIN_bit.__shortl +#define FIO0PINL_bit FIO0PIN_bit.__shortl_bit +#define FIO0PINU FIO0PIN_bit.__shortu +#define FIO0PINU_bit FIO0PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO0SET, 0x3FFFC018,__READ_WRITE,__fgpio0_bits); +#define FIO0SET0 FIO0SET_bit.__byte0 +#define FIO0SET0_bit FIO0SET_bit.__byte0_bit +#define FIO0SET1 FIO0SET_bit.__byte1 +#define FIO0SET1_bit FIO0SET_bit.__byte1_bit +#define FIO0SET2 FIO0SET_bit.__byte2 +#define FIO0SET2_bit FIO0SET_bit.__byte2_bit +#define FIO0SET3 FIO0SET_bit.__byte3 +#define FIO0SET3_bit FIO0SET_bit.__byte3_bit +#define FIO0SETL FIO0SET_bit.__shortl +#define FIO0SETL_bit FIO0SET_bit.__shortl_bit +#define FIO0SETU FIO0SET_bit.__shortu +#define FIO0SETU_bit FIO0SET_bit.__shortu_bit +__IO_REG32_BIT(FIO0CLR, 0x3FFFC01C,__WRITE ,__fgpio0_bits); +#define FIO0CLR0 FIO0CLR_bit.__byte0 +#define FIO0CLR0_bit FIO0CLR_bit.__byte0_bit +#define FIO0CLR1 FIO0CLR_bit.__byte1 +#define FIO0CLR1_bit FIO0CLR_bit.__byte1_bit +#define FIO0CLR2 FIO0CLR_bit.__byte2 +#define FIO0CLR2_bit FIO0CLR_bit.__byte2_bit +#define FIO0CLR3 FIO0CLR_bit.__byte3 +#define FIO0CLR3_bit FIO0CLR_bit.__byte3_bit +#define FIO0CLRL FIO0CLR_bit.__shortl +#define FIO0CLRL_bit FIO0CLR_bit.__shortl_bit +#define FIO0CLRU FIO0CLR_bit.__shortu +#define FIO0CLRU_bit FIO0CLR_bit.__shortu_bit +__IO_REG32_BIT(IO1PIN, 0xE0028010,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1SET, 0xE0028014,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1DIR, 0xE0028018,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1CLR, 0xE002801C,__WRITE ,__gpio1_bits); +__IO_REG32_BIT(FIO1DIR, 0x3FFFC020,__READ_WRITE,__fgpio1_bits); +#define FIO1DIR0 FIO1DIR_bit.__byte0 +#define FIO1DIR0_bit FIO1DIR_bit.__byte0_bit +#define FIO1DIR1 FIO1DIR_bit.__byte1 +#define FIO1DIR1_bit FIO1DIR_bit.__byte1_bit +#define FIO1DIR2 FIO1DIR_bit.__byte2 +#define FIO1DIR2_bit FIO1DIR_bit.__byte2_bit +#define FIO1DIR3 FIO1DIR_bit.__byte3 +#define FIO1DIR3_bit FIO1DIR_bit.__byte3_bit +#define FIO1DIRL FIO1DIR_bit.__shortl +#define FIO1DIRL_bit FIO1DIR_bit.__shortl_bit +#define FIO1DIRU FIO1DIR_bit.__shortu +#define FIO1DIRU_bit FIO1DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO1MASK, 0x3FFFC030,__READ_WRITE,__fgpio1_bits); +#define FIO1MASK0 FIO1MASK_bit.__byte0 +#define FIO1MASK0_bit FIO1MASK_bit.__byte0_bit +#define FIO1MASK1 FIO1MASK_bit.__byte1 +#define FIO1MASK1_bit FIO1MASK_bit.__byte1_bit +#define FIO1MASK2 FIO1MASK_bit.__byte2 +#define FIO1MASK2_bit FIO1MASK_bit.__byte2_bit +#define FIO1MASK3 FIO1MASK_bit.__byte3 +#define FIO1MASK3_bit FIO1MASK_bit.__byte3_bit +#define FIO1MASKL FIO1MASK_bit.__shortl +#define FIO1MASKL_bit FIO1MASK_bit.__shortl_bit +#define FIO1MASKU FIO1MASK_bit.__shortu +#define FIO1MASKU_bit FIO1MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO1PIN, 0x3FFFC034,__READ_WRITE,__fgpio1_bits); +#define FIO1PIN0 FIO1PIN_bit.__byte0 +#define FIO1PIN0_bit FIO1PIN_bit.__byte0_bit +#define FIO1PIN1 FIO1PIN_bit.__byte1 +#define FIO1PIN1_bit FIO1PIN_bit.__byte1_bit +#define FIO1PIN2 FIO1PIN_bit.__byte2 +#define FIO1PIN2_bit FIO1PIN_bit.__byte2_bit +#define FIO1PIN3 FIO1PIN_bit.__byte3 +#define FIO1PIN3_bit FIO1PIN_bit.__byte3_bit +#define FIO1PINL FIO1PIN_bit.__shortl +#define FIO1PINL_bit FIO1PIN_bit.__shortl_bit +#define FIO1PINU FIO1PIN_bit.__shortu +#define FIO1PINU_bit FIO1PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO1SET, 0x3FFFC038,__READ_WRITE,__fgpio1_bits); +#define FIO1SET0 FIO1SET_bit.__byte0 +#define FIO1SET0_bit FIO1SET_bit.__byte0_bit +#define FIO1SET1 FIO1SET_bit.__byte1 +#define FIO1SET1_bit FIO1SET_bit.__byte1_bit +#define FIO1SET2 FIO1SET_bit.__byte2 +#define FIO1SET2_bit FIO1SET_bit.__byte2_bit +#define FIO1SET3 FIO1SET_bit.__byte3 +#define FIO1SET3_bit FIO1SET_bit.__byte3_bit +#define FIO1SETL FIO1SET_bit.__shortl +#define FIO1SETL_bit FIO1SET_bit.__shortl_bit +#define FIO1SETU FIO1SET_bit.__shortu +#define FIO1SETU_bit FIO1SET_bit.__shortu_bit +__IO_REG32_BIT(FIO1CLR, 0x3FFFC03C,__WRITE ,__fgpio1_bits); +#define FIO1CLR0 FIO1CLR_bit.__byte0 +#define FIO1CLR0_bit FIO1CLR_bit.__byte0_bit +#define FIO1CLR1 FIO1CLR_bit.__byte1 +#define FIO1CLR1_bit FIO1CLR_bit.__byte1_bit +#define FIO1CLR2 FIO1CLR_bit.__byte2 +#define FIO1CLR2_bit FIO1CLR_bit.__byte2_bit +#define FIO1CLR3 FIO1CLR_bit.__byte3 +#define FIO1CLR3_bit FIO1CLR_bit.__byte3_bit +#define FIO1CLRL FIO1CLR_bit.__shortl +#define FIO1CLRL_bit FIO1CLR_bit.__shortl_bit +#define FIO1CLRU FIO1CLR_bit.__shortu +#define FIO1CLRU_bit FIO1CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO2DIR, 0x3FFFC040,__READ_WRITE,__fgpio2_bits); +#define FIO2DIR0 FIO2DIR_bit.__byte0 +#define FIO2DIR0_bit FIO2DIR_bit.__byte0_bit +#define FIO2DIR1 FIO2DIR_bit.__byte1 +#define FIO2DIR1_bit FIO2DIR_bit.__byte1_bit +#define FIO2DIR2 FIO2DIR_bit.__byte2 +#define FIO2DIR2_bit FIO2DIR_bit.__byte2_bit +#define FIO2DIR3 FIO2DIR_bit.__byte3 +#define FIO2DIR3_bit FIO2DIR_bit.__byte3_bit +#define FIO2DIRL FIO2DIR_bit.__shortl +#define FIO2DIRL_bit FIO2DIR_bit.__shortl_bit +#define FIO2DIRU FIO2DIR_bit.__shortu +#define FIO2DIRU_bit FIO2DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO2MASK, 0x3FFFC050,__READ_WRITE,__fgpio2_bits); +#define FIO2MASK0 FIO2MASK_bit.__byte0 +#define FIO2MASK0_bit FIO2MASK_bit.__byte0_bit +#define FIO2MASK1 FIO2MASK_bit.__byte1 +#define FIO2MASK1_bit FIO2MASK_bit.__byte1_bit +#define FIO2MASK2 FIO2MASK_bit.__byte2 +#define FIO2MASK2_bit FIO2MASK_bit.__byte2_bit +#define FIO2MASK3 FIO2MASK_bit.__byte3 +#define FIO2MASK3_bit FIO2MASK_bit.__byte3_bit +#define FIO2MASKL FIO2MASK_bit.__shortl +#define FIO2MASKL_bit FIO2MASK_bit.__shortl_bit +#define FIO2MASKU FIO2MASK_bit.__shortu +#define FIO2MASKU_bit FIO2MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO2PIN, 0x3FFFC054,__READ_WRITE,__fgpio2_bits); +#define FIO2PIN0 FIO2PIN_bit.__byte0 +#define FIO2PIN0_bit FIO2PIN_bit.__byte0_bit +#define FIO2PIN1 FIO2PIN_bit.__byte1 +#define FIO2PIN1_bit FIO2PIN_bit.__byte1_bit +#define FIO2PIN2 FIO2PIN_bit.__byte2 +#define FIO2PIN2_bit FIO2PIN_bit.__byte2_bit +#define FIO2PIN3 FIO2PIN_bit.__byte3 +#define FIO2PIN3_bit FIO2PIN_bit.__byte3_bit +#define FIO2PINL FIO2PIN_bit.__shortl +#define FIO2PINL_bit FIO2PIN_bit.__shortl_bit +#define FIO2PINU FIO2PIN_bit.__shortu +#define FIO2PINU_bit FIO2PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO2SET, 0x3FFFC058,__READ_WRITE,__fgpio2_bits); +#define FIO2SET0 FIO2SET_bit.__byte0 +#define FIO2SET0_bit FIO2SET_bit.__byte0_bit +#define FIO2SET1 FIO2SET_bit.__byte1 +#define FIO2SET1_bit FIO2SET_bit.__byte1_bit +#define FIO2SET2 FIO2SET_bit.__byte2 +#define FIO2SET2_bit FIO2SET_bit.__byte2_bit +#define FIO2SET3 FIO2SET_bit.__byte3 +#define FIO2SET3_bit FIO2SET_bit.__byte3_bit +#define FIO2SETL FIO2SET_bit.__shortl +#define FIO2SETL_bit FIO2SET_bit.__shortl_bit +#define FIO2SETU FIO2SET_bit.__shortu +#define FIO2SETU_bit FIO2SET_bit.__shortu_bit +__IO_REG32_BIT(FIO2CLR, 0x3FFFC05C,__WRITE ,__fgpio2_bits); +#define FIO2CLR0 FIO2CLR_bit.__byte0 +#define FIO2CLR0_bit FIO2CLR_bit.__byte0_bit +#define FIO2CLR1 FIO2CLR_bit.__byte1 +#define FIO2CLR1_bit FIO2CLR_bit.__byte1_bit +#define FIO2CLR2 FIO2CLR_bit.__byte2 +#define FIO2CLR2_bit FIO2CLR_bit.__byte2_bit +#define FIO2CLR3 FIO2CLR_bit.__byte3 +#define FIO2CLR3_bit FIO2CLR_bit.__byte3_bit +#define FIO2CLRL FIO2CLR_bit.__shortl +#define FIO2CLRL_bit FIO2CLR_bit.__shortl_bit +#define FIO2CLRU FIO2CLR_bit.__shortu +#define FIO2CLRU_bit FIO2CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO3DIR, 0x3FFFC060,__READ_WRITE,__fgpio3_bits); +#define FIO3DIR0 FIO3DIR_bit.__byte0 +#define FIO3DIR0_bit FIO3DIR_bit.__byte0_bit +#define FIO3DIR1 FIO3DIR_bit.__byte1 +#define FIO3DIR1_bit FIO3DIR_bit.__byte1_bit +#define FIO3DIR2 FIO3DIR_bit.__byte2 +#define FIO3DIR2_bit FIO3DIR_bit.__byte2_bit +#define FIO3DIR3 FIO3DIR_bit.__byte3 +#define FIO3DIR3_bit FIO3DIR_bit.__byte3_bit +#define FIO3DIRL FIO3DIR_bit.__shortl +#define FIO3DIRL_bit FIO3DIR_bit.__shortl_bit +#define FIO3DIRU FIO3DIR_bit.__shortu +#define FIO3DIRU_bit FIO3DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO3MASK, 0x3FFFC070,__READ_WRITE,__fgpio3_bits); +#define FIO3MASK0 FIO3MASK_bit.__byte0 +#define FIO3MASK0_bit FIO3MASK_bit.__byte0_bit +#define FIO3MASK1 FIO3MASK_bit.__byte1 +#define FIO3MASK1_bit FIO3MASK_bit.__byte1_bit +#define FIO3MASK2 FIO3MASK_bit.__byte2 +#define FIO3MASK2_bit FIO3MASK_bit.__byte2_bit +#define FIO3MASK3 FIO3MASK_bit.__byte3 +#define FIO3MASK3_bit FIO3MASK_bit.__byte3_bit +#define FIO3MASKL FIO3MASK_bit.__shortl +#define FIO3MASKL_bit FIO3MASK_bit.__shortl_bit +#define FIO3MASKU FIO3MASK_bit.__shortu +#define FIO3MASKU_bit FIO3MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO3PIN, 0x3FFFC074,__READ_WRITE,__fgpio3_bits); +#define FIO3PIN0 FIO3PIN_bit.__byte0 +#define FIO3PIN0_bit FIO3PIN_bit.__byte0_bit +#define FIO3PIN1 FIO3PIN_bit.__byte1 +#define FIO3PIN1_bit FIO3PIN_bit.__byte1_bit +#define FIO3PIN2 FIO3PIN_bit.__byte2 +#define FIO3PIN2_bit FIO3PIN_bit.__byte2_bit +#define FIO3PIN3 FIO3PIN_bit.__byte3 +#define FIO3PIN3_bit FIO3PIN_bit.__byte3_bit +#define FIO3PINL FIO3PIN_bit.__shortl +#define FIO3PINL_bit FIO3PIN_bit.__shortl_bit +#define FIO3PINU FIO3PIN_bit.__shortu +#define FIO3PINU_bit FIO3PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO3SET, 0x3FFFC078,__READ_WRITE,__fgpio3_bits); +#define FIO3SET0 FIO3SET_bit.__byte0 +#define FIO3SET0_bit FIO3SET_bit.__byte0_bit +#define FIO3SET1 FIO3SET_bit.__byte1 +#define FIO3SET1_bit FIO3SET_bit.__byte1_bit +#define FIO3SET2 FIO3SET_bit.__byte2 +#define FIO3SET2_bit FIO3SET_bit.__byte2_bit +#define FIO3SET3 FIO3SET_bit.__byte3 +#define FIO3SET3_bit FIO3SET_bit.__byte3_bit +#define FIO3SETL FIO3SET_bit.__shortl +#define FIO3SETL_bit FIO3SET_bit.__shortl_bit +#define FIO3SETU FIO3SET_bit.__shortu +#define FIO3SETU_bit FIO3SET_bit.__shortu_bit +__IO_REG32_BIT(FIO3CLR, 0x3FFFC07C,__WRITE ,__fgpio3_bits); +#define FIO3CLR0 FIO3CLR_bit.__byte0 +#define FIO3CLR0_bit FIO3CLR_bit.__byte0_bit +#define FIO3CLR1 FIO3CLR_bit.__byte1 +#define FIO3CLR1_bit FIO3CLR_bit.__byte1_bit +#define FIO3CLR2 FIO3CLR_bit.__byte2 +#define FIO3CLR2_bit FIO3CLR_bit.__byte2_bit +#define FIO3CLR3 FIO3CLR_bit.__byte3 +#define FIO3CLR3_bit FIO3CLR_bit.__byte3_bit +#define FIO3CLRL FIO3CLR_bit.__shortl +#define FIO3CLRL_bit FIO3CLR_bit.__shortl_bit +#define FIO3CLRU FIO3CLR_bit.__shortu +#define FIO3CLRU_bit FIO3CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO4DIR, 0x3FFFC080,__READ_WRITE,__fgpio4_bits); +#define FIO4DIR0 FIO4DIR_bit.__byte0 +#define FIO4DIR0_bit FIO4DIR_bit.__byte0_bit +#define FIO4DIR1 FIO4DIR_bit.__byte1 +#define FIO4DIR1_bit FIO4DIR_bit.__byte1_bit +#define FIO4DIR2 FIO4DIR_bit.__byte2 +#define FIO4DIR2_bit FIO4DIR_bit.__byte2_bit +#define FIO4DIR3 FIO4DIR_bit.__byte3 +#define FIO4DIR3_bit FIO4DIR_bit.__byte3_bit +#define FIO4DIRL FIO4DIR_bit.__shortl +#define FIO4DIRL_bit FIO4DIR_bit.__shortl_bit +#define FIO4DIRU FIO4DIR_bit.__shortu +#define FIO4DIRU_bit FIO4DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO4MASK, 0x3FFFC090,__READ_WRITE,__fgpio4_bits); +#define FIO4MASK0 FIO4MASK_bit.__byte0 +#define FIO4MASK0_bit FIO4MASK_bit.__byte0_bit +#define FIO4MASK1 FIO4MASK_bit.__byte1 +#define FIO4MASK1_bit FIO4MASK_bit.__byte1_bit +#define FIO4MASK2 FIO4MASK_bit.__byte2 +#define FIO4MASK2_bit FIO4MASK_bit.__byte2_bit +#define FIO4MASK3 FIO4MASK_bit.__byte3 +#define FIO4MASK3_bit FIO4MASK_bit.__byte3_bit +#define FIO4MASKL FIO4MASK_bit.__shortl +#define FIO4MASKL_bit FIO4MASK_bit.__shortl_bit +#define FIO4MASKU FIO4MASK_bit.__shortu +#define FIO4MASKU_bit FIO4MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO4PIN, 0x3FFFC094,__READ_WRITE,__fgpio4_bits); +#define FIO4PIN0 FIO4PIN_bit.__byte0 +#define FIO4PIN0_bit FIO4PIN_bit.__byte0_bit +#define FIO4PIN1 FIO4PIN_bit.__byte1 +#define FIO4PIN1_bit FIO4PIN_bit.__byte1_bit +#define FIO4PIN2 FIO4PIN_bit.__byte2 +#define FIO4PIN2_bit FIO4PIN_bit.__byte2_bit +#define FIO4PIN3 FIO4PIN_bit.__byte3 +#define FIO4PIN3_bit FIO4PIN_bit.__byte3_bit +#define FIO4PINL FIO4PIN_bit.__shortl +#define FIO4PINL_bit FIO4PIN_bit.__shortl_bit +#define FIO4PINU FIO4PIN_bit.__shortu +#define FIO4PINU_bit FIO4PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO4SET, 0x3FFFC098,__READ_WRITE,__fgpio4_bits); +#define FIO4SET0 FIO4SET_bit.__byte0 +#define FIO4SET0_bit FIO4SET_bit.__byte0_bit +#define FIO4SET1 FIO4SET_bit.__byte1 +#define FIO4SET1_bit FIO4SET_bit.__byte1_bit +#define FIO4SET2 FIO4SET_bit.__byte2 +#define FIO4SET2_bit FIO4SET_bit.__byte2_bit +#define FIO4SET3 FIO4SET_bit.__byte3 +#define FIO4SET3_bit FIO4SET_bit.__byte3_bit +#define FIO4SETL FIO4SET_bit.__shortl +#define FIO4SETL_bit FIO4SET_bit.__shortl_bit +#define FIO4SETU FIO4SET_bit.__shortu +#define FIO4SETU_bit FIO4SET_bit.__shortu_bit +__IO_REG32_BIT(FIO4CLR, 0x3FFFC09C,__WRITE ,__fgpio4_bits); +#define FIO4CLR0 FIO4CLR_bit.__byte0 +#define FIO4CLR0_bit FIO4CLR_bit.__byte0_bit +#define FIO4CLR1 FIO4CLR_bit.__byte1 +#define FIO4CLR1_bit FIO4CLR_bit.__byte1_bit +#define FIO4CLR2 FIO4CLR_bit.__byte2 +#define FIO4CLR2_bit FIO4CLR_bit.__byte2_bit +#define FIO4CLR3 FIO4CLR_bit.__byte3 +#define FIO4CLR3_bit FIO4CLR_bit.__byte3_bit +#define FIO4CLRL FIO4CLR_bit.__shortl +#define FIO4CLRL_bit FIO4CLR_bit.__shortl_bit +#define FIO4CLRU FIO4CLR_bit.__shortu +#define FIO4CLRU_bit FIO4CLR_bit.__shortu_bit +__IO_REG32_BIT(IO0INTENR, 0xE0028090,__READ_WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO0INTENF, 0xE0028094,__READ_WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO0INTSTATR, 0xE0028084,__READ ,__gpio0_bits); +__IO_REG32_BIT(IO0INTSTATF, 0xE0028088,__READ ,__gpio0_bits); +__IO_REG32_BIT(IO0INTCLR, 0xE002808C,__WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO2INTENR, 0xE00280B0,__READ_WRITE ,__gpio2_bits); +__IO_REG32_BIT(IO2INTENF, 0xE00280B4,__READ_WRITE ,__gpio2_bits); +__IO_REG32_BIT(IO2INTSTATR, 0xE00280A4,__READ ,__gpio2_bits); +__IO_REG32_BIT(IO2INTSTATF, 0xE00280A8,__READ ,__gpio2_bits); +__IO_REG32_BIT(IO2INTCLR, 0xE00280AC,__WRITE ,__gpio2_bits); +__IO_REG32_BIT(IOINTSTATUS, 0xE0028080,__READ ,__iointst_bits); + +/*************************************************************************** + ** + ** ETHERNET + ** + ***************************************************************************/ +__IO_REG32_BIT(MAC1, 0xFFE00000,__READ_WRITE ,__mac1_bits); +__IO_REG32_BIT(MAC2, 0xFFE00004,__READ_WRITE ,__mac2_bits); +__IO_REG32_BIT(IPGT, 0xFFE00008,__READ_WRITE ,__ipgt_bits); +__IO_REG32_BIT(IPGR, 0xFFE0000C,__READ_WRITE ,__ipgr_bits); +__IO_REG32_BIT(CLRT, 0xFFE00010,__READ_WRITE ,__clrt_bits); +__IO_REG32_BIT(MAXF, 0xFFE00014,__READ_WRITE ,__maxf_bits); +__IO_REG32_BIT(SUPP, 0xFFE00018,__READ_WRITE ,__supp_bits); +__IO_REG32_BIT(TEST, 0xFFE0001C,__READ_WRITE ,__test_bits); +__IO_REG32_BIT(MCFG, 0xFFE00020,__READ_WRITE ,__mcfg_bits); +__IO_REG32_BIT(MCMD, 0xFFE00024,__READ_WRITE ,__mcmd_bits); +__IO_REG32_BIT(MADR, 0xFFE00028,__READ_WRITE ,__madr_bits); +__IO_REG32_BIT(MWTD, 0xFFE0002C,__WRITE ,__mwtd_bits); +__IO_REG32_BIT(MRDD, 0xFFE00030,__READ ,__mrdd_bits); +__IO_REG32_BIT(MIND, 0xFFE00034,__READ ,__mind_bits); +__IO_REG32_BIT(SA0, 0xFFE00040,__READ_WRITE ,__sa0_bits); +__IO_REG32_BIT(SA1, 0xFFE00044,__READ_WRITE ,__sa1_bits); +__IO_REG32_BIT(SA2, 0xFFE00048,__READ_WRITE ,__sa2_bits); +__IO_REG32_BIT(COMMAND, 0xFFE00100,__READ_WRITE ,__command_bits); +__IO_REG32_BIT(STATUS, 0xFFE00104,__READ ,__status_bits); +__IO_REG32( RXDESCRIPTOR, 0xFFE00108,__READ_WRITE ); +__IO_REG32( RXSTATUS, 0xFFE0010C,__READ_WRITE ); +__IO_REG32_BIT(RXDESCRIPTORNUMBER, 0xFFE00110,__READ_WRITE ,__rxdescrn_bits); +__IO_REG32_BIT(RXPRODUCEINDEX, 0xFFE00114,__READ ,__rxprodind_bits); +__IO_REG32_BIT(RXCONSUMEINDEX, 0xFFE00118,__READ_WRITE ,__rxcomind_bits); +__IO_REG32( TXDESCRIPTOR, 0xFFE0011C,__READ_WRITE ); +__IO_REG32( TXSTATUS, 0xFFE00120,__READ_WRITE ); +__IO_REG32_BIT(TXDESCRIPTORNUMBER, 0xFFE00124,__READ_WRITE ,__txdescrn_bits); +__IO_REG32_BIT(TXPRODUCEINDEX, 0xFFE00128,__READ_WRITE ,__txprodind_bits); +__IO_REG32_BIT(TXCONSUMEINDEX, 0xFFE0012C,__READ ,__txcomind_bits); +__IO_REG32_BIT(TSV0, 0xFFE00158,__READ ,__tsv0_bits); +__IO_REG32_BIT(TSV1, 0xFFE0015C,__READ ,__tsv1_bits); +__IO_REG32_BIT(RSV, 0xFFE00160,__READ ,__rsv_bits); +__IO_REG32_BIT(FLOWCONTROLCOUNTER, 0xFFE00170,__READ_WRITE ,__fwctrlcnt_bits); +__IO_REG32_BIT(FLOWCONTROLSTATUS, 0xFFE00174,__READ ,__fwctrlstat_bits); +__IO_REG32_BIT(RXFILTERCTRL, 0xFFE00200,__READ_WRITE ,__rxflctrl_bits); +__IO_REG32_BIT(RXFILTERWOLSTATUS, 0xFFE00204,__READ_WRITE ,__rxflwolstat_bits); +__IO_REG32_BIT(RXFILTERWOLCLEAR, 0xFFE00208,__READ_WRITE ,__rxflwolclr_bits); +__IO_REG32( HASHFILTERL, 0xFFE00210,__READ_WRITE ); +__IO_REG32( HASHFILTERH, 0xFFE00214,__READ_WRITE ); +__IO_REG32_BIT(INTSTATUS, 0xFFE00FE0,__READ ,__intstat_bits); +__IO_REG32_BIT(INTENABLE, 0xFFE00FE4,__READ_WRITE ,__intena_bits); +__IO_REG32_BIT(INTCLEAR, 0xFFE00FE8,__WRITE ,__intclr_bits); +__IO_REG32_BIT(INTSET, 0xFFE00FEC,__WRITE ,__intset_bits); +__IO_REG32_BIT(POWERDOWN, 0xFFE00FF4,__READ_WRITE ,__pwrdn_bits); + +/*************************************************************************** + ** + ** CAN + ** + ***************************************************************************/ +__IO_REG32_BIT(AFMR, 0xE003C000,__READ_WRITE ,__afmr_bits); +__IO_REG32( SFF_SA, 0xE003C004,__READ_WRITE); +__IO_REG32( SFF_GRP_SA, 0xE003C008,__READ_WRITE); +__IO_REG32( EFF_SA, 0xE003C00C,__READ_WRITE); +__IO_REG32( EFF_GRP_SA, 0xE003C010,__READ_WRITE); +__IO_REG32( ENDOFTABLE, 0xE003C014,__READ_WRITE); +__IO_REG32( LUTERRAD, 0xE003C018,__READ); +__IO_REG32_BIT(LUTERR, 0xE003C01C,__READ ,__luterr_bits); +__IO_REG32_BIT(FCANIE, 0xE003C020,__READ_WRITE ,__fcanie_bits); +__IO_REG32_BIT(FCANIC0, 0xE003C024,__READ_WRITE ,__fcanic0_bits); +__IO_REG32_BIT(FCANIC1, 0xE003C028,__READ_WRITE ,__fcanic1_bits); +__IO_REG32_BIT(CANTXSR, 0xE0040000,__READ ,__cantxsr_bits); +__IO_REG32_BIT(CANRXSR, 0xE0040004,__READ ,__canrxsr_bits); +__IO_REG32_BIT(CANMSR, 0xE0040008,__READ ,__canmsr_bits); +__IO_REG32_BIT(CAN1MOD, 0xE0044000,__READ_WRITE ,__canmod_bits); +__IO_REG32_BIT(CAN1CMR, 0xE0044004,__WRITE ,__cancmr_bits); +__IO_REG32_BIT(CAN1GSR, 0xE0044008,__READ_WRITE ,__cangsr_bits); +__IO_REG32_BIT(CAN1ICR, 0xE004400C,__READ ,__canicr_bits); +__IO_REG32_BIT(CAN1IER, 0xE0044010,__READ_WRITE ,__canier_bits); +__IO_REG32_BIT(CAN1BTR, 0xE0044014,__READ_WRITE ,__canbtr_bits); +__IO_REG32_BIT(CAN1EWL, 0xE0044018,__READ_WRITE ,__canewl_bits); +__IO_REG32_BIT(CAN1SR, 0xE004401C,__READ ,__cansr_bits); +__IO_REG32_BIT(CAN1RFS, 0xE0044020,__READ_WRITE ,__canrfs_bits); +__IO_REG32_BIT(CAN1RID, 0xE0044024,__READ_WRITE ,__canrid_bits); +__IO_REG32_BIT(CAN1RDA, 0xE0044028,__READ_WRITE ,__canrda_bits); +__IO_REG32_BIT(CAN1RDB, 0xE004402C,__READ_WRITE ,__canrdb_bits); +__IO_REG32_BIT(CAN1TFI1, 0xE0044030,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID1, 0xE0044034,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA1, 0xE0044038,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB1, 0xE004403C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN1TFI2, 0xE0044040,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID2, 0xE0044044,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA2, 0xE0044048,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB2, 0xE004404C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN1TFI3, 0xE0044050,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID3, 0xE0044054,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA3, 0xE0044058,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB3, 0xE004405C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2MOD, 0xE0048000,__READ_WRITE ,__canmod_bits); +__IO_REG32_BIT(CAN2CMR, 0xE0048004,__WRITE ,__cancmr_bits); +__IO_REG32_BIT(CAN2GSR, 0xE0048008,__READ_WRITE ,__cangsr_bits); +__IO_REG32_BIT(CAN2ICR, 0xE004800C,__READ ,__canicr_bits); +__IO_REG32_BIT(CAN2IER, 0xE0048010,__READ_WRITE ,__canier_bits); +__IO_REG32_BIT(CAN2BTR, 0xE0048014,__READ_WRITE ,__canbtr_bits); +__IO_REG32_BIT(CAN2EWL, 0xE0048018,__READ_WRITE ,__canewl_bits); +__IO_REG32_BIT(CAN2SR, 0xE004801C,__READ ,__cansr_bits); +__IO_REG32_BIT(CAN2RFS, 0xE0048020,__READ_WRITE ,__canrfs_bits); +__IO_REG32_BIT(CAN2RID, 0xE0048024,__READ_WRITE ,__canrid_bits); +__IO_REG32_BIT(CAN2RDA, 0xE0048028,__READ_WRITE ,__canrda_bits); +__IO_REG32_BIT(CAN2RDB, 0xE004802C,__READ_WRITE ,__canrdb_bits); +__IO_REG32_BIT(CAN2TFI1, 0xE0048030,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID1, 0xE0048034,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA1, 0xE0048038,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB1, 0xE004803C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2TFI2, 0xE0048040,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID2, 0xE0048044,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA2, 0xE0048048,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB2, 0xE004804C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2TFI3, 0xE0048050,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID3, 0xE0048054,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA3, 0xE0048058,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB3, 0xE004805C,__READ_WRITE ,__cantdb_bits); + +/*************************************************************************** + ** + ** USB + ** + ***************************************************************************/ +__IO_REG32_BIT(USBPORTSEL, 0xFFE0C110,__READ_WRITE ,__usbportsel_bits); +__IO_REG32_BIT(USBCLKCTRL, 0xFFE0CFF4,__READ_WRITE ,__usbclkctrl_bits); +__IO_REG32_BIT(USBCLKST, 0xFFE0CFF8,__READ ,__usbclkst_bits); +__IO_REG32_BIT(USBINTS, 0xE01FC1C0,__READ_WRITE ,__usbints_bits); +__IO_REG32_BIT(USBDEVINTST, 0xFFE0C200,__READ ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTEN, 0xFFE0C204,__READ_WRITE ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTCLR, 0xFFE0C208,__WRITE ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTSET, 0xFFE0C20C,__WRITE ,__usbdevintst_bits); +__IO_REG8_BIT( USBDEVINTPRI, 0xFFE0C22C,__WRITE ,__usbdevintpri_bits); +__IO_REG32_BIT(USBEPINTST, 0xFFE0C230,__READ ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTEN, 0xFFE0C234,__READ_WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTCLR, 0xFFE0C238,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTSET, 0xFFE0C23C,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTPRI, 0xFFE0C240,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBREEP, 0xFFE0C244,__READ_WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEPIN, 0xFFE0C248,__WRITE ,__usbepin_bits); +__IO_REG32_BIT(USBMAXPSIZE, 0xFFE0C24C,__READ_WRITE ,__usbmaxpsize_bits); +__IO_REG32( USBRXDATA, 0xFFE0C218,__READ); +__IO_REG32_BIT(USBRXPLEN, 0xFFE0C220,__READ ,__usbrxplen_bits); +__IO_REG32( TDATA, 0xFFE0C21C,__WRITE); +__IO_REG32_BIT(USBTXPLEN, 0xFFE0C224,__WRITE ,__usbtxplen_bits); +__IO_REG32_BIT(USBCTRL, 0xFFE0C228,__READ_WRITE ,__usbctrl_bits); +__IO_REG32_BIT(USBCMDCODE, 0xFFE0C210,__WRITE ,__usbcmdcode_bits); +__IO_REG32_BIT(USBCMDDATA, 0xFFE0C214,__READ ,__usbcmddata_bits); +__IO_REG32_BIT(USBDMARST, 0xFFE0C250,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBDMARCLR, 0xFFE0C254,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBDMARSET, 0xFFE0C258,__WRITE ,__usbreep_bits); +__IO_REG32( USBUDCAH, 0xFFE0C280,__READ_WRITE ); +__IO_REG32_BIT(USBEPDMAST, 0xFFE0C284,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBEPDMAEN, 0xFFE0C288,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEPDMADIS, 0xFFE0C28C,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBDMAINTST, 0xFFE0C290,__READ ,__usbdmaintst_bits); +__IO_REG32_BIT(USBDMAINTEN, 0xFFE0C294,__READ_WRITE ,__usbdmaintst_bits); +__IO_REG32_BIT(USBNDDRINTST, 0xFFE0C2AC,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBNDDRINTCLR, 0xFFE0C2B0,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBNDDRINTSET, 0xFFE0C2B4,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTST, 0xFFE0C2A0,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTCLR, 0xFFE0C2A4,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTSET, 0xFFE0C2A8,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTST, 0xFFE0C2B8,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTCLR, 0xFFE0C2BC,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTSET, 0xFFE0C2C0,__WRITE ,__usbreep_bits); + +/*************************************************************************** + ** + ** UART0 + ** + ***************************************************************************/ +/* U0DLL, U0RBR and U0THR share the same address */ +__IO_REG8( U0RBRTHR, 0xE000C000,__READ_WRITE); +#define U0DLL U0RBRTHR +#define U0RBR U0RBRTHR +#define U0THR U0RBRTHR + +/* U0DLM and U0IER share the same address */ +__IO_REG32_BIT(U0IER, 0xE000C004,__READ_WRITE ,__uartier0_bits); +#define U0DLM U0IER + +/* U0FCR and U0IIR share the same address */ +__IO_REG32_BIT(U0FCR, 0xE000C008,__READ_WRITE ,__uartfcriir_bits); +#define U0IIR U0FCR +#define U0IIR_bit U0FCR_bit + +__IO_REG8_BIT( U0LCR, 0xE000C00C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U0LSR, 0xE000C014,__READ ,__uartlsr_bits); +__IO_REG8( U0SCR, 0xE000C01C,__READ_WRITE); +__IO_REG32_BIT(U0ACR, 0xE000C020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U0FDR, 0xE000C028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U0TER, 0xE000C030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART1 + ** + ***************************************************************************/ +/* U1DLL, U1RBR and U1THR share the same address */ +__IO_REG8( U1RBRTHR, 0xE0010000,__READ_WRITE); +#define U1DLL U1RBRTHR +#define U1RBR U1RBRTHR +#define U1THR U1RBRTHR + +/* U1DLM and U1IER share the same address */ +__IO_REG32_BIT(U1IER, 0xE0010004,__READ_WRITE ,__uartier1_bits); +#define U1DLM U1IER + +/* U1FCR and U1IIR share the same address */ +__IO_REG32_BIT(U1FCR, 0xE0010008,__READ_WRITE ,__uartfcriir_bits); +#define U1IIR U1FCR +#define U1IIR_bit U1FCR_bit + +__IO_REG8_BIT( U1LCR, 0xE001000C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U1MCR, 0xE0010010,__READ_WRITE ,__uartmcr_bits); +__IO_REG8_BIT( U1LSR, 0xE0010014,__READ ,__uartlsr_bits); +__IO_REG8_BIT( U1MSR, 0xE0010018,__READ ,__uartmsr_bits); +__IO_REG8( U1SCR, 0xE001001C,__READ_WRITE); +__IO_REG32_BIT(U1ACR, 0xE0010020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U1FDR, 0xE0010028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U1TER, 0xE0010030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART2 + ** + ***************************************************************************/ +/* U2DLL, U2RBR and U2THR share the same address */ +__IO_REG8( U2RBRTHR, 0xE0078000,__READ_WRITE); +#define U2DLL U2RBRTHR +#define U2RBR U2RBRTHR +#define U2THR U2RBRTHR + +/* U2DLM and U2IER share the same address */ +__IO_REG32_BIT(U2IER, 0xE0078004,__READ_WRITE ,__uartier0_bits); +#define U2DLM U2IER + +/* U2FCR and U2IIR share the same address */ +__IO_REG32_BIT(U2FCR, 0xE0078008,__READ_WRITE ,__uartfcriir_bits); +#define U2IIR U2FCR +#define U2IIR_bit U2FCR_bit + +__IO_REG8_BIT( U2LCR, 0xE007800C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U2LSR, 0xE0078014,__READ ,__uartlsr_bits); +__IO_REG8( U2SCR, 0xE007801C,__READ_WRITE); +__IO_REG32_BIT(U2ACR, 0xE0078020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U2FDR, 0xE0078028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U2TER, 0xE0078030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART3 + ** + ***************************************************************************/ +/* U3DLL, U3RBR and U3THR share the same address */ +__IO_REG8( U3RBRTHR, 0xE007C000,__READ_WRITE); +#define U3DLL U3RBRTHR +#define U3RBR U3RBRTHR +#define U3THR U3RBRTHR + +/* U3DLM and U3IER share the same address */ +__IO_REG32_BIT(U3IER, 0xE007C004,__READ_WRITE ,__uartier0_bits); +#define U3DLM U3IER + +/* U3FCR and U3IIR share the same address */ +__IO_REG32_BIT(U3FCR, 0xE007C008,__READ_WRITE ,__uartfcriir_bits); +#define U3IIR U3FCR +#define U3IIR_bit U3FCR_bit + +__IO_REG8_BIT( U3LCR, 0xE007C00C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U3LSR, 0xE007C014,__READ ,__uartlsr_bits); +__IO_REG8( U3SCR, 0xE007C01C,__READ_WRITE); +__IO_REG32_BIT(U3ACR, 0xE007C020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U3ICR, 0xE007C024,__READ_WRITE ,__uarticr_bits); +__IO_REG32_BIT(U3FDR, 0xE007C028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U3TER, 0xE007C030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** SPI + ** + ***************************************************************************/ +__IO_REG32_BIT(S0SPCR, 0xE0020000,__READ_WRITE ,__spcr_bits); +__IO_REG32_BIT(S0SPSR, 0xE0020004,__READ ,__spsr_bits); +__IO_REG16( S0SPDR, 0xE0020008,__READ_WRITE); +__IO_REG32_BIT(S0SPCCR, 0xE002000C,__READ_WRITE ,__spccr_bits); +__IO_REG8_BIT( SPTCR, 0xE0020010,__READ_WRITE ,__sptcr_bits); +__IO_REG8_BIT( SPTSR, 0xE0020014,__READ_WRITE ,__sptsr_bits); +__IO_REG32_BIT(S0SPINT, 0xE002001C,__READ_WRITE ,__spint_bits); + +/*************************************************************************** + ** + ** SSP0 + ** + ***************************************************************************/ +__IO_REG32_BIT(SSP0CR0, 0xE0068000,__READ_WRITE ,__sspcr0_bits); +__IO_REG32_BIT(SSP0CR1, 0xE0068004,__READ_WRITE ,__sspcr1_bits); +__IO_REG32_BIT(SSP0DR, 0xE0068008,__READ_WRITE ,__sspdr_bits); +__IO_REG32_BIT(SSP0SR, 0xE006800C,__READ ,__sspsr_bits); +__IO_REG32_BIT(SSP0CPSR, 0xE0068010,__READ_WRITE ,__sspcpsr_bits); +__IO_REG32_BIT(SSP0IMSC, 0xE0068014,__READ_WRITE ,__sspimsc_bits); +__IO_REG32_BIT(SSP0RIS, 0xE0068018,__READ_WRITE ,__sspris_bits); +__IO_REG32_BIT(SSP0MIS, 0xE006801C,__READ_WRITE ,__sspmis_bits); +__IO_REG32_BIT(SSP0ICR, 0xE0068020,__READ_WRITE ,__sspicr_bits); +__IO_REG32_BIT(SSP0DMACR, 0xE0068024,__READ_WRITE ,__sspdmacr_bits); + +/*************************************************************************** + ** + ** SSP1 + ** + ***************************************************************************/ +__IO_REG32_BIT(SSP1CR0, 0xE0030000,__READ_WRITE ,__sspcr0_bits); +__IO_REG32_BIT(SSP1CR1, 0xE0030004,__READ_WRITE ,__sspcr1_bits); +__IO_REG32_BIT(SSP1DR, 0xE0030008,__READ_WRITE ,__sspdr_bits); +__IO_REG32_BIT(SSP1SR, 0xE003000C,__READ ,__sspsr_bits); +__IO_REG32_BIT(SSP1CPSR, 0xE0030010,__READ_WRITE ,__sspcpsr_bits); +__IO_REG32_BIT(SSP1IMSC, 0xE0030014,__READ_WRITE ,__sspimsc_bits); +__IO_REG32_BIT(SSP1RIS, 0xE0030018,__READ_WRITE ,__sspris_bits); +__IO_REG32_BIT(SSP1MIS, 0xE003001C,__READ_WRITE ,__sspmis_bits); +__IO_REG32_BIT(SSP1ICR, 0xE0030020,__READ_WRITE ,__sspicr_bits); +__IO_REG32_BIT(SSP1DMACR, 0xE0030024,__READ_WRITE ,__sspdmacr_bits); + +/*************************************************************************** + ** + ** SD/MMC + ** + ***************************************************************************/ +__IO_REG32_BIT(MCIPOWER, 0xE008C000,__READ_WRITE ,__mcipower_bits); +__IO_REG32_BIT(MCICLOCK, 0xE008C004,__READ_WRITE ,__mciclock_bits); +__IO_REG32( MCIARGUMENT, 0xE008C008,__READ_WRITE); +__IO_REG32_BIT(MCICOMMAND, 0xE008C00C,__READ_WRITE ,__mcicommand_bits); +__IO_REG32_BIT(MCIRESPCMD, 0xE008C010,__READ ,__mcirespcmd_bits); +__IO_REG32( MCIRESPONSE0, 0xE008C014,__READ); +__IO_REG32( MCIRESPONSE1, 0xE008C018,__READ); +__IO_REG32( MCIRESPONSE2, 0xE008C01C,__READ); +__IO_REG32( MCIRESPONSE3, 0xE008C020,__READ); +__IO_REG32( MCIDATATIMER, 0xE008C024,__READ_WRITE); +__IO_REG16( MCIDATALENGTH, 0xE008C028,__READ_WRITE); +__IO_REG32_BIT(MCIDATACTRL, 0xE008C02C,__READ_WRITE ,__mcidatactrl_bits); +__IO_REG16( MCIDATACNT, 0xE008C030,__READ); +__IO_REG32_BIT(MCISTATUS, 0xE008C034,__READ ,__mcistatus_bits); +__IO_REG32_BIT(MCICLEAR, 0xE008C038,__WRITE ,__mciclear_bits); +__IO_REG32_BIT(MCIMASK0, 0xE008C03C,__READ_WRITE ,__mcistatus_bits); +__IO_REG32_BIT(MCIMASK1, 0xE008C040,__READ_WRITE ,__mcistatus_bits); +__IO_REG32_BIT(MCIFIFOCNT, 0xE008C048,__READ ,__mcififocnt_bits); +__IO_REG32( MCIFIFO0, 0xE008C080,__READ_WRITE); +__IO_REG32( MCIFIFO1, 0xE008C084,__READ_WRITE); +__IO_REG32( MCIFIFO2, 0xE008C088,__READ_WRITE); +__IO_REG32( MCIFIFO3, 0xE008C08C,__READ_WRITE); +__IO_REG32( MCIFIFO4, 0xE008C090,__READ_WRITE); +__IO_REG32( MCIFIFO5, 0xE008C094,__READ_WRITE); +__IO_REG32( MCIFIFO6, 0xE008C098,__READ_WRITE); +__IO_REG32( MCIFIFO7, 0xE008C09C,__READ_WRITE); +__IO_REG32( MCIFIFO8, 0xE008C0A0,__READ_WRITE); +__IO_REG32( MCIFIFO9, 0xE008C0A4,__READ_WRITE); +__IO_REG32( MCIFIFO10, 0xE008C0A8,__READ_WRITE); +__IO_REG32( MCIFIFO11, 0xE008C0AC,__READ_WRITE); +__IO_REG32( MCIFIFO12, 0xE008C0B0,__READ_WRITE); +__IO_REG32( MCIFIFO13, 0xE008C0B4,__READ_WRITE); +__IO_REG32( MCIFIFO14, 0xE008C0B8,__READ_WRITE); +__IO_REG32( MCIFIFO15, 0xE008C0BC,__READ_WRITE); + +/*************************************************************************** + ** + ** I2C0 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C0CONSET, 0xE001C000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C0STAT, 0xE001C004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C0DAT, 0xE001C008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C0ADR, 0xE001C00C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C0SCLH, 0xE001C010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C0SCLL, 0xE001C014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C0CONCLR, 0xE001C018,__WRITE ,__i2conclr_bits); + +//The names of the registers above have been corrected according to the chip +//documentation. The defines below are aliases with the old names for backwards +//compatibility. +#define I20CONSET I2C0CONSET +#define I20STAT I2C0STAT +#define I20DAT I2C0DAT +#define I20ADR I2C0ADR +#define I20SCLH I2C0SCLH +#define I20SCLL I2C0SCLL +#define I20CONCLR I2C0CONCLR + +/*************************************************************************** + ** + ** I2C1 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C1CONSET, 0xE005C000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C1STAT, 0xE005C004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C1DAT, 0xE005C008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C1ADR, 0xE005C00C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C1SCLH, 0xE005C010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C1SCLL, 0xE005C014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C1CONCLR, 0xE005C018,__WRITE ,__i2conclr_bits); + +//The names of the registers above have been corrected according to the chip +//documentation. The defines below are aliases with the old names for backwards +//compatibility. +#define I21CONSET I2C1CONSET +#define I21STAT I2C1STAT +#define I21DAT I2C1DAT +#define I21ADR I2C1ADR +#define I21SCLH I2C1SCLH +#define I21SCLL I2C1SCLL +#define I21CONCLR I2C1CONCLR + +/*************************************************************************** + ** + ** I2C2 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C2CONSET, 0xE0080000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C2STAT, 0xE0080004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C2DAT, 0xE0080008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C2ADR, 0xE008000C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C2SCLH, 0xE0080010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C2SCLL, 0xE0080014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C2CONCLR, 0xE0080018,__WRITE ,__i2conclr_bits); + +/*************************************************************************** + ** + ** I2S + ** + ***************************************************************************/ +__IO_REG32_BIT(I2SDAO, 0xE0088000,__READ_WRITE ,__i2sdao_bits); +__IO_REG32_BIT(I2SDAI, 0xE0088004,__READ_WRITE ,__i2sdai_bits); +__IO_REG32( I2STXFIFO, 0xE0088008,__WRITE); +__IO_REG32( I2SRXFIFO, 0xE008800C,__READ); +__IO_REG32_BIT(I2SSTATE, 0xE0088010,__READ ,__i2sstate_bits); +__IO_REG32_BIT(I2SDMA1, 0xE0088014,__READ_WRITE ,__i2sdma_bits); +__IO_REG32_BIT(I2SDMA2, 0xE0088018,__READ_WRITE ,__i2sdma_bits); +__IO_REG32_BIT(I2SIRQ, 0xE008801C,__READ_WRITE ,__i2sirq_bits); +__IO_REG32_BIT(I2STXRATE, 0xE0088020,__READ_WRITE ,__i2stxrate_bits); +__IO_REG32_BIT(I2SRXRATE, 0xE0088024,__READ_WRITE ,__i2srxrate_bits); + +/*************************************************************************** + ** + ** TIMER0 + ** + ***************************************************************************/ +__IO_REG32_BIT(T0IR, 0xE0004000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T0TCR, 0xE0004004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T0TC, 0xE0004008,__READ_WRITE); +__IO_REG32( T0PR, 0xE000400C,__READ_WRITE); +__IO_REG32( T0PC, 0xE0004010,__READ_WRITE); +__IO_REG32_BIT(T0MCR, 0xE0004014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T0MR0, 0xE0004018,__READ_WRITE); +__IO_REG32( T0MR1, 0xE000401C,__READ_WRITE); +__IO_REG32( T0MR2, 0xE0004020,__READ_WRITE); +__IO_REG32( T0MR3, 0xE0004024,__READ_WRITE); +__IO_REG32_BIT(T0CCR, 0xE0004028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T0CR0, 0xE000402C,__READ); +__IO_REG32( T0CR1, 0xE0004030,__READ); +__IO_REG32( T0CR2, 0xE0004034,__READ); +__IO_REG32( T0CR3, 0xE0004038,__READ); +__IO_REG32_BIT(T0EMR, 0xE000403C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T0CTCR, 0xE0004070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER1 + ** + ***************************************************************************/ +__IO_REG32_BIT(T1IR, 0xE0008000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T1TCR, 0xE0008004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T1TC, 0xE0008008,__READ_WRITE); +__IO_REG32( T1PR, 0xE000800C,__READ_WRITE); +__IO_REG32( T1PC, 0xE0008010,__READ_WRITE); +__IO_REG32_BIT(T1MCR, 0xE0008014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T1MR0, 0xE0008018,__READ_WRITE); +__IO_REG32( T1MR1, 0xE000801C,__READ_WRITE); +__IO_REG32( T1MR2, 0xE0008020,__READ_WRITE); +__IO_REG32( T1MR3, 0xE0008024,__READ_WRITE); +__IO_REG32_BIT(T1CCR, 0xE0008028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T1CR0, 0xE000802C,__READ); +__IO_REG32( T1CR1, 0xE0008030,__READ); +__IO_REG32( T1CR2, 0xE0008034,__READ); +__IO_REG32( T1CR3, 0xE0008038,__READ); +__IO_REG32_BIT(T1EMR, 0xE000803C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T1CTCR, 0xE0008070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER2 + ** + ***************************************************************************/ +__IO_REG32_BIT(T2IR, 0xE0070000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T2TCR, 0xE0070004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T2TC, 0xE0070008,__READ_WRITE); +__IO_REG32( T2PR, 0xE007000C,__READ_WRITE); +__IO_REG32( T2PC, 0xE0070010,__READ_WRITE); +__IO_REG32_BIT(T2MCR, 0xE0070014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T2MR0, 0xE0070018,__READ_WRITE); +__IO_REG32( T2MR1, 0xE007001C,__READ_WRITE); +__IO_REG32( T2MR2, 0xE0070020,__READ_WRITE); +__IO_REG32( T2MR3, 0xE0070024,__READ_WRITE); +__IO_REG32_BIT(T2CCR, 0xE0070028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T2CR0, 0xE007002C,__READ); +__IO_REG32( T2CR1, 0xE0070030,__READ); +__IO_REG32( T2CR2, 0xE0070034,__READ); +__IO_REG32( T2CR3, 0xE0070038,__READ); +__IO_REG32_BIT(T2EMR, 0xE007003C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T2CTCR, 0xE0070070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER3 + ** + ***************************************************************************/ +__IO_REG32_BIT(T3IR, 0xE0074000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T3TCR, 0xE0074004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T3TC, 0xE0074008,__READ_WRITE); +__IO_REG32( T3PR, 0xE007400C,__READ_WRITE); +__IO_REG32( T3PC, 0xE0074010,__READ_WRITE); +__IO_REG32_BIT(T3MCR, 0xE0074014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T3MR0, 0xE0074018,__READ_WRITE); +__IO_REG32( T3MR1, 0xE007401C,__READ_WRITE); +__IO_REG32( T3MR2, 0xE0074020,__READ_WRITE); +__IO_REG32( T3MR3, 0xE0074024,__READ_WRITE); +__IO_REG32_BIT(T3CCR, 0xE0074028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T3CR0, 0xE007402C,__READ); +__IO_REG32( T3CR1, 0xE0074030,__READ); +__IO_REG32( T3CR2, 0xE0074034,__READ); +__IO_REG32( T3CR3, 0xE0074038,__READ); +__IO_REG32_BIT(T3EMR, 0xE007403C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T3CTCR, 0xE0074070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** Watchdog + ** + ***************************************************************************/ +__IO_REG32_BIT(WDMOD, 0xE0000000,__READ_WRITE ,__wdmod_bits); +__IO_REG32( WDTC, 0xE0000004,__READ_WRITE); +__IO_REG32_BIT(WDFEED, 0xE0000008,__WRITE ,__wdfeed_bits); +__IO_REG32( WDTV, 0xE000000C,__READ); +__IO_REG32_BIT(WDCLKSEL, 0xE0000010,__READ_WRITE ,__wdclksel_bits); + +/*************************************************************************** + ** + ** A/D Converters + ** + ***************************************************************************/ +__IO_REG32_BIT(AD0CR, 0xE0034000,__READ_WRITE ,__adcr_bits); +__IO_REG32_BIT(AD0GDR, 0xE0034004,__READ_WRITE ,__adgdr_bits); +__IO_REG32_BIT(ADINTEN, 0xE003400C,__READ_WRITE ,__adinten_bits); +__IO_REG32_BIT(ADDR0, 0xE0034010,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR1, 0xE0034014,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR2, 0xE0034018,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR3, 0xE003401C,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR4, 0xE0034020,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR5, 0xE0034024,__READ ,__addr_bits); +__IO_REG32_BIT(ADSTAT, 0xE0034030,__READ ,__adstat_bits); + +/*************************************************************************** + ** + ** D/A Converter + ** + ***************************************************************************/ +__IO_REG32_BIT(DACR, 0xE006C000,__READ_WRITE ,__dacr_bits); + +/*************************************************************************** + ** + ** PWM1 + ** + ***************************************************************************/ +__IO_REG32_BIT(PWM1IR, 0xE0018000,__READ_WRITE ,__pwmir_bits); +__IO_REG32_BIT(PWM1TCR, 0xE0018004,__READ_WRITE ,__pwmtcr1_bits); +__IO_REG32( PWM1TC, 0xE0018008,__READ_WRITE); +__IO_REG32( PWM1PR, 0xE001800C,__READ_WRITE); +__IO_REG32( PWM1PC, 0xE0018010,__READ_WRITE); +__IO_REG32_BIT(PWM1MCR, 0xE0018014,__READ_WRITE ,__pwmmcr_bits); +__IO_REG32( PWM1MR0, 0xE0018018,__READ_WRITE); +__IO_REG32( PWM1MR1, 0xE001801C,__READ_WRITE); +__IO_REG32( PWM1MR2, 0xE0018020,__READ_WRITE); +__IO_REG32( PWM1MR3, 0xE0018024,__READ_WRITE); +__IO_REG32_BIT(PWM1CCR, 0xE0018028,__READ_WRITE ,__pwmccr_bits); +__IO_REG32( PWM1CR0, 0xE001802C,__READ_WRITE); +__IO_REG32( PWM1CR1, 0xE0018030,__READ_WRITE); +__IO_REG32( PWM1CR2, 0xE0018034,__READ_WRITE); +__IO_REG32( PWM1CR3, 0xE0018038,__READ_WRITE); +__IO_REG32( PWM1EMR, 0xE001803C,__READ_WRITE); +__IO_REG32( PWM1MR4, 0xE0018040,__READ_WRITE); +__IO_REG32( PWM1MR5, 0xE0018044,__READ_WRITE); +__IO_REG32( PWM1MR6, 0xE0018048,__READ_WRITE); +__IO_REG32_BIT(PWM1PCR, 0xE001804C,__READ_WRITE ,__pwmpcr_bits); +__IO_REG32_BIT(PWM1LER, 0xE0018050,__READ_WRITE ,__pwmler_bits); +__IO_REG32_BIT(PWM1CTCR, 0xE0018070,__READ_WRITE ,__pwmctcr_bits); + +/*************************************************************************** + ** + ** RTC + ** + ***************************************************************************/ +__IO_REG32_BIT(ILR, 0xE0024000,__READ_WRITE ,__ilr_bits); +__IO_REG32_BIT(CTC, 0xE0024004,__READ ,__ctc_bits); +__IO_REG32_BIT(CCR, 0xE0024008,__READ_WRITE ,__rtcccr_bits); +__IO_REG32_BIT(CIIR, 0xE002400C,__READ_WRITE ,__ciir_bits); +__IO_REG32_BIT(AMR, 0xE0024010,__READ_WRITE ,__amr_bits); +__IO_REG32_BIT(CTIME0, 0xE0024014,__READ ,__ctime0_bits); +__IO_REG32_BIT(CTIME1, 0xE0024018,__READ ,__ctime1_bits); +__IO_REG32_BIT(CTIME2, 0xE002401C,__READ ,__ctime2_bits); +__IO_REG32_BIT(SEC, 0xE0024020,__READ_WRITE ,__sec_bits); +__IO_REG32_BIT(MIN, 0xE0024024,__READ_WRITE ,__min_bits); +__IO_REG32_BIT(HOUR, 0xE0024028,__READ_WRITE ,__hour_bits); +__IO_REG32_BIT(DOM, 0xE002402C,__READ_WRITE ,__dom_bits); +__IO_REG32_BIT(DOW, 0xE0024030,__READ_WRITE ,__dow_bits); +__IO_REG32_BIT(DOY, 0xE0024034,__READ_WRITE ,__doy_bits); +__IO_REG32_BIT(MONTH, 0xE0024038,__READ_WRITE ,__month_bits); +__IO_REG32_BIT(YEAR, 0xE002403C,__READ_WRITE ,__year_bits); +__IO_REG32_BIT(CISS, 0xE0024040,__READ_WRITE ,__ciss_bits); +__IO_REG32_BIT(ALSEC, 0xE0024060,__READ_WRITE ,__sec_bits); +__IO_REG32_BIT(ALMIN, 0xE0024064,__READ_WRITE ,__min_bits); +__IO_REG32_BIT(ALHOUR, 0xE0024068,__READ_WRITE ,__hour_bits); +__IO_REG32_BIT(ALDOM, 0xE002406C,__READ_WRITE ,__dom_bits); +__IO_REG32_BIT(ALDOW, 0xE0024070,__READ_WRITE ,__dow_bits); +__IO_REG32_BIT(ALDOY, 0xE0024074,__READ_WRITE ,__doy_bits); +__IO_REG32_BIT(ALMON, 0xE0024078,__READ_WRITE ,__month_bits); +__IO_REG32_BIT(ALYEAR, 0xE002407C,__READ_WRITE ,__year_bits); +__IO_REG32_BIT(PREINT, 0xE0024080,__READ_WRITE ,__preint_bits); +__IO_REG32_BIT(PREFRAC, 0xE0024084,__READ_WRITE ,__prefrac_bits); + +/*************************************************************************** + ** + ** DMA + ** + ***************************************************************************/ +__IO_REG32_BIT(DMACINTSTATUS, 0xFFE04000,__READ ,__dmacintstatus_bits); +__IO_REG32_BIT(DMACINTTCSTATUS, 0xFFE04004,__READ ,__dmacinttcstatus_bits); +__IO_REG32_BIT(DMACINTTCCLEAR, 0xFFE04008,__WRITE ,__dmacinttcclear_bits); +__IO_REG32_BIT(DMACINTERRSTAT, 0xFFE0400C,__READ ,__dmacinterrstat_bits); +__IO_REG32_BIT(DMACINTERRCLR, 0xFFE04010,__WRITE ,__dmacinterrclr_bits); +__IO_REG32_BIT(DMACRAWINTTCSTATUS, 0xFFE04014,__READ ,__dmacrawinttcstatus_bits); +__IO_REG32_BIT(DMACRAWINTERRORSTATUS, 0xFFE04018,__READ ,__dmacrawinterrorstatus_bits); +__IO_REG32_BIT(DMACENBLDCHNS, 0xFFE0401C,__READ ,__dmacenbldchns_bits); +__IO_REG32_BIT(DMACSOFTBREQ, 0xFFE04020,__READ_WRITE,__dmacsoftbreq_bits); +__IO_REG32_BIT(DMACSOFTSREQ, 0xFFE04024,__READ_WRITE,__dmacsoftsreq_bits); +__IO_REG32_BIT(DMACSOFTLBREQ, 0xFFE04028,__READ_WRITE,__dmacsoftlbreq_bits); +__IO_REG32_BIT(DMACSOFTLSREQ, 0xFFE0402C,__READ_WRITE,__dmacsoftlsreq_bits); +__IO_REG32_BIT(DMACCONFIGURATION, 0xFFE04030,__READ_WRITE,__dmacconfig_bits); +__IO_REG32_BIT(DMACSYNC, 0xFFE04034,__READ_WRITE,__dmacsync_bits); +__IO_REG32( DMACC0SRCADDR, 0xFFE04100,__READ_WRITE); +__IO_REG32( DMACC0DESTADDR, 0xFFE04104,__READ_WRITE); +__IO_REG32_BIT(DMACC0LLI, 0xFFE04108,__READ_WRITE,__dma_lli_bits); +__IO_REG32_BIT(DMACC0CONTROL, 0xFFE0410C,__READ_WRITE,__dma_ctrl_bits); +__IO_REG32_BIT(DMACC0CONFIGURATION, 0xFFE04110,__READ_WRITE,__dma_cfg_bits); +__IO_REG32( DMACC1SRCADDR, 0xFFE04120,__READ_WRITE); +__IO_REG32( DMACC1DESTADDR, 0xFFE04124,__READ_WRITE); +__IO_REG32_BIT(DMACC1LLI, 0xFFE04128,__READ_WRITE,__dma_lli_bits); +__IO_REG32_BIT(DMACC1CONTROL, 0xFFE0412C,__READ_WRITE,__dma_ctrl_bits); +__IO_REG32_BIT(DMACC1CONFIGURATION, 0xFFE04130,__READ_WRITE,__dma_cfg_bits); + +/*************************************************************************** + ** Assembler-specific declarations + ***************************************************************************/ + +#ifdef __IAR_SYSTEMS_ASM__ +#endif /* __IAR_SYSTEMS_ASM__ */ + +/*************************************************************************** + ** + ** Interrupt vector table + ** + ***************************************************************************/ +#define RESETV 0x00 /* Reset */ +#define UNDEFV 0x04 /* Undefined instruction */ +#define SWIV 0x08 /* Software interrupt */ +#define PABORTV 0x0C /* Prefetch abort */ +#define DABORTV 0x10 /* Data abort */ +#define IRQV 0x18 /* Normal interrupt */ +#define FIQV 0x1C /* Fast interrupt */ + +/*************************************************************************** + ** + ** DMA Controller peripheral devices lines + ** + ***************************************************************************/ +#define DMA_SSP0TX 0 /* SPI0 Tx */ +#define DMA_SSP0RX 1 /* SPI0 Rx */ +#define DMA_SSP1TX 2 /* SPI1 Tx */ +#define DMA_SSP1RX 3 /* SPI1 Rx */ +#define DMA_MMCSD 4 /* MMC/SD */ +#define DMA_I2S0 5 /* I2S Channel 0 */ +#define DMA_I2S1 6 /* I2S Channel 1 */ + +/*************************************************************************** + ** + ** VIC Interrupt channels + ** + ***************************************************************************/ +#define VIC_WDT 0 /* Watchdog */ +#define VIC_SW 1 /* Software interrupts */ +#define VIC_DEBUGRX 2 /* Embedded ICE, DbgCommRx */ +#define VIC_DEBUGTX 3 /* Embedded ICE, DbgCommTx */ +#define VIC_TIMER0 4 /* Timer 0 (Match 0-3 Capture 0-3) */ +#define VIC_TIMER1 5 /* Timer 1 (Match 0-3 Capture 0-3) */ +#define VIC_UART0 6 /* UART 0 (RLS, THRE, RDA, CTI) */ +#define VIC_UART1 7 /* UART 1 (RLS, THRE, RDA, CTI, MSI) */ +#define VIC_PWM1 8 /* PWM 01 (Match 0-6 Capture 0-3) */ +#define VIC_I2C0 9 /* I2C 0 (SI) */ +#define VIC_SPI 10 /* SPI 0, SSP 0 */ +#define VIC_SSP1 11 /* SSP 1 */ +#define VIC_PLL 12 /* PLL lock (PLOCK) */ +#define VIC_RTC 13 /* RTC (RTCCIF, RTCALF) */ +#define VIC_EINT0 14 /* External interrupt 0 (EINT0) */ +#define VIC_EINT1 15 /* External interrupt 1 (EINT1) */ +#define VIC_EINT2 16 /* External interrupt 2 (EINT2) */ +#define VIC_EINT3 17 /* External interrupt 3 (EINT3) */ +#define VIC_AD0 18 /* A/D converter 0 */ +#define VIC_I2C1 19 /* I2C 1 */ +#define VIC_BOD 20 /* Brown out detect */ +#define VIC_ETHERNET 21 /* Ethernet */ +#define VIC_USB 22 /* USB Low and High priority */ +#define VIC_CAN12 23 /* CAN1,2 Tx, Rx */ +#define VIC_MMC 24 /* SD/MMC */ +#define VIC_GP_DMA 25 /* DMA channel 0, DMA channel 1 */ +#define VIC_TIMER2 26 /* Timer 2 (Match 0-3 Capture 0-3) */ +#define VIC_TIMER3 27 /* Timer 3 (Match 0-3 Capture 0-3) */ +#define VIC_UART2 28 /* UART 2 (RLS, THRE, RDA, CTI) */ +#define VIC_UART3 29 /* UART 3 (RLS, THRE, RDA, CTI, MSI) */ +#define VIC_I2C2 30 /* I2C 0 (SI) */ +#define VIC_I2S 31 /* I2S Rx, Tx */ + +#endif /* __IOLPC2368_H */ diff --git a/.svn/pristine/06/064e186630a3031de2e5e002c6dca24892a28619.svn-base b/.svn/pristine/06/064e186630a3031de2e5e002c6dca24892a28619.svn-base new file mode 100644 index 0000000..097c3cc --- /dev/null +++ b/.svn/pristine/06/064e186630a3031de2e5e002c6dca24892a28619.svn-base @@ -0,0 +1,364 @@ +#ifndef _CCRSPROTOCOL_H_ +#define _CCRSPROTOCOL_H_ + +#define CC_TIME_OUT 300 + +#define SYNC 0x02 //!< synchronization byte +#define ACK 0x00 //!< ACK code +#define NAK 0xFF //!< NAK code +#define ST_INV_CMD 0x30 //!< INVALID COMMAND response + +/** \defgroup Addr Device Addresses +* @{ +*/ +#define ADDR_BB 0x01 //!< Address for Bill-To-Bill units +#define ADDR_CHANGER 0x02 //!< Address for Coin Changer +#define ADDR_FL 0x03 //!< Address for Bill Validators +#define ADDR_CR 0x04 //!< Address for Smart Card Reader +/**@} */ + +/** \defgroup Cmds Interface commands +* @{ +*/ +#define RESET 0x30 //! +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + + +#endif diff --git a/.svn/pristine/09/0962d2e7cbf504c49130f659d5962dddccac528e.svn-base b/.svn/pristine/09/0962d2e7cbf504c49130f659d5962dddccac528e.svn-base new file mode 100644 index 0000000..57ad459 --- /dev/null +++ b/.svn/pristine/09/0962d2e7cbf504c49130f659d5962dddccac528e.svn-base @@ -0,0 +1,2798 @@ +#include +#include "data.h" +#include "datadesc.h" +#include "menu.h" +#include "menudesc.h" +#include "fram_map.h" +#include +#include +#include +#include +#include "control.h" +#include "fiscal.h" +#include "time.h" +#include "CRC16.h" +#include "modem_task.h" +#include "modem.h" + +extern CPU_INT32U modem_status; + +/************************************* + +*************************************/ +CPU_INT32U ChannelIndex=0; +TRangeValueULONG const ChannelIndexRange = {0, CHANNELS_NUM-1}; +CPU_INT08U const ChannelIndexName[] = " "; +CPU_INT08U const* ChannelItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; + +TDataDescStruct const ChannelIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStIndexName[] = ".."; + +TDataDescStruct const ChannelStIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStLongIndexName[] = ".."; + +TDataDescStruct const ChannelStLongIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStLongIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + email +*************************************/ +extern TRangeValueULONG const WorkTimeRange; + +TDataDescStruct const LastEmailSendTime = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, LastEmailTime), // FRAM + (void*)&WorkTimeRange, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableChannelRange = {0, 1}; +CPU_INT08U const EnableChannelName[] = ""; +CPU_INT08U const EnableChannelList_str0[] = "."; +CPU_INT08U const EnableChannelList_str1[] = "."; +CPU_INT08U const *EnableChannelList[] = {EnableChannelList_str0, EnableChannelList_str1}; + + +TDataDescStruct const EnableChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Enable), // FRAM + (void*)&EnableChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableChannelName, // + DATA_IS_INDEX, // ( ) + EnableChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const NameChannelRange = {0, 2}; +CPU_INT08U const NameChannelName[] = ""; +CPU_INT08U const NameChannelList_str0[] = "#"; +CPU_INT08U const NameChannelList_str1[] = ""; +CPU_INT08U const NameChannelList_str2[] = ""; +CPU_INT08U const *NameChannelList[] = {NameChannelList_str0, NameChannelList_str1, NameChannelList_str2}; + + +TDataDescStruct const NameChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Name), // FRAM + (void*)&NameChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + NameChannelName, // + DATA_IS_INDEX, // ( ) + NameChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + ( ) +*************************************/ +TRangeValueULONG const StartButtonNameRange = {0, 1}; +CPU_INT08U const StartButtonNameName[] = ""; +CPU_INT08U const StartButtonNameList_str0[] = ""; +CPU_INT08U const StartButtonNameList_str1[] = ""; +CPU_INT08U const *StartButtonNameList[] = {StartButtonNameList_str0, StartButtonNameList_str1}; + + +TDataDescStruct const StartButtonNameDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, StartButtonName), // FRAM + (void*)&StartButtonNameRange, // + NULL, // + 0, // + StartButtonNameName, // + DATA_IS_INDEX, // ( ) + StartButtonNameList, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EnableValidatorRange = {0, 1}; +CPU_INT08U const EnableValidatorName[] = "-"; +CPU_INT08U const OnOffList_str0[] = "."; +CPU_INT08U const OnOffList_str1[] = "."; +CPU_INT08U const *EnableValidatorList[] = {OnOffList_str0, OnOffList_str1}; + + +TDataDescStruct const EnableValidatorDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableValidator), // FRAM + (void*)&EnableValidatorRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableValidatorName, // + DATA_IS_INDEX, // ( ) + EnableValidatorList, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableModemRange = {0, 1}; +CPU_INT08U const EnableModemName[] = ""; +CPU_INT08U const *EnableModemList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableModem(void) +{ + CPU_INT32U en = 0; + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + + if (en) + { + if (!IsModemConn()) + { + modem_status = 2; + } + else if (!IsModemConf()) + { + modem_status = 1; + } + PostModemTask(MODEM_TASK_RECONNECT); + } +} + +TDataDescStruct const EnableModemDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableModem), // FRAM + (void*)&EnableModemRange, // + OnchangeEnableModem, // + sizeof(CPU_INT32U), // + EnableModemName, // + DATA_IS_INDEX, // ( ) + EnableModemList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +TRangeValueULONG const EnableEmailErrorSendRange = {0, 1}; +CPU_INT08U const EnableEmailErrorSendName[] = ". ."; +CPU_INT08U const *EnableEmailErrorSendList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableEmailErrorSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailErrorSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailErrorSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ModemStatusName[] = ""; +CPU_INT08U const *ModemStatusList[] = {"", "..", " "}; + +TDataDescStruct const ModemStatusDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + &modem_status, // FRAM + NULL, // + NULL, // + 0, // + ModemStatusName, // + DATA_IS_INDEX, // ( ) + ModemStatusList,// + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const EnableEmailJournalSendName[] = "."; + +TDataDescStruct const EnableEmailJournalSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailJournalSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailJournalSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const ClearJournalAfterSendName[] = "."; + +TDataDescStruct const ClearJournalAfterSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ClearJournalAfterSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + ClearJournalAfterSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + , : +*************************************/ +TRangeValueULONG const StatSendHourRange = {0, 60*24 - 1}; +CPU_INT08U const StatSendHourName[] = "T."; + +TDataDescStruct const StatSendHourMinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_HOUR_MIN, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.StatSendHourMin), // FRAM + (void*)&StatSendHourRange, // + NULL, // + 0, // + StatSendHourName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 9 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableCoinRange = {0, 1}; +CPU_INT08U const EnableCoinName[] = "-"; +CPU_INT08U const *EnableCoinList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableCoin(void) +{ +} + +TDataDescStruct const EnableCoinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableCoinAcceptor), // FRAM + (void*)&EnableCoinRange, // + OnchangeEnableCoin, // + sizeof(CPU_INT32U), // + EnableCoinName, // + DATA_IS_INDEX, // ( ) + EnableCoinList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const CoinPerPulseRange = {1, 9999}; +CPU_INT08U const CoinPerPulseName[] = "./."; + +TDataDescStruct const CoinPerPulseDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.CoinPerPulse), // FRAM + (void*)&CoinPerPulseRange, // + NULL, // + 0, // + CoinPerPulseName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalRange = {0, 1}; +CPU_INT08U const EnableFiscalName[] = ""; +CPU_INT08U const *EnableFiscalList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableFiscalDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscal), // FRAM + (void*)&EnableFiscalRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalName, // + DATA_IS_INDEX, // ( ) + EnableFiscalList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const DisableFiscalErrorsRange = {0, 1}; +CPU_INT08U const DisableFiscalErrorsName[] = ".."; +CPU_INT08U const DisableFiscalErrorsList_str0[] = ""; +CPU_INT08U const DisableFiscalErrorsList_str1[] = ""; +CPU_INT08U const *DisableFiscalErrorsList[] = {DisableFiscalErrorsList_str0, DisableFiscalErrorsList_str1}; + +TDataDescStruct const DisableFiscalErrorsDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DisableFiscalErrors), // FRAM + (void*)&DisableFiscalErrorsRange, // + NULL, // + sizeof(CPU_INT32U), // + DisableFiscalErrorsName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U WorkTime[CHANNELS_NUM]; +TRangeValueULONG const WorkTimeRange = {0, 0xffffffffL}; +CPU_INT08U const WorkTimeName[] = "."; + +TDataDescStruct const WorkTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + &WorkTime, // FRAM + (void*)&WorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + WorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutBeforeRange = {0, 999}; +CPU_INT08U const TimeOutBeforeName[] = " ,."; + +TDataDescStruct const TimeOutBeforeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutBefore), // FRAM + (void*)&TimeOutBeforeRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutBeforeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 30 +}; + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutAfterRange = {0, 99}; +CPU_INT08U const TimeOutAfterName[] = " ,."; + +TDataDescStruct const TimeOutAfterDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutAfter), // FRAM + (void*)&TimeOutAfterRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutAfterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 3 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MaxWorkTimeRange = {1, 999}; +CPU_INT08U const MaxWorkTimeName[] = "Tmax,."; + +TDataDescStruct const MaxWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MaxWorkTime), // FRAM + (void*)&MaxWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MaxWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 20 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MinWorkTimeRange = {1, 999}; +CPU_INT08U const MinWorkTimeName[] = "Tmin,."; + +TDataDescStruct const MinWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MinWorkTime), // FRAM + (void*)&MinWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MinWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 5 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const WeekEndRange = {0, 4}; +CPU_INT08U const WeekEndName[] = ":"; +CPU_INT08U const WeekEndList_str0[] = ""; +CPU_INT08U const WeekEndList_str1[] = "-"; +CPU_INT08U const WeekEndList_str2[] = "-"; +CPU_INT08U const WeekEndList_str3[] = "-"; +CPU_INT08U const WeekEndList_str4[] = "-"; +CPU_INT08U const *WeekEndList[] = {WeekEndList_str0, WeekEndList_str1, WeekEndList_str2, WeekEndList_str3, WeekEndList_str4, NULL}; + +TDataDescStruct const WeekEndDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.WeekEnd), // FRAM + (void*)&WeekEndRange, // + NULL, // + sizeof(CPU_INT32U), // + WeekEndName, // + DATA_IS_INDEX, // ( ) + WeekEndList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const DeferredStartRange = {0, 1}; +CPU_INT08U const DeferredStartName[] = "."; +CPU_INT08U const DeferredStart_str0[] = ""; +CPU_INT08U const DeferredStart_str1[] = ""; +CPU_INT08U const *DeferredStartList[] = {DeferredStart_str0, DeferredStart_str1, NULL}; + +TDataDescStruct const DeferredStartDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, DefferedStartEnabled), // FRAM + (void*)&DeferredStartRange, // + NULL, // + sizeof(CPU_INT32U), // + DeferredStartName, // + DATA_IS_INDEX, // ( ) + DeferredStartList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PeriodIndexRange = {0, 0xffffffff/*CHANNELS_NUM*PRICE_PERIODS_NUM-1*/}; +CPU_INT08U const PeriodIndexName[] = ""; +CPU_INT08U const *PeriodWeekendIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; + +CPU_INT32U PeriodIndex = 0; + +void OnChangePeriodIndex(void) +{ + if ((PeriodIndex == 0xffffffff) || (PeriodIndex < ChannelIndex*PRICE_PERIODS_NUM)) PeriodIndex = (ChannelIndex+1)*PRICE_PERIODS_NUM-1; + else if (PeriodIndex >= (ChannelIndex+1)*PRICE_PERIODS_NUM) PeriodIndex = (ChannelIndex)*PRICE_PERIODS_NUM; +} + +TDataDescStruct const PeriodWeekendIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekendIndexList, // + DATA_INIT_ENABLE, + 0 +}; + +CPU_INT08U const *PeriodWeekdaysIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; +TDataDescStruct const PeriodWeekdaysIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekdaysIndexList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekendRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekendName[] = ",."; + +TDataDescStruct const PriceWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekend), // FRAM + (void*)&PriceWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekdaysRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekdaysName[] = ",."; + +TDataDescStruct const PriceWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekdays), // FRAM + (void*)&PriceWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekendRange = {1, 999}; +CPU_INT08U const PriceTimeWeekendName[] = " ,."; + +TDataDescStruct const PriceTimeWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekend), // FRAM + (void*)&PriceTimeWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekdaysRange = {1, 999}; +CPU_INT08U const PriceTimeWeekdaysName[] = " ,."; + +TDataDescStruct const PriceTimeWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekdays), // FRAM + (void*)&PriceTimeWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekdaysRange = {0, 24}; +CPU_INT08U const T_Start_WeekdaysName[] = ","; + +TDataDescStruct const T_Start_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekdays), // FRAM + (void*)&T_Start_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekdaysRange = {0, 24}; +CPU_INT08U const T_End_WeekdaysName[] = ","; + +TDataDescStruct const T_End_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekdays), // FRAM + (void*)&T_End_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekendRange = {0, 24}; +CPU_INT08U const T_Start_WeekendName[] = ","; + +TDataDescStruct const T_Start_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekend), // FRAM + (void*)&T_Start_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekendRange = {0, 24}; +CPU_INT08U const T_End_WeekendName[] = ","; + +TDataDescStruct const T_End_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekend), // FRAM + (void*)&T_End_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +CPU_INT32U InitByDefault = 0; + +TRangeValueULONG const InitByDefaultRange = {0, 1}; +CPU_INT08U const InitByDefaultName[] = ""; +CPU_INT08U const InitByDefaultList_str0[] = ""; +CPU_INT08U const InitByDefaultList_str1[] = ""; +CPU_INT08U const *InitByDefaultList[] = {InitByDefaultList_str0, InitByDefaultList_str1}; + + +void OnChangeInitByDefault(void) +{ + int i = 0; + if (InitByDefault == 0) return; + while (AllDataArray[i].ptr != NULL) + { + InitDescByDefault(AllDataArray[i].ptr); + i++; + } + InitByDefault = 0; +} + + +TDataDescStruct const InitByDefaultDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&InitByDefault, // FRAM + (void*)&InitByDefaultRange, // + OnChangeInitByDefault, // + 0, // + InitByDefaultName, // + DATA_IS_INDEX, // ( ) + InitByDefaultList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + Z- +*************************************/ +CPU_INT32U PrintZReportCmd = 0; + +CPU_INT08U const PrintZReportName[] = "Z-"; +CPU_INT08U const PrintZReportList_str0[] = ""; +CPU_INT08U const PrintZReportList_str1[] = ""; +CPU_INT08U const *PrintZReportList[] = {PrintZReportList_str0, PrintZReportList_str1}; + + +void OnChangePrintZReportCmd(void) +{ +} + +TDataDescStruct const PrintZReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintZReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintZReportCmd, // + 0, // + PrintZReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + X- +*************************************/ +CPU_INT32U PrintXReportCmd = 0; + +CPU_INT08U const PrintXReportName[] = "X-"; + +void OnChangePrintXReportCmd(void) +{ +} + +TDataDescStruct const PrintXReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintXReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintXReportCmd, // + 0, // + PrintXReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const ErrorJournalIndexName[] = " #"; +CPU_INT32U ErrorJournalIndex = 0; + +void OnChangeErrorJournalIndex(void) +{ + if (ErrorJournalIndex == 0xffffffff) ErrorJournalIndex = ERROR_RECORDS_NUM-1; + else if (ErrorJournalIndex > ERROR_RECORDS_NUM-1) ErrorJournalIndex = 0; +} + +TDataDescStruct const ErrorJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ErrorJournalIndex, // FRAM + (void*)&ErrorJournalIndexRange, // + OnChangeErrorJournalIndex, // + 0, // + ErrorJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorNumberRange = {0, ERRORS_NUM-1}; +CPU_INT08U const *ErrorNumberList0[ERRORS_NUM] = {"", + " ", + " ", + "1Ch60h-.", + "1Ch61h-.", + "1Ch64h-.", + "1Ch65h-.", + "1Ch66h-.", + "1Ch67h-.", + "1Ch68h-.", + "1Ch69h-.", + "1Ch6Ch-.", + "/:41h-", + "/:42h-", + "/:43h- ", + "/:44h-", + "/:45h-", + "/:50h-", + "/:51h- .", + "/:52h-", + "/:53h- .", + "/:54h-", + "/:65h-", + "/:66h-", + "/:67h- .", + "", + "", + + ":01h-", + ":02h-", + ":03h-", + ":04h-.-", + ":05h-", + ":06h- ", + ":07h-.-", + ":08h-", + ":09h-.", + ":0Ah- ", + ":0Bh-.", + ":11h- ", + ":12h-", + ":13h- ", + ":14h-", + ":15h-", + ":16h-", + ":17h- ", + ":18h- ", + ":19h- ", + ":1Ah- ", + ":1Bh-", + ":1Ch-", + ":1Dh-", + ":1Fh-", + ":20h-", + ":21h- ", + ":22h- ", + ":23h- ", + ":24h-", + ":25h-", + ":28h- ", + ":33h-", + ":35h-", + ":36h-", + ":37h-", + ":38h- ", + ":39h-", + ":3Ah-", + ":3Ch-:", + ":3Eh-", + ":3Fh-", + ":40h-", + ":41h-", + ":42h-", + ":43h-", + ":44h-", + ":45h-C", + ":46h- ", + ":47h-", + ":48h-", + ":4Ah- ", + ":4Bh- ", + ":4Ch-", + ":4Dh-", + ":4Eh-", + ":4Fh- ", + ":50h- ", + ":51h-", + ":52h-", + ":53h-", + ":54h-", + ":56h- .", + ":57h-:", + ":58h-", + ":59h-", + ":5Bh-", + ":5Ch-", + ":5Dh-", + ":5Eh-", + ":5Fh-.", + ":60h-", + ":61h-", + ":62h-", + ":63h-", + ":64h- ", + ":65h- ", + ":66h-", + ":67h- ", + ":68h- ", + ":69h-", + ":6Ah-", + ":6Bh- ", + ":6Ch- .", + ":6Dh- ", + ":6Eh-", + ":6Fh-", + ":70h-", + ":71h-", + ":72h- ", + ":73h- ", + ":74h- ", + ":75h-", + ":76h-:", + ":77h-:", + ":78h- ", + ":79h- ", + ":7Ah- ", + ":7Bh-", + ":7Ch- ", + ":7Dh-", + ":7Eh-", + ":7Fh-", + ":80h-", + ":81h-", + ":82h-", + ":83h-", + ":84h-", + ":85h-", + ":86h-", + ":87h-", + ":88h-", + ":89h-", + ":8Ah-", + ":8Bh-", + ":8Ch-.", + ":8Dh-", + ":8Eh- ", + ":8Fh- ", + ":90h- .", + ":91h- ", + ":92h-", + ":93h-", + ":94h-", + ":A0h- ", + ":A1h-", + ":A2h-: ", + ":A3h-", + ":A4h- ", + ":A5h- ", + ":A6h-", + ":A7h-", + ":A8h-:", + ":A9h-:", + ":AAh-", + ":B0h-:", + ":B1h-:", + ":B2h-:", + ":C0h-", + ":C1h-:", + ":C2h-", + ":C3h-", + ":C4h-", + //":5h-", + //":C6h-", + //":C7h- ", + //":8h-", + +}; + +TDataDescStruct const JournalErrorNumberDesc0 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList0, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const *ErrorNumberList1[ERRORS_NUM] = {"", + "", + "", + " ", + " .", + " .", + " ", + " ", + " . ", + " ", + " .", + " ", + "", + "", + "", + " ", + "", + " ", + ".", + ".", + "", + "", + "", + ".", + "", + "", + " ", + "1,2 ", + " 1", + " 2", + " ", + " ", + " ", + " ", + " .", + " ", + " BCD", + " ", + "", + " ", + " ", + "", + " ", + " ", + "", + "", + " ", + "", + " ", + ". ", + " ", + " ", + " ", + "", + "", + "", + ".", + "", + "2 ", + " ", + "", + "", + " .", + "", + " ", + " ", + " .", + ". ", + ". ", + " ", + " ", + " 2", + " 3", + " 4", + " ", + " ", + " ", + " ", + " ", + "", + ". ", + ". ", + " 24 ", + "", + ".", + " ", + " 2 ", + " 3 ", + " 4 ", + " ", + " - ", + " ", + " .", + " ", + " 24", + " ", + "", + " ", + " ", + " ", + " -", + " ", + "", + " ", + " ", + " ", + " ", + " ", + "", + "", + "", + " ", + " ", + " ", + "", + "", + ".", + ".", + "", + "", + " ", + " ", + "", + "", + "", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + "", + " ", + " ", + "", + " ", + " ", + " ", + "", + ". ", + " ", + "", + " ", + ". ", + "", + " ", + " ", + "", + " -", + " ", + " ", + " ", + " ", + "", + " ", + " ", + //".. ", + //".", + //"", + //"" + +}; + +TDataDescStruct const JournalErrorNumberDesc1 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList1, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + - +*************************************/ +CPU_INT08U const *ErrorNumberListEng[ERRORS_NUM] = +{ + "Net oshibki", + "Oshibka svyazi c kupuropriemnikom", + "Kriticheskaya oshibka kupuropriemnika", + "Vybros kupury po mag.datchiku", + "Vybros kupury pri transportirovke", + "Vybros kupury po identifikacii", + "Vybros kupury po verifikacii", + "Vybros kupury po opt.datchiku", + "Vybros kupury po zapretu", + "Vybros kupury po emk.datchiku", + "Vybros kupury po dline", + "Kasseta zapolnena", + "Kasseta otsutstvuet", + "Zamin v kupuropriemnike", + "Zamin v kassete", + "Popytka obmana", + "Oshibka stekernogo motora", + "Oshibka skorosti transp.motora", + "Oshibka transp.motora", + "Oshibka mehanizmavyravnivaniya", + "Kasseta otsutstvuet", + "Oshibka optiki", + "Oshibka magn.datchika", + "Oshibka emk.datchika", + "Nekriticheskaya oshibka kupuropriemnika", + + "Oshibka svyazi s modemom", + "Oshibka svyazi s FR", + "Oshibka FR 0x01", + "Oshibka FR 0x02", + "Oshibka FR 0x03", + "Oshibka FR 0x04", + "Oshibka FR 0x05", + "Oshibka FR 0x06", + "Oshibka FR 0x07", + "Oshibka FR 0x08", + "Oshibka FR 0x09", + "Oshibka FR 0x0A", + "Oshibka FR 0x0B", + "Oshibka FR 0x11", + "Oshibka FR 0x12", + "Oshibka FR 0x13", + "Oshibka FR 0x14", + "Oshibka FR 0x15", + "Oshibka FR 0x16", + "Oshibka FR 0x17", + "Oshibka FR 0x18", + "Oshibka FR 0x19", + "Oshibka FR 0x1A", + "Oshibka FR 0x1B", + "Oshibka FR 0x1C", + "Oshibka FR 0x1D", + "Oshibka FR 0x1F", + "Oshibka FR 0x20", + "Oshibka FR 0x21", + "Oshibka FR 0x22", + "Oshibka FR 0x23", + "Oshibka FR 0x24", + "Oshibka FR 0x25", + "Oshibka FR 0x28", + "Oshibka FR 0x33", + "Oshibka FR 0x35", + "Oshibka FR 0x36", + "Oshibka FR 0x37", + "Oshibka FR 0x38", + "Oshibka FR 0x39", + "Oshibka FR 0x3A", + "Oshibka FR 0x3C", + "Oshibka FR 0x3E", + "Oshibka FR 0x3F", + "Oshibka FR 0x40", + "Oshibka FR 0x41", + "Oshibka FR 0x42", + "Oshibka FR 0x43", + "Oshibka FR 0x44", + "Oshibka FR 0x45", + "Oshibka FR 0x46", + "Oshibka FR 0x47", + "Oshibka FR 0x48", + "Oshibka FR 0x4A", + "Oshibka FR 0x4B", + "Oshibka FR 0x4C", + "Oshibka FR 0x4D", + "Oshibka FR 0x4E", + "Oshibka FR 0x4F", + "Oshibka FR 0x50", + "Oshibka FR 0x51", + "Oshibka FR 0x52", + "Oshibka FR 0x53", + "Oshibka FR 0x54", + "Oshibka FR 0x56", + "Oshibka FR 0x57", + "Oshibka FR 0x58", + "Oshibka FR 0x59", + "Oshibka FR 0x5B", + "Oshibka FR 0x5C", + "Oshibka FR 0x5D", + "Oshibka FR 0x5E", + "Oshibka FR 0x5F", + "Oshibka FR 0x60", + "Oshibka FR 0x61", + "Oshibka FR 0x62", + "Oshibka FR 0x63", + "Oshibka FR 0x64", + "Oshibka FR 0x65", + "Oshibka FR 0x66", + "Oshibka FR 0x67", + "Oshibka FR 0x68", + "Oshibka FR 0x69", + "Oshibka FR 0x6A", + "Oshibka FR 0x6B", + "Oshibka FR 0x6C", + "Oshibka FR 0x6D", + "Oshibka FR 0x6E", + "Oshibka FR 0x6F", + "Oshibka FR 0x70", + "Oshibka FR 0x71", + "Oshibka FR 0x72", + "Oshibka FR 0x73", + "Oshibka FR 0x74", + "Oshibka FR 0x75", + "Oshibka FR 0x76", + "Oshibka FR 0x77", + "Oshibka FR 0x78", + "Oshibka FR 0x79", + "Oshibka FR 0x7A", + "Oshibka FR 0x7B", + "Oshibka FR 0x7C", + "Oshibka FR 0x7D", + "Oshibka FR 0x7E", + "Oshibka FR 0x7F", + "Oshibka FR 0x80", + "Oshibka FR 0x81", + "Oshibka FR 0x82", + "Oshibka FR 0x83", + "Oshibka FR 0x84", + "Oshibka FR 0x85", + "Oshibka FR 0x86", + "Oshibka FR 0x87", + "Oshibka FR 0x88", + "Oshibka FR 0x89", + "Oshibka FR 0x8A", + "Oshibka FR 0x8B", + "Oshibka FR 0x8C", + "Oshibka FR 0x8D", + "Oshibka FR 0x8E", + "Oshibka FR 0x8F", + "Oshibka FR 0x90", + "Oshibka FR 0x91", + "Oshibka FR 0x92", + "Oshibka FR 0x93", + "Oshibka FR 0x94", + "Oshibka FR 0xA0", + "Oshibka FR 0xA1", + "Oshibka FR 0xA2", + "Oshibka FR 0xA3", + "Oshibka FR 0xA4", + "Oshibka FR 0xA5", + "Oshibka FR 0xA6", + "Oshibka FR 0xA7", + "Oshibka FR 0xA8", + "Oshibka FR 0xA9", + "Oshibka FR 0xAA", + "Oshibka FR 0xB0", + "Oshibka FR 0xB1", + "Oshibka FR 0xB2", + "Oshibka FR 0xC0", + "Oshibka FR 0xC1", + "Oshibka FR 0xC2", + "Oshibka FR 0xC3" + "Oshibka FR 0xC4" +}; + +TDataDescStruct const JournalErrorNumberDescEng = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberListEng, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalErrorTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EventJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const EventJournalIndexName[] = " #"; +CPU_INT32U EventJournalIndex = 0; + +void OnChangeEventJournalIndex(void) +{ + TEventRecord record; + + if (EventJournalIndex == 0xffffffff) EventJournalIndex = EVENT_RECORDS_NUM-1; + else if (EventJournalIndex > ERROR_RECORDS_NUM-1) EventJournalIndex = 0; + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +TDataDescStruct const EventJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&EventJournalIndex, // FRAM + (void*)&EventJournalIndexRange, // + OnChangeEventJournalIndex, // + 0, // + EventJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalEventTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &EventJournalIndexDesc, // + (void*)offsetof(TFramMap, EventRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TEventRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U SystemTime; + +TDataDescStruct const SystemTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +void OnSetTime(void) +{ + TRTC_Data rtc; + Sec2Date(&rtc, SystemTime); + RTC_SetTime(&rtc); +} + +TDataDescStruct const SystemTimeEditDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + OnSetTime, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U ClearJournalCmd = 0; + +CPU_INT08U const ClearJournalCmdName[] = ""; +CPU_INT08U const ClearJournalCmdList_str0[] = ""; +CPU_INT08U const ClearJournalCmdList_str1[] = ""; +CPU_INT08U const *ClearJournalCmdList[] = {ClearJournalCmdList_str0, ClearJournalCmdList_str1}; + +void OnChangeClearJournalCmd(void) +{ + if (ClearJournalCmd) + { + ClearErrorJournal(); + ClearEventJournal(); + ClearJournalCmd = 0; + } +} + +TDataDescStruct const ClearJournalCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearJournalCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearJournalCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT08U const CounterRunName[] = ""; + +TDataDescStruct const CounterRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterRun), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterMoneyName[] = ",."; + +TDataDescStruct const CounterMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterMoney), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterTimeName[] = ".."; + +TDataDescStruct const CounterTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterTime), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterRunLong), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterMoneyLong), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterTimeLong), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelRun[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelMoney[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelRunLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelMoneyLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelTimeLong), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U ClearStatCmd = 0; + +CPU_INT08U const ClearStatCmdName[] = ""; + +void OnChangeClearStatCmd(void) +{ + if (ClearStatCmd) + { + ClearCounters(); + ClearStatCmd = 0; + } +} + +TDataDescStruct const ClearStatCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearStatCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearStatCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalDayClearRange = {0, 2}; +CPU_INT08U const EnableFiscalDayClearName[] = "."; +CPU_INT08U const *EnableFiscalDayClearList[] = {".", "", ""}; + +TDataDescStruct const EnableFiscalDayClearDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscalDayClear), // FRAM + (void*)&EnableFiscalDayClearRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalDayClearName, // + DATA_IS_INDEX, // ( ) + EnableFiscalDayClearList, // + DATA_INIT_ENABLE, + 1 // +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const BillFormatRange = {0, 1}; +CPU_INT08U const BillFormatName[] = ":"; +CPU_INT08U const BillFormatList_str0[] = "-*"; +CPU_INT08U const BillFormatList_str1[] = ""; +CPU_INT08U const *BillFormatList[] = {BillFormatList_str0, BillFormatList_str1}; + +TDataDescStruct const BillFormatDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.BillFormat), // FRAM + (void*)&BillFormatRange, // + NULL, // + sizeof(CPU_INT32U), // + BillFormatName, // + DATA_IS_INDEX, // ( ) + BillFormatList, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ServiceNameRange = {0, 0}; +CPU_INT08U const ServiceNameName[] = ""; +CPU_INT08U const *ServiceNameList[] = {" "}; + +TDataDescStruct const ServiceNameDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ServiceName), // FRAM + (void*)&ServiceNameRange, // + NULL, // + sizeof(CPU_INT32U), // + ServiceNameName, // + DATA_IS_INDEX, // ( ) + ServiceNameList, // + DATA_INIT_DISABLE, + 0 // +}; + +/************************************* + +*************************************/ +TDataDescStruct const AcceptedMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, FRAM_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + Crc16 +*************************************/ +TDataDescStruct const AcceptedMoneyCRC16Desc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PassRange = {0, 9999}; +CPU_INT08U const PassName[] = " b"; + +void OnChangePass(void) +{ + // CRC + CPU_INT32U pass,crc; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); +} + +TDataDescStruct const PassDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Pass), // FRAM + (void*)&PassRange, // + OnChangePass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + DEFAULT_PASSWORD +}; + +/************************************* + CRC +*************************************/ +TDataDescStruct const PassCRCDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_Pass), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U TempPass = 0; + +void OnChangeTempPass(void) +{ + CPU_INT32U pass; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + + if (GetCurrentMenu() == SetPassMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {GoToPreviousMenu(); GoToMenu(SetNewPassMenuPanel);} + } + else if (GetCurrentMenu() == ResetSettingsMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {InitByDefault = 1; OnChangeInitByDefault(); GoToPreviousMenu(); GoToMenu(SettingsIsReset);} + } + else if (GetCurrentMenu() == ClearStatMenu) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearStatCmd = 1; OnChangeClearStatCmd(); GoToPreviousMenu(); GoToMenu(StatIsReset);} + } + else if (GetCurrentMenu() == ClearJournalMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearJournalCmd = 1; OnChangeClearJournalCmd(); GoToPreviousMenu(); GoToMenu(JournalIsReset);} + } + +} + +TDataDescStruct const PassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +CPU_INT08U const PassTempName1[] = " b"; + +TDataDescStruct const PassTempDesc1 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName1, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +TRangeValueULONG const MasterPassRange = {0, 99999999}; +CPU_INT08U const MasterPassTempName[] = "b"; + +void OnChangeMasterPass(void) +{ + CPU_INT32U pass, crc; + + if (TempPass == MASTER_PASSWORD) + { + TempPass = 0; + pass = DEFAULT_PASSWORD; + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); + + GoToPreviousMenu(); + GoToPreviousMenu(); + GoToMenu(SetNewPassMenuPanel); + } +} + +TDataDescStruct const MasterPassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&MasterPassRange, // + OnChangeMasterPass, // + 0, // + (void*)&MasterPassTempName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const PassTempName2[] = " b"; + +TDataDescStruct const PassTempDesc2 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName2, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const SendTestEmailName[] = "."; +CPU_INT32U send_test; + +void OnChangeSendTestEmail(void) +{ + if (send_test) + { + PostModemTask(MODEM_TASK_SEND_TEST_MSG); + send_test = 0; + } +} + +TDataDescStruct const SendTestEmailDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)&send_test, // FRAM + (void*)&EnableEmailErrorSendRange, // + OnChangeSendTestEmail, // + sizeof(CPU_INT32U), // + SendTestEmailName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U BillnomViewIndex; +TRangeValueULONG const BillnomIndexRange = {0, 23}; +CPU_INT08U const BillnomName[] = " #"; +CPU_INT08U const* BillnomItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}; + +TDataDescStruct const BillnomIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &BillnomViewIndex, // FRAM + (void*)&BillnomIndexRange, // + NULL, // + 0, // + BillnomName, // + DATA_IS_INDEX, // ( ) + BillnomItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U BillNominals[24]; +CPU_INT08U const BillnomValName[] = ",."; + +TDataDescStruct const BillnomDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + 24, // + (void*)&BillnomIndexDesc, // + (void*)&BillNominals, // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomValName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillnomCountersName[] = "-"; + +TDataDescStruct const BillnomCountersDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + 24, // + &BillnomIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterBillNominals[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomCountersName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillCounterName[] = " "; + +TDataDescStruct const BillCounterDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.BillsCount), // FRAM + NULL, // + NULL, // + 0, // + BillCounterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + ID +*************************************/ +CPU_INT08U const DeviceIDName[] = "ID -"; +TRangeValueULONG const DeviceIDRange = {0, 9999}; + +TDataDescStruct const DeviceIDDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DeviceId), // FRAM + (void*)&DeviceIDRange, // + NULL, // + 0, // + DeviceIDName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasSendFlagDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasEmailFlag), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasMoney), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +//************************************************** +//************************************************** +//************************************************** +const TDataDescArrayStruct AllDataArray[] = { + &WorkTimeDesc, + &ChannelIndexDesc, + &EnableChannelDesc, + &EnableValidatorDesc, + &EnableModemDesc, + &EnableFiscalDesc, + &EnableCoinDesc, + &TimeOutBeforeDesc, + &TimeOutAfterDesc, + &MaxWorkTimeDesc, + &MinWorkTimeDesc, + &WeekEndDesc, + &PeriodWeekendIndexDesc, + &PeriodWeekdaysIndexDesc, + + &PriceWeekendDesc, + &PriceWeekdaysDesc, + + &PriceTimeWeekendDesc, + &PriceTimeWeekdaysDesc, + &T_Start_WeekdaysDesc, + &T_End_WeekdaysDesc, + &T_Start_WeekendDesc, + &T_End_WeekendDesc, + + &PrintZReportDesc, + &PrintXReportDesc, + &ErrorJournalIndexDesc, + &SystemTimeDesc, + &SystemTimeEditDesc, + &CoinPerPulseDesc, + + &BillFormatDesc, + &NameChannelDesc, + + &PassDesc, + &DeviceIDDesc, + + &EnableEmailErrorSendDesc, + &EnableEmailJournalSendDesc, + &ClearJournalAfterSendDesc, + &StatSendHourMinDesc, + &SendTestEmailDesc, + &BillnomIndexDesc, + + &DeferredStartDesc, + &StartButtonNameDesc, + + NULL +}; + + diff --git a/.svn/pristine/09/0986d6aa69edd2709d47cc1ad07666411e99b021.svn-base b/.svn/pristine/09/0986d6aa69edd2709d47cc1ad07666411e99b021.svn-base new file mode 100644 index 0000000..7f02c00 --- /dev/null +++ b/.svn/pristine/09/0986d6aa69edd2709d47cc1ad07666411e99b021.svn-base @@ -0,0 +1,851 @@ +#define BSP_GLOBALS +#include + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U VIC_SpuriousInt; + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static void PLL_Init (void); +static void MAM_Init (void); +static void GPIO_Init (void); +static void VIC_Init (void); + +static void Tmr_TickInit (void); + +static void VIC_Dummy (void); /* Prototypes for dummy interrupt handlers */ +static void VIC_DummyWDT (void); +static void VIC_DummySW (void); +static void VIC_DummyDEBUGRX (void); +static void VIC_DummyDEBUGTX (void); +static void VIC_DummyTIMER0 (void); +static void VIC_DummyTIMER1 (void); +static void VIC_DummyUART0 (void); +static void VIC_DummyUART1 (void); +static void VIC_DummyPWM01 (void); +static void VIC_DummyI2C0 (void); +static void VIC_DummySPI (void); +static void VIC_DummySSP1 (void); +static void VIC_DummyPLL (void); +static void VIC_DummyRTC (void); +static void VIC_DummyEINT0 (void); +static void VIC_DummyEINT1 (void); +static void VIC_DummyEINT2 (void); +static void VIC_DummyEINT3 (void); +static void VIC_DummyAD0 (void); +static void VIC_DummyI2C1 (void); +static void VIC_DummyBOD (void); +static void VIC_DummyETHERNET(void); +static void VIC_DummyUSB (void); +static void VIC_DummyCAN01 (void); +static void VIC_DummyMMC (void); +static void VIC_DummyGP_DMA (void); +static void VIC_DummyTIMER2 (void); +static void VIC_DummyTIMER3 (void); +static void VIC_DummyUART2 (void); +static void VIC_DummyUART3 (void); +static void VIC_DummyI2C2 (void); +static void VIC_DummyI2S (void); + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +********************************************************************************************************* +** GLOBAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* BSP_Init() +* +* Description : Initialize the Board Support Package (BSP). +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) This function SHOULD be called before any other BSP function is called. +********************************************************************************************************* +*/ + +void BSP_Init (void) +{ + PLL_Init(); /* Initialize the PLL */ + MAM_Init(); /* Initialize the Memory Acceleration Module */ + GPIO_Init(); /* Initialize the board's I/Os */ + VIC_Init(); /* Initialize the Vectored Interrupt Controller */ + + Tmr_TickInit(); /* Initialize the uC/OS-II tick interrupt */ +} + + +/* +********************************************************************************************************* +* BSP_CPU_ClkFreq() +* +* Description : Get the CPU clock frequency. +* +* Argument(s) : none. +* +* Return(s) : The CPU clock frequency, in Hz. +********************************************************************************************************* +*/ + +CPU_INT32U BSP_CPU_ClkFreq (void) +{ + CPU_INT32U msel; + CPU_INT32U nsel; + CPU_INT32U fin; + CPU_INT32U pll_clk_feq; /* When the PLL is enabled, this is Fcco */ + CPU_INT32U clk_div; + CPU_INT32U clk_freq; + + + switch (CLKSRCSEL & 0x03) { /* Determine the current clock source */ + case 0: + fin = IRC_OSC_FRQ; + break; + + case 1: + fin = MAIN_OSC_FRQ; + break; + + case 2: + fin = RTC_OSC_FRQ; + break; + + default: + fin = IRC_OSC_FRQ; + break; + } + + if ((PLLSTAT & (1 << 25)) > 0) { /* If the PLL is currently enabled and connected */ + msel = (CPU_INT32U)(PLLSTAT & 0x3FFF) + 1; /* Obtain the PLL multiplier */ + nsel = (CPU_INT32U)((PLLSTAT >> 16) & 0x0F) + 1; /* Obtain the PLL divider */ + pll_clk_feq = (2 * msel * (fin / nsel)); /* Compute the PLL output frequency */ + } else { + pll_clk_feq = (fin); /* The PLL is bypassed */ + } + + clk_div = (CPU_INT32U)(CCLKCFG & 0xFF) + 1; /* Obtain the CPU core clock divider */ + clk_freq = (CPU_INT32U)(pll_clk_feq / clk_div); /* Compute the ARM Core clock frequency */ + + return (clk_freq); +} + +/* +********************************************************************************************************* +* BSP_CPU_PclkFreq() +* +* Description : Get the peripheral clock frequency for a specific peripheral. +* +* Argument(s) : pclk The peripheral clock ID, one of PCLK_??? defined in bsp.h. +* +* Return(s) : The peripheral's clock in Hz +********************************************************************************************************* +*/ + + +CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk) +{ + CPU_INT32U clk_freq; + CPU_INT32U selection; + + + clk_freq = BSP_CPU_ClkFreq(); + + switch (pclk) { + case PCLK_WDT: + case PCLK_TIMER0: + case PCLK_TIMER1: + case PCLK_UART0: + case PCLK_UART1: + case PCLK_PWM0: + case PCLK_PWM1: + case PCLK_I2C0: + case PCLK_SPI: + case PCLK_RTC: + case PCLK_SSP1: + case PCLK_DAC: + case PCLK_ADC: + case PCLK_CAN1: + case PCLK_CAN2: + case PCLK_ACF: + selection = ((PCLKSEL0 >> (pclk * 2)) & 0x03); + if (selection == 0) { + return (clk_freq / 4); + } else if (selection == 1) { + return (clk_freq); + } else if (selection == 2) { + return (clk_freq / 2); + } else { + return (clk_freq / 8); + } + + case PCLK_BAT_RAM: + case PCLK_GPIO: + case PCLK_PCB: + case PCLK_I2C1: + case PCLK_SSP0: + case PCLK_TIMER2: + case PCLK_TIMER3: + case PCLK_UART2: + case PCLK_UART3: + case PCLK_I2C2: + case PCLK_MCI: + case PCLK_SYSCON: + selection = ((PCLKSEL1 >> ((pclk - 16) * 2)) & 0x03); + if (selection == 0) { + return (clk_freq / 4); + } else if (selection == 1) { + return (clk_freq); + } else if (selection == 2) { + return (clk_freq / 2); + } else { + return (clk_freq / 8); + } + + default: + return (0); + } +} + + +/* +********************************************************************************************************* +* OS_CPU_ExceptHndlr() +* +* Description : Handle any exceptions. +* +* Argument(s) : except_id ARM exception type: +* +* OS_CPU_ARM_EXCEPT_RESET 0x00 +* OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01 +* OS_CPU_ARM_EXCEPT_SWI 0x02 +* OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03 +* OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04 +* OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05 +* OS_CPU_ARM_EXCEPT_IRQ 0x06 +* OS_CPU_ARM_EXCEPT_FIQ 0x07 +* +* Return(s) : none. +* +* Caller(s) : OS_CPU_ARM_EXCEPT_HANDLER(), which is declared in os_cpu_a.s. +********************************************************************************************************* +*/ + +void OS_CPU_ExceptHndlr (CPU_DATA except_id) +{ + CPU_FNCT_VOID pfnct; + CPU_INT32U *sp; + + /* If this exception is either an IRQ or FIQ */ + if ((except_id == OS_CPU_ARM_EXCEPT_IRQ) || (except_id == OS_CPU_ARM_EXCEPT_FIQ)) { + pfnct = (CPU_FNCT_VOID)VICADDRESS; /* Read the interrupt vector from the VIC */ + if (pfnct != (CPU_FNCT_VOID)0) { /* Make sure we don't have a NULL pointer */ + (*pfnct)(); /* Execute the ISR for the interrupting device */ + VICADDRESS = 1; /* Acknowlege the VIC interrupt */ + } + } else { + sp = (CPU_INT32U *)OSTCBCur->OSTCBStkPtr; + APP_TRACE_INFO(("\nCPU_ARM_EXCEPTION #%d trapped.\n", except_id)); + APP_TRACE_INFO(("R0 : 0x%08x\n", *(sp + 0x01))); + APP_TRACE_INFO(("R1 : 0x%08x\n", *(sp + 0x02))); + APP_TRACE_INFO(("R2 : 0x%08x\n", *(sp + 0x03))); + APP_TRACE_INFO(("R3 : 0x%08x\n", *(sp + 0x04))); + APP_TRACE_INFO(("R4 : 0x%08x\n", *(sp + 0x05))); + APP_TRACE_INFO(("R5 : 0x%08x\n", *(sp + 0x06))); + APP_TRACE_INFO(("R6 : 0x%08x\n", *(sp + 0x07))); + APP_TRACE_INFO(("R7 : 0x%08x\n", *(sp + 0x08))); + APP_TRACE_INFO(("R8 : 0x%08x\n", *(sp + 0x09))); + APP_TRACE_INFO(("R9 : 0x%08x\n", *(sp + 0x0A))); + APP_TRACE_INFO(("R10 : 0x%08x\n", *(sp + 0x0B))); + APP_TRACE_INFO(("R11 : 0x%08x\n", *(sp + 0x0C))); + APP_TRACE_INFO(("R12 : 0x%08x\n", *(sp + 0x0D))); + APP_TRACE_INFO(("SP : 0x%08x\n", sp)); + APP_TRACE_INFO(("LR : 0x%08x\n", *(sp + 0x0E))); + APP_TRACE_INFO(("PC : 0x%08x\n", *(sp + 0x0F))); + APP_TRACE_INFO(("CPSR: 0x%08x\n", *(sp + 0x00))); + + /* Infinite loop on other exceptions. */ + /* Should be replaced by other behavior (reboot, etc.) */ + while (DEF_TRUE) { + ; + } + } +} + + +/* +********************************************************************************************************* +* BSP_IntDisAll() +* +* Description : Disable ALL interrupts. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +void BSP_IntDisAll (void) +{ + VICINTENCLEAR = 0xFFFFFFFFL; /* Disable ALL interrupts */ +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** uC/OS-II TIMER FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* Tmr_TickInit() +* +* Description : Initialize uC/OS-II's tick source. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void Tmr_TickInit (void) +{ + CPU_INT32U pclk_freq; + CPU_INT32U rld_cnts; + + /* VIC timer #0 Initialization */ + VICINTSELECT &= ~(1 << VIC_TIMER0); /* Configure the timer interrupt as an IRQ source */ + VICVECTADDR4 = (CPU_INT32U)Tmr_TickISR_Handler; /* Set the vector address */ + VICINTENABLE = (1 << VIC_TIMER0); /* Enable the timer interrupt source */ + + pclk_freq = BSP_CPU_PclkFreq(PCLK_TIMER0); /* Get the peripheral clock frequency */ + + rld_cnts = pclk_freq / OS_TICKS_PER_SEC; /* Calculate the # of counts necessary for the OS ticker */ + + T0TCR = (1 << 1); /* Disable and reset counter 0 and the prescale counter 0 */ + T0TCR = 0; /* Clear the reset bit */ + T0PC = 0; /* Prescaler is set to no division */ + + T0MR0 = rld_cnts-1; + T0MCR = 3; /* Interrupt on MR0 (reset TC), stop TC */ + + T0CCR = 0; /* Capture is disabled. */ + T0EMR = 0; /* No external match output. */ + T0TCR = 1; /* Enable timer 0 */ +} + + +/* +********************************************************************************************************* +* Tmr_TickISR_Handler() +* +* Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +void Tmr_TickISR_Handler (void) +{ + T0IR = 0xFF; /* Clear timer #0 interrupt */ + + OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */ +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** LOCAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* PLL_Init() +* +* Description : Set up and activate the PLL. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) The PLL output frequency is calculated by: +* +* Fcco = 2 * Fin * m / n +* +* where +* +* Fin is the PLL input clock (here, the main oscillator) +* M is the PLL clock multiplier. The value (M - 1) is programmed in PLLCFG. +* N is the PLL clock divider. The value (N - 1) is programmed in PLLCFG. +* +* (2) Fcco must be between 250 and 550 MHz. The ARM Core clock must never exceed 72 MHz. +* Set clk_div to divide Fcco accordingly. +* +* (3) When using the USB device, you must choose Fcco as a multiple of 96 MHz, and then +* set clk_div_usb to divide Fcco to exactly 48 MHz. +* +* (4) In this example +* +* Fin = 12MHz, +* M = 12, +* N = 1, +* clk_div = 6, and +* clk_div_usb = 6. +* +* Therefore, Fcco = 2 * Fin * M / N = (2 * 12 * 12 / 1) = 288MHz. +* The processor clock = (Fcco / clk_div) = (288MHz / 6) = 48MHz. +* Finally, the USB clock = (Fcco / clk_div_usb) = (288MHz / 6) = 48MHz. +* +* (5) A PLL errata on early revisions of the part prevent Fcco from being greater than 288MHz. +* +* (6) For later revisions, M = 20, clk_div = 8, and clk_div_usb = 10 will yield 60MHz for +* the processor clock and 48MHz for the USB clock. +********************************************************************************************************* +*/ + +static void PLL_Init (void) +{ +#if CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL /* Allocate storage for CPU status register */ + CPU_SR cpu_sr = 0; +#endif + + CPU_INT32U m; + CPU_INT32U n; + CPU_INT32U clk_div; + CPU_INT32U clk_div_usb; + + + m = 11; /* PLL Multiplier = 20, MSEL bits = 12 - 1 = 11 */ + n = 0; /* PLL Divider = 1, NSEL bits = 1 - 1 = 0 */ + clk_div = 3; /* Configure the ARM Core clock div to 6. CCLKSEL = 6 - 1 */ + clk_div_usb = 5; /* Configure the USB clock divider to 6, USBSEL = 6 - 1 */ + + if ((PLLSTAT & DEF_BIT_25) > 0) { /* If the PLL is already running */ + CPU_CRITICAL_ENTER(); + PLLCON &= ~DEF_BIT_01; /* Disconnect the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + } + + CPU_CRITICAL_ENTER(); + PLLCON &= ~DEF_BIT_00; /* Disable the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + SCS &= ~DEF_BIT_04; /* OSCRANGE = 0, Main OSC is between 1 and 20 Mhz */ + SCS |= DEF_BIT_05; /* OSCEN = 1, Enable the main oscillator */ + SCS |= DEF_BIT_00; /* access to all ports as fast io */ + + while ((SCS & DEF_BIT_06) == 0) { /* Wait until OSCSTAT is set (Main OSC ready to be used) */ + ; + } + + CLKSRCSEL = DEF_BIT_00; /* Select main OSC, 12MHz, as the PLL clock source */ + + CPU_CRITICAL_ENTER(); + PLLCFG = (m << 0) | (n << 16); /* Configure the PLL multiplier and divider */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + CPU_CRITICAL_ENTER(); + PLLCON |= DEF_BIT_00; /* Enable the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + CCLKCFG = clk_div; /* Configure the ARM Core Processor clock divider */ + USBCLKCFG = clk_div_usb; /* Configure the USB clock divider */ + + while ((PLLSTAT & DEF_BIT_26) == 0) { /* Wait for PLOCK to become set */ + ; + } + + PCLKSEL0 = 0xAAAAAAAA; /* Set peripheral clocks to be half of main clock */ + PCLKSEL1 = 0x22AAA8AA; + + CPU_CRITICAL_ENTER(); + PLLCON |= DEF_BIT_01; /* Connect the PLL. The PLL is now the active clock source */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + while ((PLLSTAT & DEF_BIT_25) == 0) { /* Wait PLLC, the PLL connect status bit to become set */ + ; + } +} + + +/* +********************************************************************************************************* +* MAM_Init() +* +* Description : Initialize the Memory Acceleration Module. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void MAM_Init (void) +{ + CPU_INT32U clk_freq; + + + clk_freq = BSP_CPU_ClkFreq(); /* Get the current core clock frequency */ + + MAMCR = 0; /* Disable MAM functionality */ + + if (clk_freq < 20000000) { /* Compare current clock frequency with MAM modes */ + MAMTIM = 1; /* Set MAM fetch cycles to 1 processor clock in duration */ + } + + if (clk_freq < 40000000) { + MAMTIM = 2; /* Set MAM fetch cycles to 2 processor clock in duration */ + } + + if (clk_freq >= 40000000) { + MAMTIM = 3; /* Set MAM fetch cycles to 3 processor clock in duration */ + } + + MAMCR = 2; /* Enable full MAM functionality */ +} + + +/* +********************************************************************************************************* +* GPIO_Init() +* +* Description : Initializes the GPIO pins. All the I/O pins are initialized in this function +* so you don't have to look at multiple places for I/O initialization. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) Refer to the LPC2378 User Manual, Chapter 9 for a detailed Pin Assignment +********************************************************************************************************* +*/ + +static void GPIO_Init (void) +{ + IO0DIR = 0; + IO1DIR = 0; + FIO0DIR = 0; + FIO1DIR = 0; + FIO2DIR = 0; + FIO3DIR = 0; + FIO4DIR = 0; + + FIO0MASK = 0; + FIO1MASK = 0; + FIO2MASK = 0; + FIO3MASK = 0; + FIO4MASK = 0; + + PINSEL0 = 0; + PINSEL1 = 0; + PINSEL2 = 0; + PINSEL3 = 0; + PINSEL4 = 0; + PINSEL5 = 0; + PINSEL6 = 0; + PINSEL7 = 0; + PINSEL8 = 0; + PINSEL9 = 0; + PINSEL10 = 0; +} + + +/* +********************************************************************************************************* +* VIC_Init() +* +* Description : Initialize the Vectored Interrupt Controller +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void VIC_Init (void) +{ + VICINTENCLEAR = 0xFFFFFFFF; /* Disable ALL interrupts */ + VICADDRESS = 0; /* Acknowlege any pending VIC interrupt */ + VICPROTECTION = 0; /* Allow VIC register access in User of Priviledged modes */ + + VICVECTADDR0 = (CPU_INT32U)VIC_DummyWDT; /* Set the vector address */ + VICVECTADDR1 = (CPU_INT32U)VIC_DummySW; + VICVECTADDR2 = (CPU_INT32U)VIC_DummyDEBUGRX; + VICVECTADDR3 = (CPU_INT32U)VIC_DummyDEBUGTX; + VICVECTADDR4 = (CPU_INT32U)VIC_DummyTIMER0; + VICVECTADDR5 = (CPU_INT32U)VIC_DummyTIMER1; + VICVECTADDR6 = (CPU_INT32U)VIC_DummyUART0; + VICVECTADDR7 = (CPU_INT32U)VIC_DummyUART1; + VICVECTADDR8 = (CPU_INT32U)VIC_DummyPWM01; + VICVECTADDR9 = (CPU_INT32U)VIC_DummyI2C0; + VICVECTADDR10 = (CPU_INT32U)VIC_DummySPI; + VICVECTADDR11 = (CPU_INT32U)VIC_DummySSP1; + VICVECTADDR12 = (CPU_INT32U)VIC_DummyPLL; + VICVECTADDR13 = (CPU_INT32U)VIC_DummyRTC; + VICVECTADDR14 = (CPU_INT32U)VIC_DummyEINT0; + VICVECTADDR15 = (CPU_INT32U)VIC_DummyEINT1; + VICVECTADDR16 = (CPU_INT32U)VIC_DummyEINT2; + VICVECTADDR17 = (CPU_INT32U)VIC_DummyEINT3; + VICVECTADDR18 = (CPU_INT32U)VIC_DummyAD0; + VICVECTADDR19 = (CPU_INT32U)VIC_DummyI2C1; + VICVECTADDR20 = (CPU_INT32U)VIC_DummyBOD; + VICVECTADDR21 = (CPU_INT32U)VIC_DummyETHERNET; + VICVECTADDR22 = (CPU_INT32U)VIC_DummyUSB; + VICVECTADDR23 = (CPU_INT32U)VIC_DummyCAN01; + VICVECTADDR24 = (CPU_INT32U)VIC_DummyMMC; + VICVECTADDR25 = (CPU_INT32U)VIC_DummyGP_DMA; + VICVECTADDR26 = (CPU_INT32U)VIC_DummyTIMER2; + VICVECTADDR27 = (CPU_INT32U)VIC_DummyTIMER3; + VICVECTADDR28 = (CPU_INT32U)VIC_DummyUART2; + VICVECTADDR29 = (CPU_INT32U)VIC_DummyUART3; + VICVECTADDR30 = (CPU_INT32U)VIC_DummyI2C2; + VICVECTADDR31 = (CPU_INT32U)VIC_DummyI2S; +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** DUMMY INTERRUPT HANDLERS +********************************************************************************************************* +********************************************************************************************************* +*/ + +static void VIC_Dummy (void) +{ + while (DEF_TRUE) { + ; + } +} + +static void VIC_DummyWDT (void) +{ + VIC_SpuriousInt = VIC_WDT; + VIC_Dummy(); +} + +static void VIC_DummySW (void) +{ + VIC_SpuriousInt = VIC_SW; + VIC_Dummy(); +} + +static void VIC_DummyDEBUGRX (void) +{ + VIC_SpuriousInt = VIC_DEBUGRX; + VIC_Dummy(); +} + +static void VIC_DummyDEBUGTX (void) +{ + VIC_SpuriousInt = VIC_DEBUGTX; + VIC_Dummy(); +} + +static void VIC_DummyTIMER0 (void) +{ + VIC_SpuriousInt = VIC_TIMER0; + VIC_Dummy(); +} + +static void VIC_DummyTIMER1 (void) +{ + VIC_SpuriousInt = VIC_TIMER1; + VIC_Dummy(); +} + +static void VIC_DummyUART0 (void) +{ + VIC_SpuriousInt = VIC_UART0; + VIC_Dummy(); +} + +static void VIC_DummyUART1 (void) +{ + VIC_SpuriousInt = VIC_UART1; + VIC_Dummy(); +} + +static void VIC_DummyPWM01 (void) +{ + VIC_SpuriousInt = VIC_PWM1; + VIC_Dummy(); +} + +static void VIC_DummyI2C0 (void) +{ + VIC_SpuriousInt = VIC_I2C0; + VIC_Dummy(); +} + +static void VIC_DummySPI (void) +{ + VIC_SpuriousInt = VIC_SPI; + VIC_Dummy(); +} + +static void VIC_DummySSP1 (void) +{ + VIC_SpuriousInt = VIC_SSP1; + VIC_Dummy(); +} + +static void VIC_DummyPLL (void) +{ + VIC_SpuriousInt = VIC_PLL; + VIC_Dummy(); +} + +static void VIC_DummyRTC (void) +{ + VIC_SpuriousInt = VIC_RTC; + VIC_Dummy(); +} + +static void VIC_DummyEINT0 (void) +{ + VIC_SpuriousInt = VIC_EINT0; + VIC_Dummy(); +} + +static void VIC_DummyEINT1 (void) +{ + VIC_SpuriousInt = VIC_EINT1; + VIC_Dummy(); +} + +static void VIC_DummyEINT2 (void) +{ + VIC_SpuriousInt = VIC_EINT2; + VIC_Dummy(); +} + +static void VIC_DummyEINT3 (void) +{ + VIC_SpuriousInt = VIC_EINT3; + VIC_Dummy(); +} + +static void VIC_DummyAD0 (void) +{ + VIC_SpuriousInt = VIC_AD0; + VIC_Dummy(); +} + +static void VIC_DummyI2C1 (void) +{ + VIC_SpuriousInt = VIC_I2C1; + VIC_Dummy(); +} + +static void VIC_DummyBOD (void) +{ + VIC_SpuriousInt = VIC_BOD; + VIC_Dummy(); +} + +static void VIC_DummyETHERNET (void) +{ + VIC_SpuriousInt = VIC_ETHERNET; + VIC_Dummy(); +} + +static void VIC_DummyUSB (void) +{ + VIC_SpuriousInt = VIC_USB; + VIC_Dummy(); +} + +static void VIC_DummyCAN01 (void) +{ + VIC_SpuriousInt = VIC_CAN12; + VIC_Dummy(); +} + +static void VIC_DummyMMC (void) +{ + VIC_SpuriousInt = VIC_MMC; + VIC_Dummy(); +} + +static void VIC_DummyGP_DMA (void) +{ + VIC_SpuriousInt = VIC_GP_DMA; + VIC_Dummy(); +} + +static void VIC_DummyTIMER2 (void) +{ + VIC_SpuriousInt = VIC_TIMER2; + VIC_Dummy(); +} + +static void VIC_DummyTIMER3 (void) +{ + VIC_SpuriousInt = VIC_TIMER3; + VIC_Dummy(); +} + +static void VIC_DummyUART2 (void) +{ + VIC_SpuriousInt = VIC_UART2; + VIC_Dummy(); +} + +static void VIC_DummyUART3 (void) +{ + VIC_SpuriousInt = VIC_UART3; + VIC_Dummy(); +} + +static void VIC_DummyI2C2 (void) +{ + VIC_SpuriousInt = VIC_I2C2; + VIC_Dummy(); +} + +static void VIC_DummyI2S (void) +{ + VIC_SpuriousInt = VIC_I2S; + VIC_Dummy(); +} diff --git a/.svn/pristine/09/09b5f4319ceb5d4b7a310ad34d0e94155614e71c.svn-base b/.svn/pristine/09/09b5f4319ceb5d4b7a310ad34d0e94155614e71c.svn-base new file mode 100644 index 0000000..8d97643 --- /dev/null +++ b/.svn/pristine/09/09b5f4319ceb5d4b7a310ad34d0e94155614e71c.svn-base @@ -0,0 +1,121 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +; +; All rights reserved. Protected by international copyright laws. +; +; uC/CPU is provided in source form for FREE evaluation, for educational +; use or peaceful research. If you plan on using uC/CPU in a commercial +; product you need to contact Micrium to properly license its use in your +; product. We provide ALL the source code for your convenience and to +; help you experience uC/CPU. The fact that the source code is provided +; does NOT mean that you can use it without paying a licensing fee. +; +; Knowledge of the source code may NOT be used to develop a similar product. +; +; Please help us continue to provide the Embedded community with the finest +; software available. Your honesty is greatly appreciated. +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARM +; IAR C Compiler +; +; Filename : cpu_a.s +; Version : V1.17 +; Programmer(s) : JJL +; JDH +; ITJ +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +CPU_ARM_CTRL_INT_DIS EQU 0xC0 ; Disable both FIQ & IRQ + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;$PAGE +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; /* Allocate storage for CPU status register */ +; #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +; CPU_SR cpu_sr; +; #endif +; +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; : +; } +; +; (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note : +; +; "Disabling Interrupts at Processor Level" +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + +CPU_SR_Save_Loop + ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + ORR R1, R0, #CPU_ARM_CTRL_INT_DIS + MSR CPSR_c, R1 + MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags + AND R1, R1, #CPU_ARM_CTRL_INT_DIS + CMP R1, #CPU_ARM_CTRL_INT_DIS + BNE CPU_SR_Save_Loop ; NOT properly DISABLED (try again) + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore ; See Note #2 + MSR CPSR_c, R0 + BX LR + + +;$PAGE +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/.svn/pristine/0d/0df01c140e2cec13d2d24563b3b98728580c4d2e.svn-base b/.svn/pristine/0d/0df01c140e2cec13d2d24563b3b98728580c4d2e.svn-base new file mode 100644 index 0000000..1ca3a66 --- /dev/null +++ b/.svn/pristine/0d/0df01c140e2cec13d2d24563b3b98728580c4d2e.svn-base @@ -0,0 +1,141 @@ +#ifndef _DATA_H_ +#define _DATA_H_ + +/*! + + + - 32 - float signed long + +*/ + +#include "cpu.h" + +typedef union{ + CPU_INT32U Val32U; + CPU_INT32S Val32S; + CPU_FP32 ValFloat; +}TVariant32; + +// +typedef struct{ + CPU_INT32U Min; + CPU_INT32U Max; +}TRangeValueULONG; + +typedef struct{ + CPU_INT32S Min; + CPU_INT32S Max; +}TRangeValueSLONG; + +typedef struct{ + CPU_FP32 Min; + CPU_FP32 Max; +}TRangeValueFLOAT; + + +// +typedef struct{ + + // + CPU_INT08U Desc; + #define DATA_DESC_EDIT 0 // + #define DATA_DESC_VIEW 1 // + + // + CPU_INT08U Type; + //#define DATA_TYPE_UCHAR 0 + //#define DATA_TYPE_SCHAR 1 + #define DATA_TYPE_ULONG 2 + #define DATA_TYPE_SLONG 3 + #define DATA_TYPE_FLOAT 4 + #define DATA_TYPE_TIME 5 + #define DATA_TYPE_TIME_COUNT 6 + #define DATA_TYPE_HOUR_MIN 7 + + // + CPU_INT08U Location; + #define DATA_LOC_RAM 0 + #define DATA_LOC_FRAM 1 + + // + CPU_INT08U IsArray; + #define DATA_NO_ARRAY 0 + #define DATA_IS_ARRAY 1 + + // + CPU_INT32U ArraySize; + + // + const void* ArrayIndex; //TDataDescStruct* + + // FRAM + void* Data; + + // + void* RangeValue; + + // + void (*OnchangeFunc)(void); + + // + CPU_INT32U ArrayOffset; + + // + const CPU_INT08U* Name; + + // ( ) + CPU_INT08U IsIndex; + #define DATA_NO_INDEX 0 + #define DATA_IS_INDEX 1 + + // + const CPU_INT08U** Items; + + // + CPU_INT08U EnableInit; + #define DATA_INIT_DISABLE 0 + #define DATA_INIT_ENABLE 1 + + // + TVariant32 DefaultValue; + +}TDataDescStruct; + + +// +typedef struct{ + const TDataDescStruct* ptr; +}TDataDescArrayStruct; + +// +#define DATA_FLAG_SYSTEM_INDEX 0 +#define DATA_FLAG_DIRECT_INDEX 1 + +// +#define DATA_OK 0 +#define DATA_ERR -1 + +// + +// +extern int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf); +// +extern int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index); +// +extern int CheckAllData(void); +// +extern int InitData(const TDataDescStruct* desc); +extern int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex); +extern int InitDescByDefault(const TDataDescStruct* desc); +extern int GetDataMin(const TDataDescStruct* desc, void* buf); +extern int GetDataMax(const TDataDescStruct* desc, void* buf); + +#endif //#ifndef _DATA_H_ diff --git a/.svn/pristine/0e/0ef7114e0d267f5db15e4e56af114d31cdbdb033.svn-base b/.svn/pristine/0e/0ef7114e0d267f5db15e4e56af114d31cdbdb033.svn-base new file mode 100644 index 0000000..f0b4463 --- /dev/null +++ b/.svn/pristine/0e/0ef7114e0d267f5db15e4e56af114d31cdbdb033.svn-base @@ -0,0 +1,1248 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* ASCII STRING MANAGEMENT +* +* Filename : lib_str.c +* Version : V1.24 +* Programmer(s) : ITJ +* JDH +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define LIB_STR_MODULE +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Len() +* +* Description : Calculate length of a string. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* Return(s) : Length of string; number of characters in string before terminating NULL character. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String length calculation terminates when : +* +* (a) String pointer points to NULL. +* (1) String buffer overlaps with NULL address. +* (2) String length calculated for string up to but NOT beyond or including +* the NULL address. +* +* (b) Terminating NULL character found. +* (1) String length calculated for string up to but NOT including +* the NULL character. +********************************************************************************************************* +*/ + +CPU_SIZE_T Str_Len (CPU_CHAR *pstr) +{ + CPU_SIZE_T len; + + + len = 0; + while (( pstr != (CPU_CHAR *)0) && /* Calc str len until NULL ptr (see Note #2a) ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2b). */ + len++; + pstr++; + } + + return (len); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Copy() +* +* Description : Copy source string to destination string buffer. +* +* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1). +* +* psrc Pointer to source string to copy into destination string buffer. +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire source +* string size including the terminating NULL character. +* +* (2) String copy terminates when : +* +* (a) Destination/Source string pointer(s) are passed NULL pointers. +* (1) No string copy performed; NULL pointer returned. +* +* (b) Destination/Source string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Source string copied into destination string buffer up to but NOT beyond or +* including the NULL address; destination string buffer properly terminated +* with NULL character. +* +* (c) Source string's terminating NULL character found. +* (1) Entire source string copied into destination string buffer. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Copy (CPU_CHAR *pdest, + CPU_CHAR *psrc) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrc == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */ + ( psrc != (CPU_CHAR *)0) && + (*psrc != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2c). */ + *pstr = *psrc; + pstr++; + pstr_next++; + psrc++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Copy_N() +* +* Description : Copy source string to destination string buffer, up to a maximum number of characters. +* +* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1). +* +* psrc Pointer to source string to copy into destination string buffer. +* +* len_max Maximum number of characters to copy (see Note #2d). +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire source +* string size including the terminating NULL character. +* +* (2) String copy terminates when : +* +* (a) Destination/Source string pointer(s) are passed NULL pointers. +* (1) No string copy performed; NULL pointer returned. +* +* (b) Destination/Source string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Source string copied into destination string buffer up to but NOT beyond or +* including the NULL address; destination string buffer properly terminated +* with NULL character. +* +* (c) Source string's terminating NULL character found. +* (1) Entire source string copied into destination string buffer. +* +* (d) 'len_max' number of characters copied. +* (1) 'len_max' number of characters does NOT include the terminating NULL character. +* +* See also Note #1a. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest, + CPU_CHAR *psrc, + CPU_SIZE_T len_max) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + CPU_SIZE_T len_copy; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrc == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if copy len equals zero (see Note #2d). */ + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + pstr_next = pstr; + pstr_next++; + len_copy = 0; + + while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */ + ( psrc != (CPU_CHAR *)0) && + (*psrc != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2c); ... */ + ( len_copy < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars copied (see Note #2d). */ + *pstr = *psrc; + pstr++; + pstr_next++; + psrc++; + len_copy++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cat() +* +* Description : Append concatenation string to destination string. +* +* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1). +* +* pstr_cat Pointer to concatenation string to append to destination string. +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated +* string size including the terminating NULL character. +* +* (2) String concatenation terminates when : +* +* (a) Destination/Concatenation string pointer(s) are passed NULL pointers. +* (1) No string concatenation performed; NULL pointer returned. +* +* (b) Destination string overlaps with NULL address. +* (1) No string concatenation performed; NULL pointer returned. +* +* (c) Destination/Concatenation string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Concatenation string appended into destination string buffer up to but NOT +* beyond or including the NULL address; destination string buffer properly +* terminated with NULL character. +* +* (d) Concatenation string's terminating NULL character found. +* (1) Entire concatenation string appended to destination string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Cat (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (pstr_cat == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */ + pstr++; + } + if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */ + ( pstr_cat != (CPU_CHAR *)0) && + (*pstr_cat != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2d). */ + *pstr = *pstr_cat; + pstr++; + pstr_next++; + pstr_cat++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cat_N() +* +* Description : Append concatenation string to destination string, up to a maximum number of characters. +* +* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1). +* +* pstr_cat Pointer to concatenation string to append to destination string. +* +* len_max Maximum number of characters to concatenate (see Note #2e). +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated +* string size including the terminating NULL character. +* +* (2) String concatenation terminates when : +* +* (a) Destination/Concatenation string pointer(s) are passed NULL pointers. +* (1) No string concatenation performed; NULL pointer returned. +* +* (b) Destination string overlaps with NULL address. +* (1) No string concatenation performed; NULL pointer returned. +* +* (c) Destination/Concatenation string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Concatenation string appended into destination string buffer up to but NOT +* beyond or including the NULL address; destination string buffer properly +* terminated with NULL character. +* +* (d) Concatenation string's terminating NULL character found. +* (1) Entire concatenation string appended to destination string. +* +* (e) 'len_max' number of characters concatenated. +* (1) 'len_max' number of characters does NOT include the terminating NULL character. +* +* See also Note #1a. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat, + CPU_SIZE_T len_max) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + CPU_SIZE_T len_cat; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (pstr_cat == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if cat len equals zero (see Note #2e). */ + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */ + pstr++; + } + if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + + pstr_next = pstr; + pstr_next++; + len_cat = 0; + + while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */ + ( pstr_cat != (CPU_CHAR *)0) && + (*pstr_cat != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2d); ... */ + ( len_cat < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars cat'd (see Note #2d). */ + *pstr = *pstr_cat; + pstr++; + pstr_next++; + pstr_cat++; + len_cat++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cmp() +* +* Description : Determine if two strings are identical. +* +* Argument(s) : p1_str Pointer to first string (see Note #1). +* +* p2_str Pointer to second string (see Note #1). +* +* Return(s) : 0, if strings are identical (see Notes #2a, #2e, & #2f). +* +* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d). +* +* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d). +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String comparison terminates when : +* +* (a) BOTH string pointer(s) are passed NULL pointers. +* (1) NULL strings identical; return 0. +* +* (b) 'p1_str' passed a NULL pointer. +* (1) Return negative value of character pointed to by 'p2_str'. +* +* (c) 'p2_str' passed a NULL pointer. +* (1) Return positive value of character pointed to by 'p1_str'. +* +* (d) Non-matching characters found. +* (1) Return signed-integer difference of the character pointed to by 'p2_str' +* from the character pointed to by 'p1_str'. +* +* (e) Terminating NULL character found in both strings. +* (1) Strings identical; return 0. +* (2) Only one NULL character test required in conditional since previous condition +* tested character equality. +* +* (f) BOTH strings point to NULL. +* (1) Strings overlap with NULL address. +* (2) Strings identical up to but NOT beyond or including the NULL address; return 0. +* +* (g) 'p1_str_next' points to NULL. +* (1) 'p1_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return negative value of character pointed to by 'p2_str_next'. +* +* (h) 'p2_str_next' points to NULL. +* (1) 'p2_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return positive value of character pointed to by 'p1_str_next'. +* +* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison +* return value, 'CPU_CHAR' native data type size MUST be 8-bit. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_INT16S Str_Cmp (CPU_CHAR *p1_str, + CPU_CHAR *p2_str) +{ + CPU_CHAR *p1_str_next; + CPU_CHAR *p2_str_next; + CPU_INT16S cmp_val; + + + if (p1_str == (CPU_CHAR *)0) { + if (p2_str == (CPU_CHAR *)0) { + return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */ + } + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str); + return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */ + } + if (p2_str == (CPU_CHAR *)0) { + cmp_val = (CPU_INT16S)(*p1_str); + return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */ + } + + + p1_str_next = p1_str; + p2_str_next = p2_str; + p1_str_next++; + p2_str_next++; + while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */ + (*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */ + ( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h). */ + ( p2_str_next != (CPU_CHAR *)0)) { + p1_str_next++; + p2_str_next++; + p1_str++; + p2_str++; + } + + + if (*p1_str != *p2_str) { /* If strs NOT identical, ... */ + cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */ + + } else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */ + cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */ + + } else { + if (p1_str_next == (CPU_CHAR *)0) { + if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */ + cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */ + } else { /* If p1_str_next NULL, ... */ + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */ + } + } else { /* If p2_str_next NULL, ... */ + cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */ + } + } + + + return (cmp_val); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cmp_N() +* +* Description : Determine if two strings are identical for up to a maximum number of characters. +* +* Argument(s) : p1_str Pointer to first string (see Note #1). +* +* p2_str Pointer to second string (see Note #1). +* +* len_max Maximum number of characters to compare (see Notes #2i & #2j). +* +* Return(s) : 0, if strings are identical (see Notes #2a, #2e, #2f, #2i, & #2j). +* +* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d). +* +* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d). +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String comparison terminates when : +* +* (a) BOTH string pointer(s) are passed NULL pointers. +* (1) NULL strings identical; return 0. +* +* (b) 'p1_str' passed a NULL pointer. +* (1) Return negative value of character pointed to by 'p2_str'. +* +* (c) 'p2_str' passed a NULL pointer. +* (1) Return positive value of character pointed to by 'p1_str'. +* +* (d) Non-matching characters found. +* (1) Return signed-integer difference of the character pointed to by 'p2_str' +* from the character pointed to by 'p1_str'. +* +* (e) Terminating NULL character found in both strings. +* (1) Strings identical; return 0. +* (2) Only one NULL character test required in conditional since previous condition +* tested character equality. +* +* (f) BOTH strings point to NULL. +* (1) Strings overlap with NULL address. +* (2) Strings identical up to but NOT beyond or including the NULL address; return 0. +* +* (g) 'p1_str_next' points to NULL. +* (1) 'p1_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return negative value of character pointed to by 'p2_str_next'. +* +* (h) 'p2_str_next' points to NULL. +* (1) 'p2_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return positive value of character pointed to by 'p1_str_next'. +* +* (i) 'len_max' passed a zero length. +* (1) Zero-length strings identical; return 0. +* +* (j) First 'len_max' number of characters identical. +* (1) Strings identical; return 0. +* +* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison +* return value, 'CPU_CHAR' native data type size MUST be 8-bit. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str, + CPU_CHAR *p2_str, + CPU_SIZE_T len_max) +{ + CPU_CHAR *p1_str_next; + CPU_CHAR *p2_str_next; + CPU_INT16S cmp_val; + CPU_SIZE_T cmp_len; + + + if (len_max == 0) { /* If cmp len equals zero, rtn 0 (see Note #2i). */ + return ((CPU_INT16S)0); + } + + if (p1_str == (CPU_CHAR *)0) { + if (p2_str == (CPU_CHAR *)0) { + return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */ + } + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str); + return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */ + } + if (p2_str == (CPU_CHAR *)0) { + cmp_val = (CPU_INT16S)(*p1_str); + return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */ + } + + + p1_str_next = p1_str; + p2_str_next = p2_str; + p1_str_next++; + p2_str_next++; + cmp_len = 0; + while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */ + (*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */ + ( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h); */ + ( p2_str_next != (CPU_CHAR *)0) && + ( cmp_len < (CPU_SIZE_T)len_max)) { /* .. or len nbr chars cmp'd (see Note #2j). */ + p1_str_next++; + p2_str_next++; + p1_str++; + p2_str++; + cmp_len++; + } + + + if (cmp_len == len_max) { /* If strs identical for len nbr of chars, */ + return ((CPU_INT16S)0); /* ... rtn 0 (see Note #2j). */ + } + + if (*p1_str != *p2_str) { /* If strs NOT identical, ... */ + cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */ + + } else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */ + cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */ + + } else { + if (p1_str_next == (CPU_CHAR *)0) { + if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */ + cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */ + } else { /* If p1_str_next NULL, ... */ + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */ + } + } else { /* If p2_str_next NULL, ... */ + cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */ + } + } + + + return (cmp_val); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char() +* +* Description : Search string for first occurrence of specific character. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* srch_char Search character. +* +* Return(s) : Pointer to first occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* +* (c) String's terminating NULL character found. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char (CPU_CHAR *pstr, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */ + (*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */ + (*pstr != (CPU_CHAR )srch_char)) { /* ... or srch char found (see Note #2d). */ + pstr++; + pstr_next++; + } + + + if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char_N() +* +* Description : Search string for first occurrence of specific character, up to a maximum number of characters. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* len_max Maximum number of characters to search (see Notes #2e & #3). +* +* srch_char Search character. +* +* Return(s) : Pointer to first occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* +* (c) String's terminating NULL character found. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +* +* (e) 'len_max' number of characters searched. +* (1) 'len_max' number of characters does NOT include terminating NULL character. +* +* (3) Ideally, the 'len_max' parameter would be the last parameter in this function's +* paramter list for consistency with all other custom string library functions. +* However, the 'len_max' parameter is ordered to comply with the standard library +* function's parameter list. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char_N (CPU_CHAR *pstr, + CPU_SIZE_T len_max, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + CPU_SIZE_T len_srch; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if srch len equals zero (see Note #2e). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + pstr_next++; + len_srch = 0; + while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */ + (*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */ + (*pstr != (CPU_CHAR )srch_char) && /* ... or srch char found (see Note #2d); ... */ + ( len_srch < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars srch'd (see Note #2e). */ + pstr++; + pstr_next++; + len_srch++; + } + + + if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char_Last() +* +* Description : Search string for last occurrence of specific character. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* srch_char Search character. +* +* Return(s) : Pointer to last occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* (3) NULL address boundary handled in Str_Len(). +* +* (c) String searched from end to beginning. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char_Last (CPU_CHAR *pstr, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + CPU_SIZE_T str_len; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + str_len = Str_Len(pstr); + pstr_next += str_len; + while (( pstr_next != pstr) && /* Srch str from end until beg (see Note #2c) ... */ + (*pstr_next != srch_char)) { /* ... until srch char found (see Note #2d). */ + pstr_next--; + } + + + if (*pstr_next != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr_next); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Str() +* +* Description : Search string for first occurence of a specific search string. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* psrch_str Pointer to search string (see Note #1). +* +* Return(s) : Pointer to first occurrence of search string in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) Search string length greater than string length. +* (1) No string search performed; NULL pointer returned. +* +* (c) Search string length equal to zero. +* (1) NULL search string at end of string returned. +* +* (d) Entire string has been searched. +* (1) Maximum size of the search is defined as the subtraction of the +* search string length from the string length. +* (2) Search string not found; NULL pointer returned. +* +* (e) Search string found. +* (1) Search string found according to Str_Cmp_N() return value. +* (2) Return pointer to first occurrence of search string in string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Str (CPU_CHAR *pstr, + CPU_CHAR *psrch_str) +{ + CPU_SIZE_T str_len; + CPU_SIZE_T srch_str_len; + CPU_SIZE_T srch_len; + CPU_SIZE_T srch_ix; + CPU_BOOLEAN srch_done; + CPU_INT16S srch_cmp; + CPU_CHAR *pstr_srch_ix; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pstr == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrch_str == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + str_len = Str_Len(pstr); + srch_str_len = Str_Len(psrch_str); + if (srch_str_len > str_len) { /* If srch str len > str len, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + if (srch_str_len == 0) { /* If srch str len = 0, srch str equal NULL str; ... */ + pstr_srch_ix = (CPU_CHAR *)(pstr + str_len); /* ... rtn ptr to NULL str found in str (see Note #2c). */ + return (pstr_srch_ix); + } + + srch_len = str_len - srch_str_len; /* Determine srch len (see Note #2d1). */ + srch_ix = 0; + srch_done = DEF_NO; + while ((srch_done == DEF_NO) && (srch_ix <= srch_len)) { + pstr_srch_ix = (CPU_CHAR *)(pstr + srch_ix); + srch_cmp = Str_Cmp_N(pstr_srch_ix, psrch_str, srch_str_len); + srch_done = (srch_cmp == 0) ? DEF_YES : DEF_NO; + srch_ix++; + } + + + if (srch_cmp != 0) { /* If srch str NOT found, rtn NULL (see Note #2d). */ + return ((CPU_CHAR *)0); + } + + return (pstr_srch_ix); /* Rtn ptr to srch str found in str (see Note #2e). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_FmtNbr_32() +* +* Description : Format number into a multi-digit character string. +* +* Argument(s) : nbr Number to format (see Note #1). +* +* nbr_dig Number of integer digits to format (see Note #2). +* +* nbr_dp Number of decimal point digits to format. +* +* lead_zeros Prepend leading zeros option (DEF_YES/DEF_NO) [see Note #3]. +* +* nul NULL-character terminate option (DEF_YES/DEF_NO) [see Note #4]. +* +* pstr_fmt Pointer to character array to return formatted number string (see Note #5). +* +* Return(s) : Pointer to formatted string, if NO errors (see Note #6). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) (a) The maximum accuracy for 32-bit floating-point numbers : +* +* +* Maximum Accuracy log [Internal-Base ^ (Number-Internal-Base-Digits)] +* 32-bit Floating-point Number = ----------------------------------------------------- +* log [External-Base] +* +* log [2 ^ 24] +* = -------------- +* log [10] +* +* < 7.225 Base-10 Digits +* +* where +* Internal-Base Internal number base of floating- +* point numbers (i.e. 2) +* External-Base External number base of floating- +* point numbers (i.e. 10) +* Number-Internal-Base-Digits Number of internal number base +* significant digits (i.e. 24) +* +* (b) Some compilers' floating-point routines MAY further reduce the maximum accuracy. +* +* (c) If the total number of digits to format ('nbr_dig + nbr_dp') is greater than the +* maximum accuracy; digits following the first, significantly-accurate digits will +* be inaccurate. +* +* (2) (a) If the number of digits to format ('nbr_dig') is less than the number of significant +* integer digits of the number to format ('nbr'); then the most-significant digits of +* the formatted number will be truncated. +* +* Example : +* +* nbr = 23456.789 +* nbr_dig = 3 +* nbr_dp = 2 +* +* pstr_fmt = "456.78" +* +* (b) If number to format ('nbr') is negative but the most-significant digits of the +* formatted number are truncated (see Note #2a); the negative sign still prefixes +* the truncated formatted number. +* +* Example : +* +* nbr = -23456.789 +* nbr_dig = 3 +* nbr_dp = 2 +* +* pstr_fmt = "-456.78" +* +* (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit. +* The number of leading zeros is such that the total number integer digits is +* equal to the requested number of integer digits to format ('nbr_dig'). +* +* (b) (1) If leading zeros option DISABLED, ... +* (2) ... number of digits to format is non-zero, ... +* (3) ... & the integer value of the number to format is zero; ... +* (4) ... then one digit of '0' value is formatted. +* +* This is NOT a leading zero; but a single integer digit of '0' value. +* +* (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character +* array formatting. +* +* (b) WARNING: Unless 'pstr_fmt' character array is pre-/post-terminated, NULL-character +* terminate option DISABLED will cause character string run-on. +*$PAGE* +* (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (b) To prevent character buffer overrun : +* +* Character array size MUST be >= ('nbr_dig' + +* 'nbr_dp' + +* 1 negative sign + +* 1 decimal point + +* 1 'NUL' terminator) characters +* +* (6) String format terminates when : +* +* (a) Format string pointer is passed a NULL pointer. +* (1) No string format performed; NULL pointer returned. +* +* (b) Number successfully formatted into character string array. +********************************************************************************************************* +*/ + +#if (LIB_STR_CFG_FP_EN == DEF_ENABLED) +CPU_CHAR *Str_FmtNbr_32 (CPU_FP32 nbr, + CPU_INT08U nbr_dig, + CPU_INT08U nbr_dp, + CPU_BOOLEAN lead_zeros, + CPU_BOOLEAN nul, + CPU_CHAR *pstr_fmt) +{ + CPU_CHAR *pstr; + CPU_INT08U i; + CPU_INT32U dig_nbr; + CPU_INT32U dig_val; + CPU_FP32 dig_exp; + CPU_FP32 dp_exp; + + /* Rtn NULL if str ptr NULL (see Note #6a). */ + if (pstr_fmt == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pstr_fmt; + + if (nbr < 0.0) { /* If nbr neg, ... */ + if ((nbr_dig > 0) || /* ... & at least one dig ... */ + (nbr_dp > 0)) { /* ... or at least one dp; ... */ + nbr = -nbr; /* ... negate nbr & ... */ + *pstr++ = '-'; /* ... prefix with neg sign (see Note #2b). */ + } + } + + if (nbr_dig > 0) { + dig_exp = 1.0; + for (i = 1; i < nbr_dig; i++) { + dig_exp *= 10.0; + } + for (i = nbr_dig; i > 0; i--) { /* Fmt str for desired nbr digs. */ + dig_nbr = (CPU_INT32U)(nbr / dig_exp); + if ((dig_nbr > 0) || /* If dig nbr > 0, ... */ + (nbr_dig == 1) || /* ... OR exactly 1 dig to fmt, ... */ + (i == 1) || /* ... OR on one's dig to fmt, ... */ + (lead_zeros == DEF_YES)) { /* ... OR lead zeros opt ENABLED (see Note #3), ... */ + /* ... calc & fmt dig val. */ + dig_val = (CPU_INT32U)(dig_nbr % 10 ); + *pstr++ = (CPU_CHAR )(dig_val + '0'); + } + dig_exp /= 10.0; /* Shift to next least-significant dig. */ + } + } + + if (nbr_dp > 0) { + *pstr++ = '.'; /* Append dp prior to dp conversion. */ + dp_exp = 10.0; + for (i = 0; i < nbr_dp; i++) { /* Fmt str for desired nbr dp. */ + dig_nbr = (CPU_INT32U)(nbr * dp_exp ); + dig_val = (CPU_INT32U)(dig_nbr % 10 ); + *pstr++ = (CPU_CHAR )(dig_val + '0'); + dp_exp *= 10.0; /* Shift to next least-significant dp. */ + } + } + + if (nul != DEF_NO) { /* If NOT DISABLED, append NULL char (see Note #4). */ + *pstr = (CPU_CHAR)0; + } + + + return (pstr_fmt); +} +#endif + diff --git a/.svn/pristine/11/114bc6032f93dcfe52f4f18b844a1fb2774b9e7a.svn-base b/.svn/pristine/11/114bc6032f93dcfe52f4f18b844a1fb2774b9e7a.svn-base new file mode 100644 index 0000000..ecbb0a8 --- /dev/null +++ b/.svn/pristine/11/114bc6032f93dcfe52f4f18b844a1fb2774b9e7a.svn-base @@ -0,0 +1,12 @@ +[FLASH] +SkipProgOnCRCMatch = 1 +VerifyDownload = 1 +AllowCaching = 1 +EnableFlashDL = 2 +Override = 0 +Device="ADUC7020X62" +[BREAKPOINTS] +ShowInfoWin = 1 +EnableFlashBP = 2 +[CPU] +AllowSimulation = 1 diff --git a/.svn/pristine/13/13d341d482529a79be97c290f7d58b5422901fae.svn-base b/.svn/pristine/13/13d341d482529a79be97c290f7d58b5422901fae.svn-base new file mode 100644 index 0000000..b94ae6c --- /dev/null +++ b/.svn/pristine/13/13d341d482529a79be97c290f7d58b5422901fae.svn-base @@ -0,0 +1,63 @@ +1. : + +- : / +- - 0-120 . +- - - 0-15 . +- , . 1-120 +- , . 1-120 + + : + +- : "-", "-", "-", "-" +- , : + T1 - , , + T2 - , , + T3 - , , + T4 - , , + 4 +- : + , . 0-9999 + , . + + + +2. - . + + + +3. : + +- , . +- , . +- , . +- , . +- , . +- , . + + - . + + + +4. : + +- + : + - + - + - +- + : + - + - + - +- : , . + : + - + - +- : , . + : + - + - + + +* 1 2, 3 4 * \ No newline at end of file diff --git a/.svn/pristine/14/14d13e43d7a5eb37ac67326ed339f3ee942e6ba8.svn-base b/.svn/pristine/14/14d13e43d7a5eb37ac67326ed339f3ee942e6ba8.svn-base new file mode 100644 index 0000000..b3d1ecd --- /dev/null +++ b/.svn/pristine/14/14d13e43d7a5eb37ac67326ed339f3ee942e6ba8.svn-base @@ -0,0 +1,5810 @@ +:1000000018F09FE518F09FE518F09FE518F09FE5C0 +:1000100018F09FE5586FA0B818F09FE518F09FE51D +:10002000280401001C8500002C8500003C85000090 +:100030005085000000000000788500008C850000DD +:1000440008B4024B9C4608BC6047C0460C30000014 +:1000540070B598B00600002012900023002212A967 +:10006400BC4801F03FFB129800281ED0C94800216B +:10007400017000242406240E0A2C13D200201190AF +:1000840001232406240E220011A9C34801F02AFBEF +:100094001198002804D0BF480078401CBD4908705E +:1000A400641CE7E7BD4801210170BD4800210170CF +:1000B400BC48002101700023002214A9BA4801F0B1 +:1000C40011FB1498B949884202D1042002F01EFCA5 +:1000D40015A800F0B1FC002801D100F01BFC159814 +:1000E400401E2ED0801E00D174E1401E00D1BDE11F +:1000F400401E00D10AE2401E00D15FE1801E00D103 +:100104002BE2401E00D129E2401E00D127E2401E0E +:1001140000D125E2401E00D16BE2401E00D142E234 +:10012400401E00D166E2401E00D161E2401E01285B +:1001340000D899E2801E00D1CFE0401E00D137E103 +:10014400C6E702F051FC02F0C3FEC549086000F0A6 +:10015400A5FFC4480078401CC24908700006000E80 +:100164000A2102F047FF00290DD1BF48007800287A +:1001740003D003F05EFC002805D003F0E8F9002862 +:1001840001D103F023F804F0A5F902F01CFC0028C7 +:100194009ED103F01BFD002825D000F065FD04F07E +:1001A400D0FBD6480068802189030143D34801600D +:1001B4007A480078012812D17A480078002811D1B1 +:1001C40005F0C5FA002804D003220021002005F020 +:1001D40043FD05F0E7FE73480121017002E0714818 +:1001E4000021017074E76D48007801283ED100F0C9 +:1001F4007DFC04F0A6FB02F0E9FF6A4800780028C1 +:100204006AD005F0A4FA002804D00322BC49BC48F3 +:1002140005F022FD0120109000200F900020C04323 +:100224000E9001F0F4F904000FAA10A9B548007863 +:1002340000F0BCFD0123B34802780EA9B24801F0D6 +:1002440051FA0F9860433C2148431099FFF7F8FE98 +:100254000E993C225143814202D205F0A3FE01E0F3 +:1002640005F0B3FE4F480021017035E04B4800789B +:1002740002281ED1A14800688021890301439F48B8 +:10028400016005F08FFECC480078002807D000F00C +:10029400DBFFC9480078401EC74908701CE03F488E +:1002A400002101709748007800F0FEFF04F049FB3C +:1002B40012E03A48007800280ED190480068802166 +:1002C400890301438D48016005F06CFE8D48007878 +:1002D40000F0EAFF04F035FBFAE600200190002468 +:1002E400182C12D200200D90012322000DA9C6481B +:1002F40001F0F8F901980D9904226243C34B9A580E +:10030400514340180190641CEAE72548012101701B +:10031400019ABF49BF4805F093FFBF4804F081FB31 +:10032400019A0C21002003F0F9FC00230022C949A2 +:10033400C94801F0D7F90024182C0DD2012322005A +:1003440004206043C5490918AF4801F0CBF9641C87 +:10035400F2E7C046741201000023002201A9C0483C +:1003640001F010FA02F0B4FD02900023002202A969 +:10037400BC4801F007FA0D4802900023002202A9AC +:10038400094801F0FFF9042002F0C0FA04F082F8F1 +:100394009EE6C0461E560040240801002056004038 +:1003A400235600402456004014150100214365875C +:1003B400C6480021017004F07AFB89E604F0C4FF0A +:1003C40002F001FB0006000E02000B21002003F0E6 +:1003D400A5FC7DE601200C90002300220CA9BC485A +:1003E40001F080F905F012FE0C9941430D0001F073 +:1003F4000EF904006419200001F0F2F8B548007801 +:10040400012803D100F072FB04F09BFA2A000221B8 +:100414003C48007803F082FC01200B9000200A90F5 +:100424000020C04309900AAA0BA93648007800F0BE +:10043400BDFC01233348027809A9334801F052F97D +:100444000A9860433C2148430B99FFF7F9FD099949 +:100454003C225143814201D205F0A4FD38E6C04656 +:1004640024550040255600402656004016A805F0A5 +:10047400F0F9040001200890002007900020C043F8 +:10048400069007AA08A91F48007800F08FFC0123F2 +:100494001C48027806A91C4801F024F901F0B7F8B9 +:1004A40005000798291948433C2148430899FFF758 +:1004B400C7FD06993C22514381420FD2C048032113 +:1004C400017005F044F9002817D0032005F040FC22 +:1004D400002812D1012003F0F9FA0EE0B8480021F7 +:1004E400017005F034F9002807D0032005F0FEFB65 +:1004F400002802D1012003F0E9FAE9E53CC0FF3FFE +:10050400FFFFFF001F560040240B010013A805F055 +:10051400A0F9050001F07BF804006419200001F043 +:100524005FF86C480078012803D100F0DFFA04F08A +:1005340008FA05F00CF9002805D003220021C9436C +:10054400AD4805F089FB2A000121AC48007803F08E +:10055400E5FB139803F06DFFBAE5B9E5B8E5B7E537 +:1005640002F031FA002803D158480078002800D05E +:10057400AEE503F02BFB002804D000F075FB04F07B +:10058400E0F9A5E55348007800280BD19C48007891 +:10059400022807D300F030FD9848007800F084FE6C +:1005A40004F0CFF994E502F00EFA002803D147488D +:1005B4000078002802D08BE52156004003F006FBAA +:1005C400002804D000F050FB04F0BBF980E541485A +:1005D400007800280BD18A480078022807D300F05D +:1005E400CBFC8648007800F05FFE04F0AAF96FE5C2 +:1005F4006EE56DE502F0E7F9002803D13348007891 +:1006040000280BD064E5C0468414010090510040DA +:1006140050390100345400408052010003F0D6FAEE +:10062400002804D000F020FB04F08BF950E52948A1 +:10063400002101707148007800F036FE04F081F961 +:1006440005F085F8002804D003220021002005F0DD +:1006540003FB3DE528550040B4140100D050004090 +:10066400441501007415010018480078002800D0D2 +:100674002EE502F0A8F9002878D0A94800780028CF +:1006840000D125E503F0F0FFA649884224D102F009 +:10069400E3FF002869D002F0F4FF00A9891C1E20A2 +:1006A40005F024FF03F001F868468078002803D0A1 +:1006B4006846807803F016F802F00AFC020009216B +:1006C400002003F02BFB04F0F2F94EE02356004027 +:1006D400040A01002056004003F0C6FF92498842F4 +:1006E40021D102F0B9FF00283FD002F0CAFF00A9CF +:1006F400491C1E2005F02FFF02F0D7FF6846407802 +:10070400002803D06846407802F0ECFF02F0E0FBDA +:1007140002000821002003F001FB04F0C8F94E2078 +:1007240003F000F821E003F09FFF804988421CD1C8 +:1007340002F092FF002818D002F0A3FF69461E20A1 +:1007440005F071FF02F0B1FF68460078002803D07D +:100754006846007802F0C6FF02F0BAFB02000A21E4 +:10076400002003F0DBFA04F0A2F9B1E403F02EFA5E +:10077400002804D000F078FA04F0E3F8A8E4204854 +:100784000078002800D1A3E4AA480078002839D1D1 +:100794001A48007800F0DCFE002800D098E402F04B +:1007A40070FF02F013FD00280CD503F00FFA0028A7 +:1007B40008D002F07AFF00F057FA04F0C2F887E498 +:1007C4002256004002F071FF9A480121017000F0A6 +:1007D4008DF904F0B6F804F0BAFF002805D003221E +:1007E4000021C943044805F037FA05F0EEFBA3489D +:1007F400002101706CE4C046FFFFFF001F5600405B +:100804001E5600408B480078012800D080E001206B +:100814000590002004900020039004AA05A9A6488E +:10082400007800F0C3FA00F0F2FE0400049860437C +:100834003C2148430599FFF703FC9F4909780422AA +:1008440051439E4A505001239B48027803A99C4877 +:1008540000F048FF98480078042148439749085815 +:1008640003993C225143884250D304F070FF00287E +:1008740004D003220021002005F0EEF902F0ECFE82 +:10088400002812D08C480078042148438B49095829 +:10089400200002F069FF002807D102F019FB0200D2 +:1008A40007218548007803F039FA2200824800784D +:1008B40004214843814909587F48007803F0AEFC7D +:1008C400002000F08DFE01237B4802787A480078EE +:1008D400042148437B4909187B4800F003FF76480C +:1008E40000787A4901220A5402F0B6FE002807D0A3 +:1008F40000F0AAFC04F025F84E480221017002E041 +:100904004C4800210170CD4805210170FFF7E0FB40 +:10091400FFF7DEFB012005F0DBFFFFF7D9FB00004A +:1009240030560040D05901000C5A01003C5A0100D5 +:1009340080B502F011F801F0B4F903F043FD00F0C2 +:100944001BFE00F079FE06F0F5F861480068614985 +:1009540001405F480160604800685E4901405E48AC +:1009640001605E4800688021890301435B4801609F +:100974005B4800685B490140594801605A48006877 +:100984008021890301435848016004F0BBFCFA202C +:10099400800005F09DFF04F0EFFEA94805F098FFE4 +:1009A40002F048FE02F0A3F802F092FA02000621D7 +:1009B400002003F0B3F9002300226946A14800F0A7 +:1009C40091FE0098002807D0002000900023002208 +:1009D40069469D4800F0D6FE06F088FA002803D048 +:1009E400192003F073F802E0192003F09DF805F0D4 +:1009F4001EFB9648006800280BD14021944806F05D +:100A0400F9FF924908600723924A0021924807F0AF +:100A140037F902F05DFA9149086001F0D4FF00282B +:100A240003D18F4804F02DF802E08E4804F029F831 +:100A340009BC18472056004010B582B0040068462F +:100A4400002101706A4601218048006807F024F8FB +:100A5400010068460078002801D0002001E02160F0 +:100A6400012016BC08BC184710B5040021007748C3 +:100A7400006807F0A5F810BC08BC184722560040CF +:100A840080B50D48002101700B4800780A2811D266 +:100A9400002000900123084802786946B44800F019 +:100AA40021FE0098002805D103480078401C024923 +:100AB4000870E9E709BC18471F56004084530040FA +:100AC400540B01005C530040C40A0100145500405B +:100AD4000CC002E0FFF3FFFF4CC002E020C0FF3F68 +:100AE40030C0FF3FFFFFDFFF3CC0FF3F70B58CB05D +:100AF400A04904A805F0A4FB002104A807F096FA75 +:100B040000F085FD05002A009B4904A805F098FB28 +:100B1400012104A807F08AFA012003900020029022 +:100B2400002402AA03A9B248007800F03FF9029811 +:100B340068433C2148430399FFF782FA04002000EC +:100B44003C21FFF77DFA0B001E0020003C21FFF73B +:100B540077FA02003300894904A805F071FB0221E9 +:100B640004A807F063FA86480078002809D084486E +:100B74000078401E82490870824904A805F060FB91 +:100B840053E000200190002000900123984802784F +:100B940001A97D4800F0A6FD012395480278694625 +:100BA4007A4800F09FFDCE480078022807D3904889 +:100BB4000278521C764904A805F042FB03E075A1B3 +:100BC40004A805F03DFB01983C21484384421DD311 +:100BD400714800688021890301436F4801600098CF +:100BE4003C214843844208D304A807F0BBFB6B496B +:100BF40004AA101805F024FB17E004A807F0B2FBC0 +:100C0400674904AA101805F01BFB0EE0654800684C +:100C14008021890301436348016004A807F0A2FB13 +:100C2400614904AA101805F00BFB032104A807F07E +:100C3400FDF90CB070BC08BC1847000021560040F8 +:100C440010270000B4080100D40901002C5500400D +:100C54004C4B00405C2400405500000024550040EB +:100C6400505801001C53010000B589B0012002F066 +:100C740089FF002803D102F0D3FF002825D0BA4908 +:100C840001A805F0DDFA002101A807F0CFF9B74962 +:100C940001A805F0D5FA012101A807F0C7F9012040 +:100CA40002F070FF002860D0B14901A805F0C8FA2D +:100CB400022101A807F0BAF936A101A805F0C0FA8B +:100CC400032101A807F0B2F94FE01A2002F05AFFFD +:100CD40000281CD0A44901A805F0B2FA002101A8FB +:100CE40007F0A4F9A34901A805F0AAFA012101A873 +:100CF40007F09CF927A101A805F0A2FA022101A896 +:100D040007F094F9032101A807F090F92DE002F00F +:100D140090FE002829D0944901A805F091FA0021F9 +:100D240001A807F083F9684600210170AF4901A8C2 +:100D340005F086FA012101A807F078F9684602F067 +:100D440091FE6846027801A9A94800F0B6FE022186 +:100D540001A807F06BF96846027801A9A54800F0DC +:100D6400ACFE032101A807F061F909B008BC1847DB +:100D74002408010060390100703901008C20010051 +:100D840022560040A0200100540B0100240B010056 +:100D9400605C01000000000038C0FF3FDC4D010032 +:100DA400E84D01003CC0FF3F80390100F1B586B039 +:100DB4000F0016004A480078002802D10020C043E2 +:100DC400CDE0684601F04DFE00200490002501238B +:100DD4000748027804A9A94800F084FC0498012873 +:100DE40008D0022811D003281AD0042823D02DE0DB +:100DF4001F5600406846C078002803D06846C07873 +:100E0400052801D30120050022E06846C0780028A7 +:100E140003D06846C078062801D10120050017E0F8 +:100E24006846C078052803D06846C078062801D1F2 +:100E3400012005000CE06846C078052803D2684606 +:100E4400C078022801D20120050001E0002005003D +:100E5400002004002406240E042C43D22D062D0E5B +:100E6400002D18D001238648007804214843240625 +:100E7400240E021903A9834800F034FC012380489E +:100E84000078042148432406240E021902A97E484E +:100E940000F028FC17E00123794800780421484336 +:100EA4002406240E021903A9784800F01BFC012330 +:100EB40073480078042148432406240E021902A929 +:100EC400734800F00FFC684680780399884204D385 +:100ED400684680780299884204D3641CBAE7C04605 +:100EE4001E5600402406240E042C02D30120C043C5 +:100EF40035E02D062D0E002D18D001236048007812 +:100F0400042148432406240E02193100614800F0EC +:100F1400E9FB01235A480078042148432406240E9F +:100F2400021939005C4800F0DDFB17E00123544846 +:100F34000078042148432406240E02193100C148D4 +:100F440000F0D0FB01234E480078042148432406D6 +:100F5400240E02193900CF4800F0C4FB002007B06A +:100F6400F0BC08BC18470000685C0100903901001F +:100F7400F44D0100A03901001CB541480078401C23 +:100F840004002406240E0A2C0ED200200190012312 +:100F94002406240E220001A9BF4800F0A3FB0198F7 +:100FA400002801D1641CECE72406240E0A2C02D28A +:100FB4003348047016E0002004002406240E0A2C92 +:100FC4000ED20020009001232406240E220069463C +:100FD400B14800F087FB0098002801D1641CECE7BD +:100FE4002748047013BC08BC18470000004E0100D9 +:100FF400240E0100540E01001CB521480078401E47 +:10100400040024062416002C0ED400200190012391 +:1010140024062416220001A99F4800F063FB0198CE +:10102400002801D1641EECE724062416002C02D407 +:10103400134804701EE009200400114800782100C0 +:10104400090609160004001409040914884211DA77 +:1010540000200090012324062416220069468E48AD +:1010640000F040FB0098002802D00548047001E01D +:10107400641EE2E713BC08BC18470000840B01009F +:101084001F560040340D0100640D0100D40C010012 +:10109400040D0100740C0100140C010010B50024AF +:1010A4002406240E0A2C00D3C9E02406240E7B480F +:1010B400005D002806D002284AD009D3032800D1B5 +:1010C40092E0BAE020000006000E05F0BCFCB4E09B +:1010D4002406240E042060437149085800280CD0CB +:1010E4002406240E042060436D490858401E24063B +:1010F400240E042161436A4A50502406240E04201D +:10110400604367490858002821D120000006000EDA +:1011140005F032FC2406240E0420604360492406B2 +:10112400240E04226243DF4B9A580A502406240EEC +:101134005A48022101552406240E04206043D9494B +:101144000A58032120000006000E02F0E7FD74E0B7 +:101154002406240E042060435149085800280CD06A +:101164002406240E042060434D490858401E2406DA +:10117400240E042161434A4A50502406240E0420BC +:1011840060434749085800282DD120000006000E6E +:1011940005F059FC01232406240E22002406240E03 +:1011A400042060433E4909183E4800F09BFA240697 +:1011B400240E042060433A4908583C21484324063D +:1011C400240E04216143364A50502406240E334829 +:1011D4000321015501F07CFE0200042120000006D9 +:1011E400000E02F09BFD28E02406240E0420604338 +:1011F4002B49085800280CD02406240E04206043F0 +:1012040027490858401E2406240E04216143244A19 +:1012140050502406240E0420604321490858002815 +:101224000BD12406240E1D48002101552406240E4A +:10123400042060439B4900220A50641C30E710BC20 +:1012440008BC1847A40C010000B589B0964968464B +:1012540004F0F6FF0021684606F0E8FE934968466C +:1012640004F0EEFF0121684606F0E0FE904968466E +:1012740004F0E6FF0221684606F0D8FED449684629 +:1012840004F0DEFF0321684606F0D0FE09B008BC76 +:1012940018470000440C01002408010014550040C4 +:1012A4005C530040F40A010030B58DB00500AF482E +:1012B4000021017000242406240E0A2C13D20020DD +:1012C4000C9001232406240E22000CA9A84800F047 +:1012D40009FA0C98002804D0A4480078401CA349BB +:1012E4000870641CE7E7A1480078002820D1A149D0 +:1012F400684604F0A5FF0021684606F097FEB5494C +:10130400684604F09DFF0121684606F08FFEB2494D +:10131400684604F095FF0221684606F087FEAF494F +:10132400684604F08DFF0321684606F07FFEB5E0B1 +:101334008E480078012852D101200B9000200A9099 +:101344000AAA0BA928000006000EFFF72FFD0A9B2E +:101354000B9AB449684604F073FF0021684606F00E +:1013640065FE28000006000E00F0F2F800281DD0EB +:10137400AD49684604F064FF0121684606F056FE54 +:10138400AA49684604F05CFF0221684606F04EFE56 +:1013940028000006000E00F08DF80100684601F0F8 +:1013A400CDFC0321684606F041FE17E0A0496846DB +:1013B40004F046FF0121684606F038FE9D49684660 +:1013C40004F03EFF0221684606F030FEB04968464C +:1013D40004F036FF0321684606F028FE5EE0012390 +:1013E4002D062D0E2A006946AA4800F0A0FA684688 +:1013F40006F0B8FF2D062D0E2A00521CA6A16B463E +:10140400181804F01DFF0021684606F00FFE0120A5 +:1014140009900020089008AA09A928000006000ED7 +:10142400FFF7C4FC089B099A7E49684604F008FF4C +:101434000121684606F0FAFD28000006000E00F0BF +:1014440087F800281AD09549684604F0F9FE02216D +:10145400684606F0EBFD9249684604F0F1FE280068 +:101464000006000E00F026F80400684606F07AFF35 +:1014740021006A46101801F061FC0BE089496846B6 +:1014840004F0DEFE0221684606F0D0FD8649684677 +:1014940004F0D6FE0321684606F0C8FD0DB030BC4A +:1014A40008BC1847845300400C4E0100B4200100CE +:1014B400184E01007CB504002406240E0420604369 +:1014C4007A490E5800200190002000900025012345 +:1014D4002406240E220001A9754800F003F9012313 +:1014E4002406240E22006946724800F0FBF8009896 +:1014F4003C21484300902406240E6F48005D0028D8 +:1015040005D002280FD003D3032816D01CE01BE01B +:10151400009830182406240E04216143674A515868 +:101524004018050010E000982406240E04216143AD +:10153400624A51584018050006E02406240E04208F +:1015440060435E4908580500280076BC08BC18476B +:1015540000B501000906090E5748405C002801D077 +:10156400012000E0002008BC184700001E5600407F +:1015740024080100C03901001CB50023002269467B +:101584004F4800F0AFF80023002201A94D4800F0B5 +:10159400A9F80421684606F011FF0400019884426A +:1015A40012D0002000900421684606F007FF019045 +:1015B400002300226946424800F0E4F80023002298 +:1015C40001A9404800F0DEF813BC08BC184700002D +:1015D400B0390100244E0100C8200100DC200100C4 +:1015E4001CB5040000940421684606F0E7FE01904F +:1015F400002300226946324800F0C4F80023002288 +:1016040001A9304800F0BEF813BC08BC184780B5E7 +:101614000023002269462A4800F064F800980ABCB6 +:1016240018470000F020010004210100D039010016 +:1016340018210100705C01001CB5002300226946DA +:10164400214800F04FF80023002201A91F4800F0B0 +:1016540049F80421684606F0B1FE0400019884426A +:1016640012D01B4800900421684606F0A7FE0190A2 +:10167400002300226946144800F084F80023002265 +:1016840001A9124800F07EF813BC08BC18470000FA +:10169400785C010054080100202564002C2101001D +:1016A400304E0100E0390100F0390100845300405C +:1016B400C40A0100F40A0100145500405C530040C0 +:1016C40074120100A4120100D412010004130100D9 +:1016D4005704000008B4024B9C4608BC6047C0464F +:1016E40030840000F2B582B0040016001F00002010 +:1016F4000090E07800281AD03F063F0E012F0CD14D +:101704006068864205D3A0696168491E4843009019 +:101714000DE0A0697043009009E0002300226946AF +:10172400A068FFF7DFFF0098A16948430090A07804 +:1017340000280ED1002506F06FFE05000422009853 +:10174400E168091801A806F0A5FF2800FFF7C2FF09 +:101754000FE0A078012809D101AA0421E068009BC8 +:10176400C0180004000C07F03CF802E00020C0435D +:1017740005E0042201A9029806F08CFF0020FEBCBB +:1017840008BC1847F8B584B004000F001600002008 +:1017940001902078012802D10020C0439CE02069F8 +:1017A40000284DD025690422290003A806F072FF01 +:1017B40004222900091D02A806F06CFF0422390046 +:1017C400684606F067FF607802280AD102980099FB +:1017D400884203D300980399884236D20020C0433C +:1017E4007AE0607803280AD102980099884203DBE2 +:1017F40000980399884228DA0020C0436CE060789E +:1018040004280CD10298009907F03CF804D30098FE +:10181400039907F037F818D20020C0435CE06078E1 +:10182400052812D06078072807D10098B421C90090 +:1018340088420AD30020C0434EE00020C0434BE05E +:1018440004223900684606F025FFE07800281AD003 +:101854006846007C01280CD16068864205D3A069E3 +:101864006168491E484301900DE0A06970430190EE +:1018740009E00023002201A9A068FFF733FF0198C3 +:10188400A16948430190A07800280ED1002506F0F4 +:10189400C3FD0500042269460198E368181806F0A0 +:1018A400F9FE2800FFF716FF0FE0A078012809D100 +:1018B4006A460421E068019BC0180004000C06F08D +:1018C40014FF02E00020C04306E06069002802D053 +:1018D400606906F0EFFF002005B0F0BC08BC1847B3 +:1018E40070B505000C002869002807D02E69042271 +:1018F4003100091D200006F0CDFE01E000200400A7 +:10190400002070BC08BC184770B505000C0028699D +:10191400002806D02E6904223100200006F0BAFE09 +:1019240001E000200400002070BC08BC1847FEB58C +:1019340004000E006846037A019A69462000FFF706 +:10194400D1FE6078022836D12020205C00282CD0DB +:101954002069002818D025690098296888420CD38A +:1019640068680099884208D3009804214843616A52 +:101974000958300006F0A4FF5AE069A1300006F0CF +:101984009FFF0020C04354E02078012808D100982C +:1019940004214843616A0958300006F091FF47E08A +:1019A4005FA1300006F08CFF42E0009A5DA1300098 +:1019B40004F046FC3CE06078032805D1009A59A164 +:1019C400300004F03DFC33E06078042809D100982D +:1019D40006F0AEFF02000B00BC49300004F030FCFE +:1019E40026E06078052804D10099300001F08EF9D2 +:1019F4001EE06078062804D10099300001F0C8F98F +:101A040016E06078072810D100983C21FEF718FBF7 +:101A14000F0000983C21FEF713FB05003B002A0051 +:101A2400AB49300004F00CFC02E00020C04300E0AD +:101A34000020FEBC08BC1847F8B505000C001700D0 +:101A44001E002100280000F025F8E869002812D0C3 +:101A54002020285C002807D0200006F083FC9DA1EC +:101A6400201806F099FF06E0200006F07BFC9AA1FE +:101A7400201806F091FF200006F074FC33001B06CA +:101A84001B0E3A0021182800FFF751FF0020F2BC7A +:101A940008BC184738B504000D00E069002804D0DC +:101AA400E169280006F00CFF03E01DA1280006F000 +:101AB40007FF002032BC08BC1847F8B504000D002D +:101AC40017002020205C002804D10020287000206A +:101AD400C04321E06078022804D000202870002050 +:101AE400C04319E02069002811D026693068874274 +:101AF4000AD37068B84207D304207843616A09584E +:101B0400280006F0DDFE06E00020C04304E004A146 +:101B1400280006F0D5FE0020F2BC08BC18470000DF +:101B2400000000002564000038B504000D00012306 +:101B34002A0021002C312000FFF724FE002032BCB3 +:101B440008BC184770B584B005002E6928690028C0 +:101B540001D100208AE00422310002A806F09AFD97 +:101B640004223100091D01A806F094FDE87800283C +:101B740040D000246868844277D201232200694659 +:101B84002800FFF7AFFD687802280CD1019800996E +:101B9400884203D300980299884229D22100280060 +:101BA400FFF7C2FF24E0687803280CD1019800995C +:101BB400884203DB00980299884219DA2100280040 +:101BC400FFF7B2FF14E0687804280ED10198009959 +:101BD40006F058FE04D30098029906F053FE07D28B +:101BE40021002800FFF7A0FF02E00020C0433DE0F1 +:101BF400641CBFE70123002269462800FFF772FD39 +:101C0400687802280CD101980099884203D300987F +:101C14000299884229D200212800FFF785FF24E099 +:101C2400687803280CD101980099884203DB009856 +:101C34000299884219DA00212800FFF775FF14E0A1 +:101C4400687804280ED10198009906F01BFE04D38D +:101C54000098029906F016FE07D200212800FFF72B +:101C640063FF02E00020C04300E0002004B070BC29 +:101C740008BC184738B50500E878002809D00024C6 +:101C84006868844209D221002800FFF74DFF641CD4 +:101C9400F6E700212800FFF747FF002032BC08BC0C +:101CA400184710B50024042060430C490858002844 +:101CB40007D00420604309490858FFF743FF641C18 +:101CC400F1E7002010BC08BC18470000805C01004C +:101CD4003C4E0100200000003D00000040010100D6 +:101CE40038B505000C000123220069463448FFF78B +:101CF400F9FC280006F036FB009B2200521C3149F7 +:101D0400281804F09DFA0123220069462E48FFF7A3 +:101D1400E9FC280006F026FB009A2C49281804F058 +:101D24008FFA0123220069462948FFF7DBFC2800CB +:101D340006F018FB0099281801F000F8280006F0B6 +:101D440011FB24A1281804F07BFA31BC08BC184705 +:101D540038B505000C000123220069461E48FFF730 +:101D6400C1FC280006F0FEFA009B2200521C154913 +:101D7400281804F065FA0123220069461748FFF782 +:101D8400B1FC280006F0EEFA009A1049281804F075 +:101D940057FA0123220069461148FFF7A3FC2800E3 +:101DA40006F0E0FA0099281800F0C8FF280006F0B1 +:101DB400D9FA08A1281804F043FA31BC08BC184722 +:101DC400F410010000390100C41001001C5C010082 +:101DD400241101000D0A00008411010054110100B6 +:101DE400B411010030B58FB00400AB48006811286D +:101DF40000DBF8E100202070A7480068002815D116 +:101E04000AA800F02EFEA549200004F019FA2000CB +:101E140006F0A8FA0AA9201800F05DFF200006F0D9 +:101E2400A1FA9F49201804F00BFAD5E19A480068FA +:101E3400012834D19B49200004F002FA0023002237 +:101E440001A99948FFF74EFC200006F08BFA019A8D +:101E54009649201804F0F4F90023002201A99448BB +:101E6400FFF740FC200006F07DFA019A9149201802 +:101E740004F0E6F90023002201A98F48FFF732FCA1 +:101E8400200006F06FFA0199201800F057FF200097 +:101E940006F068FACEA1201804F0D2F99CE17E483D +:101EA4000068022807D1200006F05CFAC94920180E +:101EB40004F0C6F990E178480068032834D17949E0 +:101EC400200004F0BDF9002300226946CC48FFF746 +:101ED40009FC200006F046FA009A7449201804F020 +:101EE400AFF9002300226946C648FFF7FBFB200038 +:101EF40006F038FA009A6F49201804F0A1F900237B +:101F040000226946C048FFF7EDFB200006F02AFADC +:101F14000099201800F012FF200006F023FAACA16B +:101F2400201804F08DF957E15B48006804280BD1B0 +:101F3400CB49200004F084F9200006F013FAC949C3 +:101F4400201804F07DF947E15348006805280DD1B5 +:101F540000200500032D00DB3EE1200006F002FA1C +:101F640029002018FFF7BCFE6D1CF3E74A480068FF +:101F740006280DD103200500062D00DB2CE12000EE +:101F840006F0F0F929002018FFF7AAFE6D1CF3E70C +:101F94004148006807280DD1062005000A2D00DB02 +:101FA4001AE1200006F0DEF929002018FFF798FE58 +:101FB4006D1CF3E73848006808280BD1AA492000B3 +:101FC40004F03EF9200006F0CDF9A649201804F0EB +:101FD40037F901E13048006809280DD100200500D7 +:101FE400032D00DBF8E0200006F0BCF929002018DE +:101FF400FFF7AEFE6D1CF3E7274800680A280DD1F1 +:1020040003200500062D00DBE6E0200006F0AAF917 +:1020140029002018FFF79CFE6D1CF3E71E4800689A +:102024000B280DD1062005000A2D00DBD4E020008A +:1020340006F098F929002018FFF78AFE6D1CF3E7D3 +:10204400154800680C2839D1BC49200004F0F8F880 +:102054000023002207A9BA48FFF744FB0798002889 +:1020640011D1200006F07EF9B649201804F0E8F8F2 +:1020740009480068401C0849086007480068401C7B +:1020840005490860A8E0200006F06CF9AE49201864 +:1020940004F0D6F8A0E0C04694550040143901007D +:1020A40084FE00007C060100D40F0100285C0100BE +:1020B400A40F0100345C010004100100CC48006846 +:1020C4000D2821D10020207000200500062D00DB02 +:1020D40082E001232A0003A9AB48FFF703FB03981E +:1020E40000280BD0200006F03DF9039B042169432E +:1020F400B24A5258B249201804F0A2F8200006F05F +:1021040031F903906D1CE1E7B94800680E281CD131 +:1021140000202070062005000C2D5DDA01232A0022 +:1021240006A99948FFF7DEFA069800280BD020008C +:1021340006F018F9069B04216943A04A5258A049A5 +:10214400201804F07DF86D1CE6E7A94800680F2804 +:102154001CD1002020700C200500122D3CDA012334 +:102164002A0005A98848FFF7BDFA059800280BD076 +:10217400200006F0F7F8059B042169438F4A525862 +:102184008F49201804F05CF86D1CE6E79848006855 +:10219400102821D10020207012200500182D1BDAF0 +:1021A40001232A0004A97848FFF79CFA0498002820 +:1021B4000BD0200006F0D6F8049B042169437F4A23 +:1021C40052587F49201804F03BF86D1CE6E7C046DE +:1021D4000D0A00009400010085480068401C8449F1 +:1021E40008600020A6E082480068FF21123188427E +:1021F4003CDA8C480068002808D10020C04399E0EC +:102204006410010034100100941001007848016842 +:1022140011390CA801F06CFD00202070744800688E +:102224001138002803D18049200004F009F80C98E3 +:10223400002806D16E480068401C6D4908600020E3 +:1022440078E0200006F08EF80CA9201801F0C8FEF2 +:1022540067480068401C6649086000206AE0C04680 +:1022640034FF0000FC060100E4FF00006048006841 +:102274006E4988425CDA00200290002020705C489D +:1022840000686B494018002803D16A49200003F014 +:10229400D7FF0123564800686549421802A96648D9 +:1022A400FFF720FA0298002806D151480068401C24 +:1022B4004F49086000203DE0200006F053F85FA17C +:1022C400201803F0BDFF012349480068584942180B +:1022D40002A95948FFF706FA029908A800F003FE7C +:1022E400200006F03FF808A9201800F0F4FC2000B4 +:1022F40006F038F85249201803F0A2FF200006F037 +:1023040031F801233A490968494A8A1821184D4885 +:10231400FFF70DFB200006F025F84BA1201803F071 +:102324008FFF33480068401C31490860002001E0F9 +:102334000020C0430FB030BC08BC1847DC010100CA +:10234400B41401007C1B0100A415010000B58DB07C +:10235400274800210160002300223249A148FFF7E9 +:10236400C1F90023002269469F48FFF7BBF9009A90 +:10237400AB4901A803F064FFAA4901A805F0E6F9F6 +:102384000DB008BC184700008414010010B582B0D9 +:1023940004006846002101706A460121A2480068D1 +:1023A40005F07AFB010068460078002801D000207F +:1023B40001E02160012016BC08BC18479051004080 +:1023C4003417010010B504000948006800280AD138 +:1023D40007480068401C064908609449200003F03F +:1023E4002FFF002001E00020C04310BC08BC1847A8 +:1023F4009455004000B58DB00023002269467A4808 +:10240400FFF770F9009A8A4901A803F019FF774889 +:1024140000210160874901A805F098F90DB008BCB6 +:102424001847000098550040700201001102000096 +:10243400EFFEFFFF04030100B40E01007C20200026 +:10244400A05F0100840E01000D0A00007CB50500A8 +:1024540079480068002819D178480168684600F076 +:1024640042FD7749280003F0EBFE280005F07AFFCF +:102474006946281800F02FFC280005F073FF714905 +:102484000A687149281803F0DBFEA2E06A48006874 +:1024940001281BD16D4800680400002C0AD12800D3 +:1024A40005F060FF6A49281803F0CAFE62486421F7 +:1024B40001608EE06749280003F0C2FE280005F0A1 +:1024C40051FF6549281803F0BBFE82E05A480068B2 +:1024D40002281ED10020287000200400062C78DA7F +:1024E400042060435D4908580600002E0BD02800E4 +:1024F40005F038FF330004216143594A52585949C1 +:10250400281803F09DFE280005F02CFF0600641C2B +:10251400E4E74948006803281AD1002028700620FF +:1025240004000C2C55DA042060434C49085806007A +:10253400002E0BD0280005F015FF33000421614361 +:10254400474A52584749281803F07AFE641CE8E7C2 +:102554003948006804281AD1002028700C2004008F +:10256400122C36DA042060433C4908580600002E39 +:102574000BD0280005F0F6FE330004216143384AED +:1025840052583849281803F05BFE641CE8E72A48CF +:10259400006805281AD10020287012200400182C85 +:1025A40017DA042060432D4908580600002E0BD08A +:1025B400280005F0D7FE330004216143284A52580D +:1025C4002849281803F03CFE641CE8E70020C043B7 +:1025D40005E019480068401C17490860002076BCD3 +:1025E40008BC184744090100E41401009455004054 +:1025F40000B58DB00023002269461B48FFF772F82E +:10260400009A1A4901A803F01BFE0B48002101603F +:10261400174901A805F09AF80DB008BC1847000046 +:1026240058170100E91D000090550040981B010057 +:10263400B41B0100C923000094550040A05500407C +:10264400283901009C5500403C39010028550040C0 +:10265400CC190100DC010100A4150100D050004098 +:102664009051004034170100E4140100D01B010014 +:1026740051240000F1B58CB000200190642004F0D6 +:1026840027F904F0BFFE002827D10023002201A966 +:10269400A348FFF727F8019800281AD004F0CBFECE +:1026A400002803D19F480221016006E004F0D8FE0F +:1026B400002802D19B480121016004F017FC002886 +:1026C40003D0192001F002FA06E0192001F02CFAD7 +:1026D40002E0944800210160CEE7924800210160A5 +:1026E4000023002201A98E48FEF7FCFF0198002870 +:1026F40002D104F076FEBFE708A8FFF747FE0028E2 +:1027040000D1B7E0089801285BD0022800D187E007 +:10271400032800D1ABE00428AED10023002269468F +:102724008148FEF7DFFF009880498842A4D1002346 +:1027340000227F497F48FEF7D5FF002300227E490F +:102744007E48FEF7CFFF00200500032D14DA002099 +:102754000400032C0ADAFFF74BFF0600002E05D015 +:10276400FA20800004F0B4F8641CF2E7032C03DBC5 +:1027740004F0BCFB6D1CE8E7032D08DB00220F21ED +:10278400002001F0CBFA042000F0C0F818E000208B +:1027940000900023002269466348FEF7F3FF0023FC +:1027A400002269466348FEF7EDFF002300226946D4 +:1027B4006248FEF7E7FF00220E21002001F0AEFA86 +:1027C4005AE700200500032D14DA00200400032C2E +:1027D4000ADAFFF7BBFD0600002E05D0FA208000C0 +:1027E40004F076F8641CF2E7032C03DB04F07EFBB0 +:1027F4006D1CE8E7032D05DB00220F21002001F00A +:102804008DFA0CE000220E21002001F087FA01F07D +:1028140007FE002300224A494A48FEF7B3FF2BE78C +:1028240000200500032D14DA00200400032C0ADA2A +:10283400FFF7E0FD0600002E05D0FA20800004F02A +:1028440047F8641CF2E7032C03DB04F04FFB6D1C18 +:10285400E8E7032D05DB00220F21002001F05EFADA +:1028640004E000220E21002001F058FA04E704F0ED +:102874003DFB01E7344804F02BF80023002202A9B1 +:102884003248FEF72FFF0023002203A93048FEF749 +:1028940029FF03983C21FDF7D3FB079003983C21C3 +:1028A400FDF7CEFB0F000023002206A92548FEF702 +:1028B40019FF029904A800F016FB069909A800F074 +:1028C40012FB04A880780799884200D2D4E604A8B1 +:1028D4004078B84200D2CFE609A8007904A9097962 +:1028E40088420CD109A8807904A98979884206D143 +:1028F40009A8407904A94979884200D1BCE601209D +:1029040000F004F80E4802990160B5E610B5040021 +:1029140021001048006805F053F910BC08BC1847A2 +:10292400B4080100A4550040141501002143658733 +:102934009C55004044150100A05500407415010049 +:10294400A8550040F407010010270000440F0100BF +:10295400A40901009055004010B5002405F05CFD69 +:1029640004002F4800682F4901402D4801602E487B +:1029740000682C4901402C4801602C4800682C490F +:1029840001402A4801602B48006829490140294830 +:1029940001602000FEF79EFE012003F099FF05F080 +:1029A4003BFD040024480068400203D5234800216D +:1029B400017002E02148012101702000FEF78AFE27 +:1029C40010BC08BC184738B5002505F025FD0500E6 +:1029D4001A48007804002800FEF77CFE2000000658 +:1029E400000E32BC08BC184710B5134800684002FA +:1029F40002D50020040001E0012004000F48007803 +:102A04002406240E844206D00C4804700620FEF7E7 +:102A14002BF8012000E0002010BC08BC184700007F +:102A24000CC002E0FFCFFFFF4CC002E020C0FF3F1C +:102A3400FFFFBFFF30C0FF3F34C0FF3F32560040AE +:102A440010B5B04800684007400F04002000C007DC +:102A540002D50120FEF708F8AA48046010BC08BC9F +:102A6400184738B50400002505F0D6FC0500714868 +:102A74000068207070480068607070480068A0703A +:102A84006F480068E0706F48006820716E48006805 +:102A94006071A64800683030A0712800FEF71AFE65 +:102AA40031BC08BC184738B50400002505F0B4FC57 +:102AB400050020785F49086060785F490860A07865 +:102AC4005E490860E0785E49086020795D490860E5 +:102AD40060795D490860A079FA21C9004018A749C6 +:102AE40008602800FEF7F6FD31BC08BC184710B595 +:102AF40000248548006880218900014382480160E0 +:102B04008B4800688B4901408948016005F084FCCA +:102B140004009B4811210160092005F0AEFFC00BA1 +:102B2400401E85490860092005F0A7FF824909680D +:102B3400491C802212025143401A924908607B4882 +:102B440000689149884208D33C480068182804D298 +:102B5400764800688D49884214D389480021016071 +:102B640072488949016038480821016035480821C4 +:102B740001603248072101602F480021016080482C +:102B84001121016092489349016093480068934978 +:102B940001409148016092480721016091488021D9 +:102BA400890101609048002101609048FF21016083 +:102BB4008F48012101602000FEF78CFD10BC08BC89 +:102BC400184730B585B005000C00A07903906079F2 +:102BD400029020790190207800906378A278B94916 +:102BE400280003F02DFB05B030BC08BC184730B5F5 +:102BF4008BB005000C0004A8039005A8029006A859 +:102C0400019007A8009008AB09AAAE49280006F075 +:102C1400C1FB0498A0710598607106982071099809 +:102C2400A07008986070079820700BB030BC08BC86 +:102C340018470000204002E0244002E0284002E05F +:102C4400304002E02C4002E0384002E010B50400BD +:102C5400A078182802D30020C04339E060783C28CB +:102C640002D30120C04333E020783C2802D3022061 +:102C7400C0432DE060790D2802D26079012802D288 +:102C84000420C04324E0A079642802D30520C04373 +:102C94001EE0A079042100F0ADF900290BD1607980 +:102CA400022808D12079002802D020791E280ED3CA +:102CB4000320C0430CE02079002805D060798249C4 +:102CC400085C2179884202D20320C04300E000203E +:102CD40010BC08BC184730B585B005000C0020783E +:102CE400039060780290A078019020790090637935 +:102CF400A2797649280003F0A3FA05B030BC08BCD9 +:102D040018470000004002E0C4C01FE030B583B0A3 +:102D140004000D002900684600F0E5F8694620002B +:102D2400FFF74FFF37BC08BC184700003C4002E0E7 +:102D3400A8C11FE0FFFFF3FF804002E0F1B582B0BD +:102D44000E0030003C2100F055F93C2100F052F90E +:102D54000D0030003C2100F04DF90F003000E1215E +:102D6400090100F047F9040000972B00220098495C +:102D7400029803F065FAF7BC08BC18473C4002E02F +:102D8400084002E0844002E0DA0700003508000051 +:102D9400F1B582B00E0030003C2100F02BF93C214B +:102DA40000F028F90D0030003C2100F023F90F0059 +:102DB4003000E121090100F01DF9040000972B0007 +:102DC40022008449029803F03BFAF7BC08BC184778 +:102DD40034F1FFFF452A00000CF0FFFFFFDFFFFF87 +:102DE40034F2FFFF10F0FFFF404002E0104002E029 +:102DF4000C4002E0F8B504000D00A079462801D388 +:102E0400754801E0FA20C000A1790E183604360C8A +:102E14000C207043617947180D3F2D062D0E052DAA +:102E24003BD03604360C711EFF206E3041430091B6 +:102E34003604360C701E042100F0DCF800990818E2 +:102E4400617902225143654A515A40182179401848 +:102E540007003604360C3000042100F0CBF80029BA +:102E640003D16079032800D37F1C2D062D0E042D79 +:102E740013D018204743A0783F182D062D0E032D9C +:102E84000BD03C20474360783F182D062D0E022DB1 +:102E940003D03C20474320783F183800F2BC08BCDC +:102EA4001847000010B5040002212000FFF7A2FF1C +:102EB4004B4940183C2148432178401810BC08BCB9 +:102EC40018470000EC190100C04D01000C1A010064 +:102ED40000B583B06846FFF7C4FD6846FFF7E2FF1C +:102EE40003B008BC184770B504000D000026280084 +:102EF4003C49FDF7A5F806003000001D0721FDF749 +:102F04009FF8E1703848854204D338482D180020D2 +:102F1400A07101E04620A071FF206E300600A07968 +:102F2400042100F067F8002901D0002000E001200E +:102F3400FF216E3146182B484643B54204D3AD1BDE +:102F4400A079401CA071EAE7012060716079022831 +:102F540009D1A079042100F04DF8002901D0002006 +:102F640002E0012000E000206179214A515C0E1842 +:102F74001C484643B54204D3AD1B6079401C6071C4 +:102F8400E4E728001749FDF75BF8401C207128008E +:102F94001449FDF755F80D002800E1210901FDF75A +:102FA4004FF8A0702800E1210901FDF749F80D0050 +:102FB40028003C21FDF744F8607028003C21FDF70F +:102FC4003FF80D002800207070BC08BC18470000B2 +:102FD400A04D0100B04D01006C070000EC1B010086 +:102FE400C0BF45C28051010080436D3880BC92C788 +:102FF400C04D01007847C046802411E200106142B0 +:10300400402032E06800001A010050E10200512320 +:103014001800003A0030A0E3200851E10118A09103 +:1030240010308392200451E10114A091083083925E +:10303400200251E10112A09104308392200151E158 +:103044000111A09102308392A00051E18110A0915E +:1030540001308392010050E0A110A0E1001061E270 +:103064000130D3E24A0000DA010090E00100403070 +:1030740020C063E28CF18FE0010011E1CD18000A59 +:10308400010050E10010A0310000A0330010A02383 +:103094001EFF2FE18000B1E0010040308000B1E06C +:1030A400010040308000B1E0010040308000B1E018 +:1030B400010040308000B1E0010040308000B1E008 +:1030C400010040308000B1E0010040308000B1E0F8 +:1030D400010040308000B1E0010040308000B1E0E8 +:1030E400010040308000B1E0010040308000B1E0D8 +:1030F400010040308000B1E0010040308000B1E0C8 +:10310400010040308000B1E0010040308000B1E0B7 +:10311400010040308000B1E0010040308000B1E0A7 +:10312400010040308000B1E0010040308000B1E097 +:10313400010040308000B1E0010040308000B1E087 +:10314400010040308000B1E0010040308000B1E077 +:10315400010040308000B1E0010040308000B1E067 +:10316400010040308000B1E0010040308000B1E057 +:10317400010040308000B1E0010040303013A0E194 +:10318400110320E00000A0E002C0A0E31C0380E1E2 +:103194001EFF2FE1013093E2010090300100403026 +:1031A4000010A0E10300A3E01EFF2FE104402DE97D +:1031B4000000602293FFFFEB8220B0E10010614227 +:1031C400000060220440BDE81EFF2FE170B588B006 +:1031D4000023002204A9A048FEF784FA04980028DA +:1031E40001D1002033E103F0ADFB04000600A01B75 +:1031F40006F0E4F89949884200DB1EE1642003F0FC +:1032040067FB03F09FFB040003F036F80500012080 +:10321400C043854208D19248002101701A2000F071 +:1032240055FC0020C04312E10020C0438542DED09B +:1032340001AA8C49012003F01CF900281DD068461E +:10324400007900280ED068460079002803D068462B +:10325400007900F047FA8248012101701A2000F039 +:1032640063FC07E000F02EFA7D48002101701A206B +:1032740000F02CFC0120C043E9E0794801210170F1 +:103284001A2000F051FC022276490B3101A8801C5F +:1032940005F000FA6846C088800605D4A12000F035 +:1032A40021FA0220C043D2E0A12000F03BFA6B20B7 +:1032B40000F038FA6B48807B401E07D0401E0BD0CC +:1032C400401E0FD0401E012816D916E06B2000F0D6 +:1032D40009FA0320C043BAE06B2000F003FA04208B +:1032E400C043B4E06B2000F0FDF901A9012003F014 +:1032F400B8FA0520C043AAE079E75A48407B002881 +:1033040011D0012812D0022813D0032814D0042885 +:103314006BD005286CD006286ED0082870D00C28F5 +:1033240000D189E089E000F0CDF986E000F0CAF927 +:1033340083E000F0C7F980E00023002202A9BC4822 +:10334400FEF7D0F9029802282CD101A91E2003F01F +:1033540036F9684600794B2819D16846007900F09F +:10336400C1F9FFF7B5FD02000A21002000F0D6FCE8 +:1033740001A91E2003F057F968460079002833D0CC +:103384006846007900F0AEF90720C0435FE0684664 +:103394000079002828D06846007900F0A3F90820B5 +:1033A400C04354E00298012815D101A91E2003F05E +:1033B400D2F8FFF78DFD02000821002000F0AEFCDA +:1033C4006846007900280FD06846007900F08AF931 +:1033D4000920C0433BE00298002805D14E2000F0AC +:1033E40081F90A20C04332E027E000F06BF924E0C1 +:1033F4004F2000F077F920E0C02000F073F91CE0C2 +:1034040006AA0020002103C2083A03A80021016093 +:1034140001A80090AA4B03AA06A9012003F0CCF945 +:1034240068460079002806D06846007900F05AF909 +:103434000A20C0430BE000E0D9E6A01B05F0BEFF64 +:103444000649884201DA002001E00020C04308B0A8 +:1034540070BC08BC18470000340A010010270000A3 +:10346400265600402C5300407CB50023002201A9BD +:10347400AB48FEF737F900F004F90198002857D05B +:1034840006200500002D1BD404206843B2490858C7 +:1034940006F0B0F80A200400642003F019FA02F0E0 +:1034A400EBFE0600002E03D00020C043864200D16C +:1034B40002E0641E002CEFD1002C01D16D1EE1E767 +:1034C400002D0AD51A2000F001FBA4480021017048 +:1034D40000F0EBF80020C04336E06A46A049012022 +:1034E40002F0C7FF002819D068460078002808D0E9 +:1034F40068460078002811D06846007800F0F2F899 +:103504000CE000F0DFF89548002101701A2000F06B +:10351400DDFA00F0CAF80120C04315E08F4801210C +:1035240001701A2000F000FB00F0BFF800200BE04F +:103534008A480021017000F0C5F81A2000F0F4FA5E +:1035440000F0B3F80220C04376BC08BC18477CB531 +:103554000023002201A97248FEF7C4F800F091F894 +:103564000198002854D006200500002D18D404200A +:1035740068437949085806F03DF80220040002F037 +:103584007BFE0600002E03D00020C043864200D1FB +:1035940002E0641E002CF2D1002C01D16D1EE4E780 +:1035A400002D0AD51A2000F091FA6C480021017010 +:1035B40000F07BF80020C04336E06A4668490120E9 +:1035C40002F057FF002819D068460078002808D078 +:1035D40068460078002811D06846007800F082F828 +:1035E4000CE000F06FF85D48002101701A2000F033 +:1035F4006DFA00F05AF80120C04315E05748012144 +:1036040001701A2000F090FA00F04FF800200BE04F +:1036140052480021017000F055F81A2000F084FA95 +:1036240000F043F80220C04376BC08BC18470000F1 +:10363400E411010080B54B480068002804D1012042 +:1036440006F0EAF847490860FFF70EFF002801D1A9 +:10365400FFF7BCFD09BC184738B5002404F0DCFEB4 +:1036640004003E480078012802D10120050001E051 +:10367400002005002000FEF72DF8280032BC08BC0D +:10368400184780B56A4601213648006806F0EDF80F +:1036940068460078002806D0012003F019F968462E +:1036A40000780028EED109BC184780B5C82003F083 +:1036B4000FF92C48006806F045F909BC18470000CA +:1036C4007C1E010010B51B242406240EAA2C06D24D +:1036D40020000006000E00F027FA641CF4E710BC7A +:1036E40008BC184710B504002406240E002C14D07E +:1036F40000200006000E8F280FD20006000EC049DD +:10370400095C2406240EA14205D11B300006000EDC +:1037140000F0DCF901E0401CEBE710BC08BC1847E2 +:10372400340A010010B5040000200006000E8F28A2 +:103734000FD20006000EB249095C2406240EA142F1 +:1037440005D11B300006000E00F0EEF901E0401C2C +:10375400EBE710BC08BC1847801A0100265600404D +:103764002C5300406C550040F2B58CB005000C9809 +:10377400FA21890048433C21FCF762FC002108AA95 +:1037840003C2083A6420684300210AAA03C2083A23 +:10379400280006F011F90022B04B06F017F90022B8 +:1037A400AF4B06F013F906000F000C9806F004F96D +:1037B40002000B003000390006F006FA06F0A2FB06 +:1037C40006AA03C2083A05A800210160002004905B +:1037D400FFF757FFFFF7FAFC002804D5FFF765FF52 +:1037E4006320C043ECE00020040003AA0021012070 +:1037F40002F050FF00281AD06846007B002804D04D +:103804006846007BFFF76EFF07E0FFF75BFFA64803 +:10381400002101701A2000F059F92406240E002C0E +:1038240004D0FFF742FF0020C043C9E0641C240613 +:10383400240E002C08D0FFF7C9FC0028D5D0FFF7D0 +:1038440034FFC720C043BBE00023002204A99748EB +:10385400FDF748FF0498002836D10020040003A88F +:1038640002909348019005A80090002306AA08A995 +:10387400012002F047FF00281AD06846007B002888 +:1038840004D06846007BFFF72DFF07E0FFF71AFF1F +:103894008548002101701A2000F018F92406240E2E +:1038A400002C04D0FFF701FF0120C04388E0641C12 +:1038B4002406240E002C4DD0FFF788FC0028CED01F +:1038C400FFF7F3FE7B487BE00498012842D10020F7 +:1038D400040008AAFA208000002103C2083A6420E8 +:1038E4006843002106AA03C2083A03A8029072485A +:1038F400019005A80090002306AA08A9012002F05F +:1039040001FF00281AD06846007B002804D06846CE +:10391400007BFFF7E7FE07E0FFF7D4FE62480021D3 +:1039240001701A2000F0D2F82406240E002C04D0D2 +:10393400FFF7BBFE0220C04342E0641C2406240EB1 +:10394400002C07D0FFF742FC0028C2D0FFF7ADFEE1 +:103954005A4835E00020040003A80090584B05AAFB +:103964000AA9012002F028FF00281AD06846007B2B +:10397400002804D06846007BFFF7B4FE07E0FFF799 +:10398400A1FE4948002101701A2000F09FF8240686 +:10399400240E002C04D0FFF788FE0320C0430FE060 +:1039A400641C2406240E002C07D0FFF70FFC00280B +:1039B400D2D0FFF77AFE414802E0FFF776FE0020FE +:1039C4000DB0F0BC08BC184710B504000020000678 +:1039D400000E8F280FD20006000E0949095C240648 +:1039E400240EA14205D11B300006000E00F0CAF8D7 +:1039F40002E0401CEBE7002010BC08BC18470000A4 +:103A04009803010000B5010000200006000E8F2875 +:103A14000CD20006000E2B4A125C0906090E8A42DB +:103A240002D10006000E02E0401CEEE7002008BCB4 +:103A3400184738B5002400252D062D0E462D09D231 +:103A44002D062D0E2048405DFFF7BEFF20430400E5 +:103A54006D1CF1E7200032BC08BC18470000594037 +:103A640000004E4070B504000025002020700026A0 +:103A74003606360E462E13D23606360E1248805DB2 +:103A8400FFF7A2FF0500002D08D03606360E0E48BB +:103A9400805DFFF7B7FF1B30207001E0761CE7E77D +:103AA400280070BC08BC18472656004014120100B8 +:103AB400941E0100D4FEFFFF004A010070FEFFFFC8 +:103AC4007C1E010098030100B0050100F0B583B02D +:103AD4000400002504F0A0FC05002406240E2000A8 +:103AE4002021FFF787FA04214843BA490090019145 +:103AF4002406240E20002021FFF77CFA04214843E9 +:103B0400B4490E5801272406240E20002021FFF773 +:103B140071FA8F403743019900980F502800FDF740 +:103B2400D9FDF7BC08BC1847F0B583B004000025E4 +:103B340004F072FC05002406240E20002021FFF767 +:103B440059FA04214843A349009001912406240E04 +:103B540020002021FFF74EFA042148439D490E58C6 +:103B640001272406240E20002021FFF743FA8F406A +:103B7400BE43019900980E502800FDF7ABFDF7BC39 +:103B840008BC1847F8B506000024002504F044FCDE +:103B940005003606360E30002021FFF72BFA0421EB +:103BA40048438C490858009001273606360E3000E9 +:103BB4002021FFF71FFA8F40009807403C0028009F +:103BC400FDF788FD2000F2BC08BC184738B5002476 +:103BD400002500200090002300226946B648FDF726 +:103BE40081FD04F019FC05000098002808D1FFF7B6 +:103BF40020FF204304001A20FFF7C4FF20430400E1 +:103C04000120FFF7BFFF204304002800FDF762FDF9 +:103C1400002C01D0012000E0002032BC08BC184771 +:103C24000020704710B502242406240E192C06D255 +:103C340020000006000EFFF777FF641CF4E710BCB9 +:103C440008BC1847F1B582B00027002600250020E3 +:103C54000400FF2C1BD86A46082108206043974BB8 +:103C6400C0180004000C04F0BCFD0098002804D027 +:103C740000980021C943884201D1270007E0009839 +:103C8400A84202D3009805002600641CE1E7FF2C3B +:103C940006D93000401C80214900FCF7D1F90F00FF +:103CA400FFF716F90090029801906A46082108204F +:103CB4007843824BC0180004000C04F016FDF7BCD6 +:103CC40008BC184738B505000C00FF2C02D90020A9 +:103CD400C0430AE02A00082108206043774BC0183B +:103CE4000004000C04F07DFD002032BC08BC184721 +:103CF40038B505000C00FF2C02D90020C0430AE0AF +:103D04002A000A210A2060436D4BC0180004000CED +:103D140004F067FD002032BC08BC1847F7B584B036 +:103D240000270026002500200400FF2C1BD86A462B +:103D34000A210A206043624BC0180004000C04F0FE +:103D440050FD0098002804D000980021C9438842FF +:103D540001D1270007E00098A84202D3009805008B +:103D64002600641CE1E7FF2C06D93000401C8021AA +:103D74004900FCF765F90F00FFF7AAF800906846C0 +:103D84006946097C417268466946097D0172069854 +:103D940001906A460A210A207843494BC01800045E +:103DA400000C04F0A2FC07B0F0BC08BC184780B5B6 +:103DB400002280210901414804F0D5FC09BC1847C0 +:103DC40080B50022A02109013D4804F0CCFC09BCC7 +:103DD40018470000D453004038B504000D002D06E8 +:103DE4002D0E280001281AD002281DD0032820D027 +:103DF400042823D0062826D0072829D008282CD028 +:103E040009282FD00A2832D00B2835D00C2838D0D6 +:103E14000D283BD00E2843D00F283CD045E0614903 +:103E2400200002F00DFA44E05F49200002F008FA95 +:103E34003FE05E49200002F003FA3AE05C492000CA +:103E440002F0FEF935E05B49200002F0F9F930E0B8 +:103E54005949200002F0F4F92BE05849200002F0FF +:103E6400EFF926E05649200002F0EAF921E055492D +:103E7400200002F0E5F91CE05349200002F0E0F9CB +:103E840017E05249200002F0DBF912E0504920000B +:103E940002F0D6F90DE04F49200002F0D1F908E014 +:103EA4004D49200002F0CCF903E04CA1200002F0BF +:103EB400C7F931BC08BC1847640A0100CE070000EA +:103EC400CE0F000038B504000D002D062D0E28007D +:103ED40001281AD002281DD0032820D0042823D07A +:103EE400062826D0072829D008282CD009282FD026 +:103EF4000A2832D00B2835D00C2838D00D283BD0D6 +:103F04000E2843D00F283CD045E0B249200002F0EF +:103F140097F944E0B049200002F092F93FE0AF493C +:103F2400200002F08DF93AE0AD49200002F088F952 +:103F340035E0AC49200002F083F930E0AA492000C2 +:103F440002F07EF92BE0A949200002F079F926E07D +:103F5400A749200002F074F921E0A649200002F0EC +:103F64006FF91CE0A449200002F06AF917E0A349A4 +:103F7400200002F065F912E0A149200002F060F986 +:103F84000DE0A049200002F05BF908E09E49200002 +:103F940002F056F903E09D49200002F051F931BCCA +:103FA40008BC184778510100845101009051010068 +:103FB4009C510100A8510100B4510100104A0100B4 +:103FC400204A010088330100304A0100C051010039 +:103FD400404A01009C330100B0330100EDE5F200DA +:103FE4007CB504000D00287A002800D1EBE02800FD +:103FF40005F0C6FF01006846FEF775FF84A12000A6 +:1040040002F01EF9200004F0ADF969462018FEF70D +:1040140062FE200004F0A6F9297A2018FFF752FF67 +:10402400287A012802D0287A022816D1200004F028 +:1040340099F96A7A521C7749201802F001F9200094 +:1040440004F090F906002800001D05F099FF020015 +:104054007149A01902F0F4F8ADE0287A032815D1CB +:10406400200004F07FF96A7A521C6A49201802F091 +:10407400E7F8200004F076F906002800001D05F09A +:104084007FFF0100A019FEF759FE94E0287A042866 +:1040940010D1200004F066F96A7A521C5D49201898 +:1040A40002F0CEF8200004F05DF9C5A1201802F05A +:1040B400C7F880E0287A062807D1200004F052F9D6 +:1040C400BFA1201802F0BCF875E0287A072809D1AE +:1040D400200004F047F96A7A521C4E49201802F075 +:1040E400AFF868E0287A082807D1200004F03AF9EC +:1040F400B3A1201802F0A4F85DE0287A092807D1BA +:10410400200004F02FF9AEA1201802F099F852E033 +:10411400287A0A2807D1200004F024F9A8A120183D +:1041240002F08EF847E0287A0B2815D12800001DEC +:1041340005F026FF002807D1200004F013F9D34925 +:10414400201802F07DF836E0200004F00BF9D04985 +:10415400201802F075F82EE0287A0C280DD12000E2 +:1041640004F000F906002800001D05F009FF020014 +:10417400D649A01902F064F81DE0287A0D280DD163 +:10418400200004F0EFF806002800001D05F0F8FEFA +:104194000200CFA1A01902F053F80CE0287A0E28EF +:1041A40002D0287A0F2806D1200004F0DBF884A17D +:1041B400201802F045F8200004F0D4F8DAA1201801 +:1041C40002F03EF803E0D949200002F039F873BC4C +:1041D40008BC1847C4330100D8330100EC33010094 +:1041E40000340100504A010014340100AC1E0100E7 +:1041F400C41E01004C190100283401003C340100A4 +:10420400DC1E01006C1901008C19010050340100FE +:104214007C202000CC510100105F010070B5A6B0D5 +:1042240004000E00150002AA04212406240E042012 +:104234006043CB23DB00C0180004000C04F0D1FA67 +:1042440001AA04212406240E04206043D023DB00A9 +:10425400C0180004000C04F0C4FA6A4604212406C1 +:10426400240E04206043D523DB00C0180004000C96 +:1042740004F0B7FA0298401C02900198801901904A +:1042840000984019009002AA04212406240E042058 +:104294006043CB23DB00C0180004000C04F025FAB3 +:1042A40001AA04212406240E04206043D023DB0049 +:1042B400C0180004000C04F018FA6A46042124060D +:1042C400240E04206043D523DB00C0180004000C36 +:1042D40004F00BFA02AA0421DA20C00004F081FAE7 +:1042E40001AA0421924804F07CFA6A460421DB20E6 +:1042F400C00004F076FA0298401C029001988019DC +:10430400019000984019009002AA0421DA20C0000C +:1043140004F0EBF901AA0421854804F0E6F96A46A1 +:104324000421DB20C00004F0E0F903AA8621E82080 +:10433400C00004F056FA2406240E0420604303A9A6 +:104344000858401C2406240E0421614303AA50503B +:104354002406240E0420604303A90818806A8019E7 +:104364002406240E0421614303AA511888622406FA +:10437400240E0420604303A90818006D4019240684 +:10438400240E0421614303AA511808652198401C96 +:1043940021902298801922902398401923908421F7 +:1043A40003A804F00BF803A98431088003AA86212A +:1043B400E820C00004F099F926B070BC08BC184786 +:1043C4000000000010B5A2B06A468621E820C000B3 +:1043D40004F007FA8421684603F0F0FF04006846FD +:1043E400843000882404240C844215D086220021C1 +:1043F400684605F0D7FD8421684603F0DFFF69466F +:10440400843108806A468621E820C00004F06DF9F2 +:1044140000F006F800F03EF822B010BC08BC1847C3 +:1044240080B500228421CB20C00004F09CF909BC93 +:10443400184710B582B00400182C23D26A46042110 +:10444400042060433B4BC0180004000C04F0C9F97D +:104454000098401C00906A46042104206043354BB8 +:10446400C0180004000C04F040F96A4604213248E4 +:1044740004F0B7F90098401C00906A4604212E48C5 +:1044840004F033F913BC08BC18470000185F01009E +:10449400D851010010B582B0002000900020040023 +:1044A400182C0BD26A46042104206043214BC01807 +:1044B4000004000C04F019F9641CF1E76A460421B5 +:1044C4001D4804F012F913BC08BC1847205F010012 +:1044D4002575000070B50024AA2C1CDA20002021C8 +:1044E400FEF788FD0421484314490D580126200095 +:1044F4002021FEF77FFD8E402E40002E09D12000A2 +:104504000006000EFFF73EFB002802D02000FFF754 +:1045140099FB641CE0E720220949084804F0BAF832 +:1045240070BC08BC184700000D0A0000604A010076 +:10453400D4060000DC0600003C070000F4530040F1 +:10454400D453004030B589B005000C002878002809 +:104554000BD16A6846A1684601F072FE2100090683 +:10456400090E684605F0DAFF66E02878022855D17E +:104574006846202101703F480078002840D03E481A +:1045840000782406240E84423AD13C480068203046 +:104594000078002818D06946491C38480068FDF79F +:1045A40079FA37A1684604F0F7F93649684604F009 +:1045B400F3F935A1684604F0EFF921000906090E64 +:1045C400684605F0ABFF37E06946491C2B48006894 +:1045D400FDF760FA294800681C3005F0D1FC00287A +:1045E40003D02AA1684604F0D7F92649684604F0A6 +:1045F400D3F921000906090E684605F08FFF1BE078 +:10460400002300226946491C6868FDF715FA210059 +:104614000906090E684605F081FF0DE02878012897 +:104624000AD16A6812A1684601F00AFE210009064F +:10463400090E684605F072FF09B030BC08BC184783 +:1046440010B582B0040068460021017021000906FB +:10465400090E684605F062FF13BC08BC184780B514 +:1046640005F0C7FF09BC1847B84800687047000048 +:10467400202573002A5600402E56004084550040E1 +:104684003C000000145400403E0000003D000000C7 +:10469400F8B5AE480068407A01283BD100200400F8 +:1046A40005F0B5FF002005002D062D0E042D14D2B3 +:1046B4002D062D0E04206843A4490968096808588A +:1046C40000900098002808D021000906090E0098DF +:1046D400FFF738FF641C6D1CE6E72406240E042C47 +:1046E40006D220000006000EFFF7AAFF641CF4E7C0 +:1046F40096480068006800684078800709D5002261 +:104704001221852005F061FF00221321842005F089 +:104714005CFF13E18D480068006800680090009811 +:10472400002802D1FFF79BFF08E100210098FFF762 +:1047340009FF87480078002803D1864800210170CA +:104744001DE082480068007A042805D28048007879 +:10475400401E8049087012E07D4800787B49096852 +:10476400097A891E884205DA79480078401E794919 +:10477400087004E076480078801E76490870754811 +:104784000078401C0500012004002406240E042C9B +:104794001FD26E480068007A2D062D0E854218D26D +:1047A4002D062D0E042068436849096809680E58CF +:1047B400002E05D120000006000EFFF741FF05E0A2 +:1047C40021000906090E3000FFF7BCFE6D1C641CB5 +:1047D400DBE72406240E042C06D220000006000E7B +:1047E400FFF72EFF641CF4E759480078042148437E +:1047F4005649096809680818406806783606360E6E +:10480400002E0CD15248007852490978421A521CA1 +:104814001206120E0021DF2005F0D7FE3AE036061C +:10482400360E012E0CD14A4800784A490978421ABA +:10483400521C1206120E0021132005F0C6FE29E0B8 +:104844003606360E022E25D141480078042148430D +:104854003E4909680968081847687868007800289C +:104864000CD13B4800783B490978421A521C120685 +:10487400120E0021842005F0A8FE0BE034480078D5 +:1048840034490978421A521C1206120E0021DF2004 +:1048940005F09BFE2D480068006800684778B8075B +:1048A40009D500221221852005F08FFE0022132154 +:1048B400842005F08AFEA048007800283CD09F4858 +:1048C400006820300078002836D19C480068407881 +:1048D400022811D11E4800781E490978411A491C42 +:1048E4000906090E96480078964A12788018000640 +:1048F400000E05F039FE1CE0904800684078052859 +:1049040004D08E4800684078072812D110480078F7 +:1049140010490978411A491C0906090E884800788B +:10492400884A1278A94B9A5C80180006000E05F09C +:104934001BFE05F065FE01E005F069FEF1BC08BC54 +:104944001847A348012101707047000074550040C6 +:10495400285600402956004010B5010000200022CE +:1049640013001A00521C0C7A1B061B0EA3420CD215 +:104974001206120E042353430C68E3581C78012CCE +:1049840002D01C78022CEBD11000401E0006000E51 +:1049940010BC08BC184730B502000800401C0B00CE +:1049A4005B1C1C0023005B1C157A2406240EAC42FD +:1049B4000CD21B061B0E04245C4315682C59257865 +:1049C400012D02D02578022DEBD11800401E0006DF +:1049D400000E30BC08BC184730B503000C00641C42 +:1049E4000A00521C0906090E002901D1002015E015 +:1049F4001000421E0006000E00280CD01206120EF3 +:104A0400042050431D6828580578012D02D00578EC +:104A1400022DEDD11400601E0006000E30BC08BC4F +:104A2400184710B504006B480078082826D2694856 +:104A34000078082148436849684A12680A50654862 +:104A440000780821484364490818654909780171C8 +:104A540060480078401C5F490870604804605F4803 +:104A64000068FFF779FF5E4908706068002802D08B +:104A7400606803F01FFF56480121017010BC08BC98 +:104A8400184710B504005548046054480068FFF7FF +:104A940063FF534908706068002802D0606803F01F +:104AA40009FF4B480121017010BC08BC184780B5B0 +:104AB40048480078002822D046480078401E4549DE +:104AC400087044480078082148434349085843493A +:104AD400086040480078082148433F490818007995 +:104AE4003F4908703D4800684068002804D03B48AE +:104AF4000068406803F0DEFE35480121017009BCFE +:104B0400184780B53648007804214843A549096808 +:104B1400096808184068806800280BD0304800787D +:104B2400042148439F490968096808184068806857 +:104B3400FFF777FF09BC18472A5600408455004008 +:104B44002C5600402B5600407CB505000C00160086 +:104B5400954800684078022823D1684625210170D1 +:104B64006846302141702406240E20000A21FEF7F5 +:104B740041FA3030694688702406240E20000A2148 +:104B8400FEF738FA30316846C17068467521017104 +:104B940068460021417132006946280001F050FB4B +:104BA40010E0814800684078052804D07E480068F9 +:104BB4004078072806D10023002229007A4800689B +:104BC400FCF7B5FE73BC08BC18470000F0510100A7 +:104BD4002F56004027560040F051004074550040C5 +:104BE4002856004010B571480021017070480078C3 +:104BF400042148436B4909680968081840684068FB +:104C0400694908606A480078401C6A490978401A72 +:104C14006949087000230022684963480068FCF76A +:104C240061FD61480068103005F0AAF9040004220F +:104C34002100634803F02EFD04222100091D614870 +:104C440003F028FD5848006820300078002807D079 +:104C5400002300225C4954480068FCF768FE45E0E4 +:104C6400594951480068FCF715FF4F4800681C304B +:104C740005F086F9002803D054A1534803F08CFEB4 +:104C8400514803F06FFB401C5149087046480068C6 +:104C9400407802280ED12000001D05F071F90200B1 +:104CA4004CA1494801F0CCFA474803F05BFB4A4960 +:104CB400087014E03C4800684078052803D1464851 +:104CC4000C2101700BE0384800684078072803D1B4 +:104CD40041480421017002E03F4800210170374837 +:104CE40002683D4801783848FFF72EFF3B48012110 +:104CF400017010BC08BC1847384800210170704787 +:104D040000B587B0284800684078022812D12648A8 +:104D1400006820300078002804D1284A30A12A48AD +:104D240004F038FB0023002224491F480068FCF7E4 +:104D340029FD31E01C4800684078052814D104A9F5 +:104D44002148FDF754FF04A8FDF780FF002823D174 +:104D540004A8FEF7A7F803900023002203A9124831 +:104D64000068FCF70FFD17E00F480068407807283B +:104D740012D101AB02AA1B49134804F00BFB0298A1 +:104D84003C214843019940180090002300226946C1 +:104D940005480068FCF7F6FC10480021017007B0D4 +:104DA40008BC184774550040845500402B560040F9 +:104DB40028560040295600402E56004078550040A1 +:104DC400805500407C550040145400403D000000D4 +:104DD4002C560040257500002D5600402A560040F0 +:104DE40025640000E4510100F0B58FB007000024F1 +:104DF4006848FFF746FE0020029002A805F0BCFDBB +:104E0400002810D1641CFA20800084420BDAFA20B6 +:104E14004000844203DB60480078002803D15F48E7 +:104E240000780028E7D05D480078002804D05B486B +:104E340000210170FFF72CFC57480078002800D0AF +:104E4400B7E0002004000298002800D1AEE00298E8 +:104E540004281FD0CFD306284BD005D308280ED062 +:104E640076D3092877D0C6E7C3480178C3480068D9 +:104E7400FFF7B2FDC0490870FFF70AFCBBE7BE4864 +:104E84000178BE480068FFF786FDBB490870FFF74C +:104E9400FFFBB0E7B94800680068066870788007CF +:104EA40026D575686878022820D10023002201A93C +:104EB4002800FCF717FC0EA92800FCF725FD08A91B +:104EC4002800FCF70DFD0198401E019001980E99F1 +:104ED400884203D308980199884201D20898019026 +:104EE4000023002201A92800FCF74CFCFFF7D0FBAB +:104EF40081E7A2480068006806687078800726D5B4 +:104F040075686878022820D10023002269462800A9 +:104F1400FCF7E8FB07A92800FCF7F6FC0DA928001C +:104F2400FCF7DEFC0098401C00900098079988422A +:104F340003D30D980099884201D20798009000236A +:104F4400002269462800FCF71DFCFFF7A1FB52E78D +:104F5400FFF7ADFD4FE789480068407A012802D188 +:104F6400FFF796FB47E784480078042148438349C8 +:104F740009680968081845682878022810D16E68FD +:104F84003078002811D1FFF72DFEFA2080000400AC +:104F94000BE0C046445201002A5600402F56004000 +:104FA4002878012801D1FFF7ACFD24E7FFF770FB57 +:104FB40021E70298002800D199E10298042800D141 +:104FC40022E100D290E1062800D151E108D308285B +:104FD40000D18DE000D282E1092800D182E183E191 +:104FE400C548006820300078002823D006A9C248AC +:104FF4000068FCF789FC0CA9BF480068FCF770FC4A +:10500400BE480068401CBD490860BC480068069959 +:10501400884204D30C98B9490968884202D2B74837 +:1050240006990160B5480268B549B3480068FCF7C1 +:1050340044FD5CE0B04800684078022814D1C048C0 +:105044000078AF49085C401CBD490978AC4A50540B +:10505400BB480078AA49085C3A2848D3B848007885 +:10506400A74930220A5442E0A34800684078052842 +:105074001CD1B3480078B349085CA149085C401CC2 +:10508400AF490978AF4A515C9D4A5054AC48007806 +:10509400AC49085C9A49085C3A2828D3A8480078A7 +:1050A400A849085C964930220A5420E092480068D6 +:1050B400407807281BD1A2480078A249085C90498F +:1050C400085C401C9E4909789E4A515C8C4A5054A5 +:1050D4009B4800789B49085C8949085C3A2806D3B8 +:1050E400974800789749085C854930220A54FBE0C8 +:1050F4008148006820300078002823D00BA97E481E +:105104000068FCF701FC05A97B480068FCF7E8FB94 +:105114007A480068401E79490860784800680B990D +:10512400884204D3059875490968884202D27348B5 +:10513400059901607148026871496F480068FCF77D +:10514400BCFC60E06C4800684078022818D17C48B8 +:1051540000786B49085C401E79490978684A5054C4 +:10516400774800786649085C30284CD27448007847 +:10517400634939220A5446E02856004074550040D9 +:105184005D480068407805281CD16D4800786D4959 +:10519400085C5B49085C401E69490978694A515CAE +:1051A400574A5054664800786649085C5449085C7C +:1051B400302828D2624800786249085C5049392274 +:1051C4000A5420E04C480068407807281BD15C480A +:1051D40000785C49085C4A49085C401E58490978D3 +:1051E400584A515C464A5054554800785549085C21 +:1051F4004349085C302806D2514800785149085C7C +:105204003F4939220A546FE03B4800682030007857 +:10521400002823D00AA938480068FCF775FB04A9C4 +:1052240035480068FCF75CFB34480068401E33498D +:105234000860324800680A99884204D304982F49C8 +:105244000968884202D22D48049901602B480268FB +:105254002B4929480068FCF730FC08E038480078FE +:10526400002804D036480078401E354908703BE0D9 +:105274002148006820300078002823D003A91E4864 +:105284000068FCF741FB09A91B480068FCF728FBF0 +:105294001A480068401C19490860184800680399B6 +:1052A400884204D3099815490968884202D21348F0 +:1052B400039901601148026811490F480068FCF71E +:1052C400FCFB0BE01E4800782D490978491E8842F2 +:1052D40004DA1B480078401C1949087004E0FFF701 +:1052E4000BFD01E0FFF70CFDFFF7D2F983E5002089 +:1052F4000400FFF7CDF97EE5845500407855004061 +:105304001454004080B51F48002101701E4800213C +:1053140001701E48002101701D48002101701D48C4 +:1053240000210160402200211B4804F03BFE0B23B6 +:105334001A4A00211A4802F0A3FC09BC18470000CD +:105344002B560040F051010080B50B2002F062FDA5 +:10535400FFF785F9642001F0BBFAFFF7D3FF64205F +:1053640001F0B6FAFDF72FFB002803D10D48FFF733 +:1053740088FB02E00C48FFF784FB09BC18470000D7 +:105384002D5600402756004028560040295600401C +:105394002A56004074550040F05100405C1E004005 +:1053A400ED4D0000505801001C53010030B583B08E +:1053B40005000024B74800210160B74801210170AD +:1053C4000120FEF7B1FB0220FEF7AEFB962001F0B0 +:1053D4007FFA0023002201A9BA48FCF783F9AE48FA +:1053E400007801281ED10198002809D1AA4801217A +:1053F40001700120FEF798FB0220FEF795FBE5E71C +:1054040000F062F9002803D00120FEF75FFBDDE71E +:105414000120FEF789FB0220FEF786FB9E4800214F +:1054240001700CE00198002809D19B48012101700A +:105434000120FEF779FB0220FEF776FBC6E76946FA +:10544400032000F0D5FB002800D133E12406240E0C +:10545400002C08D068460078422804D000200400BC +:105464001320FBF701FB684600781038052822D981 +:10547400C01F04281FD9401F20D025385DD0401EEE +:105484005FD0401E69D0401E6BD0401E6DD0801E80 +:105494006FD00938042800D8A4E01538022800D8B1 +:1054A400A0E01B3800D1D0E0401E00D19EE0401E99 +:1054B40000D1F3E0F5E0FEF7B5FBF4E00220FEF7DF +:1054C40033FB68464078602812D0612814D06228E3 +:1054D4000ED0642814D0652816D0662818D0672802 +:1054E4001AD068281CD069281ED06C2820D023E04C +:1054F4000320FEF7EBFA1FE00420FEF7E7FA1BE0B7 +:105504000520FEF7E3FA17E00620FEF7DFFA13E0C2 +:105514000720FEF7DBFA0FE00820FEF7D7FA0BE0CE +:105524000920FEF7D3FA07E00A20FEF7CFFA03E0DA +:105534000B20FEF7CBFAFFE7B5E00C20FEF7C6FA26 +:10554400B1E02406240E002C06D11220FBF78CFABD +:10555400FEF768FB01200400A5E00E20FEF7B6FA72 +:10556400A1E00F20FEF7B2FA9DE01020FEF7AEFA9C +:1055740099E06846407850280ED0512810D052281F +:1055840012D0532814D0542816D0652818D0662871 +:105594001AD067281CD01EE01120FEF797FA1AE0F3 +:1055A4001220FEF793FA16E01320FEF78FFA12E0AA +:1055B4001420FEF78BFA0EE01520FEF787FA0AE0B6 +:1055C4001620FEF783FA06E01720FEF77FFA02E0C2 +:1055D4001820FEF77BFA0120FEF778FA2E48012105 +:1055E400017060E00220FEF771FA5CE00322002102 +:1055F400002000F031FB002802D10120FEF766FAFA +:1056040068464078182814D22248006805F0F2F958 +:10561400694649780C225143984A515805F0F4F9E7 +:1056240005F046FA1B4908606846407894490860CA +:1056340005E0184800210160914818210160052007 +:10564400FBF712FAFEF7EEFA2DE0684640781828C8 +:1056540014D21048006805F0CDF9694649780C2247 +:105664005143864A515805F0CFF905F021FA09490A +:105674000860684640788249086005E005480021D2 +:1056840001607F48182101600420FBF7EDF9FEF763 +:10569400C9FA08E0F45500405C0A0040FEF7C2FA7B +:1056A40001E0FEF7BFFA0120FEF73EFA754800213B +:1056B40001708BE60120FEF709FA7248012101709E +:1056C40084E600008408010010B5C82001F000F948 +:1056D40000200400182C06DA042060436A490022E2 +:1056E4000A50641CF6E700F083F8032000F04EFA39 +:1056F400002802D10020C04326E06049032000F0C6 +:1057040065FB002802D10120C0431DE000200400F5 +:10571400182C0BDA0C2060435849085805F0C8F9D6 +:1057240004216143584A5050641CF1E703220021CC +:10573400002000F091FA002802D10220C04303E0C7 +:10574400504800210170002010BC08BC184738B52F +:10575400002402F061FE04004A480078002802D1C7 +:105764000120050001E0002005002000FBF7B2FF46 +:10577400280032BC08BC184710B59620800105F0FB +:10578400D7F9002402F048FE04004048006840496C +:1057940001403E4801603F4800683D4901403D48A2 +:1057A40001603D480068102101433B4801603B48CB +:1057B400006810218843394908603948006810217D +:1057C4000143374801602000FBF784FF3548006837 +:1057D40000280AD1012004F01FF83249086006238A +:1057E400314A0021314802F04BFA10BC08BC18477A +:1057F40080B500F013F82A480068102101432848B6 +:105804000160642001F064F8294800681021014314 +:105814002748016000F016F809BC184780B56A46AD +:1058240001212048006804F020F868460078002828 +:1058340006D0012001F04CF8684600780028EED12B +:1058440009BC184780B51748006804F07BF809BC08 +:10585400184770B50400002502F0DEFD0500154868 +:10586400066814480021016005480068206028008B +:10587400FBF730FF300070BC08BC18472C480040D0 +:10588400580A00405C0A00409051004010C002E0F9 +:10589400FFFCFFFF50C002E040C0FF3F50C0FF3F8D +:1058A4005CC0FF3FF05500405C300040B153000045 +:1058B40058C0FF3FF455004008B4024B9C4608BC56 +:1058C4006047C04634AD000030B50200AE4B08005E +:1058D4001206120E504000252C002404240C082C1F +:1058E4000BD2C50704D50004000C4008584002E060 +:1058F4000004000C4008641CEFE70004000C30BCFA +:1059040008BC1847F8B507000026B878002801D06D +:10591400BC7803E038790002797944180025A01E88 +:10592400854208DA31000904090C785DFFF7CCFFE1 +:1059340006006D1CF3E730000004000CF2BC08BC48 +:105944001847F0B583B005000E000020C0430700DF +:105954000024012C50DA0620009005F099F9A8786B +:10596400002807D12879000269794118280005F038 +:10597400BBF803E0A978280005F0B6F8E878002819 +:1059840002D0E878FF2802D10020070035E09622F3 +:1059940052000099300005F0B6F800282AD030787B +:1059A400022803D00120C043070023E0B078002878 +:1059B40001D0B07803E07079317909024018009978 +:1059C400401A01900198012811DB96225200019996 +:1059D4000098301805F097F8002802D0002007003E +:1059E4000AE00220C043070005F052F902E000205B +:1059F400070001E0641CACE73800FEBC08BC184793 +:105A0400F7B50400A078002801D0A77803E0207936 +:105A14000002617947186846007960702000FFF73A +:105A240071FF0500E019801E29000170E019401E75 +:105A340029000904090C090A017081492000FFF7B3 +:105A440080FF0600002E27D1E078002824D0E078DB +:105A5400FF2821D07A488078002811D078488078AF +:105A640077490818801E007805002D042D0C744811 +:105A7400807873490818401E007800022D1801E050 +:105A8400002005006E48FFF73DFF2D042D0CA842B1 +:105A940002D00320C0430600029869490160300027 +:105AA400FEBC08BC1847F0B585B007000E00FFF730 +:105AB400B5FE0024032C60DA6A4631000906090E9B +:105AC4003800FFF79DFF050068460221017101A817 +:105AD4000621817001A80021C170002D33D10098E6 +:105AE400C078002807D100988078062803D1FFF7F2 +:105AF400A9FE280044E00098C078FF280ED1009841 +:105B0400807806280AD14F480068002833D04D48D1 +:105B140000680004000C00F0DBFE2CE001A800216A +:105B2400C1706A4631000906090E01A8FFF768FF33 +:105B340044480068002805D0424800680004000C6E +:105B440000F0C6FE19E00020C043854213D001A82E +:105B5400FF21C1706A4631000906090E01A8FFF74A +:105B64004FFF38480068002805D036480068000414 +:105B7400000C00F0ADFE641C9CE7FFF763FE2800F8 +:105B840005B0F0BC08BC1847088400001CB504002C +:105B940068462D490CC90CC00839083806226946E4 +:105BA4002A4802F077FD21000906090E2748FFF76D +:105BB4007AFF0100002917D12148C078020012069B +:105BC400120E002A0ED01206120E302A04D02048DB +:105BD4000423DB43036003E01D480523DB43036028 +:105BE400002002E0012000E0002016BC08BC184799 +:105BF40030B583B005000C00684616490CC90CC0CA +:105C04000839083806226946104802F043FD290085 +:105C14000906090E0D48FFF746FF0100002907D1C8 +:105C24000748C0782070064800796070012004E0BD +:105C3400002020700020607000203EBC08BC184783 +:105C44004C490040500A0040405C01004C4A00406E +:105C540020550040485C0100FEB505000C0016000C +:105C6400684658498CC98CC00C390C382800000C83 +:105C7400694608712800000A694648716846290087 +:105C840081712000000C6946C8712000000A694631 +:105C940008726846210041720C226946484802F0A5 +:105CA400F9FC31000906090E4548FFF7FCFE010026 +:105CB400002917D14448C07802001206120E002AA7 +:105CC4000ED01206120E302A04D03C480423DB43C3 +:105CD400036003E039480523DB430360002002E04E +:105CE400012000E00020FEBC08BC18471CB50400DD +:105CF400684696490CC90CC008390838062269461A +:105D04002F4802F0C7FC21000906090E2C48FFF7B2 +:105D1400CAFE0100002917D12B48C07802001206E0 +:105D2400120E002A0ED01206120E302A04D0894810 +:105D34000423DB43036003E086480523DB4303605D +:105D4400002002E0012000E0002016BC08BC184737 +:105D540010B5C0B0040068467D4980225200FFF7A8 +:105D6400ABFD802252006946154802F093FC2100E5 +:105D74000906090E1248FFF796FE0100002917D103 +:105D84001148C07802001206120E002A0ED0120624 +:105D9400120E302A04D06F480423DB43036003E06F +:105DA4006C480523DB430360002002E0012000E08F +:105DB400002040B010BC08BC18470000205500402B +:105DC4004C4A0040D04D01004C490040F1B586B02A +:105DD4000E0003A860490CC90CC008390838062213 +:105DE40003A95E4802F056FC6846017E5B48FFF753 +:105DF4005AFE00900098002800D0A2E05848C078CD +:105E0400302819D156488078062815D151480521E3 +:105E1400C94301600025182D0CDA0C2068430021C9 +:105E2400315050A10C2068433018001D02F048FD89 +:105E34006D1CF0E7002085E00020040048488078CD +:105E4400401F844262DA20000521FDF7D3F80500E3 +:105E54000C20454342480019C07804F0CBFD705132 +:105E640003223F480119091D01A804F0B9FF01A844 +:105E74000021C17001A90D0020000521FDF7BAF829 +:105E84000C2148433018001D290002F019FD344844 +:105E94000019C07900061BD5002531480019C079C6 +:105EA4004006400E85422FDA20000521FDF7A2F8B6 +:105EB40007000C20474320000521FDF79BF80C2127 +:105EC40048433058284904F0DBFFF0516D1CE4E7E7 +:105ED400002523480019C0794006400E854213DA94 +:105EE40020000521FDF786F807000C204743200019 +:105EF4000521FDF77FF80C21484331581A4805F075 +:105F0400A5F8F0516D1CE4E7641D97E7782C16DAC8 +:105F140020000521FDF76EF80C2148430021315083 +:105F240010A10D0020000521FDF764F80C21484361 +:105F34003018001D290002F0C3FC641DE6E70120AF +:105F440000E0002007B0F0BC08BC1847505C01001A +:105F5400B8FB000020550040585C01004C4A00404A +:105F64004C490040000000000000204110B582B000 +:105F74000400642000F0ACFC0023002269468D4834 +:105F8400FBF7B0FB0098002807D000F031F8002898 +:105F9400EFD00320FAF768FDEBE700F003F800F018 +:105FA40035F8E6E780B50023002269468148FBF70F +:105FB40099FB0098002806D07F4800688021490496 +:105FC40001437D48016009BC184780B500230022C5 +:105FD40069467848FBF786FB0098002806D0774886 +:105FE40000688021490401437448016009BC1847D2 +:105FF40038B5002402F010FA040071480568200046 +:10600400FBF768FB280032BC08BC184738B50024ED +:1060140002F002FA04006A48056869480021016038 +:106024002000FBF757FB280032BC08BC184780B59A +:1060340063480021016000F02EF80823614A002122 +:10604400614801F01DFE09BC184700B55F480068AF +:106054005E49FF220A60C1061BD55D490968090231 +:1060640013D55C4909685C4A12688A1A5B4B9A42E8 +:106074000FD3594A12688A1A594B9A4209D2504A84 +:106084001268521C4E4B1A6003E05349514A12687D +:106094000A6008BC184770B5002402F0BDF904007A +:1060A40050480068504901404E4801604F4800681C +:1060B4004D4901404D4801604D4800688021490424 +:1060C40001434B4801604B4800684B490140494833 +:1060D4000160394800688021490401433648016061 +:1060E400464800688021090401434448016044484B +:1060F4000068444901408020000208434049086088 +:1061040038480068C0210902014336480160374815 +:1061140000683C49014035480160354800683A4907 +:106124000140334801603348006837490140314831 +:106134000160172002F0A1FC060030003349F9F792 +:106144007FFF050032480068032188433049086016 +:106154002F4800680C2188432D490860681E2D498A +:1061640008602D48002101602C48072101602C485B +:10617400002101602B48032101602A4801210160AC +:1061840029480068294901402748016028482949CD +:10619400016029480A21016028488021090501601D +:1061A4000A48FF2101602000FBF794FA70BC08BC88 +:1061B40018470000D409010018C0FF3F1CC0FF3F6E +:1061C400345500405C2A0040715F0000004007E045 +:1061D40014C0FF3F2C4007E03855004099080000E8 +:1061E4002823000004C002E0FFFFFCFF44C002E0DB +:1061F40000C0FF3F10C0FF3FFFFFFFFEC4C01FE011 +:10620400ACC11FE0FF3FFFFFFFFF7FFFA08601003F +:10621400704007E00C4007E0144007E0284007E026 +:106224003C4007E0044007E00CF0FFFFFFFFFFF7EE +:106234006CF1FFFF4F6000006CF2FFFF10F0FFFFF6 +:106244000CB41CB5040004A801900A00009401AB2E +:106254006946084878441C3004F0A8FF00990022DD +:106264000A70002801D40098001B02B0019910BCE8 +:1062740003B008474326000010B582B0052003F0A0 +:1062840089FA6921684603F095FA0400002C02D1CA +:106294000120C0430EE068460078152801D1002093 +:1062A40008E068460078062802D10020C04301E0D7 +:1062B4000120C04316BC08BC184780B5052003F074 +:1062C40069FA6921684603F075FA002802D10120B1 +:1062D400C0430EE068460078152801D1002008E08C +:1062E40068460078062802D10020C04301E001205E +:1062F400C0430ABC1847F1B582B00F00140003F084 +:1063040065F8022003F046FA2000401C0006000E47 +:1063140003F040FA2000401C05006846007A03F0B0 +:1063240039FA29006846057A4D402000441E0006CB +:10633400000E002807D0387803F02CFA28003D78A6 +:1063440045407F1CF1E728000006000E03F022FA06 +:106354006921684603F02EFA002802D10020C043C8 +:1063640021E068460078152815D10026642E18DA35 +:10637400692000F0ADFAFFF7A0FF0100002901D168 +:10638400002010E00020C043814201D1761CEDE7DB +:106394000020C04307E068460078062801D10020A9 +:1063A40001E00020C043FEBC08BC1847F4B582B02D +:1063B40007000E0000203860002030700299684603 +:1063C40003F0F8F9002802D10020C0434EE06846EB +:1063D4000078022802D00020C04347E069216846C3 +:1063E40003F0E8F9002802D10020C0433EE06846EB +:1063F4000078002802D10020C04337E068460078C6 +:1064040005000A222D062D0E2900364803F0EFF967 +:10641400002802D10020C04328E00A21684603F086 +:10642400C9F9002802D10020C0431FE02C0000203D +:106434000006000E2D062D0EA84207D222000006EB +:10644400000E28490C5C5440401CF1E76846007873 +:106454002406240E844202D00020C04306E0062015 +:1064640003F098F91F48386035700020FEBC08BC62 +:10647400184731B582B00D001400002020700422AA +:1064840002A91120FFF737FF002802D00020C043E3 +:1064940025E0154A01A96846FFF788FF002802D0C5 +:1064A4000020C0431BE000984078207068460079C3 +:1064B400302802D00020C04311E000980078112851 +:1064C40003D100984078002802D00020C04306E0A1 +:1064D4002E220099891C280002F0DCF800203EBC22 +:1064E40008BC18474C4C00408813000011B583B019 +:1064F4000C00042203A94020FFF7FDFE002802D06F +:106504000020C04322E0624A01A96846FFF74EFF1B +:10651400002802D00020C04318E000984078207082 +:1065240068460079032802D00020C0430EE000989A +:106534000078402803D100984078002802D0002039 +:10654400C04303E0524800F0C3F9002004B010BC7B +:1065540008BC1847000011B583B00C00042203A93D +:106564004120FFF7C8FE002802D00020C04322E0EB +:10657400474A01A96846FFF719FF002802D0002006 +:10658400C04318E0009840782070684600790328DA +:1065940002D00020C0430EE000980078412803D1C7 +:1065A40000984078002802D00020C04303E0384817 +:1065B40000F08EF9002004B010BC08BC184711B5D7 +:1065C40083B00C00042203A9C620FFF794FE002820 +:1065D40002D00020C04322E02D4A01A96846FFF7FB +:1065E400E5FE002802D00020C04318E0009840785F +:1065F400207068460079032802D00020C0430EE0D2 +:1066040000980078C62803D100984078002802D06A +:106614000020C04303E0642000F05AF9002004B0D5 +:1066240010BC08BC184711B583B00C00042203A9A0 +:10663400C720FFF760FE002802D00020C04322E0FC +:10664400134A01A96846FFF7B1FE002802D00020D2 +:10665400C04318E000984078207068460079032809 +:1066640002D00020C0430EE000980078C72803D170 +:1066740000984078002802D00020C04303E004487A +:1066840000F026F9002004B010BC08BC1847000034 +:106694008813000031B582B00D001400042202A951 +:1066A400894801F0F7FF88480571052286498D2045 +:1066B400FFF721FE002802D00020C0431FE0834AD8 +:1066C40001A96846FFF772FE002802D00020C043EB +:1066D40015E000984078207068460079032802D0BD +:1066E4000020C0430BE0009800788D2803D1009867 +:1066F4004078002802D00020C04300E000203EBCC7 +:1067040008BC1847FBB582B017000A9E0B9D0C9C71 +:10671400042202A96C4801F0BDFF052203996A48CE +:10672400001D01F0B7FF052239006748093001F068 +:10673400B1FF65486946097C8173042231006248CF +:106744000F3001F0A7FF282200215F48133003F027 +:1067540029FC29005C48133002F0B2F83B225A4964 +:106764008020FFF7C8FD002802D00020C0431FE0AE +:10677400564A01A96846FFF719FE002802D00020F6 +:10678400C04315E0009840782070684600790328DB +:1067940002D00020C0430BE000980078802803D189 +:1067A40000984078002802D00020C04300E0002078 +:1067B40005B0F0BC08BC1847F1B582B00E00150056 +:1067C4001F00089C042202A93F4801F063FF052230 +:1067D40031003D48001D01F05DFF112200213A48BF +:1067E400093003F0DFFB0422290037481A3001F096 +:1067F40051FF2822002134481E3003F0D3FB390016 +:106804003148463002F05CF846222F498520FFF7D4 +:1068140072FD002802D00020C0431FE02B4A01A9CA +:106824006846FFF7C3FD002802D00020C04315E0EE +:1068340000984078207068460079082802D000202B +:10684400C0430BE000980078852803D10098407875 +:10685400002802D00020C04300E00020FEBC08BC99 +:10686400184711B583B00C0000202070042203A93E +:10687400B020FFF740FD002802D00020C0431FE0F5 +:10688400124A01A96846FFF791FD002802D00020B2 +:10689400C04315E0009840782070684600790328CA +:1068A40002D00020C0430BE000980078B02803D148 +:1068B40000984078002802D00020C04300E0002067 +:1068C40004B010BC08BC18474C4C004088130000AE +:1068D40070B5040000262348007801282FD2240430 +:1068E400240C012C2BD301F097FD06001E480068F0 +:1068F4003030007805002D062D0E1C48405D1A49E5 +:1069040009683131097888432D062D0E17494855F9 +:106914002D062D0E1548405D002808D11448007836 +:1069240011490968323109788843114908700E48C1 +:10693400006844853000FAF7CDFE05F0F5FD70BC23 +:1069440008BC184738B5002501F066FD0500094864 +:10695400006804002800FAF7BDFE200032BC08BC21 +:106964001847000033560040C0550040B855004059 +:1069740037560040D855004000B5664909880122C1 +:1069840082400A4363490A800006000E00280ED0A4 +:1069940002281BD012D3042827D01FD3062832D0B4 +:1069A4002AD308283ED035D3092843D049E05A4990 +:1069B400096804220A4358490A6042E057490968B1 +:1069C400802292000A4355490A603AE05349096813 +:1069D400802252000A4351490A6032E04F49096853 +:1069E40080220A434D490A602BE04C490968402241 +:1069F4000A434A490A6024E04849096820220A43B4 +:106A040046490A601DE04549096810220A43434982 +:106A14000A6016E042490968802252050A43404947 +:106A24000A600EE03F490968802212050A433D4985 +:106A34000A6006E03B490968802252050A43394945 +:106A44000A6008BC184700B532490988012282400F +:106A54009143304A11800006000E00280ED002280F +:106A64001BD012D3042827D01FD3062832D02AD310 +:106A740008283ED035D3092843D049E02A4909687B +:106A840004220A4328490A6042E02849096880220E +:106A940092000A4325490A603AE0244909688022A1 +:106AA40052000A4321490A6032E0204909688022E1 +:106AB4000A431E490A602BE01C49096840220A4324 +:106AC4001A490A6024E01949096820220A4317492F +:106AD4000A601DE01549096810220A4313490A6037 +:106AE40016E013490968802252050A4310490A60D6 +:106AF4000EE0B1490968802212050A43AE490A60D2 +:106B040006E0AD490968802252050A43AA490A6091 +:106B140008BC1847FC55004058C0FF3F18C0FF3F51 +:106B240098C0FF3F38C0FF3F5CC0FF3F1CC0FF3F21 +:106B34009CC0FF3F10B5002401F06EFC04009F4888 +:106B44000068302188439D4908609D4800683021D1 +:106B540088439B4908609B48006804210143994885 +:106B64000160994800680421884397490860974860 +:106B740000680421014395480160954800689549DF +:106B8400014093480160944800689249014092484A +:106B94000160924800688021890001438F480160A8 +:106BA4008F4800688F4901408D4801608E48006815 +:106BB4008021890001438C480160854800688B4925 +:106BC4000140834801608448006888490140824844 +:106BD4000160824800688021490001437F480160C8 +:106BE4007F480068824901407D4801607E48006812 +:106BF4008021490001437C480160754800687D4953 +:106C0400014073480160744800687A490140724841 +:106C14000160724800688021014370480160704837 +:106C24000068802188436E4908606F4800688021AD +:106C340001436D480160664800686F49014064483B +:106C44000160654800686C4901406348016063481D +:106C540000684021014361480160614800684021A7 +:106C640088435F49086060480068402101435E48EA +:106C74000160574800686149014055480160564821 +:106C840000685E490140544801605448006820216E +:106C9400014352480160524800682021884350490A +:106CA400086051480068202101434F48016048486A +:106CB400006853490140464801604748006850490C +:106CC400014045480160454800681021014343489C +:106CD40001604348006810218843414908604248E4 +:106CE4000068102101434048016046480068464955 +:106CF4000140444801604548006843490140434815 +:106D0400016043480068802149050143404801600F +:106D140040480068404901403E4801603F480068DF +:106D24008021490501433D4801603D4800683D49D3 +:106D340001403B4801603C4800683A4901403A48F8 +:106D440001603A4800688021090501433748016021 +:106D540037480068374901403548016016480068E3 +:106D6400802109050143144801602D480068264923 +:106D740001402B4801602C480068234901402A48FF +:106D840001602A48006880214905014327480160C1 +:106D940027480068204901402548016006480068EA +:106DA400802149050143044801602000FAF792FC60 +:106DB40010BC08BC184700003CC0FF3F10C002E0F4 +:106DC40050C002E040C0FF3F50C0FF3F5CC0FF3FE7 +:106DD40000C002E0FFFFF3FF40C002E000C0FF3F3D +:106DE40010C0FF3FFFFDFFFF1CC0FF3FFFFFFCFF84 +:106DF400FFFEFFFFFF3FFFFFFFCFFFFFFFF3FFFF9C +:106E0400FFFCFFFF24C002E0FFFFFFFC64C002E0C0 +:106E140080C0FF3F90C0FF3FFFFFFFEF9CC0FF3FDC +:106E24000CC002E0FFFF3FFF4CC002E020C0FF3F68 +:106E340030C0FF3FFFFFFFF780B56A460121794864 +:106E4400006802F012FD68460078002803D0012093 +:106E5400FFF73EFDF1E709BC184780B571480068AB +:106E640002F070FD09BC184710B504002078002812 +:106E74000CD005F0CEFC002803D10120FFF728FD3B +:106E8400F7E7207805F0D8FC641CEFE710BC08BCD9 +:106E94001847F2B504000025FF2D21DC009E05F003 +:106EA400A5FC00280AD1002E03D100202070002068 +:106EB40019E00120FFF70CFD761EF0E705F06EFCEB +:106EC4000100002903D50020207000200BE00800F9 +:106ED40007002770641C6D1C3F063F0E0A2FDBD190 +:106EE400002020700120F2BC08BC184738B50025EA +:106EF40001F092FA05007C48002101707B480021D2 +:106F040001602800FAF7E6FB00230022694678486E +:106F1400FAF7E8FB009800286DD0764800687649B7 +:106F24000140744801607548006873490140734822 +:106F3400016073480068802149040143704801607E +:106F440070480068704901406E4801606F480068ED +:106F54008021490401436D480160FA208000FFF755 +:106F6400B7FC6B480068802149040143684801600C +:106F74006848FFF7ADFCE120400205F027FD2948F1 +:106F84000068002804D1012002F046FC254908606D +:106F9400FFF752FF60496148FFF752F9FA2189006F +:106FA4005E4800F0CDF80400002C02D0FFF755FF36 +:106FB40023E05B495948FFF743F9FA218900574810 +:106FC40000F0BEF80400002C02D0FFF746FF14E0E6 +:106FD400FFF743FF01F020FA050044480121016056 +:106FE4002800FAF777FBFA208000FFF771FC00F025 +:106FF4003DF9040001E0002004004A48006800282C +:107004000BD10821484800F0F5FC464908601C23D0 +:10701400464A0021464800F033FE200032BC08BC3A +:107024001847000088550040F8B506000F00FFF728 +:1070340003FF05F091FB3A003E493848FFF700F999 +:107044003648FFF711FF3C493448FFF722FF002878 +:1070540004D1FFF702FF0020C04341E036492F4826 +:10706400FFF717FF002804D1FFF7F7FE0020C04305 +:1070740036E0002004002406240EA02C2DD227483C +:10708400002101702C492548FFF703FF002804D193 +:10709400FFF7E3FE0020C04322E028491F4805F023 +:1070A40073FD002819D01D4801F05CF9002814D0A4 +:1070B4001A480500194801F055F9002804D1FFF7D2 +:1070C400CCFE0020C0430BE028780028D3D02878D9 +:1070D40030706D1C761C641CF6E7FFF7BEFE0020C2 +:1070E400F2BC08BC18470000E83F00408C55004043 +:1070F400B408010004C002E0FFFFFCFF44C002E04A +:1071040000C0FF3F10C0FF3FFFFFFFFE1CC0FF3F5A +:1071140018C0FF3F60EA0000885F01002C42004075 +:10712400F85B010090550040545400405C16004048 +:1071340079260000504D010088130000905F010083 +:1071440070B504000E0005F007FB2000FFF78CFE6D +:10715400052005002800451E00281AD03100200013 +:10716400FFF797FE002811D03E49200005F00CFDE2 +:10717400002801D100200EE03B49200005F004FD69 +:10718400002802D10120C04305E0E3E70020C0430A +:1071940001E00220C04370BC08BC1847F8B50400E5 +:1071A4000E00170005F0D8FA00200500B5420CDAED +:1071B40005F02FFB002803D10120FFF789FBF7E737 +:1071C400605D05F039FB6D1CF0E705200500280023 +:1071D400451E00281AD039002000FFF75AFE002867 +:1071E40011D02049200005F0CFFC002801D1002057 +:1071F4000EE01D49200005F0C7FC002802D1012043 +:10720400C04305E0E3E70020C04301E00220C0439F +:10721400F2BC08BC1847000070B504000E0005F06D +:107224009BFA2000FFF720FE052005002800451EDC +:107234000006000E002810D031002000FFF729FEC0 +:10724400002807D091A1200005F09EFC0028EDD075 +:10725400002004E00020C04301E00220C04370BCD1 +:1072640008BC1847905F0100985F0100FEB5002735 +:10727400002000908648019001F0CEF80090C748A5 +:10728400002101700098FAF725FA0120060036065D +:10729400360E182E00D386E03606360E31000198DD +:1072A400FFF7C2FE00287CD1002004002406240E2F +:1072B4000B2C73D22406240E082060437549085809 +:1072C40001F050F805006846002101722800451EAF +:1072D40000280DD02406240E082060436D49085868 +:1072E400405D0199495D8842F0D0684601210172F0 +:1072F4006846007A00284FD12406240E08206043F3 +:107304006449085801F02EF8019909182406240E3E +:10731400082060435F4A1018406801F0D1FA002049 +:107324000500402D33DA2406240E08206043594911 +:1073340008184068405D002829D02406240E08203F +:107344006043544908184068405D0D2809D124065B +:10735400240E082060434F49081840680021415515 +:1073640015E02406240E082060434A4908184068A2 +:10737400405D0A2809D12406240E082060434549AB +:10738400081840680021415501E06D1CC9E7380028 +:107394000127A740074301E0641C87E7C820FFF7E3 +:1073A40097FA761C73E701200600002004002406E7 +:1073B400240E0B2C09D20120A0403840002802D111 +:1073C4000020060001E0641CF1E701F025F80090BC +:1073D400724806700098FAF77DF90020FEBC08BCDC +:1073E400184710B5002401F017F804006B48002179 +:1073F40001706B48002101602000FAF76BF910BCA2 +:1074040008BC184738B50024002501F005F804002D +:1074140062480078002805D061480068002801D03F +:10742400012005002000FAF755F928000006000E97 +:1074340032BC08BC184738B50024002500F0ECFF26 +:10744400040057480068002801D0012005002000EE +:10745400FAF740F928000006000E32BC08BC1847B1 +:1074640038B50024002500F0D7FF04009C480078BC +:10747400002801D0012005002000FAF72BF928008C +:107484000006000E32BC08BC184700000D0A0000BC +:107494004C4D0040B004010010B500243F48007872 +:1074A400002802D10020C04375E0FFF7C5FC8D49D8 +:1074B4008D48FEF7C5FE8D498B48FFF741FE002835 +:1074C40015D08B498848FEF7BBFE8A498648FFF7EA +:1074D40037FEFA204000FFF7FBF920000400641C8B +:1074E4000028E4D0FFF7B9FC0420C04353E08249EC +:1074F4007D48FEF7A5FE7D497B48FFF721FE002865 +:1075040004D0FFF7AAFC0520C04344E07B4A403284 +:107514007B497548FEF794FE74497348FFF710FEE3 +:10752400002804D0FFF799FC0620C04333E0734AD7 +:10753400803274496C48FEF783FE6C496A48FFF751 +:10754400FFFD002804D0FFF788FC0720C04322E099 +:107554006D4A6E496448FEF773FE64496248FFF75A +:10756400EFFD002804D0FFF778FC0820C04312E0A8 +:10757400674A68495C48FEF763FE5C495A48FFF76E +:10758400DFFD002804D0FFF768FC0920C04302E0B7 +:10759400FFF763FC002010BC08BC1847E83F00401C +:1075A4008C55004010B500244D480078002802D1C5 +:1075B4000020C04390E0FFF73FFC57494A48FEF7DC +:1075C4003FFE4A494848FFF7BBFD002814D048490C +:1075D4004548FEF735FE47494348FFF7B1FD4F489C +:1075E400FFF776F920000400641C0028E5D0FFF7BB +:1075F40034FC1820C0436FE049493B48FEF720FEA5 +:107604003A493948FFF79CFD002804D0FFF725FCD0 +:107614001920C04360E043493348FEF711FE334963 +:107624003148FFF78DFD002804D0FFF716FC1A201F +:10763400C04351E03C4A3D492B48FEF701FE2B492B +:107644002948FFF77DFD002804D0FFF706FC1B2026 +:10765400C04341E0364A37492348FEF7F1FD234948 +:107664002148FFF76DFD002804D0FFF7F6FB1C202E +:10767400C04331E0304A31491B48FEF7E1FD1B4964 +:107684001948FFF75DFD002804D0FFF7E6FB1D2035 +:10769400C04321E02A491448FEF7D2FD1349124899 +:1076A400FFF74EFD002804D0FFF7D7FB1E20C04390 +:1076B40012E0244A24490C48FEF7C2FD0B490A484B +:1076C400FFF73EFD002804D0FFF7C7FB1F20C0438F +:1076D40002E0FFF7C2FB002010BC08BC1847000002 +:1076E400E83F0040D41A01002C42004088130000F7 +:1076F400045C010030750000F01A0100283D0040D0 +:107704006C1F0100841F0100683E00409C1F0100A3 +:10771400283E0040B41F01000C1B0100102700008C +:10772400281B0100CC1F0100683F0040441B0100DE +:10773400A83E0040E41F0100E83E0040FC1F010099 +:1077440014200100A83F0040601B0100F3B585B080 +:107754000026F64395480078002802D13120C04322 +:1077640020E1FFF799FE0600002E01D0300019E158 +:10777400FFF718FF0600002E01D0300012E1FFF7DA +:107784005BFB8B4A8B498C48FEF75AFD8B498A4830 +:10779400FFF7D6FC002804D0FFF75FFB3220C0437C +:1077A40000E1874A87498448FEF74AFD83498248B5 +:1077B400FFF7C6FC002804D0FFF74FFB3320C0437B +:1077C400F0E0059A80497C48FEF73AFD7B497A4807 +:1077D400FFF7B6FC002804D0FFF73FFB3420C0437A +:1077E400E0E07A497448FEF72BFD79497248FFF7C7 +:1077F400A7FC002804D0FFF730FB3520C043D1E0BC +:107804006E48FFF765F873496B48FEF719FD704938 +:107814006948FFF795FC002804D0FFF71EFB3620CB +:10782400C043BFE06A496448FFF733FB002804D132 +:10783400FFF713FB3720C043B4E065495E48FFF708 +:1078440028FB002804D1FFF708FB3820C043A9E037 +:107854006149594805F098F9002802D03920C043FD +:10786400A0E05E480700FA208000FFF731F83800F6 +:10787400069905F0C5F9002848D1380000F072FDDA +:1078840005000024AC42F2DA2A1B55494A48FEF7A7 +:10789400D7FC4F494848FFF7BFFC002803D03A20E3 +:1078A400C043060070E002A8009001AB03AA4D4952 +:1078B400414801F06FFD039802990143002906D164 +:1078C400281B0199884202DB0198002803D13B2040 +:1078D400C043060058E03E4A01993800FFF75EFCB9 +:1078E400002803D03C20C04306004DE0384932480C +:1078F400FFF7CFFA002803D13D20C043060043E040 +:10790400019824183220FEF7E3FFBBE736492A48E2 +:10791400FEF796FC2E492848FFF712FC002803D0F6 +:107924003E20C04306002FE029492348FFF7B1FA5F +:10793400002803D13F20C043060025E024491E4807 +:10794400FFF7A7FA002803D14020C04306001BE03C +:107954002649194805F018F9002803D04120C043EE +:10796400060011E019491448FEF76AFC1849124848 +:10797400FFF7E6FB002803D04220C043060003E0E3 +:10798400FFF76BFA00200DE010490B48FEF758FC96 +:107994001748FEF79DFF0E490748FFF7D1FBFFF795 +:1079A4005CFA300007B0F0BC08BC1847E83F004060 +:1079B400283F00402C2001002C4200408813000086 +:1079C400283D0040442001005C200100045C0100CB +:1079D40030750000105C0100604D01004C4D00400A +:1079E400704D0100EC380100804D0100904D010004 +:1079F40010270000F2B5070000266C480078012823 +:107A040001D3002045E000F007FD06006848006847 +:107A1400040067480068002804D06548006840688E +:107A2400634908603000F9F755FE002C30D000F0AF +:107A3400F3FC06005F4800680500002D1ED05D4879 +:107A44005C490968096801603000F9F743FE6F601A +:107A540068460088042148433818A860EF602F6105 +:107A640068460088A8820020E88202202070002056 +:107A740020816560200004F099FC09E04C4800680E +:107A840060604B4804603000F9F724FE00200400D5 +:107A94002000F2BC08BC1847F3B581B014000026DE +:107AA40042480078012803D302202070002079E0A6 +:107AB40041480078012803D30D202070002071E094 +:107AC40000F0AAFC0600019840680500E88A012835 +:107AD40015D328690100091D296100680700E88A97 +:107AE400401EE8822869A968884201D16868286133 +:107AF4003000F9F7EFFD00202070380052E02F48E5 +:107B040000682C300078042101432C4800682C3094 +:107B140001702A4800682D30002101702748006850 +:107B2400694609894185019804F0CAFB3000F9F7D8 +:107B3400D1FD04F0F9FC00F06FFC06001F4800685A +:107B44002D300078002816D068461C4909682D316C +:107B540009780170019804F0F5FB3000F9F7BAFDDB +:107B640068460078022802D00A20207001E00E2026 +:107B74002070002016E011480068006A07000F48D2 +:107B84000068002101620D4800682C30002101705A +:107B94000A4800680021C1613000F9F79BFD00200C +:107BA40020703800FEBC08BC184700003356004063 +:107BB400B0550040D455004034560040C0550040F4 +:107BC400F2B5070000253878022801D0012031E001 +:107BD40000F022FC0500B87A00280DD0002304220E +:107BE4000099380004F00DFB06002800F9F772FD37 +:107BF40004F09AFC00201DE078680400E08AA18A61 +:107C0400884204D32800F9F765FD1E2012E0E068DD +:107C14000100091DE16000990160E08A401CE082D6 +:107C2400E068A168884201D16068E0602800F9F743 +:107C340051FD0020F2BC08BC184770B560210E4805 +:107C440004F066FC0C4805000B48183006000020C0 +:107C540004002404240C032C04D22E601835183696 +:107C6400641CF6E70020286004480349016070BCE6 +:107C740008BC18470000000030510040D4550040B3 +:107C8400F3B585B017001D00002400F0C5FB040007 +:107C94005F480078012804D32000F9F71BFD3C203D +:107CA40047E02D062D0E0420684358490858002843 +:107CB4003BD12D062D0E04206843544901220A505D +:107CC4002000F9F707FD00233A000699059804F00F +:107CD400A1FF03900020029000200190002000905A +:107CE40000230022039928000006000E04F08EFCF5 +:107CF40006003606360E002E06D1A7480078012865 +:107D04000FD104F011FC0CE000F086FB04002D06FA +:107D14002D0E042068433D4900220A502000F9F743 +:107D2400D9FC30000006000E03E02000F9F7D2FC75 +:107D3400282007B0F0BC08BC1847F7B584B01E0073 +:107D4400109D002400F068FB0400314800780128ED +:107D540004D32000F9F7BEFC3C2052E03606360E70 +:107D64000420704329490858002846D13606360EA7 +:107D740004207043254901220A502000F9F7AAFC87 +:107D84002A001204120C0E990D9800F019F92B0018 +:107D94001B041B0C069A0599049804F03BFF0390FE +:107DA4002D042D0C02950F9801900E9800906846B2 +:107DB400038E0D9A039930000006000E04F026FC91 +:107DC40007003F063F0E002F06D1734800780128B4 +:107DD4000FD104F0A9FB0CE000F01EFB04003606F2 +:107DE400360E04207043094900220A502000F9F796 +:107DF40071FC38000006000E03E02000F9F76AFC6D +:107E0400282007B0F0BC08BC18470000EC4E004026 +:107E140033560040F1B582B000266048007801284E +:107E240001D34020B4E06846007A1F2801D13E20E7 +:107E3400AEE000F0F1FA06006846007AFF2805D1AA +:107E44006846574909682E31097801726846007AF4 +:107E540004214843534908580400002C04D130003D +:107E6400F9F738FC432093E0012C04D13000F9F7F2 +:107E740031FC3D208CE03020205C05002D062D0EC9 +:107E84004948405D3121615C88432D062D0E4649E9 +:107E940048552D062D0E4448405D002806D1434820 +:107EA40000783221615C884340490870E06907002A +:107EB400002F15D02D062D0E7819C07A3121615C62 +:107EC40088432D062D0E7919C8722D062D0E7819AA +:107ED400C07A002804D1B87A3221615C8843B87230 +:107EE400606A00900098002802D0009804F024FFF3 +:107EF400002060852C20002121542D2000212154B4 +:107F04002B480078FF2804D029480078401C2849D1 +:107F140008703000F9F7DEFB04F072F900F07CFA27 +:107F2400060023480078012804D321480078401E25 +:107F34001F490870200004F06BFE1E480078401EA4 +:107F44001C4908706846007A0421484315490022F8 +:107F54000A50A069002806D1606900218161606926 +:107F64001549086005E0A069616941616069A1691A +:107F74008161124800686061104804603000F9F7BC +:107F8400A9FB05480078012801D104F0CDFA0020AE +:107F9400FEBC08BC18470000385600403356004069 +:107FA400C0550040EC4E0040B855004037560040E4 +:107FB4003456004039560040CC550040C45500406A +:107FC40000B5D30708D5930706D5002904D0491E68 +:107FD40000230360001DF8E708BC18475748002138 +:107FE40001607047B54800210160704700B5B4488E +:107FF4000078002803D152480021016002E0B04813 +:108004000021017008BC18474D480068042148430A +:108014004C490860AA480121017070474748002173 +:10802400016070474548002101607047F1B582B096 +:108034000F003F063F0E002F05D0022F09D005D3B5 +:10804400032F09D00BE09F48060009E09E48060074 +:1080540006E09E48060003E0B048060000E02CE07D +:10806400029804002078202801D1641CFAE7142225 +:108074002021300001F096FF200000F073F9050084 +:10808400142D09DA0921009128000221FAF7B2FF20 +:108094000099081A002804D52100300000F010FCD3 +:1080A4000BE021000C0028000221FAF7A3FF414253 +:1080B40070180930210000F003FCF7BC08BC184715 +:1080C40080B50023002269469548F9F70BFB009818 +:1080D400002804D1FCF7EBFC9248FCF7A2FC924880 +:1080E4000021017009BC184780B51420FEF7F0FB8D +:1080F4008D480121017009BC184730B583B08B4805 +:1081040000210160002500200400FF2C0CD8210070 +:108114006846FBF7D7FD0098A84203D300980500F2 +:1081240082480460641CF0E7002D03D18048FCF70A +:10813400A8FCFFE737BC08BC1847000060550040A6 +:108144003C5500404055004010B50400207A0028FA +:1081540000D1A7E0217A7748FBF73EFE207A012878 +:1081640002D0207A022813D1724800F0FBF8627A18 +:10817400521C71496F4B1818FEF762F82000001D5D +:1081840001F0FEFE02006D496D48FEF759F891E0DA +:10819400207A032812D1674800F0E4F8627A521C6E +:1081A4006549644B1818FEF74BF82000001D01F0D8 +:1081B400E7FE01006248FAF7C1FD7BE0207A04285B +:1081C4000ED15C4800F0CEF8627A521C5A49594BE1 +:1081D4001818FEF735F85BA15948FEF731F869E045 +:1081E400207A062804D157A15548FEF729F861E002 +:1081F400207A072806D1627A521C53495048FEF768 +:108204001FF857E0207A082804D14EA14C48FEF705 +:1082140017F84FE0207A092804D14AA14848FEF70C +:108224000FF847E0207A0A2804D146A14448FEF713 +:1082340007F83FE0207A0B280FD12000001D01F041 +:108244009FFE002804D141493D48FDF7F9FF31E084 +:108254003F493B48FDF7F4FF2CE0207A0C2809D174 +:108264002000001D01F08CFE02003A493448FDF75D +:10827400E7FF1FE0207A0D2809D12000001D01F03E +:108284007FFE020034A12E48FDF7DAFF12E0207AC7 +:108294000E2802D0207A0F280CD12AA12848FDF7F5 +:1082A400CFFF07E02D492348FDF7CAFF2B49244897 +:1082B400FDF7C6FF10BC08BC184700006855004015 +:1082C40031560040745400408C540040A454004083 +:1082D4003EB523480021016000250024FF2C0CD862 +:1082E40021006846FBF704FD0098A84203D30098D8 +:1082F40005001B480460641CF0E7002D03D10C4802 +:10830400FCF7BFFB07E0164801686846FBF7F0FC82 +:108314006846FFF719FF37BC08BC1847BC54004037 +:10832400340A01006C5A0100305600405055004098 +:10833400BC520100D4540040285F0100305F0100AA +:10834400EC54004000000000FC510100385F0100C3 +:1083540008520100405F010025750000485F0100DC +:10836400545500407847C046013080E2001FB0E118 +:108374000300000A0110D0E4000051E3FAFFFF1AE1 +:108384000A0000EA002090E528C09FE50C1052E0A6 +:108394000210D1E18C0311E10420B005FAFFFF0AB9 +:1083A4000110D0E4000051E30110D014FCFFFF1AC7 +:1083B400030050E01EFF2FE10101010170B502002E +:1083C400FF24FF200D00691E2D062D0E002D16D052 +:1083D400157865402B00521C1B061B0E02255D43BD +:1083E4000C4E755B2D042D0C2D0A45402C001B06EC +:1083F4001B0E02255D43074E755B2800E2E7240649 +:10840400240E24020006000E20430004000C70BC5D +:1084140008BC1847B8F900007847C04600000FE1CF +:10842400C01080E301F021E11EFF2FE100F021E103 +:108434001EFF2FE1D3F021E348029FE50FE0A0E106 +:1084440010FF2FE124029FE50110A0E30010C0E516 +:1084540028029FE5000090E500D090E504009DE42B +:1084640000F06FE1FFDFFDE800402DE900402DE959 +:10847400FF1F2DE900000FE101001EE3200080131F +:1084840001002DE9F0019FE5001090E500D081E5A1 +:10849400F0019FE50FE0A0E110FF2FE1D0019FE57F +:1084A400D0119FE50020D1E50020C0E5C8019FE57B +:1084B400C8119FE5002091E5002080E500D092E5F9 +:1084C4000100BDE800F06FE1FFDFFDE8B4019FE5C6 +:1084D4000FE0A0E110FF2FE194019FE594119FE5C7 +:1084E4000020D1E50020C0E58C019FE58C119FE5BB +:1084F400002091E5002080E500D092E50100BDE870 +:1085040000F06FE1FFDFFDE8FF5F2DE90E30A0E131 +:108514000000A0E3200000EAFF5F2DE90E30A0E197 +:108524000100A0E31C0000EAFF5F2DE90E30A0E18A +:108534000200A0E3180000EA04E04EE2FF5F2DE928 +:108544000E30A0E10300A0E3130000EA08E04EE2CD +:10855400FF5F2DE90E30A0E10400A0E30E0000EA65 +:1085640008E04EE2FF5F2DE90E30A0E10500A0E334 +:10857400090000EA04E04EE2FF5F2DE90E30A0E1BD +:108584000600A0E3040000EA04E04EE2FF5F2DE9E8 +:108594000E30A0E10700A0E3FFFFFFEA00104FE167 +:1085A4001F2001E2130052E31F00001A00200FE114 +:1085B4000D40A0E1D3F021E308002DE900402DE9AE +:1085C400E01F2DE9E003B4E8E0032DE902002DE902 +:1085D40098109FE50010D1E5010051E30600001A50 +:1085E4009C309FE50040D3E5014084E20040C3E5B0 +:1085F40084309FE5004093E500D084E502F02FE14C +:1086040088109FE50FE0A0E111FF2FE138D08DE243 +:10861400D3F021E370009FE50FE0A0E110FF2FE10C +:108624000100BDE800F06FE1FFDFFDE800200FE18D +:10863400D3F021E348309FE50040D3E5014084E2D4 +:108644000040C3E502F02FE140309FE50FE0A0E1D8 +:1086540013FF2FE1D3F021E324309FE50040D3E55D +:10866400014044E20040C3E502F02FE1FF9FFDE832 +:10867400385600403556004036560040C05500403C +:10868400C85500403356004093CC00004FC0000052 +:10869400178B000070B504000D001600320029008D +:1086A400200002F031FB200070BC08BC184710B554 +:1086B4000400002004F036FC0621002004F056FBE0 +:1086C400002004F03FFC10BC08BC184710B504009F +:1086D400002004F027FC0421002004F047FB0020C4 +:1086E40004F030FC10BC08BC1847F8B504000E00B8 +:1086F400170004F037FC20000004000CFFF7D7FF3C +:10870400002004F00FFC0221002004F02FFB2100C4 +:108714000904090C090A0906090E002004F026FBC5 +:1087240021000906090E002004F020FB00200500AA +:108734002D042D0C3604360CB54207D22D042D0C15 +:10874400795D002004F012FB6D1CF1E7002004F0B9 +:10875400F9FB20000004000CFFF7B8FF04F016FC3E +:10876400F1BC08BC1847F8B504000E00170004F06B +:10877400F9FB20000004000CFFF799FF002004F02F +:10878400D1FB0221002004F0F1FA21000904090CB4 +:10879400090A0906090E002004F0E8FA2100090676 +:1087A400090E002004F0E2FA002005002D042D0C2F +:1087B4003604360CB54207D239000906090E0020EA +:1087C40004F0D4FA6D1CF1E7002004F0BBFB200098 +:1087D4000004000CFFF77AFF04F0D8FBF1BC08BCDE +:1087E4001847F8B504000E00170004F0BBFB200086 +:1087F4000004000CFFF76AFF002004F093FB032140 +:10880400002004F0B3FA21000904090C090A09063E +:10881400090E002004F0AAFA21000906090E00201E +:1088240004F0A4FA002005002D042D0C3604360CA7 +:10883400B54208D2FF21002004F098FA2D042D0C33 +:1088440078556D1CF0E7002004F07CFB04F09EFBDF +:10885400F1BC08BC184710B40168001D00290FD0F2 +:108864000268436882180830DC0702D54C46641E4F +:108874001B191468121D1C601B1D091FF9D1EBE79D +:1088840010BC70477847C04640C7A0E380007CE135 +:1088940081007C911EFF2F8101C080E18CC0B0E17A +:1088A4000100002A010050E11EFF2FE100005111D8 +:1088B4001EFF2FE100470268531C036011707047CC +:1088C4007847C04601402DE9013020E0030013E35E +:1088D4000E00001A030010E30400000A0130D1E482 +:1088E4000130C0E4000033E3F9FFFF1A0C0000EA92 +:1088F40034C09FE5002091E50C3052E00230D3E112 +:108904008C0313E1042080040420B105F9FFFF0A5D +:108914000130D1E40130C0E4000033E30130D1146C +:10892400FBFFFF1A0140BDE81EFF2FE10101010119 +:108934007847C0460010A0E1810EA0E140C7A0E343 +:1089440081007CE10200003A701881030010E013FA +:108954001EFF2FE181005CE10A00009A81C0B0E1B2 +:108964001EFF2F01801401E2E01581E28CC3A0E117 +:108974008CC0B0E1401941E2FCFFFF5A8C0AA0E12F +:10898400AC1581E01EFF2FE1C111A0E17014C1E319 +:10899400E01581E21EFF2FE102001378002B03D0C3 +:1089A400521C1378002BFBD10B781370002B02D0D0 +:1089B400521C491CF8E7704708B4024B9C4608BC9B +:1089C4006047C0460C30000008B4024B9C4608BC0B +:1089D4006047C0463CD0000080B500F067F900F065 +:1089E4000BFA00F049FA00F0DBFA00F017F909BCC1 +:1089F4001847FEB5854800688007800F002803D01B +:108A0400022807D003D309E08148040008E0814824 +:108A1400040005E080200002040001E07C4804001A +:108A24007D480068800118D57B4800688004800C6C +:108A3400401C029078480068000C0007000F401C9E +:108A440001900299009120000199FFF7B5FF009968 +:108A54004143022041430D0000E025008C4800689A +:108A64000006000E401C060028003100FFF7A4FF9A +:108A740007003800FEBC08BC184770B50600FFF7B5 +:108A8400B8FF04003606360E300000280F2808D937 +:108A9400103803281ED9401F06281BD9083819D0BE +:108AA40033E07C48006802217143C8408007800F8E +:108AB4000500002D02D12000800827E0012D01D1FE +:108AC400200023E0022D02D1200040081EE02000F7 +:108AD400C0081BE0C048006831001039022251432D +:108AE400C8408007800F0500002D02D120008008B7 +:108AF4000CE0012D01D1200008E0022D02D120005C +:108B0400400803E02000C00800E0002070BC08BC5E +:108B14001847F1B582B00298062802D002980728B7 +:108B24000ED1FF20C043006801900198002806D0B0 +:108B34000198FFF7BFFEFF20C043012101605DE003 +:108B440055480068006804000299544804F050FA3B +:108B540000906168524804F04BFA0090A1685148B3 +:108B640004F046FA0090E1684F4804F041FA00909E +:108B740021699A4804F03CFA00906169984804F02D +:108B840037FA0090A169974804F032FA0090E1693D +:108B9400954804F02DFA0090216A944804F028FACC +:108BA4000090616A924804F023FA0090A16A914807 +:108BB40004F01EFA0090E16A9F4804F019FA00904C +:108BC400216B9E4804F014FA0090616B9C4804F0F9 +:108BD4000FFA009021009B4804F00AFA0700A16BE9 +:108BE400994804F005FA0600E16B984804F000FA8D +:108BF40005002168964804F0FBF9FEE7F7BC08BCC1 +:108C04001847C0480021C943016070470CC11FE0E8 +:108C140000093D00001BB70088C01FE038B58D482F +:108C24000068102188438B4908608B488B49016098 +:108C34008B48102101600120FFF71FFF0500280069 +:108C4400FA218900FFF7B8FE0400AF480221016051 +:108C5400AD4800210160834800210160601E824903 +:108C64000860824803210160814800210160814835 +:108C740000210160A4480121016031BC08BC1847EF +:108C840080B5A248FF21016003F038FA09BC1847F7 +:108C940004C11FE0A8C11FE0C0550040C816010070 +:108CA400003A0100103A0100203A0100F8B500240E +:108CB4000B2000900020070003200500052006007B +:108CC40093480068800111D504F0A4F90400914888 +:108CD4000068022188438F4908608F48AA210160F7 +:108CE4008D48552101602000FFF76EFE04F092F9D3 +:108CF4000400884800680121884386490860864842 +:108D0400AA2101608448552101602000FFF75CFE20 +:108D14008248006810218843804908607F480068C1 +:108D2400202101437D4801607C4800680121014302 +:108D34007A480160794800684006FBD578480121EB +:108D4400016004F067F90400009839040143754890 +:108D540001607148AA2101606F485521016020001B +:108D6400FFF732FE04F056F904006A480068012156 +:108D74000143684801606848AA210160664855219A +:108D840001602000FFF720FE674805606748066021 +:108D94005F4800684001FBD56548664901600E489C +:108DA4006549016004F036F904005A48006802215C +:108DB4000143584801605848AA210160564855218A +:108DC40001602000FFF700FE514800688001FBD5D8 +:108DD400F1BC08BC18470000ACC11FE0303A0100E8 +:108DE400403A0100503A0100603A0100703A010033 +:108DF400803A0100903A010010B5FFF7FAFD040033 +:108E0400D348002101604D48844202D24C480121DC +:108E140001604C48844202D2494802210160494819 +:108E2400844202D3464803210160C94802210160FB +:108E340010BC08BC18470000A03A0100B03A010079 +:108E4400C03A0100D03A0100E03A0100F03A0100D2 +:108E5400003B01000CF0FFFF10F1FFFF858C0000C8 +:108E640010F0FFFF104000E0184000E0144000E064 +:108E7400284000E03C4000E03348002101603348D2 +:108E84000021016032480021016032480021016064 +:108E9400314800210160314800210160304800213F +:108EA40001603048002101602F48002101602F48F3 +:108EB400002101602E48002101602E48002101603C +:108EC4002D48002101602D48002101602C4800211B +:108ED40001602C48002101602B48002101602B48CF +:108EE400002101602A48002101602A480021016014 +:108EF400294800210160294800210160CA48002155 +:108F04000160704714F0FFFF044000E0004000E0FF +:108F140088C01FE080C01FE08CC01FE0A0C11FE01C +:108F24000CC11FE084C01FE004C11FE008C11FE0A2 +:108F3400A8C11FE0AAAAAAAAAAA8AA22002D3101A0 +:108F440004C01FE0005A6202088002E0188002E0B8 +:108F540000C0FF3F20C0FF3F40C0FF3F60C0FF3F55 +:108F640080C0FF3F10C0FF3F30C0FF3F50C0FF3FF5 +:108F740070C0FF3F90C0FF3F00C002E004C002E0A9 +:108F840008C002E00CC002E010C002E014C002E01D +:108F940018C002E01CC002E020C002E024C002E0CD +:108FA40046480021C9430160FF20C04300210160FD +:108FB4004748002101604B484B4901604B485049E8 +:108FC400016050485449016054485549016059486A +:108FD4005949016059485F4901605F48634901602C +:108FE40063486449016068486849016068486D499C +:108FF40001606D48714901607148724901607648A9 +:109004007649016076487B4901607B487F4901606D +:109014007F488049016085488549016085488A49BF +:1090240001608A488E4901608E488F4901609348E7 +:109034009349016093489849016098489C490160AC +:109044009C489D490160A148A1490160A148A649E5 +:109054000160A648AA490160AA48AB490160AF482B +:10906400AF490160AF48B4490160B448B8490160F0 +:10907400B848B9490160704700B5FEE780B5BB4800 +:1090840000210160FFF7F8FF09BC184780B5B74815 +:1090940001210160FFF7F0FF09BC184780B5B34810 +:1090A40002210160FFF7E8FF09BC184780B5AF480B +:1090B40003210160FFF7E0FF09BC184714F0FFFF2C +:1090C40080B5AA4804210160FFF7D6FF09BC184700 +:1090D40020F0FFFF80B5A54805210160FFF7CCFF14 +:1090E40009BC184700F1FFFF8190000004F1FFFF65 +:1090F40080B59E4806210160FFF7BEFF09BC1847F2 +:109104009190000008F1FFFF80B5984807210160A5 +:10911400FFF7B2FF09BC1847A19000000CF1FFFF54 +:10912400B190000080B5914808210160FFF7A4FFC9 +:1091340009BC184710F1FFFFC590000014F1FFFFB0 +:1091440080B58A4809210160FFF796FF09BC1847DA +:1091540000C01FE0D990000018F1FFFF80B58348DC +:109164000A210160FFF788FF09BC1847F590000049 +:109174001CF1FFFF0D91000080B57C480B210160BC +:10918400FFF77AFF09BC184720F1FFFF299100007F +:1091940024F1FFFF80B575480C210160FFF76CFFD7 +:1091A40009BC18474591000028F1FFFF80B56F48BE +:1091B4000D210160FFF760FF09BC184761910000B1 +:1091C4002CF1FFFF7D91000080B568480E210160FD +:1091D400FFF752FF09BC184730F1FFFF99910000D7 +:1091E40034F1FFFF80B561480F210160FFF744FFB0 +:1091F40009BC1847B191000038F1FFFF80B55B4806 +:1092040010210160FFF738FF09BC1847CD91000019 +:109214003CF1FFFFE991000080B554481121016041 +:10922400FFF72AFF09BC184728C002E040F1FFFFFE +:109234000192000044F1FFFF80B54C481221016007 +:10924400FFF71AFF09BC18471D92000048F1FFFF01 +:1092540080B5464813210160FFF70EFF09BC18478B +:109264003D9200004CF1FFFF5592000080B53F484D +:1092740014210160FFF700FF09BC184750F1FFFFFC +:109284007192000054F1FFFF80B538481521016048 +:10929400FFF7F2FE09BC18478D92000058F1FFFF5A +:1092A40080B5324816210160FFF7E6FE09BC184775 +:1092B400A59200005CF1FFFFC192000080B52B482D +:1092C40017210160FFF7D8FE09BC184760F1FFFFC2 +:1092D400DD92000064F1FFFF80B52448182101608D +:1092E400FFF7CAFE09BC1847F592000068F1FFFFBA +:1092F40080B51E4819210160FFF7BEFE09BC18475E +:10930400119300006CF1FFFF2D93000080B5174806 +:109314001A210160FFF7B0FE09BC184770F1FFFF86 +:109324004593000074F1FFFF80B510481B210160D4 +:10933400FFF7A2FE09BC18476193000078F1FFFF14 +:1093440080B50A481C210160FFF796FE09BC184746 +:10935400759300007CF1FFFF8593000080B50348FE +:109364001D210160FFF788FE09BC184730550040F5 +:1093740080B507481E210160FFF77EFE09BC18472F +:1093840080B503481F210160FFF776FE09BC18472A +:10939400305500400DB400B582B004A800900A0016 +:1093A4006B4603A9034878440A3003F05FFE029930 +:1093B40006B008474D8400001EFF2FE100B50028C9 +:1093C40002D541420800FFE708BC184710B5002445 +:1093D400FFF722F8040000207A4908807A490880BF +:1093E4007A49088000207A4908807A4908807A49B5 +:1093F40008807A48006802218843784908607848E0 +:10940400062101602000F8F765F910BC08BC184774 +:1094140038B50025FFF700F805000024E4436E4842 +:109424000088012815D36C480088401E6A490880CA +:10943400684800886B49085C040066480088401C42 +:1094440064490880634800888021F9F7D3FD6148A6 +:1094540001802800F8F73EF9200032BC08BC184708 +:1094640070B505000026FEF7D7FF06000024574814 +:10947400008840283CD25548008800281FD15A480B +:109484000078800602D55948057034E04F480088BA +:10949400401C4E4908804B48008855490D544948A2 +:1094A4000088401C47490880464800884021F9F755 +:1094B400A1FD44480180A648032101601BE0434804 +:1094C4000088401C414908803E48008848490D54A2 +:1094D4003C480088401C3B4908803A4800884021A9 +:1094E400F9F788FD3748018099480321016002E0BB +:1094F4000020C04304003000F8F7ECF8200070BCF2 +:1095040008BC184738B53648006805002D062D0EEE +:109514006D086D076D0F2D062D0E022D24D13248D6 +:109524000078C0074BD52C480088802817D22848DB +:1095340000882C492D4A12780A5425480088401C7A +:1095440023490880224800888021F9F753FD2048E8 +:10955400018021480088401C1F4908802FE068468C +:109564002249097801702AE02D062D0E012D1FD104 +:1095740016480088012817D3134800881C49085C42 +:109584001A49087010480088401C0F4908800E488A +:1095940000884021F9F72EFD0B4801800B48008814 +:1095A400401E0A4908800AE00C480121016006E0D7 +:1095B40068460E49097801700B480078040031BCF4 +:1095C40008BC184708560040065600400A5600409A +:1095D4000E5600400C5600401056004004C000E0F7 +:1095E40008C000E06C4F004014C000E000C000E080 +:1095F40070520040F1B584B00026FEF70DFF06005E +:109604000320FFF73AFA0190019800F0D5F90022FF +:10961400504B00F0D9FA04000D00049800F0CCF986 +:1096240002000B002000290000F0CEFA04F09EFA9C +:1096340002900298FFF77CF902000B0000204649D3 +:1096440004F0ECFA04F08CFB070068463900417022 +:10965400684639000904090C090A01703F4800688A +:109664008021490401433D480160394800210160DB +:109674003B48062101603B48002101603A488021B3 +:1096840001703A4869464978017031486946097859 +:1096940001603748102101603348002101703248CD +:1096A400007803210143304801702F480078FB21E2 +:1096B40001402D4801702648012101602D480068B1 +:1096C40030218843102101432A4801602948006859 +:1096D400C021884340210143264801602648006890 +:1096E400302188432449086023480068C021884306 +:1096F4002149086021480068042101431F48016092 +:109704001E480068082188431C4908601C480068FA +:10971400042101431A4801601948006808210143E3 +:1097240017480160174800684021884315490860BC +:10973400154816490160164840210160FFF746FEAE +:109744003000F7F7C7FF05B0F0BC08BC18470000AD +:1097540004C000E0000030400000E03FC4C01FE04F +:1097640008C000E020C000E00CC000E000C000E041 +:1097740028C000E000C002E040C002E000C0FF3F9B +:1097840010C0FF3F0CF0FFFF18F1FFFF0995000028 +:1097940010F0FFFF10B5040020000006000EFFF7D4 +:1097A4005FFE002803D00120FDF792F8F4E710BC17 +:1097B40008BC1847F8B507000C0000250026F6433E +:1097C400002E0ED5FFF724FE0600002E09D5012039 +:1097D400FDF77EF8280005006D1C8442F0D20020BD +:1097E40002E0300038700120F2BC08BC184770B5A4 +:1097F40004000D0016002800451E002808D0310082 +:109804002000FFF7D7FF641C0028F4D1002000E0FB +:10981400012070BC08BC184770B5040000266148DC +:109824000078012801D300201CE0FEF7F5FD0600B6 +:109834005D48006805005C480068002804D05A4868 +:1098440000684068584908603000F7F743FF002D6E +:1098540007D0032028702C8100206860280002F0C3 +:10986400A5FD280070BC08BC1847F2B5050014001B +:1098740000262878032802D0012020705FE04948A0 +:109884000078012802D30220207058E0474800786D +:10989400012802D30D20207051E0FEF7BDFD060023 +:1098A4002889012808D32889401E28813000F7F729 +:1098B40011FF0020207042E03D4800682C30007801 +:1098C400012101433A4800682C300170384800688F +:1098D4002D300021017036480068694609884185A9 +:1098E400280002F0EDFC3000F7F7F4FE02F01CFE55 +:1098F400FEF792FD06002E4800682D3000780028FF +:1099040014D02B4800682D3000780700280002F09E +:1099140019FD3000F7F7DEFE3F063F0E022F02D09E +:109924000A20207001E00E20207008E02048006822 +:109934000021C1613000F7F7CDFE00202070F1BC9A +:1099440008BC184770B5040000252078032801D00E +:10995400012023E0FEF760FD0500A07A00280DD069 +:10996400002301220021200002F04BFC0600280005 +:10997400F7F7B0FE02F0D8FD00200FE020890D4972 +:10998400884207D02089401C20812800F7F7A2FED6 +:10999400002003E02800F7F79DFE322070BC08BCCD +:1099A4001847000033560040B0550040345600407C +:1099B400C0550040FFFF00007847C0460010B0E1EA +:1099C4004214A0130411001A1EFF2FE17847C04669 +:1099D400B0402DE9037021E0807407E2FF40A0E36A +:1099E400704E84E321CA14E0235A141004003C117D +:1099F400040035112500000A05C08CE0843AC3E157 +:109A0400403983E38115A0E1801481E3A05A81E108 +:109A140080E5A0E10210A0E19E0282E0000050E394 +:109A24000000A0E39521A0E00010A0E3932EA1E0A4 +:109A340001208213010090E00010A0E30110A1E0D6 +:109A44009305A1E040CE4CE20156B0E10200002AA9 +:109A54008220B0E10000B0E00110B1E001C0BCE23E +:109A64003E0000DAA050B0E18024D2E20000B0E26F +:109A74000C1AB1E0401941E2071081E10C00005AD0 +:109A8400041A87410000A043B040BDE81EFF2FE147 +:109A9400235A04E004003CE1040035112300000AC9 +:109AA40081E090E183E092110300001A0710A0E125 +:109AB4000000A0E3B040BDE81EFF2FE10C001CE154 +:109AC40005C08CE01200001A050015E1F6FFFF0A3C +:109AD4000116B0E10010A0010000A00314504502DB +:109AE400201A91E10006A0E105C0A0E10300004AAC +:109AF40001C04CE28000B0E10110B1E0FBFFFF5A6D +:109B040000E0A0E10150A0E1843AC3E1403983E3DD +:109B1400BFFFFFEA01C04CE28220B0E10330A3E0C2 +:109B2400400913E3FAFFFF0A01C08CE2B4FFFFEA25 +:109B340081E090E183E092110010E0038059A0E3FA +:109B4400830075E10310A08181007591D8FFFF8A1D +:109B5400041A87E10000A0E3B040BDE81EFF2FE136 +:109B640001C07CE220505CE2080000AA20506CE2B4 +:109B7400020012E1A220A0E101208213102592E14B +:109B8400300CA0E1110580E1311CA0E1080000EADD +:109B940035005CE3C4FFFFCA20C065E2802092E187 +:109BA4003025A0E1012082133105A0E1112C92E1BE +:109BB4000010A0E38024D2E20000B0E20710B1E07C +:109BC400B040BDE81EFF2FE17847C046F0002DE904 +:109BD400037021E0807407E2FF40A0E3704E84E349 +:109BE40021CA14E0235A141004003C110400351156 +:109BF400A700000A05C04CE001C04CE2C064E0E3E9 +:109C0400014506E0204B84E10005A0E1033506E0B0 +:109C1400223B83E10225B0E10210A0E31F00000A09 +:109C2400026050E00340D4E0403483E30400002A9F +:109C340001C04CE28660B0E10440A4E0026096E01A +:109C44000340B4E08660B0E10440A4E0020056E1C1 +:109C54000350D4E0026046200540A0210110B1E089 +:109C6400F7FFFF3A800EA0E38660B0E10440A4E071 +:109C7400020056E10350D4E0026046200540A021D2 +:109C84000000B0E0F7FFFF3A8660B0E10440A4E0D2 +:109C9400026056E00350D4E006001601300000EAEA +:109CA400034054E0403483E30200002A01C04CE244 +:109CB4008000B0E18440A3E0003063E2000010E1E2 +:109CC4001100000A401E81E3000090E08440B3E0EC +:109CD400034044300110A1E0000090E08440B3E070 +:109CE400034044300110A1E0000090E08440B3E060 +:109CF400034044300110A1E0000090E08440B3E050 +:109D0400034044300110B1E0F2FFFF3A844093E095 +:109D1400034044300110A1E0844093E00340443008 +:109D24000110A1E0844093E0034044300110B1E00D +:109D3400F8FFFF3A800EA0E3844093E003404430F0 +:109D44000000A0E0844093E0034044300000A0E021 +:109D5400844093E0034044300000B0E0F5FFFF3A54 +:109D6400844093E08044A0230040A0334044841303 +:109D7400810A80E1A115A0E140CE9CE20D0000DA49 +:109D8400A020B0E18024D4E20000B0E20C1AB1E0DB +:109D9400400971E3071081E10100004AF000BDE8C9 +:109DA4001EFF2FE1FF1687E3701481E30000A0E398 +:109DB400F000BDE81EFF2FE1401981E301C07CE201 +:109DC40020505CE2080000AA20506CE2040014E178 +:109DD400A440A0E101408413104594E1300CA0E1BB +:109DE400110580E1311CA0E1080000EA34005CE3C5 +:109DF4000B0000CA20C065E2804094E13045A0E138 +:109E0400014084133105A0E1114C94E10010A0E35A +:109E14008044D4E20000B0E20710B1E0F000BDE8F5 +:109E24001EFF2FE10000A0E30710A0E1F000BDE851 +:109E34001EFF2FE10C001CE10700001A050015E1CC +:109E44000C00001A01C04CE28000B0E10110A1E056 +:109E5400400911E3FAFFFF0A01C08CE201C08CE261 +:109E64008220B0E10330A3E0400913E3FAFFFF0AC4 +:109E740002C04CE260FFFFEA015085E28000B0E1DD +:109E84000110A1E0400911E3FAFFFF0A00C065E2F6 +:109E940059FFFFEA235A04E004003CE104003511B1 +:109EA4000B00000A816090E183609211E0FFFF1AC9 +:109EB400816090E10000A0E30710A0E1041A811181 +:109EC400F000BDE81EFF2F1183C092E10010E003F3 +:109ED4001EFF2FE18069A0E30000A0E3810076E18A +:109EE40083007691810076010010E0230200002AAD +:109EF400830076E10710A001041A8711F000BDE881 +:109F04001EFF2FE17847C04681C0B0E11800002A47 +:109F1400ACCAA0E140CE4CE201C09CE21400004A6D +:109F240020005CE3060000AA1FC06CE28115A0E1DA +:109F3400801481E3A00A81E1300CA0E10010A0E3C9 +:109F44001EFF2FE13FC07CE28115A0E1801481E374 +:109F5400A01A81E18005A0E1300CA051710C2050C1 +:109F6400311CA051010020500000E0430010E043E8 +:109F74001EFF2FE10000A0E30010A0E31EFF2FE16D +:109F84007847C0460330D0E50220D0E50110D0E583 +:109F94000000D0E5032482E1010480E1020880E1AD +:109FA4001EFF2FE170B504000D0016002A003100D9 +:109FB400200003F039FF200070BC08BC18473100B2 +:109FC40000B50100481E002905D000210529F8DA52 +:109FD400C046491CFAE708BC184710B5040024061B +:109FE400240EC02C05D32406240E66480019C0385C +:109FF400047865480068F021C903014362480160A0 +:10A0040062480068802149000143604801605F485C +:10A014000068802101435D48016095480068402143 +:10A024000143934801600120FFF7CAFF56480068C6 +:10A03400574901405448016053480068210009060B +:10A04400090E09090906090EC90401434E480160B5 +:10A054000120FFF7B5FF864800688021014384484A +:10A0640001600120FFF7ACFF4848006880210143EC +:10A07400464801600120FFF7A3FF434800684449B4 +:10A08400014041480160404800682406240E21072D +:10A09400090FC90401433C4801600120FFF790FF08 +:10A0A4007348006880210143714801606420FFF710 +:10A0B40087FF10BC08BC184710B50400324800687C +:10A0C400F021C90301433048016030480068802111 +:10A0D400490001432D4801602C4800688021014358 +:10A0E4002A480160624800684021014360480160D9 +:10A0F4000120FFF765FF24480068254901402248F4 +:10A1040001602148006821000906090E09090906B1 +:10A11400090EC90401431C4801600120FFF750FFE8 +:10A124005348006880210143514801600120FFF732 +:10A1340047FF16480068802101431448016001204C +:10A14400FFF73EFF10480068114901400E480160C6 +:10A154000D4800682406240E2107090FC904014391 +:10A16400094801600120FFF72BFF41480068802166 +:10A1740001433F4801606420FFF722FF10BC08BC84 +:10A18400184700003C06010014C0FF3F58C0FF3FC1 +:10A19400FFFF87FF38B505000C009C480068F021DC +:10A1A400C90301439948016031480068802149008E +:10A1B40001432F4801609648006880210143944878 +:10A1C40001602B48006840210143294801600120B7 +:10A1D400FFF7F6FE8D4800688E4901408B48016008 +:10A1E4008A48006829000906090E09090906090EAA +:10A1F400C9040143854801600120FFF7E1FE1C48C2 +:10A204000068802101431A4801602406240E012CB1 +:10A214002AD10120FFF7D4FE7D4800688021014344 +:10A224007B4801600120FFF7CBFE7848006879493C +:10A23400014076480160754800682D062D0E2907F7 +:10A24400090FC9040143714801600120FFF7B8FEFA +:10A254000748006880210143054801600120FFF799 +:10A26400AFFE0220FCF734FB31BC08BC18470000E9 +:10A274005CC0FF3F10B50024FEF7CEF8040066482A +:10A2840000686649014064480160634800686449A5 +:10A2940001406148016060480068624901405E48CD +:10A2A4000160614800685D4901405F4801605E48A3 +:10A2B40000685B4901405C4801605B48006859499B +:10A2C4000140594801605948006880214900014310 +:10A2D4005648016055480068802101435348016095 +:10A2E40052480068402101435048016050480068CA +:10A2F400504901404E4801604D4800688021884320 +:10A304004B4908604A48006840218843484908602E +:10A3140049480068C02188434749086046480068A6 +:10A3240046490140444801604348006844490140AB +:10A3340041480160404800683A4901403E48016094 +:10A3440040480068C02188433E4908603D48006891 +:10A354003A4901403B4801603A48006838490140A5 +:10A3640038480160374800682E490140354801608B +:10A3740035480068802109030143334801603248AD +:10A3840000688021490301432F4801602E4800687A +:10A394008021890301432C4801602B4800688021F7 +:10A3A400C90301432848016028480068284901403E +:10A3B4002648016025480068264901402348016079 +:10A3C4002248006824490140204801601F48006871 +:10A3D400224901401D480160214800688021014351 +:10A3E4001F4801601E480068402101431C48016069 +:10A3F4001B4800688021490001431948016020007E +:10A40400F7F768F910BC08BC1847000014C0FF3FF8 +:10A4140058C0FF3FFFFF87FF10C002E0FFFFFCFFB3 +:10A42400FF3FFFFFFFCFFFFF50C002E040C0FF3FF0 +:10A4340050C0FF3FFFFEFFFF04C002E0FFFCFFFF30 +:10A44400FFF3FFFF44C002E000C0FF3F10C0FF3F26 +:10A45400FFFFF7FFFFFFEFFFFFFFDFFFFFFFBFFF80 +:10A464005CC0FF3F80B5FFF705FF1E20FCF730FA04 +:10A4740000213020FFF78EFE2820FFF7A1FD0021E8 +:10A484003020FFF787FE2820FFF79AFD00213020B7 +:10A49400FFF780FE2820FFF793FD00212020FFF71F +:10A4A40079FE2820FFF78CFD01212820FFF772FE9A +:10A4B40001210820FFF76EFE01210120FFF76AFE4B +:10A4C40001210620FFF766FE01210C20FFF762FE42 +:10A4D40009BC184710B504002406240E002C05D02E +:10A4E400022C0DD007D3032C0FD013E001218020C0 +:10A4F400FFF750FE0FE00121C020FFF74BFE0AE0FA +:10A5040001219420FFF746FE05E00121D420FFF746 +:10A5140041FE00E0FFE710BC08BC184770B5050019 +:10A524000C0020000006000EFFF7D4FF00200600F8 +:10A53400287800280CD028780A2809D03606360E48 +:10A54400142E05D22878FFF748FD6D1C761CEFE722 +:10A554003606360E142E04D22020FFF73EFD761C5C +:10A56400F6E770BC08BC184738B504000D002D068A +:10A574002D0E002D05D0022D13D00AD3032D18D093 +:10A584001FE00121200080380006000EFFF702FEC4 +:10A5940018E00121200040380006000EFFF7FAFD04 +:10A5A40010E0012120006C380006000EFFF7F2FDD8 +:10A5B40008E0012120002C380006000EFFF7EAFD18 +:10A5C40000E0FFE731BC08BC184770B505000C007B +:10A5D400160031000906090E20000006000EFFF7E0 +:10A5E400C3FF28000006000EFFF766FD70BC08BC20 +:10A5F400184780B501210120FFF7CCFD09BC18479D +:10A6040080B501210F20FFF7C5FD09BC184780B5AF +:10A6140001210C20FFF7BEFD09BC184780B5604836 +:10A624000068604901405E4801605D4800685E4919 +:10A6340001405B4801605D4800685D4901405B483A +:10A6440001605C480068574901405A480160594814 +:10A65400006855490140574801605748006854490B +:10A66400014055480160554800688021490501436F +:10A6740052480160514800688021090501434F4850 +:10A6840001604F4800688021C90401434C480160BF +:10A694004C4800684C4901404A48016049480068F8 +:10A6A4004A49014047480160B048006848490140B0 +:10A6B400AE480160AE48006830218843AC49086068 +:10A6C400AB480068C0218843A9490860374800683E +:10A6D400A849014035480160B348006830218843E7 +:10A6E400B1490860B0480068C0218843AE49086099 +:10A6F400314800689F4901402F480160AB48006819 +:10A70400AB490140A9480160A8480068A949014033 +:10A71400A64801602A480068A7490140284801600A +:10A72400A6480068A2490140A4480160A348006803 +:10A73400A0490140A14801608C4800689E4901403D +:10A744008A4801608A4800689D4901408848016040 +:10A75400954800689A49014093480160934800680D +:10A764009849014091480160944800689549014026 +:10A7740092480160944800210180944800680028B0 +:10A784000BD104219248FDF735F99049086009235B +:10A79400904A00219048FDF773FA09BC184700005D +:10A7A40004C002E0FFFFFFFCFFFF3FFF1CC002E00C +:10A7B400FFFFCFFF44C002E05CC002E000C0FF3FE7 +:10A7C40060C0FF3F10C0FF3FFFFFFFEFFFFFFFF739 +:10A7D400FFFFFFFBF8B5070000241120FCF778F811 +:10A7E400002005007D4800688021490501437B481D +:10A7F40001607B48006880210905014378480160B5 +:10A80400784800688021C90401437648016001202A +:10A81400FCF75EF874480068800102D42800022521 +:10A82400054372480068400302D428000425054308 +:10A834006E480068000302D42800082505436848D0 +:10A844000068802149050143654801606348006848 +:10A854008021090501436148016062480068802144 +:10A86400C90401435F4801600120FCF731F85E48E8 +:10A874000068800102D42800102505435B48006865 +:10A88400400302D4280020250543584800680003EB +:10A8940002D4280040250543514800688021490519 +:10A8A40001434F4801604E48006880210905014377 +:10A8B4004B4801604E4800688021C90401434C485C +:10A8C40001600120FCF704F847480068800102D4C5 +:10A8D40028008025054345480068400303D4280028 +:10A8E40080256D00054341480068000303D4280017 +:10A8F4008025AD0005433D480068C00203D428000C +:10A904008025ED0005432404240C2D042D0CAC42B9 +:10A9140029D12D48008868400004000C002820D06C +:10A9240000263606360E0B2E1BD22748008801213E +:10A93400B140084213D10120B04029000904090C98 +:10A9440001420CD03606360E310020480068FDF76F +:10A9540037F93606360E3000C01DF6F785F8761C3A +:10A96400DFE7194805802C0037E7000070C0FF3F7F +:10A974000CC002E0FFFFF3FF10B582B0040068468C +:10A98400002101706A46012110480068FDF784F82F +:10A99400010068460078002801D0002001E0216011 +:10A9A400012016BC08BC18474CC002E020C0FF3F81 +:10A9B400FFFFFBFFFFFFF7FFFFFFFFFD30C0FF3F7F +:10A9C400FFFCFFFFFFFFEFFFFE5500407055004006 +:10A9D40004550040243D0040D9A700001CC0FF3F9F +:10A9E40018C0FF3F78C0FF3F74C0FF3F34C0FF3F33 +:10A9F4007CC0FF3F7847C0469D10A0E3000050E3B1 +:10AA04002D0D001A1EFF2FE17847C046010030E1EA +:10AA1400801421423F0D004A01C050E00C00403038 +:10AA24000C108130FF20A0E3A0CB02E0A13B12E098 +:10AA340002003C118024A0E31300000A03C04CE090 +:10AA440018005CE31EFF2FC1011482E1A03BA0E1CA +:10AA5400000482E1310C90E00200C031A0008221A8 +:10AA640019C06CE2521CC1E1001C91E12004A0E178 +:10AA740002C0D1E0830BA0E04037A0E3800073E183 +:10AA84001EFF2F31420400E01EFF2FE1FF005CE3B4 +:10AA94001EFF2F018114B0E10C001C11A1048000E1 +:10AAA4001EFF2F01170053E3E7FFFFDA1EFF2FE11C +:10AAB4007847C04680C0B0E10800002A2CCCA0E151 +:10AAC4007FC05CE20500004A1FC07CE20004A0E1F4 +:10AAD400800480E3300CA0510000E0431EFF2FE10E +:10AAE4000000A0E31EFF2FE138B505000C00200094 +:10AAF400441E002804D0287800F0BBF86D1CF6E74B +:10AB040031BC08BC184770B504000D0016002800BD +:10AB1400451E002808D03100200000F0C0F8641C55 +:10AB24000028F4D1002000E0012070BC08BC1847C4 +:10AB3400F1B584B00026FDF76FFC06000420FDF794 +:10AB44009CFF01900198FEF737FF00225F4BFFF74F +:10AB54003BF804000D000498FEF72EFF02000B00E2 +:10AB640020002900FFF730F803F000F80290029863 +:10AB7400FDF7DEFE02000B000020554903F04EF8FD +:10AB840003F0EEF807006846390041706846390062 +:10AB94000904090C090A01704E4800681021014398 +:10ABA4004C4801604C48802101704C486946497802 +:10ABB40001704B486946097801604A4810210160D8 +:10ABC4004548002101704848002101704748002190 +:10ABD40001604748006801210143454801603E483F +:10ABE4000078032101433C4801703B480078FB2175 +:10ABF4000140394801703A48002101603D4800682D +:10AC040003218843022101433A480160394800681E +:10AC14000C21884308210143364801603648006806 +:10AC24000321884334490860334800680C21884371 +:10AC34003149086031480068012101432F4801600F +:10AC44002E480068022188432C4908602C4800687B +:10AC5400012101432A480160294800680221014377 +:10AC6400274801603000F6F735FD05B0F0BC08BC9C +:10AC7400184710B5040023480078800603D4012047 +:10AC8400FBF726FEF7E71548047010BC08BC18470C +:10AC9400174800680221014315480160704770B5E8 +:10ACA40005000C00002617480078C00707D40120CF +:10ACB400FBF70EFE761CB442F5D2002003E00748F1 +:10ACC40000782870012070BC08BC18470000304090 +:10ACD4000000E03FC4C01FE00C0001E0000001E000 +:10ACE400040001E0280001E0100001E0200001E080 +:10ACF400080001E010C002E050C002E040C0FF3F85 +:10AD040050C0FF3F140001E07847C046030011E340 +:10AD14000400000A012052E20130D1240130C02491 +:10AD2400F9FFFF8A1EFF2FE1030010E31200001A4F +:10AD3400102052E20500003A30002DE93810B1E845 +:10AD4400102052E23810A0E8FBFFFF2A3000BDE8D3 +:10AD5400823EB0E10810B1280810A02804309144C4 +:10AD640004308044822FB0E1B220D1200130D1449C +:10AD7400B220C0200130C0441EFF2FE1042052E263 +:10AD84001000003A010010E30600001A043091E4B8 +:10AD9400042052E2B230C0E06338A0E1B230C0E037 +:10ADA400F9FFFF2A070000EA043091E4042052E28C +:10ADB4000130C0E46334A0E1B230C0E06338A0E104 +:10ADC4000130C0E4F7FFFF2A04208232012052E25E +:10ADD4000130D1240130C024FBFFFF8A1EFF2FE184 +:10ADE4007847C04601402DE9040052E30D00003AC3 +:10ADF400030011E31800001A7CE09FE5003091E5A0 +:10AE040003C010E20700001A042052E2AEC343203C +:10AE140003C0CC210C001E21043080040430B10591 +:10AE2400F8FFFF0A042092E2020012E10800000A7F +:10AE34000130D1E4012052E20130C0E403001311D7 +:10AE44000130D114FAFFFF1A0210B0E10020A0E390 +:10AE5400F80B001B0140BDE81EFF2FE10130D1E4D7 +:10AE6400012052E20130C0E4010053E3030011E386 +:10AE7400F9FFFF8ADFFFFF2AF2FFFFEA808080806C +:10AE84007847C046FF30A0E3A0CB13E0A12B1310FA +:10AE940003003C11030032112F00000A02C04CE0F1 +:10AEA4008024A0E3013020E0023003E0011482E1B9 +:10AEB400000482E12021A0E12111A0E1400FA0E3E0 +:10AEC400012052E001C04C3282208130822071E0A6 +:10AED400022081300000A0E0822071E00220813055 +:10AEE4000000A0E0822071E0022081300000A0E098 +:10AEF400822071E0022081300000B0E0F2FFFF3ACE +:10AF04007FC09CE2090000DA802F92E1A000A0E15A +:10AF14008014D2E28C0BB0E080087053030080E10F +:10AF24001EFF2F51FF00A043800B83411EFF2FE122 +:10AF340002C07CE2400780E319005CE3040000CA1D +:10AF440020106CE2102192E18014D2E2300CA3E0D4 +:10AF54001EFF2FE10300A0E11EFF2FE14027A0E325 +:10AF6400800072E1810072310B00003A800072E1CE +:10AF74000400003A810072E10000E023800411E340 +:10AF8400800420421EFF2FE1810072E10000E013E3 +:10AF940001002000800400021EFF2FE180C0B0E108 +:10AFA40081C0B0110700001A80C0B0E1010020E0A8 +:10AFB400800400E2830B80111EFF2F1181C0B0E1D9 +:10AFC4000000E0031EFF2FE1A0CB13E01500001AE0 +:10AFD400A1CB13E0013020E0803403E20900001A21 +:10AFE4000004A0E100C0A0E38000B0E101C04C5225 +:10AFF400FCFFFF5A0114A0E18110B0E101C08C52A2 +:10B00400FCFFFF5AAAFFFFEA00C06CE20004A0E1C3 +:10B014008000B0E101C04C52FCFFFF5A0114A0E1D2 +:10B02400801481E3A2FFFFEA013020E0803403E2D0 +:10B034000114A0E18110B0E101C08C52FCFFFF5A61 +:10B044000004A0E1800480E399FFFFEA7847C0464A +:10B05400FF20A0E3A0CB12E0A13B121002003C11A0 +:10B06400020033111500000A012020E003C08CE027 +:10B074008034A0E3011483E1000483E1913080E093 +:10B08400802402E28010B0E18000A0317FC0DCE2C5 +:10B09400360000BAA330A0E1003C93E12004A0E113 +:10B0A4008014D3E28C0BB0E080087053000082E17E +:10B0B4001EFF2F51FF00A043800B82411EFF2FE192 +:10B0C400A13B02E002003CE1020033111A00000A35 +:10B0D4008020B0E18120B0110200001A010020E0BC +:10B0E400800400E21EFF2FE1012020E0802402E220 +:10B0F4000C001CE10900001A030013E12400000AFB +:10B1040003C0A0E10004B0E18000B0E101C04C52F2 +:10B11400FCFFFF5A0114A0E1801481E3D6FFFFEA8B +:10B124000114B0E18110B0E101C04C52FCFFFF5AA0 +:10B134000004A0E1800480E3CFFFFFEA8030B0E1A7 +:10B144008130B0110000E0034037A0E3810073E1D7 +:10B154000100A081800073911EFF2F81010020E077 +:10B16400800400E2820B80E11EFF2FE10020A0E3B7 +:10B1740008C07CE220005CE3050000CA20106CE2F9 +:10B18400A330B0E1103193E18014D3E2300CA2E09B +:10B194001EFF2FE10200A0E11EFF2FE108B4024BC5 +:10B1A4009C4608BC6047C04614E10000F0B5A3B05B +:10B1B40002ACA060002016001D00E16002E0206BDC +:10B1C400761C401C20633178002904D1206B23B005 +:10B1D400F0BC08BC1847252908D10020A061E06113 +:10B1E40020626062A062E06200210CE0E068A26874 +:10B1F40002F022FFE0600028E1D10020C043E6E72E +:10B20400012008430100761C30782028F8D0232838 +:10B214000AD02B2804D02D2804D0302806D007E0EB +:10B224000220EEE70420ECE70820EAE71020E8E734 +:10B234002A280DD12868021D2A600068A06300280E +:10B2440004D5424208000421A2630143761C14E0A1 +:10B254000020A0630AE0A26B274B9A4205D093001A +:10B264009A18520080183038A063761C3078020097 +:10B27400303A1206120E0A2AEDD330782E2803D063 +:10B284000020C04360631EE0761C30782A2805D174 +:10B294002868761C021D2A600068F3E700206063BA +:10B2A4000AE0626B144B9A4205D093009A1852003C +:10B2B400801830386063761C30780200303A120609 +:10B2C400120E0A2AEDD3A18731780A487844243033 +:10B2D40002F0B4FE002801D03078761C3E21605480 +:10B2E400605C68280AD13078682810D13E20622139 +:10B2F4000BE0C0467C6D0000FFFFFF7F6C2806D189 +:10B3040030786C2803D13E2071212154761C12A878 +:10B31400606133781800253827D01C3800D185E0C7 +:10B32400001F022800D881E0133800D1A8E00938B2 +:10B334007CD0801E00D14DE1401E00D1F1E0401EC2 +:10B34400022873D9001F00D1EBE0401F3BD0401E00 +:10B3540000D195E0401E25D0C01E0DD0801E00D126 +:10B364008EE0C01E00D18BE03EE1A1692522481C7D +:10B37400A06112A8425444E12868011D29600068B4 +:10B38400626B2061002A02D5FCF7ECFF08E0002183 +:10B3940002F066FE002802D02169401A00E0606BCA +:10B3A400E0612EE12868011D296002680020C04385 +:10B3B4001040002102AA03C212A82061782102A829 +:10B3C40000F0A6F91DE13E20205C622827D0682801 +:10B3D4000FD06A281BD06C2804D0712817D0742889 +:10B3E4000ED07A282868011D2960216B006801604D +:10B3F40007E12868011D2960216B0068018000E1D4 +:10B404002868011D2960216B00680160F9E02A6841 +:10B41400101D2860206B1268C11703C2F1E0286870 +:10B42400011D2960216B00680170EAE03E20205C68 +:10B434004C282868C01D0721884301002860083172 +:10B44400296003C802AA03C2002902D5A1692D22DA +:10B4540009E0A08F810702D5A1692B2203E0C00770 +:10B4640005D5A1692022481CA06112A84254A069F4 +:10B4740012A908182061190002A800F0E3F9C0E03D +:10B484003E20225C6C2A01D1286811E0712A09D17E +:10B4940028680721C01D88430100286008312960FD +:10B4A40003C809E028686A2A02D1C01D0721F2E70F +:10B4B400011D29600068002102AF682A03C706D174 +:10B4C40002A803C802AA00210004000C10E0622AAA +:10B4D40006D102A803C802AA00210006000E07E054 +:10B4E400742A01D07A2A04D102A803C802AA00212E +:10B4F40003C23C20205C000766D502A803C80029CB +:10B5040001D1002860D02020184378285CD1A1699B +:10B5140012A830224254491C481CA06112A843546A +:10B5240052E03E20205C62280CD0682811D06A28A2 +:10B5340021D06C2829D071281DD0742816D07A28DF +:10B544000ED027E02868011D296000680006001657 +:10B5540024E02868011D29600068000400141DE02F +:10B564002868011D29600068002118E02868011D71 +:10B574002960006812E028680721C01D8843010083 +:10B5840028600831296003C809E02868011D296082 +:10B59400006803E02868011D29600068C11702AA39 +:10B5A40003C2002902DAA1692D2209E0A08F8107D4 +:10B5B40002D5A1692B2203E0C00705D5A169202289 +:10B5C400481CA06112A84254A06912A9081820615D +:10B5D4001900F4E6A169481CA0612868021D2A60CC +:10B5E400006812AA50540CE0A1692522481CA061ED +:10B5F40012A84254002B04D0A169481CA06112A8CF +:10B604004354A06BA169761C401A616A401AE1692F +:10B61400401AA16A401A216A401AE16A401A01904C +:10B624003C20205C400710D468462021017001981A +:10B6340001280ADB019F0122694602A800F0ACFC44 +:10B64400002800D0D9E57F1EF5D1A26912A902A86D +:10B6540000F0A2FC002800D0CFE5676A68463021DC +:10B664000170012F09DB0122694602A800F094FC55 +:10B67400002800D0C1E57F1EF5D1E269216902A846 +:10B6840000F08AFC002800D0B7E5A76A684630219C +:10B694000170012F09DB0122694602A800F07CFC3D +:10B6A400002800D0A9E57F1EF5D1E0692169226A4E +:10B6B400091802A800F070FC002800D09DE5E76A94 +:10B6C400684630210170012F09DB0122694602A876 +:10B6D40000F062FC002800D08FE57F1EF5D13C20ED +:10B6E400205C400700D46EE5684620210170019873 +:10B6F400012800DA67E5019F0122694602A800F0EB +:10B704004BFC002800D078E57F1E00D15BE5F3E711 +:10B71400F2B50600706984B002906846007C6F2818 +:10B7240001D1082708E06846007C202101437829DC +:10B7340001D00A2700E0102703CE6A463C24083EC5 +:10B7440003C26A46127C642A03D06A46127C692AC0 +:10B7540009D1002907DA684603C800220023121A17 +:10B764006D468B410CC5684603C800290FD10028DB +:10B774000DD1706B00280AD1082F3BD1305D000732 +:10B7840038D5029830213B303B24017032E06846C2 +:10B7940003C83A00FB17641EFFF700FD303212069F +:10B7A400120E3A2A03D36846007C513812180298C4 +:10B7B400FB170255684603C83A00FFF7EFFC6A46D8 +:10B7C40003C2684603C8002901D1002804D00299A5 +:10B7D400306909198842DAD3082F0BD13C20305C38 +:10B7E400000707D50298005D302803D00298641E34 +:10B7F400302101553C20001BF06102990919316187 +:10B80400716B884206DA081A0D497062B08F0140E4 +:10B81400B18710E000290ED53C21715C14220A4046 +:10B82400102A08D1B16BB269891A726A891A0C1A82 +:10B83400012C00DB746205B0F0BC08BC18470000A2 +:10B84400EFFF0000F3B503C891B002AA07AD03C22D +:10B8540012A80078202101436846017061290CD0A8 +:10B864001198406B002802D51198062104E004D1F8 +:10B87400672902D11198012141631198AD4A4168A9 +:10B88400080D104090422BD1080318D1119800687C +:10B89400002814D111980321C16112A800786138DD +:10B8A4000006000E1A2847D32548784492300090A9 +:10B8B4001198009900690322FFF726FA17E21198FC +:10B8C4000321C16112A8007861380006000E1A280D +:10B8D4002ED31C4979446C31119803220069EBE79B +:10B8E400010018D1119802F09BFC012813DB0027FA +:10B8F400002069460978612931D1119930220969FA +:10B904000A70119A491C4B1C136112AA1278612AFD +:10B914001ED178221DE01199874A49680A40874957 +:10B924001143119A51608649471A0020C043E0E749 +:10B93400054979441231CFE7044878440E30B6E71C +:10B944004467000038670000306700003467000077 +:10B9540058220A701199119A8969891C91610028E9 +:10B9640003D1002468468480B5E1684600786128E4 +:10B9740000D0A2E01198446B002C01D5212400E0F2 +:10B98400641C03C86A462404241403C202A803C81E +:10B99400661C0022002302F067FC684603C802AA62 +:10B9A40002D280231B06594003C2381F694688808F +:10B9B40007AF684600217F1C0177012E31DB02A806 +:10B9C40003C80022002302F06DFC2AD21C2102A825 +:10B9D40002F086FC02A803C802F0C2F9F61F0500B3 +:10B9E400012E09DB02F0EEF902000B0002A803C8E5 +:10B9F40002F008FD02AA03C2FF1D072004E0290784 +:10BA04007F1E090F39702D11012D01DB401EF6D563 +:10BA1400401E03D47F1E00213970F9E7FF1D012E5B +:10BA2400CDDA07A8401C07AD391A6D1CA14200DA13 +:10BA34000C002404241437D42000884206DA07A911 +:10BA440009184978082901D30F2100E0002107AA29 +:10BA5400121801E0641E521E1378401E8B42F9D066 +:10BA64000F2904D107A909184A78521C4A700028E2 +:10BA740006D568468088694607AD001D641C888029 +:10BA840024042414601E0FD429180A7830321206B4 +:10BA9400120E3A2A03D312AB1B783A3BD2180A701F +:10BAA400401E491E0028F0D51198406B002800D490 +:10BAB40011E11198611E41630DE102A803C800223F +:10BAC400002302F0D1FB06D202A803C880231B0680 +:10BAD40002AA594003C2884888493F043F14474397 +:10BAE4003800F7F787FA6946888004200D5E844998 +:10BAF4000720421B0020012A24DB140002AAC0CA2A +:10BB040002AA03C2E00707D502A803C832003B001B +:10BB1400FDF75CFF06000F0002A80CC8641002A821 +:10BB240003C8FDF753FF02AA002C03C2EAD102A8FE +:10BB3400C0C02BE0FF070000FFFF0F800000E03FC4 +:10BB4400FE0300006F4F544204AA002603C2002CD7 +:10BB540014D0E00707D504A803C832003B00FDF762 +:10BB640035FF06000F0004A80CC8641004A803C81D +:10BB7400FDF72CFF04AA002C03C2EAD102A803C8D3 +:10BB840032003B00FEF720F802AA03C268460078A0 +:10BB9400662801D10A3500E006251198406B40194A +:10BBA4000490142801DB132004906846302107AC6C +:10BBB4000177641C0498012841DB02A803C802F041 +:10BBC4001BFD083405940500042428000A21FCF711 +:10BBD400F3FE0E0028000A21FCF7EEFE050005988E +:10BBE4003036401E0690067028000A21FCF7E4FE59 +:10BBF4000E0028000A21FCF7DFFE05000698303607 +:10BC0400401E05900670641EDFD1059C049808341C +:10BC1400083804900128CDDB02A803C802F0ECFC2C +:10BC2400FDF7CAFE02000B0002A803C802F0EAFBFB +:10BC3400354B0022FDF7CAFE02AA03C2BDE707A9DD +:10BC4400497807A8401C07AD201A6D1C30296A46A4 +:10BC540008D1694689886D1C401E491E9180297847 +:10BC64003029F6D069460978662903D10421515E4A +:10BC7400491C06E069460978652901D1012100E0E3 +:10BC84000021119A526B541824042414A04200DA9F +:10BC94000400240424141ED42100814204DA685CC4 +:10BCA400352801D3392000E030206A1800E0641EF2 +:10BCB400521E1378491E8342F9D0392802D1685C98 +:10BCC400401C6854002906D56846808869466D1E64 +:10BCD400401C641C888069460420085E23041B14ED +:10BCE400009012A8017811982A0000F00FF813B000 +:10BCF400F0BC08BC1847000097750000A08601003E +:10BD0400000024400000F03F84D79741F6B587B087 +:10BD140004000E9F666B1D00012D02DAACA0012504 +:10BD240008902020084366280CD0672800D085E0BE +:10BD340003213F04C9433F148F4200DA83E0B74232 +:10BD440000DB80E07F1C66280BD03C20205C0007D1 +:10BD540002D4B54200DA2E003F043F14F61B00D58E +:10BD640000262369E1693F0458183F14012F24DA9F +:10BD7400491C30220270012E03DA3C20205C0007AB +:10BD840002D52E205854491C7842E161864200DADB +:10BD940077423F043F147842F619A062AE4200DABB +:10BDA40035002D042D142562E06908992A0018181D +:10BDB400FEF7AAFF701BE062D6E0BD4216DA0899CE +:10BDC4002A00FEF7A1FFE069791B4019E061A16236 +:10BDD400012E03DA3C21615C090705D521692E2275 +:10BDE4000A54206A401C2062E662BDE008993A00C9 +:10BDF400FEF78AFFE069ED1BC119E161012E03DA48 +:10BE04003C20205C000704D5481CE06120692E22F8 +:10BE140042542D042D14AE4200DA350008982369EB +:10BE2400C119E0692D042D142A001818FEF76CFFBF +:10BE3400E0694019E061701BA06295E061296846E1 +:10BE440014D1702115E0B54204DA3C20205C0007CF +:10BE540000D42E00761E00D500266846007F672891 +:10BE6400684601D1652104E0452102E0412901D160 +:10BE740050210177089AE16912782369481C5A54C1 +:10BE84000899491C0091012E03DA3C21615C0907E1 +:10BE940002D52E211954401CE061012E11DB6D1EC8 +:10BEA4002D042D14AE4200DA350000992D042D1412 +:10BEB4002A001818FEF728FFE0694019E061701B9A +:10BEC400A062E06921693F0408186946097F01708E +:10BED400401C3F1404D42B210170401C089005E041 +:10BEE4002D210170401C0890380047423F04002572 +:10BEF4003F1403AE012F0FDB0A22390001A802F020 +:10BF04009BFB02986D1C3070019F761C3F043F140C +:10BF1400012FF1DA022D0BDA6846007F202101435C +:10BF2400652905D10898302101700898401C0890B3 +:10BF3400002D06D10898302101700898401C089003 +:10BF44000CE0012D0ADB6D1E089903A8405D30301A +:10BF540008700898401C0890012DF4DAE169226900 +:10BF640008985118401A20623C20205C142101409A +:10BF740010290DD1A069E1694018A16A4018216A0D +:10BF84004018E16A4018A16B884201DA081A60621D +:10BF940009B0F0BC08BC184770B506000C001500C9 +:10BFA4000020002D11D02178F068B26802F044F826 +:10BFB400F060002807D0306B641C401C3063002004 +:10BFC4006D1EF0D101E00020C04370BC08BC1847CE +:10BFD4003000320008B4024B9C4608BC6047C0469F +:10BFE4003084000008B4024B9C4608BC6047C0463D +:10BFF400D084000008B4024B9C4608BC6047C0468D +:10C004003884000008B4024B9C4608BC6047C04614 +:10C014006C84000080B500F0F5FD00F0FDF900F03F +:10C0240013FA00F04BFA00F0D4F900F05FFE02F0CE +:10C0340015FBFBF702FE00F029FA02F041FB00F0C9 +:10C04400E5FD02F075FC09BC184710B500246548ED +:10C054000078012834D1FCF7DFF904006248007845 +:10C06400012804D360480078401E5F4908705E4888 +:10C074000078002821D15D48007800281DD100F007 +:10C0840084FA5B4800785B490978884215D058489F +:10C0940000780421484358490858584908605748CB +:10C0A4000068406B401C554909684863A44800680F +:10C0B400401CA3490860FFF795FF2000FFF78AFFA3 +:10C0C40010BC08BC184780B546480078002813D136 +:10C0D40000F05BFA47484649097801704448007803 +:10C0E400042148434449085844490860AD48434939 +:10C0F40009680160FFF77EFF09BC184770B5002688 +:10C1040000F0C7FDFCF788F90600A7480068401C4A +:10C11400A54908603000FFF75DFF32480078012828 +:10C124005DD1BC480078002803D0022807D003D38F +:10C134000BE0012005000DE0002005000AE00120CD +:10C144000500B4480121017004E001200500B14854 +:10C15400002101702D062D0E002D40D0B948006835 +:10C1640004002E20205C1F2839D0FCF755F9060066 +:10C17400608D00282ED0608D401E60850004000C68 +:10C18400002827D12C20205C3721084209D02C20FC +:10C19400205CC82101402C2021542D200121215450 +:10C1A40002E02D20002121542C20205C000711D412 +:10C1B400B54800783221615C0143B34801703020F6 +:10C1C400205CD149085C3121615C01433020205C52 +:10C1D400CD4A115464693000FFF7FCFEC1E770BC1E +:10C1E40008BC1847385600403356004034560040C7 +:10C1F4003656004035560040EC4E0040C8550040CD +:10C204007047FFB501008E7AAB4FBE5D3300012647 +:10C214009E4035001B061B0ECE18F67AA64FBE5D57 +:10C224006F463E7001266F463F78BE4034001B06C1 +:10C234001B0EDE006F463F78F61930001B061B0EFE +:10C24400CE18F67AA6431B061B0ECF18FE721B06E9 +:10C254001B0ECE18F67A002E02D18E7AAE438E7261 +:10C264000006000E04264643A84FBE59320000269D +:10C2740056850026D661019E16622D266F463F7BA9 +:10C2840097552C26965D6F463F7ABE432C27D6558C +:10C294002C26965D002E0DD17B4E36782E437A4F98 +:10C2A4003E701B061B0E984EF65C26431B061B0EA7 +:10C2B400954FFE540006000E04B0F0BC08BC1847AD +:10C2C40000B5384A1268D061364A126830321278A2 +:10C2D40011000906090E8C4A525C324B1B6831333B +:10C2E4001B789A430906090E874B5A540906090E0E +:10C2F400854A525C002A08D1634A1278294B1B688C +:10C3040032331B789A43604B1A70264A12683032D3 +:10C3140012788218D27A234B1B6831331B7813436B +:10C32400204A1268303212788218D372827A1D4BF6 +:10C334001B6832331B781343837208BC1847000010 +:10C34400AC55004000B5174A12683032127811001B +:10C354000906090E4218D27A124B1B6831331B7836 +:10C364009A430906090E4318DA720906090E42189F +:10C37400D27A002A06D1827A0A4B1B6832331B78A0 +:10C384009A438272074A12682D3200231370054AB9 +:10C3940012682C3200231370024A12680023D361FE +:10C3A40008BC1847C0550040D855004000B50023CC +:10C3B400837203000B33190000231A001206120EB5 +:10C3C400042A04D200230B70491C521CF6E708BC53 +:10C3D400184770B5A0217E4800F09AF87C48050003 +:10C3E4007B4810300600002004002404240C092C8F +:10C3F40006D2002028706E6010351036641CF4E7F5 +:10C40400002028700020686072487149016070BC87 +:10C4140008BC18473A5600406F48002101606F4835 +:10C42400002101706E48002101706E4800210170E6 +:10C434006D48002101706D48002101606C480021A5 +:10C4440001607047CC55004000B50F4A00231370BB +:10C454002D4A1000002211000906090E042904D2F5 +:10C4640000220270401C491CF6E7624A0023137044 +:10C47400614A00231370614A00231360AC4A00230D +:10C48400136008BC184700003756004000B585B05B +:10C4940003200490002003908020029058480190CB +:10C4A400584800901F23584A0021A248FBF745FC36 +:10C4B40005B008BC18470000B8FC000070B599210D +:10C4C400C9009D4800F024F88021104800F020F8AD +:10C4D40099480500984848300600002004002406C6 +:10C4E400240E102C04D26E6148354836641CF6E7DD +:10C4F4000020686191480021016091488E490160E3 +:10C5040070BC08BC18470000B8550040EC4E004011 +:10C5140000B50904090C012904D300220270401C4F +:10C52400491EF6E708BC184710B50024FBF774FF52 +:10C5340004002A480078002821D1294800780028DE +:10C544001DD100F022F82C4800782A490978884245 +:10C5540015D029480078042148437A4908582749C6 +:10C56400086026480068406B401C244909684863F9 +:10C574001E480068401C1D490860FFF743FD200069 +:10C58400FFF728FD10BC08BC18476F4909786F4AAB +:10C59400515C08000006000EC1000006000E6C4A43 +:10C5A400125C6A4B9A5C8918134A1170704738B54B +:10C5B40004000025FBF730FF05000D480068401C0F +:10C5C4000B4908602800FFF705FD00F022FBF1E7A6 +:10C5D4004C4E0040B0550040D85500403356004002 +:10C5E400345600403956004038560040AC5500409F +:10C5F400BC5500403556004036560040C8550040F2 +:10C604002C440040FFFF000028460040FEB5040013 +:10C614000A9F0026FBF700FF060049480068050052 +:10C62400002D7DD06869464908603000FFF7D2FCD0 +:10C63400009828602E202C542C20002129542D20D1 +:10C644000021295400206885099868600898E860EA +:10C654000198A8602F8268460089688233200021EF +:10C664002954302021000906090EC9082954012043 +:10C674003021695C8840322168542F206107490FBA +:10C68400295401202F21695C8840312168540020FD +:10C69400E8610020686200202862002068630020AE +:10C6A400E8630020A8630020286400206864280050 +:10C6B40000F0EEFA280000F0AAFAFBF7ADFE06003F +:10C6C4002406240E042060431E490D501B480068B4 +:10C6D40068610020A86119480068002802D0174842 +:10C6E4000068856115480560174800783221695C47 +:10C6F4000143154801703020285C1549095C31203C +:10C70400285C08433021695C114A50541148007870 +:10C71400401C104908703000FFF75CFC002003E067 +:10C724003000FFF757FC4220FEBC08BC184700004D +:10C73400C0550040B3C5000060300040CC550040F7 +:10C74400C4550040EC4E004037560040B8FC000091 +:10C75400B85500403956004010B50024FBF75CFE84 +:10C76400040000208D4908808D4908808D49088087 +:10C7740000208D4908808D4908808D4908808D48A6 +:10C784000068022188438B4908608B4806210160B8 +:10C794002000FFF71FFC10BC08BC184738B5002563 +:10C7A400FBF73AFE05000024E44381480088012891 +:10C7B40015D37F480088401E7D4908807B48008847 +:10C7C4007E49085C040079480088401C7749088049 +:10C7D400764800888021F6F70DFC74480180280013 +:10C7E400FFF7F8FB200032BC08BC184738B500241A +:10C7F400FBF712FE040000256D480088012801D3D0 +:10C80400012005002000FFF7E5FB280032BC08BC2E +:10C81400184738B50024FBF7FFFD040000256148E4 +:10C824000088402801D2012005002000FFF7D2FB38 +:10C83400280032BC08BC184770B505000026FBF779 +:10C84400EBFD060000245748008840283CD2554898 +:10C85400008800281FD15A480078800602D559481C +:10C86400057034E04F480088401C4E4908804B480E +:10C87400008855490D5449480088401C47490880A0 +:10C88400464800884021F6F7B5FB44480180A94892 +:10C89400032101601BE043480088401C4149088093 +:10C8A4003E48008848490D543C480088401C3B4998 +:10C8B40008803A4800884021F6F79CFB37480180FD +:10C8C4009C480321016002E00020C04304003000C2 +:10C8D400FFF780FB200070BC08BC184738B5364809 +:10C8E400006805002D062D0E6D086D076D0F2D06D1 +:10C8F4002D0E022D24D132480078C0074BD52C4888 +:10C904000088802817D2284800882C492D4A12789C +:10C914000A5425480088401C23490880224800887E +:10C924008021F6F767FB2048018021480088401CDD +:10C934001F4908802FE068462249097801702AE0DF +:10C944002D062D0E012D1FD116480088012817D35E +:10C95400134800881C49085C1A490870104800886C +:10C96400401C0F4908800E4800884021F6F742FB1E +:10C974000B4801800B480088401E0A4908800AE0E1 +:10C984000C480121016006E068460E4909780170EF +:10C994000B480078040031BC08BC1847145600400A +:10C9A40012560040165600401A56004018560040D1 +:10C9B4001C560040048007E0088007E0EC4F00406C +:10C9C400148007E0008007E0B0520040F1B584B065 +:10C9D4000026FBF721FD06001820FCF74EF8019015 +:10C9E4000198FCF7E9FF0022534BFDF7EDF8040032 +:10C9F4000D000498FCF7E0FF02000B002000290062 +:10CA0400FDF7E2F801F0B2F802900298FBF790FF0C +:10CA140002000B000020494901F000F901F0A0F9DF +:10CA24000700684639004170684639000904090C5A +:10CA3400090A0170424800688021490401434048C2 +:10CA440001603C48002101603E48062101603E48E7 +:10CA5400002101603D48802101703D4869464978C4 +:10CA6400017034486946097801603A481021016030 +:10CA740036480021017035480078032101433348CA +:10CA8400017032480078FB21014030480170294888 +:10CA94000121016030480068304901408020400392 +:10CAA40008432D4908602C4800682D490140802026 +:10CAB400C0030843284908602A4800682749014000 +:10CAC400284801602748006825490140254801603D +:10CAD400254800688021C900014323480160224899 +:10CAE40000682249014020480160214800688021F3 +:10CAF400C90001431E4801601D48006880210901E6 +:10CB040001431B4801601B4800681B490140194848 +:10CB140001601A481A4901601A48802149050160D8 +:10CB2400FFF71AFE3000FFF755FA05B0F0BC08BC59 +:10CB340018470000048007E0000030400000E03F98 +:10CB4400C4C01FE0088007E0208007E00C8007E0F5 +:10CB5400008007E0288007E000C002E0FFFFCFFF6D +:10CB6400FFFF3FFF40C002E000C0FF3FFFF7FFFFB1 +:10CB740010C0FF3F0CF0FFFFFFFFFFEF70F1FFFF5E +:10CB8400E1C8000010F0FFFF7847C046003021E004 +:10CB9400030013E31100001A002FB0E10500000A9E +:10CBA4000120D0E40130D1E4010052E3030052211A +:10CBB400F8FFFF0A0E0000EA3CC09FE5002090E564 +:10CBC400003091E5030052E10C3042000230C30111 +:10CBD4008C0313010420B0050430B105F8FFFF0AEB +:10CBE4000120D0E40130D1E4010052E303005221DA +:10CBF400FAFFFF0A030052E01EFF2FE101010101C9 +:10CC0400084733002B480021018070477047704764 +:10CC14007047704770B50400100066087600350050 +:10CC24000560001F244E0660001F244E0660001F8E +:10CC3400234E0660001F234E0660001F224E06602E +:10CC4400001F224E0660001F214E0660001F214E69 +:10CC54000660001F204E0660001F204E0660001F65 +:10CC64001F4E0660001F1F4E0660001F1E4E06600A +:10CC7400001F01602600F60703D5001F3326066057 +:10CC840002E0001F1326066070BC08BC18477047FA +:10CC9400704780B507480088401C0649088005484D +:10CCA4000088642804D303480021018001F0FCFCBF +:10CCB40009BC18470456004014141414121212121A +:10CCC4001111111110101010090909090808080898 +:10CCD40007070707060606060505050504040404F8 +:10CCE40003030303020202020101010170B53C21A6 +:10CCF4000F48FFF70DFC0E4805000D480C300600E8 +:10CD0400002004002404240C042C06D200202870E3 +:10CD14006E600C350C36641CF4E70020287000208B +:10CD2400686004480249016070BC08BC18470000F0 +:10CD3400F0520040B455004030B545682B000568FA +:10CD44002C00002B07D1C5682A005460002C06D0A3 +:10CD54000025656003E01C60002C00D063608568DA +:10CD6400290000254D6230BC08BC184700B50200FC +:10CD74008A480906090E016089480068C006FBD488 +:10CD8400864800680006000E08BC184780B5854830 +:10CD94000068802189030143824801608248006859 +:10CDA400824901408020C00008437F4908608048D0 +:10CDB4000068800080088021090601437C480160E6 +:10CDC4007C480068032188437A49086079480068F0 +:10CDD4000C218843082101437648016075480068A6 +:10CDE4003021884320210143724801607248006861 +:10CDF400800080088021090601436F4801606F4864 +:10CE04000068032188436D4908606C4800680C2160 +:10CE1400884308210143694801606848006830215B +:10CE240088432021014365480160654800686549DD +:10CE3400014063480160644800688021490201435D +:10CE440061480160614800688021490201435F48EC +:10CE540001605B4800688021090201435848016071 +:10CE640057480068802189020143554801605448AD +:10CE740000688021C9020143514801605448006898 +:10CE84000F2188430721014351480160504800683D +:10CE9400302188434E4908604D480068402188434A +:10CEA4004B4908604A480068802188434849086023 +:10CEB40047480068474901408020400008434449EE +:10CEC4000860454800680121884343490860424896 +:10CED400006802210143404801603F480068042182 +:10CEE40088433D4908603C480068082188433A4922 +:10CEF40008603A480068FF2188430221014337480B +:10CF0400016037480021016036480021016036483D +:10CF14000068002804D10120FCF77EFC3249086037 +:10CF240009BC184700B501000906090E002906D1FD +:10CF34002E4800688022520202432C4802600020DE +:10CF440008BC184700B501000906090E002906D1DE +:10CF54001E4800688022520202431C4802600020DE +:10CF640008BC184780B56A4601211F480068FCF7D1 +:10CF74007CFC68460078002806D00120F9F7A8FC5C +:10CF8400684600780028EED109BC184780B51648D9 +:10CF94000068FCF7D7FC09BC18470000088006E0CD +:10CFA4000C8006E0C4C01FE0ACC11FE0FFF3FFFF2C +:10CFB40000C002E004C002E040C002E044C002E05D +:10CFC40010C0FF3FFFFFFEFF00C0FF3F18C0FF3F40 +:10CFD400008006E0FF00FFFF048006E0108006E00A +:10CFE400148006E0248006E0EC5500401CC0FF3F9E +:10CFF4000EB400B582B003A9009102006B46012172 +:10D00400034878440A30FEF7D1F8029906B008477D +:10D01400F54B00007847C04600000FE1C01080E3E4 +:10D0240001F021E100100FE1C01001E2C00051E362 +:10D03400F9FFFF1A1EFF2FE100F021E11EFF2FE18F +:10D0440080B503005869401E58611969491C0028BD +:10D05400196106D458681B680122002101F01EFDE5 +:10D0640001E00020C0430ABC18470000F0B58BB0B3 +:10D074000190029118680027FF43002601AC3D008F +:10D0840003902661E2601CE02069019B401C206142 +:10D0940002980122002101F001FD0100093905294E +:10D0A400F2D32028F0D02169491EB842216105D06D +:10D0B400019B01000298002201F0F0FCE068401C92 +:10D0C400E060E06801780B00093B052BDCD32029E4 +:10D0D400DAD0002907D1002D00DA002528000BB092 +:10D0E400F0BC08BC1847252907D1401CE060017832 +:10D0F4002A291CD1401CE0601AE0019B00902069A1 +:10D104000122401C20610298002101F0C7FC009913 +:10D1140009788842D2D02169491EB8422161DAD007 +:10D12400019B01000298002201F0B8FCD3E7002122 +:10D1340020202154A6610BE0A1697B08994205D007 +:10D144008B005918490051183039A161401CE06026 +:10D15400E0680278110030390A29EDD3E7610178DB +:10D164002AA000F06BFF002804D0E0680178401C7E +:10D17400E06000E0002121202154205C682806D1D1 +:10D18400E068017868290DD12121622207E06C282A +:10D1940008D1E06801786C2904D121217122401C56 +:10D1A4006254E060E06801781AA000F047FF0028AC +:10D1B40019D12069019B401C2061029801220021A1 +:10D1C40001F06CFC010009390529F2D32028F0D0C4 +:10D1D4002169491EB842216105D0019B01000298D2 +:10D1E400002201F05BFC01A800F018F8012803DA22 +:10D1F400002D00D573E771E7002D00D5002522200E +:10D20400205C002800D159E76D1C57E7686A6C74EC +:10D214007A4C000063436E5B0000000010B504000C +:10D22400222000212154E068007825385FD01C3882 +:10D2340025D0001F022822D913381CD0C01E70D05C +:10D24400801F1CD0801E12D0401E14D0401E022805 +:10D2540015D9001F0FD0401F15D0401E01280AD930 +:10D26400001F42D0801E06D0C01E04D05BE0200008 +:10D2740000F05DF858E0200000F046F954E020008A +:10D2840000F050FA50E02020205C00282BD121200F +:10D29400205C62280BD0682818D06A280ED06C282D +:10D2A4001BD071280AD0742817D07A2815E0A068FA +:10D2B400011DA16021690068017014E0A268101DBD +:10D2C400A06020691268C11703C20CE0A068011DA8 +:10D2D400A16021690068018005E0A068011DA160CA +:10D2E40021690068016001201EE00121BFE7206977 +:10D2F4000122401C20616068236801F0CFFB2528CF +:10D30400F1D022690021521EC9438842226106D00D +:10D31400236801006068002201F0C0FB00210800BE +:10D3240002E0C943A3E7002010BC08BC1847F2B5CB +:10D33400040084B0002003900498002600282CD513 +:10D34400E068401CE06001785E2904D1411CE16082 +:10D354000078029000E00296E06801785D2900D12F +:10D36400401C5D2100F06AFE002804D1002005B0B5 +:10D37400F0BC08BC1847E168421A00920191E060D1 +:10D384000098032809DB821E01982D21401C00F01F +:10D3940067FE002801D001200390A069012805DA66 +:10D3A4000498002801D0574800E001206061202043 +:10D3B400205C00280CD1A068011DA160076807E06B +:10D3C4003D7022202654E0697F1C401EE061022645 +:10D3D4002000FFF735FE00210500C943884278D0BC +:10D3E4000498012817DB28000938052801D3202DCB +:10D3F40065D120690022401E2061606823682900ED +:10D4040001F04CFB0498002801D0022E6FD0022EAC +:10D4140063D10120ABE7002851D50398002810D12F +:10D424000298009A002806D10198290000F018FEFD +:10D434000028DED005E00198290000F011FE002844 +:10D44400D7D1039800283AD00299019A2806000EF1 +:10D454000029009921D106E0984202DB93788342A7 +:10D464002DDAD21CC91E032908D353782D2B137827 +:10D47400F2D0834223D0521C491EF4E70029B8D0CD +:10D48400137883421BD0521C491EF7E7984202DBF3 +:10D4940093788342ADDAD21CC91E03290DD3537885 +:10D4A4002D2B1378F2D08342A3D0521C491EF4E7EB +:10D4B400137883429DD0521C491E0029F8D12020A4 +:10D4C400205C002883D1E0690126002800D077E79A +:10D4D4008FE72069401E206194E7F00704D4002000 +:10D4E400C043854200D041E70020C0433FE72020ED +:10D4F400205C00288DD1E069002800D136E70020A7 +:10D50400387086E7FFFFFF7FF0B50400A06989B09B +:10D51400012800DA8248606101AE2000FFF790FD27 +:10D5240005002B2D01D02D2D06D168460571761CE2 +:10D534002000FFF785FD0500684600210170E068C2 +:10D544000078642801D0752801D10A270EE06928E3 +:10D5540001D100270AE06F2801D1082706E07028CE +:10D5640003D020210143782900D11027302D28D160 +:10D574006846012101702000FFF762FD202101436C +:10D5840009060500090E782917D1002F01D0102FA4 +:10D5940007D110272000FFF753FD0500684600213E +:10D5A4000170302D11D12000FFF74AFD05006846B7 +:10D5B40001210170302D0CD1F5E7002FF1D108279E +:10D5C400EFE7002F16D10A2714E0684600780028F8 +:10D5D40010D030203070761C0CE001A81F30864239 +:10D5E40001D23570761C2000FFF72AFD050068463D +:10D5F400012101700020C04385421FD02906090E75 +:10D60400612901D3573909E0412901D3373905E0AC +:10D6140030390906090E0A2900D3FF210906380604 +:10D62400090E000E8142D8D320690022401E2061D9 +:10D6340060682368290001F031FA02E02069401E85 +:10D64400206168460078002808D101A8864203D1E9 +:10D654000020C04385425FD000205DE00020307090 +:10D664002020205C002856D1E0680178642901D08C +:10D67400692929D13A00002101A801F06DFA22227A +:10D684000123A3542122A25C622A0BD0682A15D05C +:10D694006A2A0DD06C2A39D0712A09D0742A35D05F +:10D6A4007A2A33E0A268131DA3601268107032E076 +:10D6B400A268131DA360126803C22CE0A268131DA4 +:10D6C400A3601268108026E03A00002101A801F04E +:10D6D4000BFB22220123A354E2681278702A15D08E +:10D6E4002122A25C622ADDD0682AE7D06A2A07D008 +:10D6F4006C2A0BD0712ADBD0742A07D07A2A05E071 +:10D70400A268131DA360126803C204E0A268131D7B +:10D71400A36012681060012009B0F0BC08BC18476F +:10D72400FFFFFF7FF0B50700B86995B0012800DA64 +:10D734001A48786104AC3800FFF782FC0500002029 +:10D7440001902B2D01D02D2D06D168460574641C43 +:10D754003800FFF775FC050068460A214170002176 +:10D764000170302D29D13800FFF76AFC20210143D4 +:10D7740009060500090E782912D0684601210170B6 +:10D78400302D00D0F4E03800FFF75AFC050068465D +:10D7940001210170302D00D0EDE0F4E7FFFFFF7FA1 +:10D7A4003020207078206070A41C3800FFF748FCFB +:10D7B4000500684610214170E2E720202843000656 +:10D7C400000E6E286ED1684641706E262670641C69 +:10D7D4003800FFF735FC2021014309060500090E36 +:10D7E400612915D038690021401EC9438D42386132 +:10D7F40000D087E16846007800283FD104A884421D +:10D8040000D086E10020C043854200D081E1A9E137 +:10D8140061202070641C3800FFF712FC20210143B2 +:10D8240009060500090E6E29DCD13800FFF708FC53 +:10D83400050028280DD038690021401EC9438D42B7 +:10D84400386119D078683B680022290001F026F974 +:10D8540012E03800FFF7F4FB0100050061391A29D2 +:10D86400F7D3010041391A29F3D330380A28F0D309 +:10D874005F2DEED0292DB5D12670641C00202070B8 +:10D884002020385C002800D06BE1684640780B28E3 +:10D8940000D340E1019A002104A801F0F9FA02AA98 +:10D8A40003C244E1692869D1684641706920207047 +:10D8B400641C3800FFF7C4FB20210143090605005E +:10D8C400090E6E298ED16E202070641C3800FFF77B +:10D8D400B7FB2021014309060500090E662900D083 +:10D8E40080E73800FFF7ACFB20210143090605005F +:10D8F400090E69290DD038690021401EC9438D42A3 +:10D90400386132D078683B680022290001F0C6F8FB +:10D914002BE03800FFF794FB2021014309060500A2 +:10D92400090E6E2900D05DE73800FFF789FB20213E +:10D93400014309060500090E692900D052E73800A1 +:10D94400FFF77EFB2021014309060500090E742917 +:10D9540000D047E73800FFF773FB20210143090695 +:10D964000500090E792900D03CE76620207084E781 +:10D974000078002802D030202070641C002609E0C2 +:10D984000198401C01903800FFF75AFB05006846D7 +:10D99400012101700020C043854224D02806000ED6 +:10D9A400612801D3573809E0412801D3373805E00D +:10D9B40030380006000E0A2800D3FF206946497853 +:10D9C4000006000E884205D2242ED9DA2570641C84 +:10D9D400761CD8E72E2D06D12E202070641C38002A +:10D9E400FFF72EFB0500002E23D1302D0BD101981B +:10D9F400401E01903800FFF723FB05006846012113 +:10DA04000170302DF3D00198002812D530202070F9 +:10DA14000198641C401C01900BE0242E02DA25704E +:10DA2400641C761C3800FFF70BFB050068460121D7 +:10DA340001700020C043854215D02806000E6128DD +:10DA440001D3573809E0412801D3373805E030388D +:10DA54000006000E0A2800D3FF2069464978000614 +:10DA6400000E8842D9D368460078002800D1B9E670 +:10DA740069464978202028430A2905D10006000E6A +:10DA8400652800D0AEE604E00006000E702800D041 +:10DA9400A8E62570641C3800FFF7D2FA05002B2D88 +:10DAA40001D02D2D05D12570641C3800FFF7C8FA6C +:10DAB4000500684600210170302D0BD13800FFF7B6 +:10DAC400BFFA0500684601210170302DF6D03020E0 +:10DAD4002070641C2800002630380A2802D381E60E +:10DAE400082E02DA2570641C761C3800FFF7A8FAA9 +:10DAF4000500684601210170280030380A2800D347 +:10DB040070E6EDE778683B680022290000F0C6FF64 +:10DB140070E6002026E00022002104A801F0B8F9F4 +:10DB240002AA03C20198810002A800F0D9FB2220B6 +:10DB3400012139542120385C6C2807D1B868011DB3 +:10DB4400B960026802A803C803C20AE04C28F5D0F1 +:10DB5400BC68201DB86002A803C800F007F821685B +:10DB64000860012015B0F0BC08BC18477847C046CF +:10DB740080C9A0E381007CE12500008AE1CFA0E117 +:10DB840070C45CE280095C230900003A8CC0B0E1F7 +:10DB9400FF055C331A00002A2CC1B0E10CC2A0E1DD +:10DBA4006CC0A0E18011B0E18014D1E2A00EACE021 +:10DBB4001EFF2FE18115A0E1A01A81E18005B0E1EB +:10DBC40001108113801481E3CC0AA0E1090060E212 +:10DBD400210050E30800002A8CCF80E120C06CE2D1 +:10DBE400110CB0E18004D0E220C06CE2310CA0E161 +:10DBF40080C40CE20C00A0E01EFF2FE18C0FA0E11A +:10DC04001EFF2FE17F04A0E3800880E30C0F80E176 +:10DC14001EFF2FE10000E0E31EFF2FE17847C0461E +:10DC240050002DE903C031E080342342F901004A59 +:10DC3400024050E00360D1E00300002A040050E0F9 +:10DC44000610D1E0042092E00630B3E080C9A0E3DE +:10DC540081007CE18340DC308044A0E32B00002A77 +:10DC640021CAA0E1236A4CE0350056E3370000CA1C +:10DC7400833584E1A335A0E1811584E1C115A0E1D8 +:10DC8400200056E3080000BA206056E20220B011DA +:10DC94007346A0E1334624E001408413330690E048 +:10DCA4000010B1E20800002A0B0000EA7246A0E16D +:10DCB4003226A0E1024024E0732622E0332622E04B +:10DCC400020090E03316B1E00300003AA110B0E185 +:10DCD4006000B0E16440B0E101408423401981E276 +:10DCE400A020B0E18024D4E20000B0E20C1AA1E04C +:10DCF4005000BDE880C9A0E381007CE11EFF2F3104 +:10DD04000000A0E3211AA0E1011AA0E11EFF2FE107 +:10DD140081007CE10F00002A836092E10B00000A7D +:10DD240081005CE10600008A21CAA0E10430C3E15D +:10DD340001604CE2340056E3CEFFFFDA5000BDE848 +:10DD44001EFF2FE18034C3E3020090E00310B1E032 +:10DD54005000BDE81EFF2FE15000BDE81EFF2FE17B +:10DD64007847C04681C0A0E1ACCAA0E140CE4CE2F5 +:10DD740001C09CE20C00004A1FC07CE20C00004A77 +:10DD84008110B0E10115A0E1801481E3A00A81E1D2 +:10DD9400300CA0E1000010E18004A04300006022E8 +:10DDA4001EFF2F21010040421EFF2FE10000A0E3CF +:10DDB4001EFF2FE1800411E38004E0538004A0439C +:10DDC4001EFF2FE17847C0460010B0E11EFF2F016F +:10DDD40000006042C214A0434214A053400B50E31D +:10DDE4000008A03140174132400750E30004A0313D +:10DDF40080184132400550E30002A03140184132FE +:10DE0400400450E30001A03180194132800450E302 +:10DE14008000A03140194132C01941E2A01581E0CF +:10DE2400800AA0E11EFF2FE17847C046022CB0E132 +:10DE3400222482E1222882E1010080E0033010E202 +:10DE44000400000A031051E01100003A833FB0E1DE +:10DE540001206045B22060210230A0E110402DE98C +:10DE640002C0A0E102E0A0E1101051E20C50202910 +:10DE7400FCFFFF8A811EB0E10C002029042020450C +:10DE84000111B0E1B2206021012060451040BDE8DD +:10DE94001EFF2FE1031091E001206015020011E341 +:10DEA400012060151EFF2FE1000050E39D10A0E348 +:10DEB400401F8143000070421EFF2F01400B50E3BE +:10DEC4000008A03110104132400750E30004A03193 +:10DED40008104132400550E30002A03104104132E1 +:10DEE400400450E30001A03102104132800450E3A9 +:10DEF4008000A0310110413200CCB0E12004A0E147 +:10DF040080C4DCE2810BA0E01EFF2FE1010030E1C0 +:10DF140080142142BFF2FF4A000051E180C42082F4 +:10DF2400800421820C10A0814037A0E3800073E1BB +:10DF3400810053312B00002AA0CBA0E1A13BDCE0FF +:10DF44000800003A8024A0E3011482E11800008A4A +:10DF5400800471E00600003AA004B0E1A010B021F2 +:10DF64008C0BA0E01EFF2FE1010050E01EFF2F01EB +:10DF74008004B0E10120A0E3012082528000B0516E +:10DF8400FCFFFF5A8000A0E1A004A0E16C34A0E1F2 +:10DF9400023C53E0E30080801EFF2F81800880E371 +:10DFA40043CCA0E1833FA0E101C06CE2300C83E1EB +:10DFB4001EFF2FE1180053E31EFF2FC13123A0E100 +:10DFC400121371E001208233800472E08000A031DA +:10DFD40000C0CCE2802BB0E1A004A0E18014D2E226 +:10DFE4008C0BA0E01EFF2FE1800073E10E00002ADD +:10DFF4008120B0E10900000AA0CBA0E1A13B4CE0E4 +:10E00400020053E3040000BA8114A0E18024A0E3D9 +:10E01400170053E3E8FFFFDA1EFF2FE1A20040E000 +:10E024008030B0E10000A0031EFF2FE1810073E106 +:10E034000000E0231EFF2FE1104734007847C0465C +:10E044000020D0E5FF1001E2010052E3020031E1BB +:10E054000120F085FBFFFF8A0000A0131EFF2FE1C3 +:10E064007847C046FF1001E2030010E30500000AF0 +:10E07400012052E21C00003A0130D0E4030031E1F7 +:10E08400F8FFFF1A160000EA082052E20E00003AD8 +:10E09400042082E230002DE9011481E1011881E1BC +:10E0A4004CC09FE5043090E4042052E20130232068 +:10E0B400AC4343200340C4210C001421F8FFFF0AA1 +:10E0C4003000BDE8FF1001E2040050E2082092E2B3 +:10E0D4000130D0E4012052E203003121FBFFFF8A2A +:10E0E4000100A013010050E21EFF2FE10000B0E385 +:10E0F4001EFF2FE18080808080C413E20100005A5B +:10E10400002072E20030E3E241C03CE00E00001A5D +:10E1140001C093E11B00001A00502DE90210A0E198 +:10E12400B8D3FFEB0120A0E10010A0E30030A0E38E +:10E134000050BDE81EFF2FE10130A0E10020A0E166 +:10E144000010A0E30000A0E31EFF2FE100502DE922 +:10E154000100003A000070E20010E1E2EBFFFFEB87 +:10E164000050BDE88CC0B0E10200003A000070E24B +:10E174000010E1E20C001CE11EFF2F51002072E2AE +:10E184000030E3E21EFF2FE1020050E103C0D1E0C2 +:10E19400E8FFFF3A03C092E13F03000A30002DE993 +:10E1A40000C0A0E3022092E00330B3E00300002AA1 +:10E1B400030051E10200500101C08C22F8FFFF2A44 +:10E1C4006330B0E16220A0E18054A0E320405CE22F +:10E1D4003544A0210050A023355CA0310040A03379 +:10E1E400010000EAA330B0E16220A0E1020050E1A6 +:10E1F40003C0D1E0020040200C10A0210440B4E090 +:10E204000550B5E0F6FFFF3A0020A0E10130A0E19F +:10E214000400A0E10510A0E13000BDE81EFF2FE1DD +:10E22400104B70B401004A684C688020000602401C +:10E2340001201C404C6002D10C68002C0DD04D68AC +:10E244000C686E00E50F35434D6064000C60401EA1 +:10E25400EC02F4D54C6823404B604B681A434A6087 +:10E2640070BC7047FFFF0F007847C04680C9A0E329 +:10E2740081007CE183007C911EFF2F8101C083E13A +:10E284008CC090E10CC092E10200002A030051E12D +:10E29400020050011EFF2FE1010053110000520142 +:10E2A4001EFF2FE17847C04680C9A0E381007CE1CE +:10E2B40083007C911EFF2F8103C081E18CC090E11B +:10E2C4000CC092E10200002A010053E10000520157 +:10E2D4001EFF2FE103005111020050011EFF2FE128 +:10E2E400F8B5444E040060680D00000D3040B042A3 +:10E2F40009D16068000302D12068002801D00220FF +:10E3040074E0012072E0010006D12000FFF788FFCD +:10E31400012801DB002069E0012D0CDB311A8D425C +:10E3240009D36068002802D53349002001E00020A9 +:10E33400310503C4E5E74142A94207DA61682F4A7F +:10E3440028180A400005104360604DE06368626865 +:10E35400802109061B03401E1B0BCE0A2D181E43E9 +:10E3640028000A40002335306660352802D36260F5 +:10E374002360CFE728001E260025F643B04204DAC6 +:10E3840066682568266020306360434211D02668A1 +:10E3940067686D1EAD412020ED43C01AED0F864025 +:10E3A400354326688740DE40374327606068D8409D +:10E3B40060606068104360601148854204D28D42F9 +:10E3C4000CD12078C00709D52068401C2060206843 +:10E3D400002803D16068401C606005E060689042DA +:10E3E40002D12068002895D00020C043F2BC08BCAC +:10E3F4001847C046FF0700000000F0FFFFFF0F8032 +:10E40400010000807847C04650002DE903C031E088 +:10E414008034234205FEFF4A024050E00360D1E00D +:10E424000400002A806426E2040050E00610D1E0D3 +:10E43400042092E00630B3E080C9A0E381007CE1CF +:10E444008340DC308044A0E35500002A21CAA0E1C7 +:10E45400236A4CE0360056E34F0000CA010056E33D +:10E46400280000CA0CCAA0E1833584E1A23A83E102 +:10E474008225A0110225A001A330A001811584E109 +:10E48400A01A81E1800572E00310D1E01600004A71 +:10E494000010A0010000A0030060A0132060A003EE +:10E4A400010011013C00000A0300004A016086E2F9 +:10E4B400000090E00110B1E0FBFFFF5AECCFA0E1B7 +:10E4C40086CA5CE00160DCE3ECC0A0E10600008ADF +:10E4D400806976E2A66AA0E180C40CE23006A0E17D +:10E4E400710620E03116A0E1010020E0A005B0E1B2 +:10E4F400810A80E18014C1E3A040B0210000B0E2B1 +:10E50400A115ACE0240000EA833584E1A335A0E141 +:10E51400811584E1A115A0E1200056E3080000DA8A +:10E52400206056E20220B0117346A0E1334624E095 +:10E5340001408413004074E23306D0E00010C1E2CD +:10E54400080000EA7246A0E13226A0E1024024E07D +:10E55400732622E03336A0E1032022E0004074E277 +:10E564000200D0E00310C1E0400911E30500001AE5 +:10E5740001C04CE28C2AB0E10200000A8440B0E100 +:10E584000000B0E00110A1E04019C1E3A030B0E107 +:10E594008034D4E20000B0E20C1AA1E05000BDE8DF +:10E5A4001EFF2FE181007CE10F00002A8034C3E3C9 +:10E5B400836092E10900000A8CC0A0E181005CE163 +:10E5C4000400008A21CAA0E101604CE2340056E351 +:10E5D400CEFFFFDAF0FFFFEA020050E00310D1E0C3 +:10E5E400816090E10010A003EBFFFFEA83007C014F +:10E5F4000010E023E8FFFFEA7847C04681C0B0E19D +:10E604000A00002AACCAA0E140CE4CE201C09CE260 +:10E614000600004A1FC07CE28115A0E1801481E35A +:10E62400A00A81E1300CA0510000E0431EFF2FE15D +:10E634000000A0E31EFF2FE17CB504000E001500CE +:10E6440030002900F4F7D6FC45430090701B01907C +:10E65400684603C803C476BC08BC184738B56421AF +:10E664001048FDF755FF0F480400002005002D0455 +:10E674002D0C042D0AD22D042D0C142068430949B5 +:10E6840008181430606014346D1CF0E700206060DA +:10E6940003480449016031BC08BC1847000000006D +:10E6A400D05500406C50004010B596480068FBF708 +:10E6B40049F9040020000006000E10BC08BC1847ED +:10E6C40070B5902189009248FDF722FF40219148BE +:10E6D400FDF71EFF8E4805008D48243006000020FB +:10E6E40004002404240C0F2C09D264202870212057 +:10E6F40000212954EE6024352436641CF1E764209B +:10E7040028702120002129540020E860824800213B +:10E7140001607D48002101807C481021018055481A +:10E724007B4901600120FBF777F87C4908600020F1 +:10E73400FBF772F87349086000F003F870BC08BC7A +:10E74400184700B585B00320049000200390802072 +:10E75400029073480190734800901D23724A00216F +:10E764007248F9F7EAFA05B008BC1847FCB504008A +:10E774000D002120032121542D062D0E012D05D13C +:10E78400E06965490968401860610DE0A0690028E6 +:10E7940005D1E069604909684018606104E0A06936 +:10E7A4005D49096840186061684600906069082105 +:10E7B400FAF702F900988180684680880821484366 +:10E7C4005449081807003868002805D13C60002027 +:10E7D400E0600120B88007E0386806003C60E6602D +:10E7E4003461B888401CB88000202061F3BC08BCA8 +:10E7F4001847FCB504006846009060690821FAF7E0 +:10E80400DBF80098818068468088082148434149A4 +:10E81400081807003868A04207D1E06805003D6089 +:10E82400002D0AD00020286107E020690500E06877 +:10E834000600EE60002E00D0356121200121215414 +:10E844000020E06000202061B888401EB880F3BC3E +:10E8540008BC184780B56A46002130480068FBF7B9 +:10E8640004F809BC184780B52C480068FBF76AF81F +:10E8740009BC1847E8550040F1B582B001AA00214F +:10E8840020480068FAF7F1FFFFF7E4FF2248006828 +:10E89400401C21490860204800680821FAF78CF8D8 +:10E8A4000F003F043F0C082078431A4908180090D1 +:10E8B400009800680400002C20D0E0680600164888 +:10E8C40000686169884217D1606805002800002843 +:10E8D40003D0A168200000F0E3FA2000FFF789FFCD +:10E8E4002020205C022804D101212000FFF73EFFF4 +:10E8F40002E02120022121543400DCE7FFF7B3FFBA +:10E90400BCE70000E45500400256004000560040B9 +:10E91400EC3F004030520040DC550040E0550040E0 +:10E924002C460040FDFF0000284800407DE8000020 +:10E934002D4908002D4908002D4908002D490800DB +:10E944002D4908002D4908002D4908002D490800CB +:10E954002D4908002D4908002D4908002D490800BB +:10E964002D4908002D4908002D4908002D490800AB +:10E974002D4908002D4908002D4908002D4908009B +:10E984002D4908002D4908002D4908002D4908008B +:10E994002D4908002D4908002D4908002D4908007B +:10E9A4002D4908002D4908002D4908002D4908006B +:10E9B4002D4908002D4908002D4908002D4908005B +:10E9C4002D4908002D4908002D4908002D4908004B +:10E9D4002D4908002D4908002D4908002D4908003B +:10E9E4002D4908007047C04610600100086001000E +:10E9F400126001001460010016600100186001003B +:10EA04001A6001001C6001001E600100206001000A +:10EA140022600100246001002660010028600100DA +:10EA24002A6001002C6001002E60010030600100AA +:10EA3400326001003460010036600100386001007A +:10EA44003A6001003C6001003E600100406001004A +:10EA5400426001004460010046600100486001001A +:10EA64004A6001004C6001004E60010050600100EA +:10EA740052600100546001005660010058600100BA +:10EA84005A6001005C6001005E600100606001008A +:10EA94006260010064600100786001001847F2B50B +:10EAA40006001F0082B0002901D16846029034009C +:10EAB40000E0641C2078010009390529F9D32028D5 +:10EAC400F7D005002D2D01D02B2D01D1641C00E0C1 +:10EAD4002B250299200000F045F8029A126894420E +:10EAE40001D1029A1660029A1268964203D1002953 +:10EAF40011D100280FD12B2D03D180231B0699425D +:10EB040009D22D2D19D1802301221B06994214D339 +:10EB140001D8904211D300F0C5F922210160002FE1 +:10EB240001D0012038602D2D03D180210020090659 +:10EB34000EE00020C04341080AE02D2D04D100223C +:10EB44000023121A8B4101E002000B00100019008F +:10EB540003B0F0BC08BC184780B50023FFF79FFF43 +:10EB64000CBC1847FDB50D0086B0002B01D0002168 +:10EB74001960069C00E0641C20780100093905290D +:10EB8400F9D32028F7D02D2801D02B2803D16946AA +:10EB94000870641C02E068462B2101700798002865 +:10EBA40003D4012801D0252806DB002D01D00698C6 +:10EBB4002860002000218FE001280BDB102818D1E9 +:10EBC4002078302815D1607820210143782910D18C +:10EBD400A41C0EE02078302801D00A2008E06078D8 +:10EBE40020210143782902D110200790F0E7082062 +:10EBF400079003942078302803D1641C20783028AF +:10EC0400FBD000260027029404A8C0C06846C04672 +:10EC140038A10196417014E004A9C0C1079A69465D +:10EC24004978D317401A0006000E01903000019E67 +:10EC34003900360600F03EF9360E002736184F41EB +:10EC4400641C2178080041381A2800D22031079A20 +:10EC540028A0FFF705FA0028DED10398A042A4D02B +:10EC6400079902982DA2515C201A401A25D4012834 +:10EC740017DA019A00231206120E3900B01A9941CC +:10EC84008F420ED301D886420BD3079AD317FCF7D1 +:10EC940085FA02000B0004A803C88B4201D182420A +:10ECA4000BD000F0FFF8222101600898002801D061 +:10ECB400012101600AA6C0CE09E0684600782D282B +:10ECC40005D100200021801BB94106000F00002D52 +:10ECD40000D02C603000390009B0F0BC08BC1847E3 +:10ECE400FFFFFFFFFFFFFFFF80B50023FFF73AFFA1 +:10ECF4000CBC184730313233343536373839616219 +:10ED0400636465666768696A6B6C6D6E6F70717257 +:10ED1400737475767778797A0000000000004129D1 +:10ED2400211C191716151413121211111110101099 +:10ED34000F0F0F0F0E0E0E0E0E0E0E0D0D0D0D0DF0 +:10ED44000D000000FDB588B004000D0008A800F017 +:10ED5400BDF80821014001910A99002901D000223F +:10ED64000A6008218843012836D1089902200090BE +:10ED740004AB2A00200000F03DF9040004D102AAEB +:10ED84000020002103C21DE00598FFF71BF802AA2A +:10ED940003C2022C16DB04AD0835641E394B02A8ED +:10EDA40003C80022FAF712FE060028680F00FFF7D6 +:10EDB40009F832003B00FEF731FF02AA03C22D1D01 +:10EDC400641EEBD1099804990A9B421802A803C84F +:10EDD40000F01CFA02AA48E0022837D108990090F2 +:10EDE40004AB2A00200000F0E9FA040004D102AACE +:10EDF4000020002103C21DE00598FEF7E3FF02AAEC +:10EE040003C2022C16DB04AD0835641E1E4B02A897 +:10EE140003C80022FAF7DAFD060028680F00FEF79F +:10EE2400D1FF32003B00FEF7F9FE02AA03C22D1DFA +:10EE3400641EEBD1049902A8FFF752FA0A9B099ABF +:10EE440002A803C800F0E2F902AA0EE0032803D1E5 +:10EE54000E4902AA002008E0042802AA03D10020D7 +:10EE6400C043410801E00020002103C201980006CC +:10EE740002A803C802D08022120651400BB0F0BC95 +:10EE840008BC184765CDCD410000B0410000F07FBB +:10EE940080B50023FFF756FF0CBC18471EFF2FE177 +:10EEA40028473500024880B500F092FB0ABC184799 +:10EEB400F85500407847C04690030CE091C22CE01E +:10EEC400920081E00C1081E01EFF2FE1F8B40200F3 +:10EED40010680B00009001000020002500E0491C90 +:10EEE4000C782600093E052EF9D3202CF7D02D2CC2 +:10EEF40001D1082501E02B2C00D1491C0E782027D4 +:10EF0400202437436E2F28D1491C0D782543612DC9 +:10EF140004D1491C0D782C436E2C01D0009918E0C3 +:10EF2400491C0C0025780420282D12D1641C257856 +:10EF34002E003700613F1A2FF8D33700413F1A2FB4 +:10EF4400F4D3303E0A2EF1D35F2DEFD0292D00D11A +:10EF5400611C002B4AD0196048E0692F28D1491C54 +:10EF64000E7826436E2E04D1491C0E782643662E55 +:10EF740001D00099EDE70320491C28430D7825436F +:10EF8400692DE6D14E1C357825436E2DE1D1761CD2 +:10EF940035782543692DDCD1761C35782543742DCD +:10EFA400D7D1761C35782C43792CD2D1711CD0E77B +:10EFB400302E19D148780443782C15D1881C037855 +:10EFC4002E2B00D1401C00780300613B062B06D396 +:10EFD4000300413B062B02D330380A2802D2022018 +:10EFE400891C02E0012000E0012028431160F2BCEA +:10EFF40070473600F5B590B017980E00C1001C009C +:10F00400002508182E2800DB2D2025606560019559 +:10F014003178302905D10121761C019131783029CC +:10F02400F9D0002704A905E02268521C22600122BD +:10F03400761C019232781300303B0A2B05D2B84279 +:10F04400F2DB303ACA557F1CF1E72E2A00D1761C38 +:10F05400002F0BD13178302908D12168761C491E44 +:10F0640021600121019131783029F6D031780A00EC +:10F07400303A0A2A0CD2B84206DB04AA3039D155F8 +:10F0840021687F1C491E21600121761C0191EDE756 +:10F09400B84215DA04A909180A78052A03D3491EC7 +:10F0A4000A78521C0A700700206807E004A8C019F7 +:10F0B400401E007800280AD120687F1E401C206072 +:10F0C400012FF3DA002F02D1684605740127019855 +:10F0D40000285CD00920009038000921F3F78AFF4A +:10F0E4000920401A00900921F3F784FF02950029B2 +:10F0F40000D00125012F1FDB029804A9085C092117 +:10F1040003900098F3F776FF002904D103996D1C4E +:10F11400A800215008E0A800201801688A005118AE +:10F12400039A4900891801600098401C00900298D5 +:10F13400401C0290B842DFDB30782021014365296E +:10F1440025D10096761C30782B2801D02D2801D1AA +:10F15400761C00E02B200023002109E0134B994288 +:10F1640004DA8B005918490051183039761C0123F0 +:10F1740032781700303F0A2FF0D32D2801D1080030 +:10F184004142206840182060002B00D1009E119855 +:10F19400002805D00198002800D1109E119806601F +:10F1A400280012B0F0BC08BC1847C04600E1F505C1 +:10F1B400000000006749F8B5040060681600000DFF +:10F1C4001F000840884201D100250EE0010004D14F +:10F1D4002000FFF725F80128F6DA61685E4A0A4044 +:10F1E4005E49114361605E49451A03CC32003B001D +:10F1F400083CFAF7EBFB03C4083C2904091420007B +:10F20400FFF76EF8F2BC08BC18470000FBB5140009 +:10F214001F0082B0002C06D002A803C800220023DD +:10F2240000F0D8F905D102A803C805B0F0BC08BCA9 +:10F23400184747496A46002003C2002C4AD5604259 +:10F244000400C0464BA608250EE0E00709D5684631 +:10F2540003C802000B0003CE083EFAF7B7FB6A4668 +:10F2640003C2640808366D1E002C01D0002DECD1B9 +:10F2740003983849000D0840884201D100250EE06A +:10F28400010004D102A8FEF7CBFF0128F6DA0399A6 +:10F29400314A0A403149114303913149451A02A8C0 +:10F2A40003C86A460CCAFAF78FFC02AA03C22904EF +:10F2B400091402A8FFF714F8050036D5002CB2D0C3 +:10F2C40028A20CCA02A8FFF775FF05002DD5641EFD +:10F2D400F6D1A8E7012C28DB26A60825E00709D5E6 +:10F2E400684603C802000B0003CE083EFAF76EFB23 +:10F2F4006A4603C2641008366D1E012C01DB002D22 +:10F30400ECD168460CC8FFF755FF05000DD5012C5C +:10F3140089DB16A20CCA02A8FFF74CFF050004D52E +:10F32400641E012C00DA7EE7F3E72D042D1402D0CD +:10F33400012D00D077E7FFF7B5FD22210160002FF2 +:10F3440000D170E738680121014339606BE70000A0 +:10F354000000F03FFF070000FFFF0F800000E03FC8 +:10F36400FE030000436FAC642806C80A3CBF737FE9 +:10F37400DD4F15750000000000002440000000006F +:10F3840000005940000000000088C3400000000055 +:10F3940084D797410080E03779C34143176E05B5A0 +:10F3A400B5B89346F5F93FE9034F384D321D30F9AE +:10F3B4004877825A3CBF737FDD4F1575F5B58DB024 +:10F3C40014980C00C1001E000027081A009024287D +:10F3D40001DB232000903760776001972078302884 +:10F3E40005D10120641C019020783028F9D0C04652 +:10F3F4006BA00025029005E03068401C30600120BD +:10F40400641C01902178162265A0FEF729FE0028CD +:10F414000AD00099A942EFDB0299401A66A1085C60 +:10F4240004A948556D1CEAE720782E2800D1641CF5 +:10F43400002D0BD12078302808D13068641C401E80 +:10F4440030600120019020783028F6D021781622EF +:10F4540053A0FEF705FE002810D00099A94209DB4D +:10F464004FA1401A54A1085C04A9485530686D1C8A +:10F47400401E30600120641C0190E7E70098A84218 +:10F4840015DA04A908180178082903D3401E017865 +:10F49400491C01703068009D07E004A84019401E13 +:10F4A400007800280AD130686D1E401C3060012DA0 +:10F4B400F3DA002D02D16846077401253068800014 +:10F4C4003060019800285AD00720009028000721B6 +:10F4D400F3F790FD0720401A00900721F3F78AFD07 +:10F4E4000297002900D00127012D1DDB029804A9F1 +:10F4F400085C072103900098F3F77CFD002904D1F0 +:10F5040003997F1CB800315006E0039AB800301804 +:10F5140001680901891801600098401C0090029854 +:10F52400401C0290A842E1DB20782021014370298D +:10F5340025D10094641C20782B2801D02D2801D1DA +:10F54400641C00E02B200023002109E0134B9942A6 +:10F5540004DA8B005918490051183039641C01230E +:10F5640022781500303D0A2DF0D32D2801D1080052 +:10F574004142306840183060002B00D1009C0E9846 +:10F58400002805D00198002800D10D9C0E98046035 +:10F5940038000FB0F0BC08BC1847000000E1F505C6 +:10F5A40030313233343536373839616263646566F5 +:10F5B4004142434445460000000102030405060796 +:10F5C40008090A0B0C0D0E0F0A0B0C0D0E0F000090 +:10F5D400704737007847C046020050E11EFF2F11E4 +:10F5E40003C081E18CC090E11EFF2F01030051E1B3 +:10F5F4001EFF2F1180C9A0E381007CE10C003C3187 +:10F604001EFF2FE100B583B00020009000230022EC +:10F6140069467348F2F766F80098002819D000206C +:10F6240001900023002201A96E48F2F7ABF8F7F726 +:10F6340002FF002803D1C0480221016006E0F7F769 +:10F644000FFF002802D1BC48012101600320F3F719 +:10F654005DF90FBC184700B583B00023002201A94F +:10F664006048F2F73FF80198002807D00020009086 +:10F674000023002269465A48F2F784F80FBC184761 +:10F6840000B5B54800680021C943884207D0B24894 +:10F6940000689549096804225143884207D2924878 +:10F6A400006804214843C01CAB4908600EE0AA4826 +:10F6B40000688D490968491C04225143884205D3D6 +:10F6C4008948006804214843A349086008BC1847D6 +:10F6D40010B50024A1480068002810D0042060431D +:10F6E4009F490858002807D0042060439C490858C3 +:10F6F400F2F7C0FA641CF1E798480021016010BCDD +:10F7040008BC18477047704700B596480068002148 +:10F71400C943884203D19348FF21016006E0914820 +:10F724000068FF2802D98F480021016008BC1847EF +:10F73400E0B58D4800680021C943884203D18A4856 +:10F74400FF21016006E088480068FF2802D9864846 +:10F7540000210160844801686846F4F7C9FA6846E4 +:10F76400F8F7F2FC0FBC184700B583B07F48016876 +:10F774006846F3F7B8FB6846F3F795F90FBC1847EA +:10F7840080B57B480068002806D0F4F710FBF4F736 +:10F7940017FB77480021016009BC184780B57548FC +:10F7A4000068002804D0F4F73BFE72480021016091 +:10F7B40009BC184700B583B00023002201A96E4894 +:10F7C400F1F790FF042101A8F8F7F8FD0090002359 +:10F7D400002269466948F1F7D5FF0FBC18470000BD +:10F7E400B4080100D409010080B500230022694651 +:10F7F4006148F1F777FFF4F737FF6149884214D184 +:10F80400009860490968884209D05E4802680D2161 +:10F814000020F4F783FA5C48F5F703F961E0F5F7A3 +:10F8240046F95A48F5F7FDF85BE0F4F71DFF58492F +:10F83400884219D1009853490968884209D051482F +:10F8440002680D210020F4F769FA4F48F5F7E9F84A +:10F8540047E0424801210160FFF73AFFF5F727F935 +:10F864004C48F5F7DEF83CE0F4F7FEFE4A498842DE +:10F8740019D1009843490968884209D0414802686F +:10F884000D210020F4F74AFA3F48F5F7CAF828E0BA +:10F89400384801210160FFF781FFF5F708F93F4877 +:10F8A400F5F7BFF81DE0F4F7DFFE3D49884218D1B3 +:10F8B400009834490968884209D0324802680D2109 +:10F8C4000020F4F72BFA3048F5F7ABF809E02848A4 +:10F8D40001210160FFF754FFF5F7E9F83148F5F726 +:10F8E400A0F809BC184700003C55004000B583B09F +:10F8F400244800682C4988421CD122480021016018 +:10F904002A48009004216846F8F758FD0190002326 +:10F91400002269461848F1F735FF0023002201A9A7 +:10F924001648F1F72FFFF5F7C2F8F5F7C0F81748B6 +:10F93400F5F777F80FBC1847A455004080B51C486C +:10F944000068002805D00220F2F7E0FF18480021E3 +:10F95400016009BC18470000405500404455004070 +:10F9640040010100505500405455004024550040CA +:10F97400585500405C550040D412010004130100A6 +:10F98400105601006055004080580100A056010047 +:10F9940070560100BC580100A0530100EC5801004E +:10F9A400D05301001C590100CD6CAC005704000079 +:10F9B40064550040000005800F800A001B801E0073 +:10F9C40014001180338036003C00398028002D80DB +:10F9D40027802200638066006C00698078007D8047 +:10F9E40077807200500055805F805A004B804E0033 +:10F9F40044004180C380C600CC00C980D800DD80AB +:10FA0400D780D200F000F580FF80FA00EB80EE0092 +:10FA1400E400E180A000A580AF80AA00BB80BE0006 +:10FA2400B400B180938096009C00998088008D80FA +:10FA340087808200838186018C01898198019D8160 +:10FA440097819201B001B581BF81BA01AB81AE014A +:10FA5400A401A181E001E581EF81EA01FB81FE01BE +:10FA6400F401F181D381D601DC01D981C801CD81B2 +:10FA7400C781C201400145814F814A015B815E011A +:10FA840054015181738176017C01798168016D8112 +:10FA940067816201238126012C01298138013D817E +:10FAA40037813201100115811F811A010B810E016A +:10FAB40004010181038306030C03098318031D83D6 +:10FAC40017831203300335833F833A032B832E03BA +:10FAD40024032183600365836F836A037B837E032E +:10FAE40074037183538356035C03598348034D8322 +:10FAF40047834203C003C583CF83CA03DB83DE038A +:10FB0400D403D183F383F603FC03F983E803ED8381 +:10FB1400E783E203A383A603AC03A983B803BD83ED +:10FB2400B783B203900395839F839A038B838E03D9 +:10FB340084038183800285828F828A029B829E0253 +:10FB440094029182B382B602BC02B982A802AD8249 +:10FB5400A782A202E382E602EC02E982F802FD82B5 +:10FB6400F782F202D002D582DF82DA02CB82CE02A1 +:10FB7400C402C182438246024C02498258025D8219 +:10FB840057825202700275827F827A026B826E0201 +:10FB940064026182200225822F822A023B823E0275 +:10FBA40034023182138216021C02198208020D8269 +:10FBB4000782020202000636000000000000000076 +:10FBC4000000000000000000000000000000000031 +:10FBD4000000000000000000000000000000000021 +:10FBE4000000000000000000000000000000000011 +:10FBF4000000000000000000000000000000000001 +:10FC040000000000000000000000000000000000F0 +:10FC140000000000000000000000000000000000E0 +:10FC240000000000000000000000000000000000D0 +:10FC340000000000000000000000000000000000C0 +:10FC440000000000000000000000000000000000B0 +:10FC540000000000000000000000000000000000A0 +:10FC64000000000000000000000000000000000090 +:10FC74000000000000000000000000000000000080 +:10FC84000000000000000000000000000000000070 +:10FC94000000000000000000000000000000000060 +:10FCA4000000000000000000000000000000000050 +:10FCB4000000000000000100020001000300010038 +:10FCC4000200010004000100020001000300010021 +:10FCD4000200010005000100020001000300010010 +:10FCE4000200010004000100020001000300010001 +:10FCF40002000100060001000200010003000100EF +:10FD040002000100040001000200010003000100E0 +:10FD140002000100050001000200010003000100CF +:10FD240002000100040001000200010003000100C0 +:10FD340002000100070001000200010003000100AD +:10FD440002000100040001000200010003000100A0 +:10FD5400020001000500010002000100030001008F +:10FD64000200010004000100020001000300010080 +:10FD7400020001000600010002000100030001006E +:10FD84000200010004000100020001000300010060 +:10FD9400020001000500010002000100030001004F +:10FDA4000200010004000100020001000300010040 +:10FDB4000200010000C09FE51CFF2FE17DFE000052 +:10FDC40000502DE9FAFFFFEB0020A0E1000092E5CE +:10FDD4000030E0E3030050E10400000A0210A0E157 +:10FDE4000200A0E3563412EF0000A0E3000082E515 +:10FDF400040092E5030050E10400000A041082E2CA +:10FE04000200A0E3563412EF0000A0E3040082E5F0 +:10FE14000140BDE81EFF2FE110402DE910D04DE256 +:10FE24000040A0E1E2FFFFEB0020A0E1040192E723 +:10FE3400010070E30B00001A34108FE200108DE50E +:10FE4400000054E30010A0030410A01304108DE577 +:10FE54000310A0E308108DE50D10A0E10100A0E35C +:10FE6400563412EF040182E710D08DE21040BDE851 +:10FE74001EFF2FE13A74740000487047480A00409E +:10FE84000D0A0D0A2D2D2D2D2D2D2D2D2D2D2D2D24 +:10FE94002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8E +:10FEA4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7E +:10FEB4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6E +:10FEC4002D0D0A53746174697374696B61206F62D8 +:10FED40073686179612E204B6F726F746B69652052 +:10FEE40073636865746368696B692E0D0A2D2D2D23 +:10FEF4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2E +:10FF04002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D +:10FF14002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D +:10FF24002D2D2D2D2D2D2D2D2D2D0D0A00000000F4 +:10FF34000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2D30 +:10FF44002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDD +:10FF54002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCD +:10FF64002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0DDD +:10FF74000A53746174697374696B6120706F206BC8 +:10FF8400616E616C616D2E204B6F726F746B69656D +:10FF94002073636865746368696B692E0D0A2D2D7F +:10FFA4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7D +:10FFB4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6D +:10FFC4002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D5D +:10FFD4002D2D2D2D2D2D2D2D2D2D2D0D0A00000017 +:10FFE4000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2D80 +:0CFFF4002D2D2D2D2D2D2D2D2D2D2D2DE5 +:020000040001F9 +:100000002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D20 +:100010002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D10 +:100020002D2D2D0D0A53746174697374696B6120F1 +:10003000706F206B616E616C616D2E20446C696E17 +:100040006E79652073636865746368696B692E0DEA +:100050000A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DF3 +:100060002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DC0 +:100070002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DB0 +:100080002D2D2D2D2D2D2D2D2D2D2D2D2D2D0D0AE3 +:10009000000000000D0A2D2D2D2D2D2D2D2D2D2D87 +:1000A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D80 +:1000B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D70 +:1000C0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D60 +:1000D0002D2D2D0D0A53746174697374696B612041 +:1000E0006F6273686179612E20446C696E6E796508 +:1000F0002073636865746368696B690D0A2D2D2D23 +:100100002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1F +:100110002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0F +:100120002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DFF +:100130002D2D2D2D2D2D2D2D2D2D0D0A00000000E6 +:10014000940A0100640701002408010084080100EA +:10015000B4080100340A0100D4090100C40A0100F6 +:10016000F40A0100240B0100540B0100840B010070 +:10017000B40B0100E40B0100140C0100440C01005D +:10018000740C0100A40C0100D40C0100040D01004A +:10019000340D0100640D0100940D0100C40D010037 +:1001A000F40D0100440F0100740F0100040A010066 +:1001B0001412010054080100D4120100E4140100DB +:1001C000E40801004409010074090100A4090100C8 +:1001D000F413010024140100000000000D0A2D2D6D +:1001E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3F +:1001F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2F +:100200002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1E +:100210002D2D2D2D2D2D2D2D2D2D2D0D0A4B7570A8 +:1002200075726F707269656D6E696B2E0D0A2D2D7A +:100230002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DEE +:100240002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDE +:100250002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCE +:100260002D2D2D2D2D2D2D2D2D2D2D0D0A00000088 +:100270000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2DF1 +:100280002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9E +:100290002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8E +:1002A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D9E +:1002B0000A5A6875726E616C20736F62797469791D +:1002C0000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2DA1 +:1002D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4E +:1002E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3E +:1002F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D4E +:100300000A0000000D0A2D2D2D2D2D2D2D2D2D2D0A +:100310002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D +:100320002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DFD +:100330002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DED +:100340002D2D2D0D0A5A6875726E616C206F7368C1 +:1003500069626F6B0D0A2D2D2D2D2D2D2D2D2D2D1F +:100360002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DBD +:100370002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DAD +:100380002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9D +:100390002D2D2D0D0A00000001020304050607089B +:1003A000090A0B1112131415161718191A1B1C1D04 +:1003B0001F202122232425283335363738393A3C6B +:1003C0003E3F4041424344454647484A4B4C4D4ED0 +:1003D0004F5051525354565758595B5C5D5E5F60A5 +:1003E0006162636465666768696A6B6C6D6E6F7085 +:1003F0007172737475767778797A7B7C7D7E7F8075 +:100400008182838485868788898A8B8C8D8E8F9064 +:1004100091929394A0A1A2A3A4A5A6A7A8A9AAB0CB +:10042000B1B2C0C1C2C3C40000000FE11F00C0E3ED +:10043000130080E300F021E154D09FE51F00C0E3EA +:100440001B0080E300F021E148D09FE51F00C0E3DE +:10045000170080E300F021E13CD09FE51F00C0E3DE +:10046000110080E300F021E130D09FE51F00C0E3E0 +:10047000120080E300F021E124D09FE51F00C0E3DB +:100480001F0080E300F021E118D09FE518009FE5F0 +:1004900010FF2FE1405B0040905C0040A05C0040FA +:1004A000805C0040405C0040405A0040A0170100C2 +:1004B000BC5B0100283D0040C85B0100683D004076 +:1004C000004D0100A83D0040D45B0100E83D004024 +:1004D000E05B0100283E0040EC5B0100683E00400C +:1004E000104D0100A83E0040D8380100E83E004011 +:1004F000204D0100283F0040304D0100683F004082 +:10050000404D0100A83F004010402DE940109FE5FC +:100510000F1081E03C1081E238409FE50F4084E0FD +:10052000344084E2040051E10700000A002091E514 +:10053000040081E2011082E00FE0A0E111FF2FE151 +:100540000010A0E1040051E1F7FFFF1A1040BDE8E0 +:100550001EFF2FE1D4120000F412000080B5F8F75E +:1005600052FBFBF759FD0523044A00210448F7F725 +:1005700089FBFBF7AAFD09BC18470000243900409D +:100580008505010010B50400F8F728FAFA2080006C +:10059000F6F7A0F9F9F768FFFAF742F8FCF7F8FB6D +:1005A000F0F7C8F9FA208000F6F794F9FAE7380076 +:1005B0000102060A0B11131417181A1C1D1F2324FD +:1005C00038393A3C3E3F404142434447484C4E5103 +:1005D000525354575B64676A6B70717475767778A1 +:1005E000797B808182838788898A8BA0A1A3A4A537 +:1005F000A6A7A8A9C2C4000010402DE910D04DE262 +:100600000230A0E100008DE504108DE50040A0E17E +:1006100008308DE50120A0E30D10A0E10500A0E366 +:10062000563412EF000043E00410A0E10000A0E106 +:1006300010D08DE21040BDE81EFF2FE141A042A185 +:10064000E045A3A4A5034BA74D484FA8504354A988 +:10065000AA58E1ABACE2ADAE02AFB0B161B2B3B497 +:10066000E365B6B7B8B9BABBBCBD6FBE7063BF793E +:10067000E478E5C0C1E6C2C3C4C5C6C77C205673D2 +:1006800065676F2064656E65672C207275622E2029 +:100690007C20567365676F207365616E736F76207B +:1006A0007C20567365676F206E617261626F746B38 +:1006B0006120683A6D3A73200D0A000030402DE940 +:1006C0000CD04DE20140A0E10250A0E10100A0E306 +:1006D000D1FDFFEB00008DE504408DE508508DE570 +:1006E0000D10A0E10500A0E3563412EF000045E034 +:1006F0000CD08DE23040BDE81EFF2FE17C204B6125 +:100700006E616C207C2044656E65672C207275627A +:100710002E207C205365616E736F76207C204E61A5 +:100720007261626F746B6120683A6D3A730D0A00F2 +:10073000000051E30000A0030000001A1EFF2FE19B +:1007400000502DE9010050E3020050130100001A8F +:10075000D9FFFFEB000000EAA6FFFFEB0240BDE877 +:100760001EFF2FE10002000000000000000000005A +:100770003C550040305D010000000000000000001A +:100780002850010001000000A00900400100000005 +:100790000000000000020000000000000000000057 +:1007A0003C550040305D01000000000000000000EA +:1007B0008049010001000000A00900400100000084 +:1007C0000000000000020000000000000000000027 +:1007D0003C550040305D01000000000000000000BA +:1007E0003450010001000000A00900400100000099 +:1007F00000000000000201000000000000000000F6 +:10080000D6190000C85D01000000000000000000D3 +:1008100000000000000000000000000000000000D8 +:1008200000000000000201010A000000640701004E +:1008300004000000385D010000000000040000001A +:100840004050010001000000F809004000000000D5 +:1008500000000000000201010A000000640701001E +:10086000F4000000505D01000000000004000000E2 +:100870004C50010001000000000A00400000000090 +:100880000000000000020100000000000000000065 +:100890001C060000605D0100000000000400000074 +:1008A0005850010001000000080A0040010000004B +:1008B0000100000000020100000000000000000034 +:1008C00024060000785D010009F600000400000025 +:1008D000805D010001000000100A004001000000DE +:1008E0000000000000020100000000000000000005 +:1008F00040060000885D01000000000004000000C8 +:100900006450010001000000180A004001000000CE +:1009100000000000010200000000000000000000D4 +:10092000A45500400000000000000000000000008E +:10093000905D010001000000E0090040010000009E +:1009400000000000000201000000000000000000A4 +:1009500048060000885D010000000000040000005F +:100960009049010001000000180A00400100000049 +:100970000000000000020100000000000000000074 +:100980004C060000885D010000000000040000002B +:100990007050010001000000180A00400100000032 +:1009A000000000000007010000000000000000003F +:1009B00050060000985D01000000000000000000EB +:1009C000A05D010000000000000000000100000028 +:1009D000090000000002010000000000000000000B +:1009E00020060000A85D01005BF600000400000086 +:1009F0007C50010001000000200A004001000000BE +:100A000000000000000201000000000000000000E3 +:100A100034060000B05D010000000000000000008E +:100A200088500100000000000000000001000000EC +:100A300001000000000201000000000000000000B2 +:100A400028060000B85D010000000000040000005E +:100A5000F05F010001000000280A004001000000D2 +:100A60000000000000020100000000000000000083 +:100A70003C060000C05D0100000000000400000012 +:100A8000A049010001000000300A00400100000000 +:100A900000000000010200010A00000064070100DC +:100AA000AC530040C85D01000000000004000000DD +:100AB0009450010000000000000000000100000050 +:100AC00000000000000201010A00000064070100AC +:100AD0002C000000D05D01000000000004000000B8 +:100AE000B04901000000000000000000010000000B +:100AF0001E000000000201010A000000640701005E +:100B000054000000D85D0100000000000400000057 +:100B1000743301000000000000000000010000002C +:100B200003000000000201010A0000006407010048 +:100B30007C000000E05D01000000000004000000F7 +:100B4000A0500100000000000000000001000000B3 +:100B500014000000000201010A0000006407010007 +:100B6000A4000000E85D0100000000000400000097 +:100B7000AC50010000000000000000000100000077 +:100B800005000000000201010A00000064070100E6 +:100B9000CC000000F05D0100000000000400000037 +:100BA000B850010001000000C80900400100000029 +:100BB0000000000000020000000000000000000033 +:100BC00040550040185E010085F60000000000005E +:100BD0007B60010001000000F807004001000000F8 +:100BE0000000000000020000000000000000000003 +:100BF00040550040185E010085F60000000000002E +:100C00007B600100010000009C0800400100000022 +:100C1000000000000002010128000000B40B0100E8 +:100C20003C040000205E0100000000000400000001 +:100C3000C45001000000000000000000000000009F +:100C40000F0000000002010128000000E40B010079 +:100C50009C030000285E010000000000040000006A +:100C6000D050010000000000000000000000000063 +:100C70000F0000000002010128000000B40B010079 +:100C80007C050000305E0100000000000400000050 +:100C9000C04901000000000000000000000000004A +:100CA000010000000002010128000000E40B010027 +:100CB000DC040000385E01000000000004000000B9 +:100CC000D04901000000000000000000000000000A +:100CD000010000000002010128000000E40B0100F7 +:100CE0001C010000405E0100000000000400000044 +:100CF000DC500100000000000000000000000000C7 +:100D0000000000000002010128000000E40B0100C7 +:100D1000BC010000485E010000000000040000006B +:100D2000505E010000000000000000000100000013 +:100D3000180000000002010128000000B40B0100AF +:100D40005C020000585E010000000000040000008A +:100D5000E85001000000000000000000000000005A +:100D6000000000000002010128000000B40B010097 +:100D7000FC020000605E01000000000004000000B2 +:100D8000685E01000000000000000000010000009B +:100D90001800000000020000000000000000000039 +:100DA00048550040705E010009F700000000000097 +:100DB000785E010001000000380A004001000000D8 +:100DC0000000000000020000000000000000000021 +:100DD0004C550040705E01000BF700000000000061 +:100DE000885E010001000000380A00400100000098 +:100DF00000000000000200000000000000000000F1 +:100E000050550040905E01000DF70000000000000A +:100E1000F45001000000000000000000010000008C +:100E2000000000000102010100010000F40D0100BA +:100E3000D2070000985E01000000000008000000DA +:100E40000000000001000000000000400000000061 +:100E5000000000000102010100010000F40D01008A +:100E6000D2070000985E01000000000008000000AA +:100E70000000000001000000A80200400000000087 +:100E8000000000000102010100010000F40D01005A +:100E9000D2070000985E010000000000080000007A +:100EA00000000000010000005005004000000000AC +:100EB000000000000105010100010000F40D010027 +:100EC000CE07000000000000000000000800000045 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000020000000000000000000000 +:100EF00054550040A05E010035F7000000000000DE +:100F0000005101000000000000000000010000008E +:100F1000000000000105010100010000E40E0100D5 +:100F2000CE0F000000000000000000000A000000DA +:100F300000000000000000000000000000000000B1 +:100F4000000000000105000000000000000000009B +:100F500024550040000000000000000000000000D8 +:100F60000000000000000000000000000000000081 +:100F7000000000000005000000000000000000006C +:100F800024550040000000006DF700000000000044 +:100F90000000000000000000000000000000000051 +:100FA000000000000102010000000000000000003D +:100FB000D00600000000000000000000000000005B +:100FC000A85E01000000000000000000000000001A +:100FD000000000000102010000000000000000000D +:100FE000D806000000000000000000000000000023 +:100FF0000C51010000000000000000000000000093 +:1010000000000000010601000000000000000000D8 +:10101000D4060000000000000000000000000000F6 +:10102000B05E0100000000000000000000000000B1 +:1010300000000000010201000000000000000000AC +:10104000B8070000000000000000000000000000E1 +:10105000A85E010000000000000000000000000089 +:10106000000000000102010000000000000000007C +:10107000C0070000000000000000000000000000A9 +:101080000C51010000000000000000000000000002 +:101090000000000001060100000000000000000048 +:1010A000BC0700000000000000000000000000007D +:1010B000B05E010000000000000000000000000021 +:1010C00000000000010201010A0000009407010075 +:1010D00058060000000000000000000004000000AE +:1010E000A85E0100000000000000000000000000F9 +:1010F00000000000010201010A0000009407010045 +:10110000A80600000000000000000000040000002D +:101110000C51010000000000000000000000000071 +:1011200000000000010601010A0000009407010010 +:101130008006000000000000000000000400000025 +:10114000B05E010000000000000000000000000090 +:1011500000000000010201010A00000094070100E4 +:101160004007000000000000000000000400000034 +:10117000A85E010000000000000000000000000068 +:1011800000000000010201010A00000094070100B4 +:1011900090070000000000000000000004000000B4 +:1011A0000C510100000000000000000000000000E1 +:1011B00000000000010601010A0000009407010080 +:1011C00068070000000000000000000004000000AC +:1011D000B05E010000000000000000000000000000 +:1011E00000000000000201000000000000000000FC +:1011F0002C060000B85E01000000000004000000A2 +:101200001851010001000000EC090040010000003D +:1012100001000000000201000000000000000000CA +:1012200038060000C05E010000000000040000005D +:10123000C85E010001000000400A004000000000FC +:10124000010000000002010000000000000000009A +:1012500030060000D85E010000000000040000001D +:101260007C60010001000000540A00400000000002 +:10127000000000000002010000000000000000006B +:10128000C607000000000000000000000000000091 +:10129000000000000000000000000000000000004E +:1012A000000000000002010000000000000000003B +:1012B000CA0700000000000000000000000000005D +:1012C000000000000000000000000000000000001E +:1012D000000000000002010000000000000000000B +:1012E000CE190000E05E0100B9F700000000000028 +:1012F000305101000000000000000000000000006C +:10130000570400000002010000000000000000007F +:10131000D2190000000000000000000000000000E2 +:1013200000000000000000000000000000000000BD +:1013300000000000000200000000000000000000AB +:1013400060550040E05E0100EDF700000000000085 +:10135000305101000000000000000000000000000B +:10136000000000000002000000000000000000007B +:1013700060550040E05E0100EDF700000000000055 +:101380003C510100000000000000000000000000CF +:10139000000000000002000000000000000000004B +:1013A00060550040E85E0100F1F800000000000018 +:1013B000F05E0100000000000000000000000000DE +:1013C000000000000002000000000000000000001B +:1013D00060550040E05E0100EDF7000000000000F5 +:1013E0004851010000000000000000000000000063 +:1013F00000000000000200000000000000000000EB +:1014000064550040885D010041F9000004000000BF +:101410005451010001000000300A004001000000AA +:1014200000000000000200000000000000000000BA +:1014300068550040F85E0100000000000000000058 +:10144000E0490100010000004009004001000000E7 +:101450000000000001020001180000002414010037 +:101460009051004000000000000000000400000057 +:10147000F049010000000000000000000000000032 +:101480000000000001020101180000002414010006 +:10149000DC06000000000000000000000400000066 +:1014A000005F0100000000000000000000000000DC +:1014B0000000000001020100000000000000000028 +:1014C0003C070000000000000000000000000000D9 +:1014D000605101000000000000000000000000005A +:1014E00000000000000201000000000000000000F9 +:1014F00054060000085F010000000000000000002A +:101500006C5101000000000000000000010000001C +:1015100000000000000201000100000000000000C7 +:10152000DA190000000000000000000004000000C4 +:1015300000000000000000000000000000000000AB +:101540000000000000020100010000000000000097 +:10155000DE19000000000000000000000400000090 +:10156000000000000000000000000000000000007B +:101570000000000000020100010000000000000067 +:10158000E21900000000000000000000040000005C +:10159000000000000000000000000000000000004B +:1015A000000000007C2020202020204E6F6D696EFE +:1015B000616C2C207275622E20202020207C20203F +:1015C0002020204B6F6C696368657374766F0D0A19 +:1015D00000000000205501002C5501003855010085 +:1015E00044550100505501005C550100685501004B +:1015F00074550100805501008C5501000000000069 +:1016000038B500250400ED43AC420AD068460470AA +:1016100001226946012000F009F8012801D12000CB +:1016200000E0280032BC08BC184739007847C046A3 +:1016300000502DE9000050E30100004A3BFCFFEBA5 +:10164000000000EA0000A0E30240BDE81EFF2FE119 +:101650004B72697469636865736B617961206F733C +:101660006869626B61206B757075726F7072696505 +:101670006D6E696B610000004E656B726974696321 +:101680006865736B617961206F736869626B612053 +:101690006B757075726F707269656D6E696B6100E4 +:1016A00010B400210268001D002A0BD00368001D41 +:1016B000DC0702D54C46641E1B1919601B1D121F46 +:1016C000FBD1EFE710BC70470A4350555F41524DC4 +:1016D0005F455843455054494F4E2023256420749C +:1016E0007261707065642E0A000000004F736869B3 +:1016F000626B6120737679617A692063206B757003 +:1017000075726F707269656D6E696B6F6D00000048 +:10171000567962726F73206B757075727920707272 +:1017200069207472616E73706F727469726F766B18 +:10173000650000007C2020202020202531336420FB +:10174000202020207C2020202020253131642020D2 +:10175000202020200D0A00005265706F72742066F0 +:10176000726F6D20736F6C617269756D2064657640 +:101770006963652069642025642E000000C09FE530 +:101780001CFF2FE1C517010000C09FE51CFF2FE1E2 +:101790005D05010000C09FE51CFF2FE1C917010096 +:1017A0000100A0E3F4FFFFEB000050E355FBFF1B3B +:1017B0000000A0E3F3FFFFEBF5FFFFEB030000EBFE +:1017C000FDFFFFEA0120704780B500F011F8C04628 +:1017D00000502DE97AF9FFEB2620A0E3802B82E36D +:1017E0000210A0E11800A0E3563412EFFBFFFFEA5D +:1017F0007847C0460070B0E10700B0E1F3FFFFEBAF +:10180000FDFFFFEA030008001968002A02D1491E03 +:10181000196070470878002802D10020C043704743 +:10182000481C18600878704779FEFFFFDC4B000009 +:10183000600A0040000000002370FFFF600A000003 +:101840004448000000000040000000005679627229 +:101850006F73206B757075727920706F206D616782 +:101860002E6461746368696B75000000567962725A +:101870006F73206B757075727920706F2069646565 +:101880006E746966696B616369690000567962729A +:101890006F73206B757075727920706F207665722A +:1018A0006966696B6163696900000000567962725C +:1018B0006F73206B757075727920706F206F707404 +:1018C0002E6461746368696B7500000056796272FA +:1018D0006F73206B757075727920706F20656D6BFA +:1018E0002E6461746368696B750000004F736869EA +:1018F000626B6120736B6F726F73746920747261B5 +:101900006E73702E6D6F746F726100004F73686933 +:10191000626B61206D6568616E697A6D617679725E +:1019200061766E6976616E69796100004F736869EE +:10193000626B6120465220307843334F736869628E +:101940006B6120465220307843340000207C2020F8 +:1019500050656368617427206F74636865746120E3 +:10196000697A20627566657261200000207C202003 +:101970004F736869626B61206F74707261766B6916 +:1019800020652D6D61696C2000000000207C202006 +:10199000452D6D61696C206F74707261766C656E37 +:1019A0006F207573706573686E6F2000C0570100FB +:1019B000CC570100D8570100E4570100F05701004F +:1019C000FC57010008580100000000004B757075BD +:1019D000726F707269656D6E696B2062796C2070D0 +:1019E0007573742E0D0A0D0A000000002530326454 +:1019F0003A253032643A2530326420253032642F63 +:101A0000253032642F25303264000000323025301A +:101A100032642F253032642F253032642025303255 +:101A2000643A253032643A25303264005679627265 +:101A30006F73206B757075727920706F207A61708A +:101A400072657475000000004F736869626B6120F5 +:101A50007374656B65726E6F676F206D6F746F72F4 +:101A6000610000004F736869626B61207376796171 +:101A70007A692073206D6F64656D6F6D00000000E2 +:101A800060090000C012000080250000004B00002B +:101A90000096000000E1000000C20100CC540100EB +:101AA000D8540100E4540100FC540100F05401003A +:101AB00008550100000000003C5701004857010094 +:101AC00054570100605701006C570100785701001E +:101AD0000000000041545E534943533D302C636F76 +:101AE0006E547970652C47505253300D0A00000037 +:101AF00041545E534943533D302C696E61637454C5 +:101B00004F2C223230220D0A0000000041545E5357 +:101B10004953533D302C737276547970652C22539F +:101B20006D7470220D0A000041545E534953533DB9 +:101B3000302C616C7068616265742C2231220D0A50 +:101B40000000000041545E534953533D302C616402 +:101B500064726573732C222573220D0A0000000045 +:101B600041545E534953533D302C746370506F722F +:101B7000742C222573220D0A000000004B7570752D +:101B8000726F707269656D6E696B20707573742EFB +:101B90000D0A0D0A0000000054657374206D657312 +:101BA000736167652066726F6D20736F6C61726917 +:101BB000756D2E0054657374206D65737361676570 +:101BC0002E204465766963652069642025642E00B3 +:101BD000496E636173736174696F6E2E204465761C +:101BE0006963652069642025642E00000000000000 +:101BF0001F003B005A0078009700B500D400F300A6 +:101C0000110130014E01000038B505000C00200024 +:101C1000FFF7F6FCA04200D00025280032BC08BC2B +:101C200018472300EA2FEF3A3531682DEEF8E8E146 +:101C3000EAE020F1EAEEF02E00000000D4D03A30C5 +:101C400041682DF4EEF0ECE0F220E4E0EDEDFBF580 +:101C500000000000D4D03A3042682DEDE5E8F1EF05 +:101C6000F02EFFF7E5E9EAE000000000D4D03A31B9 +:101C700037682DCEF8E8E1EAE020EDEEECE5F0E0A3 +:101C800000000000D4D03A3232682DCDE5E2E5F014 +:101C9000EDE0FF20E4E0F2E000000000D4D03A34B0 +:101CA00046682DCDE5E2E5F0EDFBE920EFE0F0EE52 +:101CB000EBFC0000D4D03A3634682DD4CF20EEF2BD +:101CC000F1F3F2F1F2E2F3E5F2000000D4D03A3899 +:101CD00044682DCEF2F0E8F6E0F2E5EBFCEDFBE92E +:101CE00000000000D4D03A3933682DC2EEF1F1F291 +:101CF000E0EDEEE2EBE5EDE8E5000000EDE0EAEE18 +:101D0000EFEBE5EDE8FF20EFEE20EDE0EBEEE3E0BA +:101D1000EC000000EDE0EAEEEFEBE5EDE8E9203263 +:101D200020E220F1ECE5EDE500000000EDE0EAEE58 +:101D3000EFEBE5EDE8E9203320E220F1ECE5EDE51D +:101D400000000000EDE0EAEEEFEBE5EDE8E920341D +:101D500020E220F1ECE5EDE500000000E7EDE0F722 +:101D6000E5EDE8E520E220EFEEEBE520E4EBE8ED41 +:101D7000FB000000E4E8E0EFE0E7EEEDE020E8F251 +:101D8000EEE3E020F7E5EAE000000000EFEE20E2FD +:101D9000EEE7E2F0E0F2E0EC20EFEEEAF3EFEEEA5D +:101DA00000000000EBE8ECE8F220EEEFE5F0E0F6F2 +:101DB000E8E920E220F7E5EAE5000000CDE5EAEEFB +:101DC000F0F02EF4EEF0ECE0F220EAEEECE0EDE4E0 +:101DD000FB000000CDE5E2E5F0EDFBE520E4E0F2FC +:101DE000E020E820E2F0E5ECFF200000CDE5F22065 +:101DF000E7E0EFF0EEF8E5EDEDFBF520E4E0EDEDEA +:101E0000FBF52000567962726F73206B75707572E6 +:101E10007920706F20646C696E6500005A616D698D +:101E20006E2076206B757075726F707269656D6E5D +:101E3000696B65004F736869626B61207472616ED3 +:101E400073702E6D6F746F72610000004F7368695C +:101E5000626B61206D61676E2E6461746368696B8B +:101E6000610000004F736869626B6120656D6B2EC5 +:101E70006461746368696B6100000000D1EFE0F198 +:101E8000E8E1EE20E7E020EFEEEAF3EFEAF32121CC +:101E900021000000D3F1EBF3E3E820F1EEEBFFF0DB +:101EA000E8FF2C20ECE8ED2E00000000207C202034 +:101EB00050656368617427205A2D6F746368657478 +:101EC00061200000207C2020506563686174272019 +:101ED000582D6F746368657461200000207C202099 +:101EE0004E657665726E6979207061726F6C27201D +:101EF00000000000E0520100EC520100F852010025 +:101F0000045301001053010000000000345301008D +:101F1000405301004C530100585301006453010029 +:101F200000000000A4550100B0550100BC5501009F +:101F3000C8550100D455010000000000AC56010056 +:101F4000B8560100C4560100D0560100DC5601000D +:101F500000000000F4560100005701000C5701007A +:101F600018570100245701000000000041545E533F +:101F70004943533D302C646E73312C222573220D5E +:101F80000A00000041545E534943533D302C7061B8 +:101F9000737377642C222573220D0A0041545E531B +:101FA0004943533D302C61706E2C222573220D0A5B +:101FB0000000000041545E534943533D302C75737B +:101FC00065722C222573220D0A00000041545E53D5 +:101FD0004953533D302C636F6E49642C2230220DDF +:101FE0000A00000041545E534953533D302C757331 +:101FF00065722C222573220D0A00000041545E53A5 +:102000004953533D302C7061737377642C222573D0 +:10201000220D0A0041545E534953533D302C736DD9 +:10202000417574682C2231220D0A000041545E5320 +:102030004953533D302C736D46726F6D2C222573BE +:10204000220D0A0041545E534953533D302C736DA9 +:10205000526370742C222573220D0A0041545E5382 +:102060004953533D302C736D5375626A2C2225738E +:10207000220D0A00686A6C747A4C00006E616E0072 +:102080004E414E00696E6600494E4600CEEFEBE0D1 +:10209000F7E5EDEE2025643A2530326400000000BB +:1020A000CFD0C5C2DBD8C5CDCE20CCC0CAD12EC2C0 +:1020B000D02E0000CFCECB62C7CEC2C0CDC8C520C7 +:1020C000D3D1CBD3C3CEE900D0C0C1CED2C020CDB6 +:1020D000C5C2CEC7CCCEC6CDC00000002121212173 +:1020E0002121212121212121212121212100000043 +:1020F000D6C5CDC0202564F0F3E12E2F2564ECE891 +:10210000ED2E0000C0CFCFC0D0C0D220D0C0C1CEF5 +:10211000D2C0C5D200000000C4CBDF20CDC0D7C0E4 +:10212000CBC020D0C0C1CED2DB000000C2DBC1C515 +:10213000D0C8D2C520C4D02ECAC0CDC0CB000000AC +:10214000CAC0CD2E3120CFC5D02E3120C2DBD52E36 +:1021500000000000CAC0CD2E3120CFC5D02E3220C5 +:10216000C2DBD52E00000000CAC0CD2E3120CFC565 +:10217000D02E3320C2DBD52E00000000CAC0CD2EE9 +:102180003120CFC5D02E3420C2DBD52E0000000078 +:10219000CAC0CD2E3220CFC5D02E3120C2DBD52EE5 +:1021A00000000000CAC0CD2E3220CFC5D02E322074 +:1021B000C2DBD52E00000000CAC0CD2E3220CFC514 +:1021C000D02E3320C2DBD52E00000000CAC0CD2E99 +:1021D0003220CFC5D02E3420C2DBD52E0000000027 +:1021E000CAC0CD2E3320CFC5D02E3120C2DBD52E94 +:1021F00000000000CAC0CD2E3320CFC5D02E322023 +:10220000C2DBD52E00000000CAC0CD2E3320CFC5C2 +:10221000D02E3320C2DBD52E00000000CAC0CD2E48 +:102220003320CFC5D02E3420C2DBD52E00000000D5 +:10223000CAC0CD2E3420CFC5D02E3120C2DBD52E42 +:1022400000000000CAC0CD2E3420CFC5D02E3220D1 +:10225000C2DBD52E00000000CAC0CD2E3420CFC571 +:10226000D02E3320C2DBD52E00000000CAC0CD2EF8 +:102270003420CFC5D02E3420C2DBD52E0000000084 +:10228000CAC0CD2E3520CFC5D02E3120C2DBD52EF1 +:1022900000000000CAC0CD2E3520CFC5D02E322080 +:1022A000C2DBD52E00000000CAC0CD2E3520CFC520 +:1022B000D02E3320C2DBD52E00000000CAC0CD2EA8 +:1022C0003520CFC5D02E3420C2DBD52E0000000033 +:1022D000CAC0CD2E3620CFC5D02E3120C2DBD52EA0 +:1022E00000000000CAC0CD2E3620CFC5D02E32202F +:1022F000C2DBD52E00000000CAC0CD2E3620CFC5CF +:10230000D02E3320C2DBD52E00000000CAC0CD2E57 +:102310003620CFC5D02E3420C2DBD52E00000000E1 +:10232000CAC0CD2E3720CFC5D02E3120C2DBD52E4E +:1023300000000000CAC0CD2E3720CFC5D02E3220DD +:10234000C2DBD52E00000000CAC0CD2E3720CFC57D +:10235000D02E3320C2DBD52E00000000CAC0CD2E07 +:102360003720CFC5D02E3420C2DBD52E0000000090 +:10237000CAC0CD2E3820CFC5D02E3120C2DBD52EFD +:1023800000000000CAC0CD2E3820CFC5D02E32208C +:10239000C2DBD52E00000000CAC0CD2E3820CFC52C +:1023A000D02E3320C2DBD52E00000000CAC0CD2EB7 +:1023B0003820CFC5D02E3420C2DBD52E000000003F +:1023C000CAC0CD2E3920CFC5D02E3120C2DBD52EAC +:1023D00000000000CAC0CD2E3920CFC5D02E32203B +:1023E000C2DBD52E00000000CAC0CD2E3920CFC5DB +:1023F000D02E3320C2DBD52E00000000CAC0CD2E67 +:102400003920CFC5D02E3420C2DBD52E00000000ED +:10241000CAC0CD2E313020CFC5D02E3120C2DBD561 +:102420002E000000CAC0CD2E313020CFC5D02E32B4 +:1024300020C2DBD52E000000CAC0CD2E313020CF07 +:10244000C5D02E3320C2DBD52E000000CAC0CD2E51 +:10245000313020CFC5D02E3420C2DBD52E00000075 +:10246000CAC0CD2E3120CFC5D02E3120C1D3C42E2D +:1024700000000000CAC0CD2E3120CFC5D02E3220A2 +:10248000C1D3C42E00000000CAC0CD2E3120CFC55C +:10249000D02E3320C1D3C42E00000000CAC0CD2EE0 +:1024A0003120CFC5D02E3420C1D3C42E000000006F +:1024B000CAC0CD2E3220CFC5D02E3120C1D3C42EDC +:1024C00000000000CAC0CD2E3220CFC5D02E322051 +:1024D000C1D3C42E00000000CAC0CD2E3220CFC50B +:1024E000D02E3320C1D3C42E00000000CAC0CD2E90 +:1024F0003220CFC5D02E3420C1D3C42E000000001E +:10250000CAC0CD2E3320CFC5D02E3120C1D3C42E8A +:1025100000000000CAC0CD2E3320CFC5D02E3220FF +:10252000C1D3C42E00000000CAC0CD2E3320CFC5B9 +:10253000D02E3320C1D3C42E00000000CAC0CD2E3F +:102540003320CFC5D02E3420C1D3C42E00000000CC +:10255000CAC0CD2E3420CFC5D02E3120C1D3C42E39 +:1025600000000000CAC0CD2E3420CFC5D02E3220AE +:10257000C1D3C42E00000000CAC0CD2E3420CFC568 +:10258000D02E3320C1D3C42E00000000CAC0CD2EEF +:102590003420CFC5D02E3420C1D3C42E000000007B +:1025A000CAC0CD2E3520CFC5D02E3120C1D3C42EE8 +:1025B00000000000CAC0CD2E3520CFC5D02E32205D +:1025C000C1D3C42E00000000CAC0CD2E3520CFC517 +:1025D000D02E3320C1D3C42E00000000CAC0CD2E9F +:1025E0003520CFC5D02E3420C1D3C42E000000002A +:1025F000CAC0CD2E3620CFC5D02E3120C1D3C42E97 +:1026000000000000CAC0CD2E3620CFC5D02E32200B +:10261000C1D3C42E00000000CAC0CD2E3620CFC5C5 +:10262000D02E3320C1D3C42E00000000CAC0CD2E4E +:102630003620CFC5D02E3420C1D3C42E00000000D8 +:10264000CAC0CD2E3720CFC5D02E3120C1D3C42E45 +:1026500000000000CAC0CD2E3720CFC5D02E3220BA +:10266000C1D3C42E00000000CAC0CD2E3720CFC574 +:10267000D02E3320C1D3C42E00000000CAC0CD2EFE +:102680003720CFC5D02E3420C1D3C42E0000000087 +:10269000CAC0CD2E3820CFC5D02E3120C1D3C42EF4 +:1026A00000000000CAC0CD2E3820CFC5D02E322069 +:1026B000C1D3C42E00000000CAC0CD2E3820CFC523 +:1026C000D02E3320C1D3C42E00000000CAC0CD2EAE +:1026D0003820CFC5D02E3420C1D3C42E0000000036 +:1026E000CAC0CD2E3920CFC5D02E3120C1D3C42EA3 +:1026F00000000000CAC0CD2E3920CFC5D02E322018 +:10270000C1D3C42E00000000CAC0CD2E3920CFC5D1 +:10271000D02E3320C1D3C42E00000000CAC0CD2E5D +:102720003920CFC5D02E3420C1D3C42E00000000E4 +:10273000CAC0CD2E313020CFC5D02E3120C1D3C458 +:102740002E000000CAC0CD2E313020CFC5D02E3291 +:1027500020C1D3C42E000000CAC0CD2E313020CFFE +:10276000C5D02E3320C1D3C42E000000CAC0CD2E48 +:10277000313020CFC5D02E3420C1D3C42E0000006C +:102780003143683630682DE2FBE1F02EEAF3EFFECC +:10279000F0FB00003143683631682DE2FBE1F02E9A +:1027A000EAF3EFFEF0FB00003143683634682DE2B7 +:1027B000FBE1F02EEAF3EFFEF0FB00003143683658 +:1027C00035682DE2FBE1F02EEAF3EFFEF0FB0000AE +:1027D0003143683636682DE2FBE1F02EEAF3EFFE76 +:1027E000F0FB00003143683637682DE2FBE1F02E44 +:1027F000EAF3EFFEF0FB00003143683638682DE263 +:10280000FBE1F02EEAF3EFFEF0FB00003143683607 +:1028100039682DE2FBE1F02EEAF3EFFEF0FB000059 +:102820003143683643682DE2FBE1F02EEAF3EFFE18 +:10283000F0FB0000EA2FEF3A3433682DE7E0ECE8D4 +:10284000ED20E22000000000EA2FEF3A3533682D3A +:10285000EEF8E8E1EAE020ECE5F52E00EA2FEF3AA9 +:102860003637682DEEF8E8E1EAE020E5ECEA2E00E4 +:10287000D4D03A3031682DEDE5E8F1EFF0E0E2E553 +:10288000ED000000D4D03A3032682DEEF2F1F3F2D0 +:10289000F1F2E2F3E5F20000D4D03A3033682DEEE5 +:1028A000F2F1F3F2F1F2E2F3E5F20000D4D03A30C3 +:1028B00034682DEDE5EAEEF0F02EEF2DF0FB000090 +:1028C000D4D03A3036682DD4CF20E220F0E5E6E8C7 +:1028D000ECE50000D4D03A3037682DEDE5EAEEF0B3 +:1028E000F02EEF2DF0FB0000D4D03A3131682DED01 +:1028F000E520E2E2E5E4E5EDE0000000D4D03A3185 +:1029000032682DE7E0E2EEE4F1EAEEE900000000D3 +:10291000D4D03A3133682DF2E5EAF3F9E0FF20E450 +:10292000E0F2E000D4D03A3138682DCEF8E8E1EAA0 +:10293000E020E4E0F2FB0000D4D03A3139682DCD3C +:10294000E5F220E4E0EDEDFBF5000000D4D03A31F3 +:1029500041682DCEEEF8E8E1EAE020D4CF00000097 +:10296000D4D03A3142682DC7E0E2EEE4F1EAEEE974 +:1029700000000000D4D03A3144682DCFEEE2F0E5FB +:10298000E6E4E5EDE0000000D4D03A3146682DCE13 +:10299000F2F1F3F2F1F2E2F3E5F20000D4D03A32D0 +:1029A00030682DCFE5F0E5EFEEEBEDE5EDE8E50085 +:1029B000D4D03A3231682DCEF8E8E1EAE020F1F3E4 +:1029C000ECECFB00D4D03A3233682DCDE5F220E7B1 +:1029D000E0EFE8F1E8000000D4D03A3238682DC2C8 +:1029E00020D4CF20E1EEEBE5E5000000D4D03A336F +:1029F00033682DCDE5EAEEF0F0E5EAF2EDFBE50017 +:102A0000D4D03A3335682DCDE5EAEEF0F0E5EAF2C0 +:102A1000EDFBE900D4D03A3336682DCDE5EAEEF08F +:102A2000F0E5EAF2EDFBE500D4D03A3338682DCE7C +:102A3000F8E8E1EAE020E220CFC7D300D4D03A336F +:102A400039682DC2EDF3F2F0E5EDEDFFFF00000077 +:102A5000D4D03A3341682DCFE5F0E5EFEEEBEDE56C +:102A6000EDE8E500D4D03A3345682DCFE5F0E5EF49 +:102A7000EEEBEDE5EDE8E500D4D03A3346682DCF36 +:102A8000E5F0E5EFEEEBEDE5EDE8E500D4D03A3426 +:102A900030682DCFE5F0E5EFEEEBEDE5EDE8E50094 +:102AA000D4D03A3431682DCFE5F0E5EFEEEBEDE52B +:102AB000EDE8E500D4D03A3432682DCFE5F0E5EF0B +:102AC000EEEBEDE5EDE8E500D4D03A3433682DCFF8 +:102AD000E5F0E5EFEEEBEDE5EDE8E500D4D03A34D6 +:102AE00034682DCFE5F0E5EFEEEBEDE5EDE8E50040 +:102AF000D4D03A3436682DCDE520F5E2E0F2E0E5B9 +:102B0000F2000000D4D03A3437682DCFE5F0E5EF7D +:102B1000EEEBEDE5EDE8E500D4D03A3438682DCFA2 +:102B2000E5F0E5EFEEEBEDE5EDE8E500D4D03A3485 +:102B300041682DCEF2EAF0FBF220F7E5EA00000052 +:102B4000D4D03A3442682DC1F3F4E5F020F7E5EA39 +:102B5000E0000000D4D03A3443682DCFE5F0E5EF33 +:102B6000EEEBEDE5EDE8E500D4D03A3530682DC860 +:102B7000E4E5F220EFE5F7E0F2FC0000D4D03A35CE +:102B800031682DCFE5F0E5EFEEEBEDE5EDE8E500A2 +:102B9000D4D03A3532682DCFE5F0E5EFEEEBEDE538 +:102BA000EDE8E500D4D03A3533682DCFE5F0E5EF18 +:102BB000EEEBEDE5EDE8E500D4D03A3534682DCF05 +:102BC000E5F0E5EFEEEBEDE5EDE8E500D4D03A35E4 +:102BD00042682DCFE5F0E5EFEEEBEDE5EDE8E50041 +:102BE000D4D03A3545682DCDE5EAEEF0F0E5EAF2CD +:102BF000EDE0FF00D4D03A3630682DCFE5F0E5EFB8 +:102C0000EEEBEDE5EDE8E500D4D03A3631682DCFB6 +:102C1000E5F0E5EFEEEBEDE5EDE8E500D4D03A3692 +:102C200032682DCFE5F0E5EFEEEBEDE5EDE8E50000 +:102C3000D4D03A3633682DCFE5F0E5EFEEEBEDE595 +:102C4000EDE8E500D4D03A3635682DCDE520F5E243 +:102C5000E0F2E0E5F2000000D4D03A3636682DCF3D +:102C6000E5F0E5EFEEEBEDE5EDE8E500D4D03A3642 +:102C700037682DCEF8E8E1EAE020F1E2FFE7E8006E +:102C8000D4D03A3638682DCDE520F5E2E0F2E0E523 +:102C9000F2000000D4D03A3639682DCFE5F0E5EFE8 +:102CA000EEEBEDE5EDE8E500D4D03A3642682DCD07 +:102CB000E5F220F7E5EAEEE2EEE90000D4D03A369C +:102CC00043682DCDE5F220EAEEEDF2F02E00000093 +:102CD000D4D03A3644682DCDE520F5E2E0F2E0E5C7 +:102CE000F2000000D4D03A3645682DCFE5F0E5EF8C +:102CF000EEEBEDE5EDE8E500D4D03A3646682DCFB1 +:102D0000E5F0E5EFEEEBEDE5EDE8E500D4D03A37A0 +:102D100030682DCFE5F0E5EFEEEBEDE5EDE8E50011 +:102D2000D4D03A3732682DCAEEECE0EDE4E020ED85 +:102D3000E5000000D4D03A3733682DCAEEECE0ED60 +:102D4000E4E020EDE5000000D4D03A3734682DCE21 +:102D5000F8E8E1EAE020CEC7D3000000D4D03A374B +:102D600038682DC7E0ECE5EDE020CFCE0000000094 +:102D7000D4D03A3739682DC7E0ECE5EDE020D4CF68 +:102D800000000000D4D03A3743682DCDE520F1EEA5 +:102D9000E2EFE0E4E0E5F200D4D03A3746682DCF28 +:102DA000E5F0E5EFEEEBEDE5EDE8E500D4D03A38FF +:102DB00034682DCFE5F0E5EFEEEBEDE5EDE8E5006D +:102DC000D4D03A3835682DCFE5F0E5EFEEEBEDE500 +:102DD000EDE8E500D4D03A3836682DCFE5F0E5EFE0 +:102DE000EEEBEDE5EDE8E500D4D03A3837682DCFCD +:102DF000E5F0E5EFEEEBEDE5EDE8E500D4D03A38AF +:102E000038682DCFE5F0E5EFEEEBEDE5EDE8E50018 +:102E1000D4D03A3839682DCFE5F0E5EFEEEBEDE5AB +:102E2000EDE8E500D4D03A3841682DCFE5F0E5EF84 +:102E3000EEEBEDE5EDE8E500D4D03A3842682DCF71 +:102E4000E5F0E5EFEEEBEDE5EDE8E500D4D03A385E +:102E500045682DCDF3EBE5E2EEE920E8F2EEE30084 +:102E6000D4D03A3930682DCFEEEBE520EFF0E5E233 +:102E70002E000000D4D03A3932682DCDE0EBEEE6DA +:102E8000E5EDE8E500000000D4D03A4130682DCEF1 +:102E9000F8E8E1EAE020F1E2FFE7E800D4D03A41C7 +:102EA00033682DCDE5EAEEF0F0E5EAF2EDEEE5006F +:102EB000D4D03A4134682DC0E2E0F0E8FF20DDCA0A +:102EC000CBC70000D4D03A4135682DC0E2E0F0E82D +:102ED000FF20CAD100000000D4D03A4141682DCF74 +:102EE000E5F0E5EFEEEBEDE5EDE8E500D4D03A43B3 +:102EF00032682DCFF0E5E2FBF8E5EDE8E5000000F3 +:102F0000D4D03A4333682DCDE5F1EEE2EFE0E4E5CD +:102F1000EDE8E500D4D03A4334682DCDE5F1EEE29A +:102F2000EFE0E4E5EDE8E500EAF3EFFEF0EEEFF0C8 +:102F3000E8E5ECEDE8EAEEEC00000000EFEE20E85A +:102F4000E4E5EDF2E8F4E8EAE0F6E8E80000000085 +:102F5000EFEE20EEEFF2E8F72EE4E0F2F7E8EAF326 +:102F600020000000EFEE20E5ECEAEEF1F22EE4E0C6 +:102F7000F2F7E8EAF3000000F1F2E5EAE5F0EDEE41 +:102F8000E3EE20ECEEF2EEF0E0000000F2F0E0ED17 +:102F9000F1EFEEF0F22EECEEF2EEF0E000000000C9 +:102FA000D4CF312CD4CF3220E8EBE820F7E0F1FB8E +:102FB00000000000E7E0EFF0EEF8E5EDEDFBF520B6 +:102FC000E4E0EDEDFBF50000EDEEECE5F020F3E6DE +:102FD000E520E2E2E5E4E5ED00000000ECE5EDFCD3 +:102FE000F8E520E4E0F2FB20E220D4CF000000006E +:102FF000EFEEF1EBE5E4EDFFFF20E7E0EFE8F1FCB9 +:1030000000000000EFE0ECFFF2FC20F0E5E3E8F167 +:10301000F2F0EEE200000000E4E5EDE5E6EDEEE3BF +:10302000EE20F0E5E3E8F1F2F0E0000032F520F107 +:10303000E1EEE9EDFBF520E7E0EFE8F1E5E900007E +:10304000EFE0F0E0ECE5F2F0FB20E220EAEEECE06D +:10305000EDE4E500EDE0EAEEEFEBE5EDE8FF20E280 +:1030600020F1ECE5EDE50000EDE5E2E5F0EDFBE952 +:1030700020F0E5E32EEDEEECE5F00000EDE0EAEE09 +:10308000EF2EEFEE20F1E5EAF6E8FFEC000000009D +:10309000EDE0EAEEEF2EEFEE20F1EAE8E4EAE0EC14 +:1030A00000000000E4E8E0EFE0E7EEEDE020F1EA08 +:1030B000E8E4EEEA00000000E4E8E0EFE0E7EEED2F +:1030C000E020EEEFEBE0F2FB00000000E4E8E0EFD0 +:1030D000E0E7EEEDE020EEEFEBE0F2FB2032000067 +:1030E000E4E8E0EFE0E7EEEDE020EEEFEBE0F2FB0E +:1030F00020330000E4E8E0EFE0E7EEEDE020EEEF63 +:10310000EBE0F2FB20340000ECE5EDFCF8E520E814 +:10311000F2EEE3E020F7E5EAE0000000EDE0EBE8A6 +:10312000F7EDEEF1F2E820E220EAE0F1F1E500004F +:10313000EEEFE5F0E0F6E8FF20EDE5E2EEE7ECEE9D +:10314000E6EDE000EDE0EAEEEF2EEFEE20EDE0EB55 +:10315000EEE3E0EC00000000E1E5E7EDE0EB2EF14E +:10316000F3ECECE020E1EEEBFCF8E500EFF0E5E25B +:10317000FBF1E8EBE020323420F7E0F1E000000062 +:10318000EDE0EAEEEFEBE5EDE8E920E220F1ECE539 +:10319000EDE50000EEF8E8E1EAE020EAEEEB2DE2F2 +:1031A000E020F1ECE5ED0000EAEEECE0EDE4FB20E0 +:1031B000EFF0EEE4EEEBE6E5EDE8FF00EEF2EAF02C +:1031C000FBF220E4F0F3E3E8EC20EEEF2E00000049 +:1031D000E4E8E0EFE0E7EEEDE020EDE0E4E1E0E25E +:1031E000EEEA0000E4E8E0EFE0E7EEEDE020EAEEF2 +:1031F000EB2DE2E000000000E4E8E0EFE0E7EEEDB8 +:10320000E020EEF2E4E5EBE000000000E4E5EDE5AF +:10321000E320EFEE20EDE0EBEEE3E0EC0000000059 +:10322000EFEE20E2FBEFEBE0F2E520E220F1ECE54F +:10323000EDE50000EFEE20E2EEE7E2F0E0F2E0EC98 +:1032400020EFF0EEE4E0E600EFEE20E2EDE5F1E560 +:10325000EDE8FE20E220F1ECE5EDE500EFEE20EDFB +:10326000E0E4E1E0E2EAE0EC20E220F7E5EAE50074 +:10327000EFEE20F1EAE8E4EAE0EC20E220F7E5EA0C +:10328000E5000000E8F2EEE320F1EAE8E4EAE820F5 +:10329000E220F7E5EAE50000F0E0E7ECE5F020E207 +:1032A00020EDE0F1F2F0EEE9EAE0F500E3F0E0ED28 +:1032B000E8F6F320EFEEEBFF20EFE5F7E0F2E800B1 +:1032C000CEC7D320EFF0EEF8EBEE20F3F1EFE5F808 +:1032D000EDEE0000E2F0E5EC2EF0E5F1F3F0F12088 +:1032E000DDCACBC700000000CFE5F0E5EFEEEBED67 +:1032F000E5EDE8E520EAEEEB2DE2E000CFE5F0E5D4 +:10330000EFEEEBEDE5EDE8E520F1F3ECECFB000092 +:10331000D3E6E520E0EAF2E8E2E8E7E8F0EEE2E012 +:10332000EDE00000E8F2EEE3EEE220F7E5EAE0206F +:10333000E820DDCACBC700004B6173736574612060 +:103340007A61706F6C6E656E610000004B61737323 +:10335000657461206F747375747374767565740029 +:103360004F736869626B6120737679617A69207343 +:1033700020465200CFE0F3E7E020EFEEF1EBE52C42 +:10338000ECE8ED2E00000000CFE5F7E0F2FC20EEC7 +:10339000F2F72EE8E720E1F3F42E0000CEF8E8E1A2 +:1033A000EAE020EEF2EFF02E652D6D61696C000011 +:1033B000452D6D61696C20EEF2EFF02EF3F1EFE533 +:1033C000F8EDEE00207C2020566E6573656E61205E +:1033D0006B75707572612000207C2020566E6573BD +:1033E000656E79206D6F6E6574792000207C2020D9 +:1033F0004E616368616C6F207365616E736120005C +:10340000207C20204B6F6E65F1207365616E7361C7 +:1034100020000000207C2020506563686174272014 +:10342000636865636B612000207C2020536D656EAE +:10343000612072656A696D6120000000207C202097 +:10344000496E6361737361636979612000000000F4 +:10345000207C20204E657420736F627974697961D5 +:1034600020000000C2E2EEE420ECE0F1F2E5F02DF5 +:10347000EFE0F0EEEBFF00002D2D2D2D2D2D2D2D4D +:103480002D2D2D2D2D2D2D2D2D2D2D002D2D2D2D99 +:103490002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0089 +:1034A00014520100205201002C5201003852010038 +:1034B000000000002D2D2D2D2D2D2D2D2D2D2D2DF0 +:1034C0002D2D2D2D2D2D2D002020202020C2CDC8CA +:1034D000CCC0CDC8C52020202020000020202020E6 +:1034E000C8CDCAC0D1D1C0D6C8DF2020202000005E +:1034F000505201005C5201006852010074520100F8 +:10350000000000008C52010098520100A4520100FA +:10351000B052010000000000D1C5D0C2C8D120E2E5 +:10352000E5F02ECFCE2030332E313900CEF7E8F142 +:10353000F2EAE020F1F2E0F2E8F1F2E8EAE8000075 +:10354000D1D2C0D2C8D1D2C8CAC820C2C2C5C4C88C +:10355000D2C5000020C6D3D0CDC0CBCEC220C2C2BF +:10356000C5C4C8D2C5000000DC530100E853010007 +:10357000F453010000540100000000001854010041 +:1035800024540100305401003C54010000000000AC +:10359000CACED0CED2CAC8C520D1D7C5D2D7C8CA04 +:1035A000C800000054540100605401006C54010034 +:1035B0007854010000000000C4CBC8CDCDDBC5208D +:1035C000D1D7C5D2D7C8CAC80000000090540100A6 +:1035D0009C540100A8540100B454010000000000F4 +:1035E000D3F1F2E0EDEEE2EAE020EFE0F0EEEBFF07 +:1035F00000000000D3F1F2E0EDEEE2EAE020E2F0BC +:10360000E5ECE5EDE80000002020C2C2C5C4C8D248 +:10361000C520D2C5CAD3D9C8E900000020CDC0D189 +:10362000D2D0CEC5CA20C2C2C5C4C8D2C50000000F +:10363000CDC0D1D2D0CEE9CAC820CCCECDC5D2CE55 +:10364000CFD02E0020CDC0D1D2D0CEE9CAC820CC58 +:10365000CEC4C5CCC0000000205801002C58010089 +:1036600038580100445801000000000020CDE5E278 +:10367000E5F0EDFBE920EFE0F0EEEBFC00000000F0 +:10368000745801005C58010068580100745801002A +:1036900000000000202020D3F1F2E0EDEEE2EBE5A7 +:1036A000EDFB2020000000008C580100985801001C +:1036B000A4580100B058010000000000E0580100CB +:1036C000C8580100D4580100E05801000000000073 +:1036D00010590100F8580100045901001059010067 +:1036E00000000000CFD0CED1CCCED2D020C6D3D0D7 +:1036F000CDC0CBCEC2000000CEF7E8F1F2EAE02068 +:10370000E6F3F0EDE0EBEEE20000000028590100E6 +:1037100034590100405901004C59010000000000DB +:103720005A2DEEF2F7E5F220E8E720E1F3F4E5F0B8 +:10373000E000000064590100705901007C5901004B +:103740008859010000000000CDE0EFE5F7E0F2E06D +:10375000F2FC20F1F3F2EEF7EDFBE900EEF2F7E513 +:10376000F220E1E5E720E3E0F8E5EDE8FF3F0000C7 +:10377000C4C02D535441525420202053544F502D37 +:10378000CDC5D200A0590100AC590100B8590100C3 +:10379000C459010000000000CDE0EFE5F7E0F2E0E1 +:1037A000F2FC20F1F3F2EEF7EDFBE900EEF2F7E5C3 +:1037B000F220F120E3E0F8E5EDE8E5EC3F00000061 +:1037C000DC590100E8590100F4590100005A0100D8 +:1037D00000000000205A2DCED2D7C5D2DB20C8C7AA +:1037E00020C1D3D4C5D0C000CDE0EFE5F7E0F2E0D2 +:1037F000F2FC20F1F3F2EEF7EDFBE50020EEF2F73C +:10380000E5F2FB20E8E720E1F3F4E5F0E03F00001B +:10381000185A0100245A0100305A0100C45901000D +:1038200000000000EFE5F7E0F2FC20EDE5E2EEE756 +:10383000ECEEE6EDE0000000785A0100845A010049 +:10384000905A01009C5A010000000000B45A010087 +:10385000C05A0100CC5A0100D85A010000000000F3 +:10386000D3D1D2C0CDCEC2CAC020C2D0C5CCC5CD66 +:10387000C80000002020CEC1D9C0DF20D1D2C0D2E4 +:10388000C8D1D2C8CAC00000CAEEF0EEF2EAE8E53C +:1038900020F1F7E5F2F7E8EAE8000000C4EBE8ED14 +:1038A000EDFBE520F1F7E5F2F7E8EAE800000000BB +:1038B00020D1D2C0D22DCAC020CFCE20CAC0CDC008 +:1038C000CBC0CC00805B01008C5B0100985B0100E9 +:1038D000A45B0100000000005B736D74705F706199 +:1038E0007373776F72645D3D000000005E5349534F +:1038F000573A2025642C2025642C202564000000E4 +:103900007C20202532642020207C20253131642039 +:103910000000000053797374656D6E6F65207672D8 +:10392000656D79613A2000005672656D7961206994 +:103930006E63617373616369693A20000D0A0D0A51 +:1039400053756D6D61202564207275622E0D0A001D +:103950002020D1D3CCCCC020257520F0F3E12E005F +:10396000C2EDE5F1E8F2E520E4E5EDFCE3E8000076 +:10397000CFF0E8EDFFF2EE20256420F0F3E12E0019 +:10398000CDC5C4CED1D22EC4C5CDC5C30000000064 +:10399000CAD3CFDED0CECFD0C8C5CCCDC8CAC00028 +:1039A000CDC5D220D1C2DFC7C820D120D4D00000DD +:1039B000C2CEC762CCC8D2C520D7C5CA000000009D +:1039C000CDC5D220C2CACBDED7C5CDCDDBD5000058 +:1039D000C4CE20D1CBC5C42ED1C5C0CDD1C03A00F4 +:1039E000C2DBC1C5D0C8D2C520CAC0CDC0CB000083 +:1039F000C820CDC0C6CCC8D2C520D1D2C0D0D2003C +:103A0000523020203A203078253038780A000000E3 +:103A1000523120203A203078253038780A000000D2 +:103A2000523220203A203078253038780A000000C1 +:103A3000523320203A203078253038780A000000B0 +:103A4000523420203A203078253038780A0000009F +:103A5000523520203A203078253038780A0000008E +:103A6000523620203A203078253038780A0000007D +:103A7000523720203A203078253038780A0000006C +:103A8000523820203A203078253038780A0000005B +:103A9000523920203A203078253038780A0000004A +:103AA000523130203A203078253038780A00000032 +:103AB000523131203A203078253038780A00000021 +:103AC000523132203A203078253038780A00000010 +:103AD000535020203A203078253038780A000000F2 +:103AE0004C5220203A203078253038780A000000E7 +:103AF000504320203A203078253038780A000000E2 +:103B0000435053523A203078253038780A0000006C +:103B1000EEF8E8E1EAE020F1E2FFE7E820F100005A +:103B2000EEF8E8E1EAE020F0E0E1EEF2FB00000070 +:103B3000EA2FEF3A3431682DEAE0F1F1E5F2E000E6 +:103B4000EA2FEF3A3432682DEAE0F1F1E5F2E000D5 +:103B5000EA2FEF3A3434682DE7E0ECE8ED0000009E +:103B6000EA2FEF3A3435682DEFEEEFFBF2EAE00092 +:103B7000EA2FEF3A3530682DEEF8E8E1EAE0000090 +:103B8000EA2FEF3A3532682DEEF8E8E1EAE000007E +:103B9000EA2FEF3A3534682DEAE0F1F1E5F2E00082 +:103BA000EA2FEF3A3635682DEEF8E8E1EAE000005A +:103BB000EA2FEF3A3636682DEEF8E8E1EAE0000049 +:103BC000D4D03A3038682DEAEEECE0EDE4E00000C5 +:103BD000D4D03A3039682DEDE5EAEEF0F02E000051 +:103BE000D4D03A3135682DD1ECE5EDE0000000008D +:103BF000D4D03A3136682DD1ECE5EDE0000000007C +:103C0000D4D03A3234682DCEE1EBE0F1F2FC000082 +:103C1000D4D03A3337682DCAEEECE0EDE4E0000092 +:103C2000D4D03A3343682DDDCACBC73A0000000038 +:103C3000D4D03A3435682D43F3ECECE000000000BA +:103C4000D4D03A3444682DC2EDEEF1E8ECE0FF0048 +:103C5000D4D03A3445682DD1ECE5EDE00000000009 +:103C6000D4D03A3536682DCDE5F220E4EEEA2E00C8 +:103C7000D4D03A3537682DDDCACBC73A00000000F2 +:103C8000D4D03A3538682DCEE6E8E4E0EDE8E5003A +:103C9000D4D03A3539682DC4EEEAF3ECE5EDF20004 +:103CA000D4D03A3543682DCFEEEDE8E6E5EDEE00F1 +:103CB000D4D03A3544682DD2E0E1EBE8F6E00000DC +:103CC000D4D03A3546682DCEF2F0E8F62E0000004A +:103CD000D4D03A3641682DCEF8E8E1EAE0000000A1 +:103CE000D4D03A3731682DCEF8E8E1EAE0000000A0 +:103CF000D4D03A3735682DCEF8E8E1EAE00000008C +:103D0000D4D03A3736682DCFF0E8EDF2E5F03A003E +:103D1000D4D03A3737682DCFF0E8EDF2E5F03A002D +:103D2000D4CF3A3741682DCFEEEBE520EDE500002A +:103D3000D4D03A3742682DCEF8E8E1EAE00000003E +:103D4000D4D03A3744682DCDE5E2E5F0EDFBE9004B +:103D5000D4D03A3745682DCDE5E2E5F0EDEEE5004B +:103D6000D4D03A3830682DCEF8E8E1EAE00000001F +:103D7000D4D03A3831682DCEF8E8E1EAE00000000E +:103D8000D4D03A3832682DCEF8E8E1EAE0000000FD +:103D9000D4D03A3833682DCEF8E8E1EAE0000000EC +:103DA000D4D03A3843682DCEF2F0E8F62E00000069 +:103DB000D4D03A3846682DCAE0F1F1E020EDE500B4 +:103DC000D4D03A3931682DC2FBF5EEE420E7E000AB +:103DD000D4D03A3934682DC8F1F7E5F0EFE0ED00C2 +:103DE000D4D03A4132682DDDCACBC73A200000005A +:103DF000D4D03A4136682DC8F1F7E5F0EFE0ED0098 +:103E0000D4D03A4138682DC7CACBC73A0000000069 +:103E1000D4D03A4139682DDDCACBC73A0000000042 +:103E2000D4D03A4230682DDDCACBC73A000000003A +:103E3000D4D03A4231682DDDCACBC73A0000000029 +:103E4000D4D03A4232682DDDCACBC73A0000000018 +:103E5000D4D03A4330682DCAEEEDF2F0EEEBFC0020 +:103E6000D4D03A4331682DDDCACBC73A00000000F8 +:103E7000EAF3EFFEF0EEEFF0E8E5ECEDE8EAE00063 +:103E8000EFEE20ECE0E32EE4E0F2F7E8EAF30000E6 +:103E9000EFF0E820F2F0E0EDF1EFEEF0F22E0000AE +:103EA000EFEE20E2E5F0E8F4E8EAE0F6E8E82000EA +:103EB000EAF3EFFEF0EEEFF0E8E5ECEDE8EAE5001E +:103EC000E2FBF0E0E2EDE8E2E0EDE8FF00000000F8 +:103ED000E220EAEEECE0EDE4E520EA20D4CF0000B9 +:103EE000E2FBE2EEE4E020E4E0EDEDFBF5000000B3 +:103EF000E220EAEEECE0EDE4E520D4CF00000000A3 +:103F0000E4EBE8EDE020EAEEECE0EDE4FB2000007D +:103F1000EDEEECE5F020EDE520E2E2E5E4E5ED0094 +:103F2000EFEEE2F0E5E6E42E20E7E0EFE8F1FC005A +:103F3000E0EAF22EEFE5F0E5EFEEEBEDE5EDE00087 +:103F4000EDE520EFEEE4E4E5F0E62ED4D00000004D +:103F5000EEF8E8E1EAE020CFCE20D4D00000000067 +:103F6000EFF0E5E42EEAEEECE0EDE4FB000000000B +:103F7000EDE0EFF0FFE6E5EDE8E5203234C20000C9 +:103F8000EDE520EEEFF0E5E4E5EBE5EDE000000027 +:103F9000EFF0E820F3ECEDEEE6E5EDE8E8000000F8 +:103FA000E4E8E0EFE0E7EEEDE020F6E5EDFB000011 +:103FB000E4E5EDE5E320E220F1E5EAF6E8E80000DB +:103FC000E4E5EDE5E320EFEE20EDE0EBEEE3F300DA +:103FD000EDE5F220E8ECEFF3EBFCF1EEE20000009F +:103FE000F0E5E4E0EAF2E8F0F3E5F2F1FF000000CA +:103FF000EEE1EEF0F3E4EEE2E0EDE8FF00000000B9 +:10400000E8F2EEE320EDE0E4E1E0E2EAE8000000BF +:10401000F4E8F1EAE0EBE8E7E8F0EEE2E0EDE000FA +:10402000F1EEF1F2EEFFEDE8E520DDCACBC70000CE +:10403000E220F1EEF1F2E0E2E520DDCACBC70000BC +:10404000E4E0F2FB20E820E2F0E5ECE5EDE800003A +:10405000F1F3F2EEF7EDFBE920EEF2F7E5F2000006 +:10406000EDEEECE5F0EEE220F1ECE5ED0000000015 +:104070005A616D696E2076206B617373657465009B +:10408000506F7079746B61206F626D616E610000BA +:104090004F736869626B61206F7074696B690000AF +:1040A0004F736869626B612046522030783031006E +:1040B0004F736869626B612046522030783032005D +:1040C0004F736869626B612046522030783033004C +:1040D0004F736869626B612046522030783034003B +:1040E0004F736869626B612046522030783035002A +:1040F0004F736869626B6120465220307830360019 +:104100004F736869626B6120465220307830370007 +:104110004F736869626B61204652203078303800F6 +:104120004F736869626B61204652203078303900E5 +:104130004F736869626B61204652203078304100CD +:104140004F736869626B61204652203078304200BC +:104150004F736869626B61204652203078313100BC +:104160004F736869626B61204652203078313200AB +:104170004F736869626B612046522030783133009A +:104180004F736869626B6120465220307831340089 +:104190004F736869626B6120465220307831350078 +:1041A0004F736869626B6120465220307831360067 +:1041B0004F736869626B6120465220307831370056 +:1041C0004F736869626B6120465220307831380045 +:1041D0004F736869626B6120465220307831390034 +:1041E0004F736869626B612046522030783141001C +:1041F0004F736869626B612046522030783142000B +:104200004F736869626B61204652203078314300F9 +:104210004F736869626B61204652203078314400E8 +:104220004F736869626B61204652203078314600D6 +:104230004F736869626B61204652203078323000DB +:104240004F736869626B61204652203078323100CA +:104250004F736869626B61204652203078323200B9 +:104260004F736869626B61204652203078323300A8 +:104270004F736869626B6120465220307832340097 +:104280004F736869626B6120465220307832350086 +:104290004F736869626B6120465220307832380073 +:1042A0004F736869626B6120465220307833330067 +:1042B0004F736869626B6120465220307833350055 +:1042C0004F736869626B6120465220307833360044 +:1042D0004F736869626B6120465220307833370033 +:1042E0004F736869626B6120465220307833380022 +:1042F0004F736869626B6120465220307833390011 +:104300004F736869626B61204652203078334100F8 +:104310004F736869626B61204652203078334300E6 +:104320004F736869626B61204652203078334500D4 +:104330004F736869626B61204652203078334600C3 +:104340004F736869626B61204652203078343000C8 +:104350004F736869626B61204652203078343100B7 +:104360004F736869626B61204652203078343200A6 +:104370004F736869626B6120465220307834330095 +:104380004F736869626B6120465220307834340084 +:104390004F736869626B6120465220307834350073 +:1043A0004F736869626B6120465220307834360062 +:1043B0004F736869626B6120465220307834370051 +:1043C0004F736869626B6120465220307834380040 +:1043D0004F736869626B6120465220307834410027 +:1043E0004F736869626B6120465220307834420016 +:1043F0004F736869626B6120465220307834430005 +:104400004F736869626B61204652203078344400F3 +:104410004F736869626B61204652203078344500E2 +:104420004F736869626B61204652203078344600D1 +:104430004F736869626B61204652203078353000D6 +:104440004F736869626B61204652203078353100C5 +:104450004F736869626B61204652203078353200B4 +:104460004F736869626B61204652203078353300A3 +:104470004F736869626B6120465220307835340092 +:104480004F736869626B6120465220307835360080 +:104490004F736869626B612046522030783537006F +:1044A0004F736869626B612046522030783538005E +:1044B0004F736869626B612046522030783539004D +:1044C0004F736869626B6120465220307835420034 +:1044D0004F736869626B6120465220307835430023 +:1044E0004F736869626B6120465220307835440012 +:1044F0004F736869626B6120465220307835450001 +:104500004F736869626B61204652203078354600EF +:104510004F736869626B61204652203078363000F4 +:104520004F736869626B61204652203078363100E3 +:104530004F736869626B61204652203078363200D2 +:104540004F736869626B61204652203078363300C1 +:104550004F736869626B61204652203078363400B0 +:104560004F736869626B612046522030783635009F +:104570004F736869626B612046522030783636008E +:104580004F736869626B612046522030783637007D +:104590004F736869626B612046522030783638006C +:1045A0004F736869626B612046522030783639005B +:1045B0004F736869626B6120465220307836410043 +:1045C0004F736869626B6120465220307836420032 +:1045D0004F736869626B6120465220307836430021 +:1045E0004F736869626B6120465220307836440010 +:1045F0004F736869626B61204652203078364500FF +:104600004F736869626B61204652203078364600ED +:104610004F736869626B61204652203078373000F2 +:104620004F736869626B61204652203078373100E1 +:104630004F736869626B61204652203078373200D0 +:104640004F736869626B61204652203078373300BF +:104650004F736869626B61204652203078373400AE +:104660004F736869626B612046522030783735009D +:104670004F736869626B612046522030783736008C +:104680004F736869626B612046522030783737007B +:104690004F736869626B612046522030783738006A +:1046A0004F736869626B6120465220307837390059 +:1046B0004F736869626B6120465220307837410041 +:1046C0004F736869626B6120465220307837420030 +:1046D0004F736869626B612046522030783743001F +:1046E0004F736869626B612046522030783744000E +:1046F0004F736869626B61204652203078374500FD +:104700004F736869626B61204652203078374600EB +:104710004F736869626B61204652203078383000F0 +:104720004F736869626B61204652203078383100DF +:104730004F736869626B61204652203078383200CE +:104740004F736869626B61204652203078383300BD +:104750004F736869626B61204652203078383400AC +:104760004F736869626B612046522030783835009B +:104770004F736869626B612046522030783836008A +:104780004F736869626B6120465220307838370079 +:104790004F736869626B6120465220307838380068 +:1047A0004F736869626B6120465220307838390057 +:1047B0004F736869626B612046522030783841003F +:1047C0004F736869626B612046522030783842002E +:1047D0004F736869626B612046522030783843001D +:1047E0004F736869626B612046522030783844000C +:1047F0004F736869626B61204652203078384500FB +:104800004F736869626B61204652203078384600E9 +:104810004F736869626B61204652203078393000EE +:104820004F736869626B61204652203078393100DD +:104830004F736869626B61204652203078393200CC +:104840004F736869626B61204652203078393300BB +:104850004F736869626B61204652203078393400AA +:104860004F736869626B6120465220307841300096 +:104870004F736869626B6120465220307841310085 +:104880004F736869626B6120465220307841320074 +:104890004F736869626B6120465220307841330063 +:1048A0004F736869626B6120465220307841340052 +:1048B0004F736869626B6120465220307841350041 +:1048C0004F736869626B6120465220307841360030 +:1048D0004F736869626B612046522030784137001F +:1048E0004F736869626B612046522030784138000E +:1048F0004F736869626B61204652203078413900FD +:104900004F736869626B61204652203078414100E4 +:104910004F736869626B61204652203078423000E4 +:104920004F736869626B61204652203078423100D3 +:104930004F736869626B61204652203078423200C2 +:104940004F736869626B61204652203078433000B3 +:104950004F736869626B61204652203078433100A2 +:104960004F736869626B6120465220307843320091 +:10497000D3F1EBF3E3E820F1EEEBFFF0E8FF00000A +:10498000CACED02ED1D72ECAC0CDC0CB00000000D9 +:10499000CEF2EFF02EE6F3F0EDE0EBFB00000000CE +:1049A000C8E3EDEEF0E8F02EEEF82ED4D0000000D3 +:1049B000CFE0F3E7E020E4EE2CF1E5EA2E00000082 +:1049C000C7E020E2F0E5ECFF2CECE8ED2E00000063 +:1049D000C7E020E2F0E5ECFF2CECE8ED2E00000053 +:1049E000202020CDCECCC8CDC0CB2023000000009D +:1049F000C7EDE0F7E5EDE8E52CF0F3E12E0000006F +:104A0000D3F1EBF3E3E820F1EEEBFFF0E8FF000079 +:104A1000CFE5F7E0F2FC205A2DEEF2F7E5F2E000E8 +:104A2000CFE5F7E0F2FC20582DEEF2F7E5F2E000DA +:104A3000D1ECE5EDE020F0E5E6E8ECE00000000078 +:104A4000CDE5E2E5F0EDFBE920EFE0F0EEEBFC0078 +:104A5000207C2020566B6C756368656E696520004C +:104A60006E6574207A61706973690D0A0000000038 +:104A7000D6E5EDFB20E220E1F3E4EDE800000000E4 +:104A8000D6E5EDFB20E220E2FBF5EEE4EDFBE500F0 +:104A90002020C8E4E5F220EFF0EEE2E5F0EAE000E5 +:104AA0002020EEE1EEF0F3E4EEE2E0EDE8FF21009D +:104AB00020202020C220E6F3F0EDE0EBE50000002E +:104AC000202020E7E0EFE8F1E5E920EDE5F2000045 +:104AD00020202020D1D2C0D2C8D1D2C8CAC0000064 +:104AE000D1F7E5F2F7E8EAE820EAF3EFFEF000009C +:104AF000202020C4CBDF20CED7C8D1D2CAC8000026 +:104B00007C53010088530100945301000000000011 +:104B1000202020C4CBDF20CED7C8D1D2CAC8000005 +:104B2000AC530100B8530100C45301000000000061 +:104B300020202020CDC0D1D2D0CEE9CAC8000000AC +:104B4000CEE1EEF0F3E4EEE2E0EDE8E50000000097 +:104B5000D1E1F0EEF120EDE0F1F2F0EEE5EA000057 +:104B6000EC550100F855010004560100000000005A +:104B7000C2C2C5C4C8D2C520CCC0D1D2C5D02D00B8 +:104B800020202020C4CBDF20D1C1D0CED1C0000056 +:104B90004C56010058560100645601000000000008 +:104BA0002020C2C2C5C4C8D2C520CDCEC2DBE90018 +:104BB000202020CEC1CED0D3C4CEC2C0CDC8C50027 +:104BC000CCEEEDE5F2EEEFF0E8E5ECEDE8EA000022 +:104BD000202020CDC0D1D2D0CEE9CAC820D4D00068 +:104BE000905701009C570100A857010000000000E9 +:104BF0002020202020CEF8E8E1EAE020000000009C +:104C000020202020E7E0E2EEE4F1EAE8E5200000E1 +:104C10002020202020E7EDE0F7E5EDE8FF00000090 +:104C200020202020EFE0F0E0ECE5F2F0EEE20000E2 +:104C300020202020D1F2E0F2E8F1F2E8EAE00000E2 +:104C40002020202020EEF7E8F9E5EDE0000000004C +:104C50002020202020C6F3F0EDE0EBFB2000000038 +:104C60002020202020EEF7E8F9E5EDFB0000000011 +:104C7000C6F3F0EDE0EB20EEF8E8E1EEEA0000002C +:104C8000C6F3F0EDE0EB20F1EEE1FBF2E8E9000025 +:104C9000202020202020CED2D7C5D2DB000000006B +:104CA0002020202020582DCED2D7C5D200000000D1 +:104CB00020202020205A2DCED2D7C5D200000000BF +:104CC000202020D4D020EEF2EAEBFEF7E5ED000044 +:104CD000485A0100545A0100605A010000000000C7 +:104CE000205B01002C5B0100385B0100000000002C +:104CF000505B01005C5B0100685B0100000000008C +:104D00005B61705F70617373776F72645D3D00000B +:104D10005B736D74705F757365725D3D00000000BC +:104D20005B736D74705F6D61696C5D3D00000000C8 +:104D30005B736D74705F7365727665725D3D0000C4 +:104D40005B736D74705F706F72745D3D0000000086 +:104D500041542B434D47523D25640D0A000000008D +:104D60005E534953573A20302C20310D0A00000081 +:104D700041545E534953573D302C25640D0A0000C1 +:104D800041545E534953573D302C302C310D0A00AD +:104D90005E534953573A20302C20320D0A00000050 +:104DA000253032643A253032643A253032640000CE +:104DB00025643A253032643A253032640000000020 +:104DC000001F1C1F1E1F1E1F1F1E1F1E1F00000076 +:104DD00002000C340000000000000000CCC0CAD16A +:104DE0002ED1C5C0CDD10000C0CFCF2EC3CED2CEE4 +:104DF000C2000000CDC5D220D1C2DFC7C80000006C +:104E0000CED8C8C1CAC020D4D0000000D1CFC0D1F4 +:104E1000C8C1CE20C7C00000CFCEC6C0CBD3E9D119 +:104E2000D2C00000CAC0CDC0CBCEC221000000005D +:104E3000CED1D2C0CBCED1623A2000002530326430 +:104E40003A25303264000000CEF82EEAEEEDF42E62 +:104E500000000000CDE5F220F1E2FFE7E8000000ED +:104E6000D4D03A3035682DEDE5F20000D4D03A3197 +:104E700034682DD4CF000000D4D03A3143682DC51A +:104E8000F1F2FC00D4D03A3235682DCDE5F20000C5 +:104E9000D4D03A4131682DDDCACBC700D4D03A41D5 +:104EA00037682DDDCACBC700EFF0E820E7E0ECE87B +:104EB000EDE50000EFEE20E7E0EFF0E5F2F30000B3 +:104EC000EFEE20E4EBE8EDE500000000E7E0EFEEB8 +:104ED000EBEDE5EDE0000000EEF2F1F3F2F1F2E2CD +:104EE000F3E5F200E220EAE0F1F1E5F2E50000008E +:104EF000ECE0E32EE4E0F2F7E8EAE000F1E2FFE7BD +:104F0000E820F120D4D00000EDE520EFEEE4E42E1F +:104F1000D4CF0000EFE0ECFFF2E820D4CF00000097 +:104F2000EBE8F6E5EDE7E8FF00000000EFE5F0E56F +:104F3000EFEEEBEDE5EDE000F3E6E520EEF2EAF072 +:104F4000FBF2E000EDE520EEF2EAF0FBF2E000001B +:104F5000E0EAF2E8E2E8E7E0F6E8E800EFE0F0E0B7 +:104F6000ECE5F2F000000000EFE0F0E0ECE5F2F03C +:104F7000FB000000E8F2EEE3E020F7E5EAE00000E5 +:104F8000EFE5F0E5EFEEEBEDE5ED0000E4EBFF2003 +:104F9000EFEEE2F2EEF0E000EEEFE5F0E0F6E8FF33 +:104FA00000000000E8F2EEE320F7E5EAE000000090 +:104FB000EEF2F0E5E7F7E8EAE0000000EFEEE4E407 +:104FC000E5F0E62E00000000EDE5F220F1E8E3ED6B +:104FD000E0EBE000F4EEF0ECE0F220E4E0F2FB00C5 +:104FE000F1E2FFE7E820F120D4CF0000EDE0EBE8AC +:104FF000F7EDEEF1F2E80000EFEE20EFF0EEE4E086 +:10500000E6E0EC00EFEE20EFEEEAF3EFEAE0EC0092 +:10501000EDE0EFF0FFE6E5EDE8FF00004E657420FF +:105020006F736869626B690020202020CAC0CDC000 +:10503000CB000000C4CB2ED1D72ECAC0CDC0CB0030 +:10504000D1EEF1F2EEFFEDE8E5000000CDE0E7E2A1 +:10505000E0EDE8E500000000CAF3EFFEF0EEEFF04F +:105060002DEA0000CEEFEEE22EEEE120EEF82E006B +:10507000CEF72EE6F3F0EDE0EBFB0000CCEEEDE535 +:10508000F2EEEFF02DEA0000D0F3E12E2FE8ECEF86 +:105090002E000000C2F02EF0E0E1EEF2FB00000076 +:1050A000546D61782CECE8ED2E000000546D696EB3 +:1050B0002CECE8ED2E000000C2FBF5EEE4EDFBE584 +:1050C0003A000000D6E5EDE02CF0F3E12E00000000 +:1050D000D6E5EDE02CF0F3E12E000000CDE0F7E0A6 +:1050E000EBEE2CF700000000CDE0F7E0EBEE2CF744 +:1050F00000000000C7E0EFE8F1FC20230000000002 +:10510000C7E0EFE8F1FC202300000000C4E5EDFC5F +:10511000E3E82CF0F3E12E00C7E0EAF02EF1ECE535 +:10512000EDFB0000EAEEEB2DE2EE2AF6E5EDE00005 +:105130002020CFC0D0CECB62000000002020202055 +:10514000CFC0D0CECB620000202020CFC0D0CECBAD +:1051500062000000CEF2EFF02EF2E5F1F200000066 +:10516000C2F1E5E3EE20EAF3EFFEF000494420F35C +:10517000F1F22DE2E0000000C2ED2EEAF3EFFEF0C6 +:10518000E0200000C2ED2EECEEEDE5F2FB20000089 +:10519000CDE0F72EF1E5E0EDF1E02000CAEEED2ED6 +:1051A000F1E5E0EDF1E02000C2EAEBFEF7E5EDE825 +:1051B000E5000000CFE5F7E0F2FC20F7E5EAE000CB +:1051C000C8EDEAE0F1F1E0F6E8FF00006B616E6126 +:1051D0006C202564200000006E617374726F696B2F +:1051E00061000000253032643A253032640000004E +:1051F000000103040607090A0C0D0F10EAE0EDE0B8 +:10520000EB20256400000000EDE0F1F2F0EEE9EAA9 +:10521000E000000000000000783401000000000001 +:1052200000000000904A01000000000000000000A3 +:10523000A04A010000000000000000008C340100C2 +:1052400000000000A0340100000000000401000084 +:1052500000000000B4340100000000000000000065 +:10526000C83401000000000000000000DC34010030 +:105270000000000000000000345400400000000066 +:10528000F0340100000000000401000000000000F4 +:105290007D6001000000000000000000B04A010035 +:1052A0000000000000000000C04A010000000000F3 +:1052B000000000007E6001000000000004350100D5 +:1052C0000000000004010000CDE0F1F2F0EEE9EA98 +:1052D000E8000000D1F2E0F2E8F1F2E8EAE00000D4 +:1052E000000100001835010000000000010000006E +:1052F000C85201001455010001000000D452010001 +:105300007053010001000000505F01005859010076 +:1053100001000000585F010094590100F41E0100D3 +:105320000000000005000000CFEE20EAE0EDE0EB19 +:10533000E0EC000000010000D04A01000000000085 +:105340000100000028530100745B0100010000000F +:10535000605F0100445B010001000000E04A0100C1 +:1053600048540100010000002C350100A053010049 +:105370000C1F0100000000000500000000010000FB +:10538000F04A01000000000000010000403501006B +:105390000000000002000000C41301000000000033 +:1053A000004B0100E17F000003000000000100004D +:1053B000104B010000000000000100005435010006 +:1053C0000000000002000000C41301000000000003 +:1053D000204B0100E17F00000300000002030000F9 +:1053E000940701000000000002000000C41001004A +:1053F0000000000002000000F410010000000000A6 +:1054000002000000241101000000000068350100C6 +:105410000000000004010000020300002414010049 +:105420000000000002000000541401000000000011 +:1054300002000000841401000000000002000000CF +:10544000B4140100000000007C350100E97F000079 +:105450000401000000010000903501000000000080 +:1054600002000000A40F0100000000000200000084 +:10547000D40F010000000000020000000410010031 +:1054800000000000A435010000000000040100003D +:1054900000010000B835010000000000020000001B +:1054A0003410010000000000020000006410010040 +:1054B0000000000002000000941001000000000045 +:1054C000CC350100000000000401000000010000D4 +:1054D000304B01000000000001000000685F010087 +:1054E0009855010001000000404B010030570100B9 +:1054F00001000000E035010010560100010000002D +:10550000F4350100145B010001000000504B010064 +:10551000705601009C1A0100000000000600000007 +:105520000203000064070100000000000200000008 +:1055300024080100000000000200000054080100DF +:105540000000000002000000C40A0100000000008A +:1055500002000000F40A0100000000000200000048 +:10556000540B01000000000002000000240B0100A9 +:105570000000000002000000840B01000000000099 +:1055800001000000704A0100E05501000100000028 +:10559000804A0100E8560100D4150100F17F0000A7 +:1055A0000A00000002030000E40B010000000000FC +:1055B00002000000D40C0100000000000200000006 +:1055C000040D01000000000002000000440C010076 +:1055D0000000000002000000A40C01000000000018 +:1055E000241F01000D8000000500000000010000E4 +:1055F0000836010000000000020000003413010022 +:105600000000000001000000643401004056010069 +:10561000604B010021800000030000000001000039 +:10562000704B010000000000020000009413010014 +:10563000000000001C560100285601000000000078 +:10564000345601002180000003000000000100002A +:10565000804B010000000000000100001C3601002A +:1056600000000000020000006413010000000000C0 +:10567000904B0100298000000300000000010000A1 +:10568000A04B01000000000002000000D412010045 +:10569000000000007C560100885601000000000058 +:1056A0009456010000000000020000000203000008 +:1056B000B40B01000000000002000000340D0100E6 +:1056C0000000000002000000640D01000000000066 +:1056D00002000000140C01000000000002000000A5 +:1056E000740C0100000000003C1F01000D80000050 +:1056F0000500000000010000B04B010000000000A8 +:105700000100000004600100845701000200000055 +:10571000840801000000000001000000C04B0100EF +:10572000B457010001000000705F0100145801002F +:10573000541F0100000000000500000000010000EF +:10574000D04B01000000000002000000340A0100FC +:105750000000000002000000E41101000000000051 +:10576000020000001412010000000000020000000E +:10577000441201000000000002000000640A010061 +:1057800000000000B81A0100000000000600000040 +:10579000000100003036010000000000020000009F +:1057A000D40901000000000002000000040A01000A +:1057B00000000000E04B01000000000003000000BA +:1057C000000100004436010000000000020000005B +:1057D000B4080100000000000200000014090100EC +:1057E0000000000002000000A40901000000000009 +:1057F0000200000044090100000000000200000057 +:10580000E41401000000000002000000F413010095 +:1058100000000000AC1901000000000007000000BB +:10582000000100007454004000000000000100006E +:105830008C5400400000000000010000A45400400F +:105840000000000000010000BC5400400000000007 +:1058500058360100850A0000040100000000000025 +:10586000F04B010000000000000000006C36010059 +:1058700000000000000000007F6001000000000048 +:10588000803601000000000004010000000000005C +:10589000943601000000000000000000004C0100F0 +:1058A0000000000000000000104C0100000000009B +:1058B00000000000204C010000000000A83601009C +:1058C000000000000401000000000000304C010056 +:1058D0000000000000000000404C0100000000003B +:1058E000000000008060010000000000BC360100E4 +:1058F000000000000401000000000000504C010006 +:105900000000000000000000604C010000000000EA +:10591000000000008160010000000000D03601009E +:10592000000000000401000000010000E436010056 +:105930000000000001000000704C0100A85A0100A6 +:1059400001000000804C0100E45A01000100000049 +:10595000F8360100D05301000C37010000000000B0 +:105960000400000000010000904C01000000000055 +:1059700001000000785F0100D05901000100000023 +:10598000805F01000C5A0100010000002037010077 +:105990003C5A010034370100C580000004000000BB +:1059A00000010000A04C0100000000000000000009 +:1059B0004837010000000000000000005C370100D3 +:1059C000000000000000000070370100000000002F +:1059D00084370100ED800000040100000001000098 +:1059E000B04C0100000000000000000098370100EA +:1059F0000000000000000000AC37010000000000C3 +:105A0000000000007037010000000000C0370100F6 +:105A1000ED8000000401000000010000D437010007 +:105A20000000000000000000E83701000000000056 +:105A300000000000FC3701000000000010380100E9 +:105A4000ED80000004010000000100008260010000 +:105A50000000000000000000C04C01000000000039 +:105A6000000000002438010000000000D04C0100BC +:105A7000000000000301000002030000F40D01001B +:105A80000000000002000000240E010000000000E1 +:105A900002000000540E010000000000020000009F +:105AA000B40E01000000000038380100FF80000043 +:105AB0000401000002030000E40E010000000000E9 +:105AC00002000000140F01000000000000000000B0 +:105AD000D45400400000000000000000EC540040DE +:105AE000000000004C380100D582000004010000D5 +:105AF000000100006038010000000000020000000A +:105B0000740F010000000000F05A0100FC5A01006F +:105B100000000000085B010000000000020000001F +:105B200000010000743801000000000001000000C6 +:105B30008838010084540100010000009C380100F5 +:105B4000C0540100E04C0100000000000300000010 +:105B500000010000B038010000000000010000005A +:105B6000883801000C540100010000009C3801003D +:105B7000B05B0100F04C01000000000003000000D9 +:105B800002030000C4070100000000000200000042 +:105B90005411010000000000020000008411010007 +:105BA0000000000002000000B4110100000000002D +:105BB000C438010000000000040100005B7265634E +:105BC00065697665725D3D005B61705F646E735DF3 +:105BD0003D0000005B61705F69705D3D000000008A +:105BE0005B61705F757365725D3D00005B61705F46 +:105BF00061706E5D3D00000041542B4350494E3FA3 +:105C00000D0A000041545E534953433D300D0A00D4 +:105C100041545E5349534F3D300D0A007C202537D7 +:105C200064207C20000000007C2025313664202088 +:105C3000000000007C202531326420207C20000000 +:105C400002000630000000000200063300000000E1 +:105C500002000635000000000200064100000000BE +:105C6000CAC0CD2E25642000CED8C8C1CAC000004D +:105C7000CDC0C6CCC8D2C500D1D2C0D0D2000000A1 +:105C800025302E3366000000EEF8E8E1EAE000007F +:105C9000EEE1ECE0EDE00000EEEFF2E8EAE8000013 +:105CA000E4E0F2F7E8EAE000ECEEE4E5ECE0000026 +:105CB000D4CF203100000000D4CF203200000000FB +:105CC000EDE5204243440000F1ECE5EDFB0000006F +:105CD000E220D4CF00000000F120D4CF000000006B +:105CE000EFE8F2E0EDE8FF00EBE5EDF2FB0000008D +:105CF000E4E0F2E000000000F7E5EAE00000000068 +:105D0000EFEEEBE5E9000000F120DDCACBC70000B3 +:105D1000DDCACBC700000000D0F3F72E0000000062 +:105D2000C0E2F2EE00000000C1F3F4E5F000000074 +:105D30000000000009000000000000000100000059 +:105D4000E2FBEAEB2E000000E2EAEB2E000000008E +:105D50000000000001000000D1EEEBFFF0E8E900D8 +:105D60000000000001000000E2FBEAEB2E00000052 +:105D7000E2EAEB2E0000000000000000010000003D +:105D8000CCEEE4E5EC0000000000000001000000A3 +:105D9000D1F2E0F2F3F10000000000009F050000E6 +:105DA00054EEF2EFF02E00000000000001000000B1 +:105DB000010000000F2700000000000001000000AB +:105DC000000000000100000000000000FFFFFFFFD6 +:105DD00000000000E7030000000000006300000076 +:105DE00001000000E703000001000000E7030000DD +:105DF0000000000004000000EFF22DE2F1000000BE +:105E0000F1E12DE2F1000000EFF22DF1E1000000E0 +:105E1000EFF22DEFED00000000000000FFFFFFFF9C +:105E2000010000000F270000010000000F27000004 +:105E300001000000E703000001000000E70300008C +:105E40000000000018000000000000001800000022 +:105E5000CAEEEDE5F62CF700000000001800000087 +:105E60000000000018000000CAEEEDE5F62CF70077 +:105E700000000000010000005A2DEEF2F7E5F200EC +:105E8000EFE5F7E0F2FC0000582DEEF2F7E5F20046 +:105E900000000000FFFFFFFF00000000A90000005D +:105EA00000000000FFFFFFFFC7E0EFF3F1EAE800AA +:105EB000C2F02EF0E0E12E00000000000200000021 +:105EC0000000000001000000D7E5EA3A00000000F1 +:105ED000F1F3ECECE0000000000000000000000026 +:105EE000000000000F27000000000000FFE0F505A3 +:105EF000CFC0D0CECB620000000000001700000031 +:105F0000CAEEEB2DE2EE0000000000000F270000BB +:105F10002564207275622E007261626F74610000E8 +:105F20002575207275622E00EAE0ED2E25640000D2 +:105F3000256420F0F3E12E00F0E0E1EEF2E0000055 +:105F4000257520F0F3E12E00EFF3F1F2EE000000F2 +:105F5000C6F3F0EDE0EBFB00CEF2F7E5F2FB00005C +:105F6000CEE1F9E0FF000000CAE0EDE0EBFB00004D +:105F7000CCEEE4E5EC000000582DEEF2F7E5F2007F +:105F80005A2DEEF2F7E5F20041540D0A0000000030 +:105F90004F4B0D0A000000004552524F520D0A00AF +:105FA00020207C202000000031300000CEEA0000DC +:105FB000EDE5F200D4CF00003131000031320000B5 +:105FC000313300003134000031350000313600003B +:105FD0003137000031380000313900003230000024 +:105FE000323100003232000032330000323400001F +:105FF000D4D00000EDE5F200E4E00000EDE5F200B1 +:10600000EDE5F200D4D00000785634120EF0B0E185 +:1060100001000A00000001001000A00001000C00B7 +:1060200014000200050000001F000100010005002F +:1060300000001400640001000400010004001800C6 +:1060400004000100040001000100010080000100C3 +:106050001100000000008000010001002000480045 +:10606000E80301001D0101001000000008000A0003 +:106070002400400208004000B40B000000000000B3 +:1060800000000000B05F0100103B0100203B010058 +:106090008027010094270100A8270100BC270100E8 +:1060A000D0270100E4270100F82701000C28010097 +:1060B00020280100303B0100403B01003428010052 +:1060C000503B0100603B0100703B0100241C0100BB +:1060D000803B010048280100903B0100A03B0100EB +:1060E000B03B01005C280100885C0100885C010075 +:1060F000702801008428010098280100AC280100C4 +:10610000604E0100C0280100D4280100C03B0100FE +:10611000D03B01003C1C0100541C0100E828010098 +:10612000FC280100102901006C4E0100E03B010039 +:10613000F03B01006C1C01002429010038290100FA +:106140004C29010060290100784E010074290100EA +:10615000882901009C290100B0290100841C01004C +:10616000C4290100003C0100844E0100D82901002F +:10617000EC290100002A0100142A0100103C010052 +:10618000282A01003C2A0100502A0100203C01007D +:10619000642A0100782A01008C2A0100A02A01004B +:1061A000B42A0100C82A0100DC2A0100303C0100A9 +:1061B000F02A0100042B0100182B01002C2B0100F8 +:1061C000402B0100542B0100403C0100503C0100D9 +:1061D0009C1C0100682B01007C2B0100902B01000E +:1061E000A42B0100B82B0100603C0100703C0100B1 +:1061F000803C0100903C0100CC2B0100A03C010040 +:10620000B03C0100E02B0100C03C0100F42B010078 +:10621000082C01001C2C0100302C0100B41C0100D2 +:10622000442C0100582C01006C2C0100802C010032 +:10623000942C0100D03C0100A82C0100BC2C0100D2 +:10624000D02C0100E42C0100F82C01000C2D0100E1 +:10625000E03C0100202D0100342D0100482D0100FB +:10626000F03C0100003D0100103D01005C2D0100EB +:10627000702D0100203D0100303D0100842D010002 +:10628000403D0100503D0100982D0100603D01009E +:10629000703D0100803D0100903D0100AC2D0100EA +:1062A000C02D0100D42D0100E82D0100FC2D0100BE +:1062B000102E0100242E0100382E0100A03D010007 +:1062C000CC1C01004C2E0100B03D0100602E0100ED +:1062D000C03D0100742E0100E41C0100D03D01000E +:1062E000882E0100904E0100E03D01009C2E01002F +:1062F000B02E0100C42E0100F03D01009C4E0100B3 +:10630000003E0100103E0100D82E0100203E010099 +:10631000303E0100403E0100503E0100603E010061 +:10632000EC2E0100002F0100142F0100B05F0100CE +:10633000282F0100703E0100A84E0100803E0100A0 +:10634000903E01003C2F0100A03E0100502F0100B3 +:10635000B44E0100642F0100C04E0100CC4E01007C +:10636000D84E0100B03E0100E44E0100905C0100F7 +:10637000782F01008C2F01008C2F0100C03E0100FE +:10638000D84E0100985C0100F04E0100A05C0100B5 +:10639000A85C0100FC4E0100A02F0100B05C0100D0 +:1063A000B85C0100D03E0100B42F0100E03E0100C6 +:1063B000F03E0100084F0100003F0100C05C0100F9 +:1063C000144F0100204F0100C82F0100DC2F0100F5 +:1063D0002C4F0100384F0100444F0100C85C010000 +:1063E000C85C0100D05C01007A600100103F010030 +:1063F000203F0100F02F010004300100183001009F +:106400007A6001007A600100504F0100303F0100C6 +:10641000504F01002C300100403001005C4F010062 +:10642000684F0100403F01007A600100503F0100C9 +:1064300054300100683001007C30010090300100D0 +:10644000A4300100B8300100CC300100E030010080 +:10645000F4300100083101001C310100FC1C010076 +:10646000744F010030310100804F010044310100C0 +:10647000583101006C3101007A600100603F010079 +:1064800080310100141D01002C1D0100441D01007C +:106490008C4F010094310100A8310100BC31010092 +:1064A000D0310100703F0100803F0100984F010092 +:1064B000A44F0100903F0100A03F0100E431010022 +:1064C000F83101007A600100B03F0100B03F0100E7 +:1064D000D85C01000C3201000C320100E05C0100CC +:1064E000E85C0100E85C0100C03F0100C03F010022 +:1064F00020320100B45F0100B04F0100BC4F010029 +:10650000BC4F01007A600100E05C0100D03F010057 +:10651000C84F01007A6001007A600100E03F01008D +:10652000F03F0100F05C0100D44F01005C1D010050 +:10653000741D0100E04F0100E04F0100E04F010039 +:10654000E04F0100EC4F0100F84F01000450010042 +:10655000343201008C1D0100483201005C32010020 +:10656000703201000040010084320100F85C01003B +:106570001040010098320100AC320100005D0100C2 +:10658000C0320100A41D0100085D0100D84E0100C9 +:10659000BC1D0100204001007A6001003040010074 +:1065A000D43201002C4F0100D41D0100EC1D01006C +:1065B000105D0100E8320100FC32010010330100DF +:1065C0004040010050400100105001002433010000 +:1065D000604001001C500100EC1601005016010043 +:1065E0004C180100101701006C1801008C180100F4 +:1065F000AC1801002C1A0100CC180100041E010087 +:10660000383301004C3301001C1E010070400100B2 +:1066100080400100481A0100EC180100341E0100FE +:106620000C1901004C330100904001004C1E010088 +:10663000641E010078160100641A01006033010035 +:10664000A0400100B0400100C0400100D040010066 +:10665000E0400100F0400100004101001041010054 +:106660002041010030410100404101005041010042 +:106670006041010070410100804101009041010032 +:10668000A0410100B0410100C0410100D041010022 +:10669000E0410100F0410100004201001042010010 +:1066A00020420100304201004042010050420100FE +:1066B00060420100704201008042010090420100EE +:1066C000A0420100B0420100C0420100D0420100DE +:1066D000E0420100F04201000043010010430100CC +:1066E00020430100304301004043010050430100BA +:1066F00060430100704301008043010090430100AA +:10670000A0430100B0430100C0430100D043010099 +:10671000E0430100F0430100004401001044010087 +:106720002044010030440100404401005044010075 +:106730006044010070440100804401009044010065 +:10674000A0440100B0440100C0440100D044010055 +:10675000E0440100F0440100004501001045010043 +:106760002045010030450100404501005045010031 +:106770006045010070450100804501009045010021 +:10678000A0450100B0450100C0450100D045010011 +:10679000E0450100F04501000046010010460100FF +:1067A00020460100304601004046010050460100ED +:1067B00060460100704601008046010090460100DD +:1067C000A0460100B0460100C0460100D0460100CD +:1067D000E0460100F04601000047010010470100BB +:1067E00020470100304701004047010050470100A9 +:1067F0006047010070470100804701009047010099 +:10680000A0470100B0470100C0470100D047010088 +:10681000E0470100F0470100004801001048010076 +:106820002048010030480100404801005048010064 +:106830006048010070480100804801009048010054 +:10684000A0480100B0480100C0480100D048010044 +:10685000E0480100F0480100004901001049010032 +:106860002049010030490100404901005049010020 +:10687000604901002C1901000000000040210100C6 +:1068800054210100682101007C21010090210100B8 +:10689000A4210100B8210100CC210100E021010068 +:1068A000F4210100082201001C2201003022010015 +:1068B00044220100582201006C22010080220100C4 +:1068C00094220100A8220100BC220100D022010074 +:1068D000E4220100F82201000C2301002023010022 +:1068E00034230100482301005C23010070230100D0 +:1068F0008423010098230100AC230100C023010080 +:10690000D4230100E8230100FC230100102401002E +:1069100024240100382401004C2401000000000060 +:106920006024010074240100882401009C240100DB +:10693000B0240100C4240100D8240100EC2401008B +:106940000025010014250100282501003C25010037 +:106950005025010064250100782501008C250100E7 +:10696000A0250100B4250100C8250100DC25010097 +:10697000F025010004260100182601002C26010044 +:106980004026010054260100682601007C260100F3 +:1069900090260100A4260100B8260100CC260100A3 +:1069A000E0260100F4260100082701001C27010051 +:1069B0003027010044270100582701006C270100FF +:1069C00000000000C29F0000D6BF000006CC0000FF +:1069D0003EE00000A6EE0000F6EF0000D6F5000055 +:1069E000AE0501002A160100A85F0100B85F010092 +:1069F000BC5F0100C05F0100C45F0100C85F01000F +:106A0000CC5F0100D05F0100D45F0100D85F0100BE +:106A1000DC5F0100E05F0100E45F0100E85F01006E +:106A2000EC5F0100C29F0000D6BF000006CC000052 +:106A30003EE00000A6EE0000F6EF0000D6F50000F4 +:106A4000AE0501002A160100A85F0100FC5F0100ED +:106A5000F85D0100005E0100085E0100105E0100AB +:106A600000000000AC5F0100484E0100544E0100E0 +:106A7000185D0100205D0100285D0100405D0100FE +:106A8000485D0100221C0100585D0100685D0100A5 +:106A9000705D0100685D0100705D0100685D0100CE +:106AA000705D0100685D0100705D0100685D0100BE +:106AB000705D0100F45F0100F85F010000600100FB +:106AC000805E010024510100D05E0100FFFFFFFF46 +:106AD000FFFFFFFF140000007049010018000000D4 +:046AE00001000000B1 +:0400000500010428CA +:00000001FF diff --git a/.svn/pristine/17/1727e06f1bce930da764fa85f332effaec9b7490.svn-base b/.svn/pristine/17/1727e06f1bce930da764fa85f332effaec9b7490.svn-base new file mode 100644 index 0000000..bd65706 --- /dev/null +++ b/.svn/pristine/17/1727e06f1bce930da764fa85f332effaec9b7490.svn-base @@ -0,0 +1,18 @@ +#ifndef _UART_H_ +#define _UART_H_ + + +#define UART2_RX_BUFSIZE 128 +#define UART2_TX_BUFSIZE 64 + + +extern void Uart2_Init(CPU_INT32U uart_speed); +extern void Uart2_Flush(void); +extern int Uart2_Gotc(void); +extern int Uart2_Getc(void); +extern int Uart2_Ready(void); +extern int Uart2_Putc(CPU_INT08U ch); + + +#endif //#ifndef _UART_H_ + diff --git a/.svn/pristine/19/194f3897cc3db72ec9889c4f8811b613f5cb00ce.svn-base b/.svn/pristine/19/194f3897cc3db72ec9889c4f8811b613f5cb00ce.svn-base new file mode 100644 index 0000000..0f799da --- /dev/null +++ b/.svn/pristine/19/194f3897cc3db72ec9889c4f8811b613f5cb00ce.svn-base @@ -0,0 +1,57 @@ +#include +#include "mode.h" +#include "app_serv.h" + +// +CPU_INT08U RecentMode; + + +void InitMode(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + + PINSEL3_bit.P1_22 = 0x0; + PINMODE3_bit.P1_22 = 0; + FIO1DIR_bit.P1_22 = 0; + FIO1MASK_bit.P1_22 = 0; + + OS_EXIT_CRITICAL(); + + OSTimeDly(1); + + OS_ENTER_CRITICAL(); + if (FIO1PIN_bit.P1_22) RecentMode = MODE_WORK; + else RecentMode = MODE_SERVICE; + OS_EXIT_CRITICAL(); +} + + +CPU_INT08U GetMode(void) +{ + CPU_INT08U mode; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + mode = RecentMode; + OS_EXIT_CRITICAL(); + return mode; +} + + +CPU_INT08U CheckMode(void) +{ + CPU_INT08U newmode; + if (FIO1PIN_bit.P1_22) newmode = MODE_WORK; + else newmode = MODE_SERVICE; + if (newmode != RecentMode) + { + RecentMode = newmode; + PostUserEvent(EVENT_MODE_CHANGE); + return 1; + } + return 0; +} diff --git a/.svn/pristine/1a/1aed176f3e7937e0b7f9c175b6509f3e5a1f4c2a.svn-base b/.svn/pristine/1a/1aed176f3e7937e0b7f9c175b6509f3e5a1f4c2a.svn-base new file mode 100644 index 0000000..6396b3e --- /dev/null +++ b/.svn/pristine/1a/1aed176f3e7937e0b7f9c175b6509f3e5a1f4c2a.svn-base @@ -0,0 +1,225 @@ +#include +#include "keyboard.h" +#include "app_serv.h" + + +#define KBRD_QUERY_LEN 4 + +OS_STK KbrdTaskStk[KBRD_TASK_STK_SIZE]; +OS_EVENT *KbrdQuery = NULL; +void *KbrdTbl[KBRD_QUERY_LEN]; + + +void KbrdTask(void *p_arg); + +unsigned long kbrd_state; + +void InitKbrd() +{ + // +/* +P0.28 MK_P24 1 +P0.27 MK_P25 2 +P3.26 MK_P26 3 +P3.25 MK_P27 a +P1.18 MK_P32 b +P1.19 MK_P33 c +*/ + // + PINSEL1_bit.P0_28 = 0x0; + PINSEL1_bit.P0_27 = 0x0; + PINSEL7_bit.P3_26 = 0x0; + + PINMODE1_bit.P0_28 = 0; + PINMODE1_bit.P0_27 = 0; + PINMODE7_bit.P3_26 = 0; + + FIO0DIR_bit.P0_28 = 1; + FIO0DIR_bit.P0_27 = 1; + FIO3DIR_bit.P3_26 = 1; + + FIO0MASK_bit.P0_28 = 0; + FIO0MASK_bit.P0_27 = 0; + FIO3MASK_bit.P3_26 = 0; + + // + PINSEL3_bit.P1_18 = 0x0; + PINSEL3_bit.P1_19 = 0x0; + PINSEL7_bit.P3_25 = 0x0; + + PINMODE3_bit.P1_18 = 0; + PINMODE3_bit.P1_19 = 0; + PINMODE7_bit.P3_25 = 0; + + FIO1DIR_bit.P1_18 = 0; + FIO1DIR_bit.P1_19 = 0; + FIO3DIR_bit.P3_25 = 0; + + FIO1MASK_bit.P1_18 = 0; + FIO1MASK_bit.P1_19 = 0; + FIO3MASK_bit.P3_25 = 0; + + // + PINSEL3_bit.P1_20 = 0x0; + PINMODE3_bit.P1_20 = 0; + FIO1DIR_bit.P1_20= 0; + FIO1MASK_bit.P1_20 = 0; + + // +/* + P1.25 MK_P39 + P1.23 MK_P37 + P1.31 MK_P20 + P0.25 MK_P7 + P1.24 MK_P38 + P0.26 MK_P6 + P1.29 MK_P45 + P0.1 MK_P47 + P2.13 MK_P50 + P2.11 MK_P52 +*/ + // 1 + PINSEL3_bit.P1_25 = 0x0; + PINMODE3_bit.P1_25 = 0; + FIO1DIR_bit.P1_25 = 0; + FIO1MASK_bit.P1_25 = 0; + + // 2 + PINSEL3_bit.P1_23 = 0x0; + PINMODE3_bit.P1_23 = 0; + FIO1DIR_bit.P1_23 = 0; + FIO1MASK_bit.P1_23 = 0; + + // 3 + PINSEL3_bit.P1_31 = 0x0; + PINMODE3_bit.P1_31 = 0; + FIO1DIR_bit.P1_31 = 0; + FIO1MASK_bit.P1_31 = 0; + + // 4 + PINSEL1_bit.P0_25 = 0x0; + PINMODE1_bit.P0_25 = 0; + FIO0DIR_bit.P0_25 = 0; + FIO0MASK_bit.P0_25 = 0; + + // 5 + PINSEL3_bit.P1_24 = 0x0; + PINMODE3_bit.P1_24 = 0; + FIO1DIR_bit.P1_24 = 0; + FIO1MASK_bit.P1_24 = 0; + + // 6 + PINSEL1_bit.P0_26 = 0x0; + PINMODE1_bit.P0_26 = 0; + FIO0DIR_bit.P0_26 = 0; + FIO0MASK_bit.P0_26 = 0; + + // 7 + PINSEL3_bit.P1_29 = 0x0; + PINMODE3_bit.P1_29 = 0; + FIO1DIR_bit.P1_29 = 0; + FIO1MASK_bit.P1_29 = 0; + + // 8 + PINSEL0_bit.P0_1 = 0x0; + PINMODE0_bit.P0_1 = 0; + FIO0DIR_bit.P0_1 = 0; + FIO0MASK_bit.P0_1 = 0; + + // 9 + PINSEL4_bit.P2_13 = 0x0; + PINMODE4_bit.P2_13 = 0; + FIO2DIR_bit.P2_13 = 0; + FIO2MASK_bit.P2_13 = 0; + + // 10 + PINSEL4_bit.P2_11 = 0x0; + PINMODE4_bit.P2_11 = 0; + FIO2DIR_bit.P2_11 = 0; + FIO2MASK_bit.P2_11 = 0; + + kbrd_state = 0; + + // + if (KbrdQuery == NULL) + { + KbrdQuery = OSQCreate(&KbrdTbl[0], KBRD_QUERY_LEN); + OSTaskCreate(KbrdTask, (void *)0, (OS_STK *)&KbrdTaskStk[KBRD_TASK_STK_SIZE-1], KBRD_TASK_PRIO); + } +} + +#define KBRD_SCAN_LINE1() {FIO0CLR_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE2() {FIO0SET_bit.P0_28 = 1; FIO0CLR_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE3() {FIO0SET_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3CLR_bit.P3_26 = 1;} + +void KbrdTask(void *p_arg) +{ + unsigned long prew_state = 0; + + while (1) + { + unsigned long state; + + OSTimeDly(17); + + state = 0; + KBRD_SCAN_LINE1(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_F1); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_F2); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_F3); + KBRD_SCAN_LINE2(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_LEFT); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_UP); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_RIGHT); + KBRD_SCAN_LINE3(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_STOP); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_DOWN); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_START); + + if (!FIO1PIN_bit.P1_20) state |= (1UL << KEY_USER_START); + + if (!FIO1PIN_bit.P1_25) state |= (1UL << KEY_DEFERRED_CH1); + if (!FIO1PIN_bit.P1_23) state |= (1UL << KEY_DEFERRED_CH2); + if (!FIO1PIN_bit.P1_31) state |= (1UL << KEY_DEFERRED_CH3); + if (!FIO0PIN_bit.P0_25) state |= (1UL << KEY_DEFERRED_CH4); + if (!FIO1PIN_bit.P1_24) state |= (1UL << KEY_DEFERRED_CH5); + if (!FIO0PIN_bit.P0_26) state |= (1UL << KEY_DEFERRED_CH6); + if (!FIO1PIN_bit.P1_29) state |= (1UL << KEY_DEFERRED_CH7); + if (!FIO0PIN_bit.P0_1) state |= (1UL << KEY_DEFERRED_CH8); + if (!FIO2PIN_bit.P2_13) state |= (1UL << KEY_DEFERRED_CH9); + if (!FIO2PIN_bit.P2_11) state |= (1UL << KEY_DEFERRED_CH10); + + if (prew_state == state) + { // + if (kbrd_state ^ state) + { // + for (unsigned long i = 0; i < KEY_COUNT; i++) + { + // + if (!(kbrd_state & (1UL << i)) && (state & (1UL << i))) + { + OSQPost(KbrdQuery, (void *)i); + PostUserEvent(EVENT_KEY_EMPTY+i); // + } + } + } + kbrd_state = state; + } + + prew_state = state; + } + +} + +int GetKbrdEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(KbrdQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + \ No newline at end of file diff --git a/.svn/pristine/23/236e5d2a903829daf058ea00ef58cab1e4e84512.svn-base b/.svn/pristine/23/236e5d2a903829daf058ea00ef58cab1e4e84512.svn-base new file mode 100644 index 0000000..2a4e912 --- /dev/null +++ b/.svn/pristine/23/236e5d2a903829daf058ea00ef58cab1e4e84512.svn-base @@ -0,0 +1,54 @@ + . + ++ 1. e-mail , ( ) (, ). + + : + / + : , 1 , 2 , 4 , 8 , 12 , 24 . + : / + * . + + : + + e-mail + ++ 2. : + // . + - , crc. + ++ 3. . + ++ 4. , . + , .. 2 , . + -> id . id e-mail. + ++ 5. : + . + - , . + ++ 6. + e-mail + + " ", " ". + + . + ++ 7. - . + ++ 8. e-mail. . + +------------------------------------------------------ + ++ 9. . ++ 10. - . ++ 11. - "Test message from modem." ++ 13. , . ++ 14. . + +------------------------------------------------------ + +* 12. . + +------------------------------------------------------ + ++ 15. e-mail , + > 0. ++ 16. . ++ 16. . diff --git a/.svn/pristine/28/289d5caa7516d130841f66ccccb602ed4ea70c9e.svn-base b/.svn/pristine/28/289d5caa7516d130841f66ccccb602ed4ea70c9e.svn-base new file mode 100644 index 0000000..52f5bfb --- /dev/null +++ b/.svn/pristine/28/289d5caa7516d130841f66ccccb602ed4ea70c9e.svn-base @@ -0,0 +1,577 @@ +; +;******************************************************************************************************** +; uC/OS-II +; The Real-Time Kernel +; +; +; (c) Copyright 1992-2007, Micrium, Weston, FL +; All Rights Reserved +; +; Generic ARM Port +; +; File : OS_CPU_A.ASM +; Version : V1.82 +; By : Jean J. Labrosse +; Jean-Denis Hatier +; +; For : ARM7 or ARM9 +; Mode : ARM or Thumb +; Toolchain : IAR's EWARM V4.11a and higher +;******************************************************************************************************** +; + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + ; External references. + EXTERN OSRunning + EXTERN OSPrioCur + EXTERN OSPrioHighRdy + EXTERN OSTCBCur + EXTERN OSTCBHighRdy + EXTERN OSIntNesting + EXTERN OSIntExit + EXTERN OSTaskSwHook + + ; Functions declared in this file. + PUBLIC OS_CPU_SR_Save + PUBLIC OS_CPU_SR_Restore + PUBLIC OSStartHighRdy + PUBLIC OSCtxSw + PUBLIC OSIntCtxSw + + ; Functions related to exception handling. + PUBLIC OS_CPU_ARM_ExceptResetHndlr + PUBLIC OS_CPU_ARM_ExceptUndefInstrHndlr + PUBLIC OS_CPU_ARM_ExceptSwiHndlr + PUBLIC OS_CPU_ARM_ExceptPrefetchAbortHndlr + PUBLIC OS_CPU_ARM_ExceptDataAbortHndlr + PUBLIC OS_CPU_ARM_ExceptAddrAbortHndlr + PUBLIC OS_CPU_ARM_ExceptIrqHndlr + PUBLIC OS_CPU_ARM_ExceptFiqHndlr + + EXTERN OS_CPU_ExceptHndlr + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +OS_CPU_ARM_CONTROL_INT_DIS EQU 0xC0 ; Disable both FIQ and IRQ. +OS_CPU_ARM_CONTROL_FIQ_DIS EQU 0x40 ; Disable FIQ. +OS_CPU_ARM_CONTROL_IRQ_DIS EQU 0x80 ; Disable IRQ. +OS_CPU_ARM_CONTROL_THUMB EQU 0x20 ; Set THUMB mode. +OS_CPU_ARM_CONTROL_ARM EQU 0x00 ; Set ARM mode. + +OS_CPU_ARM_MODE_MASK EQU 0x1F +OS_CPU_ARM_MODE_USR EQU 0x10 +OS_CPU_ARM_MODE_FIQ EQU 0x11 +OS_CPU_ARM_MODE_IRQ EQU 0x12 +OS_CPU_ARM_MODE_SVC EQU 0x13 +OS_CPU_ARM_MODE_ABT EQU 0x17 +OS_CPU_ARM_MODE_UND EQU 0x1B +OS_CPU_ARM_MODE_SYS EQU 0x1F + +OS_CPU_ARM_EXCEPT_RESET EQU 0x00 +OS_CPU_ARM_EXCEPT_UNDEF_INSTR EQU 0x01 +OS_CPU_ARM_EXCEPT_SWI EQU 0x02 +OS_CPU_ARM_EXCEPT_PREFETCH_ABORT EQU 0x03 +OS_CPU_ARM_EXCEPT_DATA_ABORT EQU 0x04 +OS_CPU_ARM_EXCEPT_ADDR_ABORT EQU 0x05 +OS_CPU_ARM_EXCEPT_IRQ EQU 0x06 +OS_CPU_ARM_EXCEPT_FIQ EQU 0x07 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + + +;********************************************************************************************************* +; CRITICAL SECTION METHOD 3 FUNCTIONS +; +; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you +; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then +; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to +; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' +; into the CPU's status register. +; +; Prototypes : OS_CPU_SR OS_CPU_SR_Save (void); +; void OS_CPU_SR_Restore (OS_CPU_SR os_cpu_sr); +; +; +; Note(s) : (1) These functions are used in general like this: +; +; void Task (void *p_arg) +; { +; /* Allocate storage for CPU status register. */ +; #if (OS_CRITICAL_METHOD == 3) +; OS_CPU_SR os_cpu_sr; +; #endif +; +; : +; : +; OS_ENTER_CRITICAL(); /* os_cpu_sr = OS_CPU_SR_Save(); */ +; : +; : +; OS_EXIT_CRITICAL(); /* OS_CPU_SR_Restore(cpu_sr); */ +; : +; : +; } +;********************************************************************************************************* + +OS_CPU_SR_Save + MRS R0, CPSR + ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts. + MSR CPSR_c, R1 + BX LR ; Disabled, return the original CPSR contents in R0. + + +OS_CPU_SR_Restore + MSR CPSR_c, R0 + BX LR + + +;********************************************************************************************************* +; START MULTITASKING +; void OSStartHighRdy(void) +; +; Note(s) : 1) OSStartHighRdy() MUST: +; a) Call OSTaskSwHook() then, +; b) Set OSRunning to TRUE, +; c) Switch to the highest priority task. +;********************************************************************************************************* + +OSStartHighRdy + + ; Change to SVC mode. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_Running ; OSRunning = TRUE; + MOV R1, #1 + STRB R1, [R0] + + ; SWITCH TO HIGHEST PRIORITY TASK: + LDR R0, ?OS_TCBHighRdy ; Get highest priority task TCB address, + LDR R0, [R0] ; Get stack pointer, + LDR SP, [R0] ; Switch to the new stack, + + LDR R0, [SP], #4 ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;********************************************************************************************************* +; PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw() +; +; Note(s) : 1) OSCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED. +; +; 2) The pseudo-code for OSCtxSw() is: +; a) Save the current task's context onto the current task's stack, +; b) OSTCBCur->OSTCBStkPtr = SP; +; c) OSTaskSwHook(); +; d) OSPrioCur = OSPrioHighRdy; +; e) OSTCBCur = OSTCBHighRdy; +; f) SP = OSTCBHighRdy->OSTCBStkPtr; +; g) Restore the new task's context from the new task's stack, +; h) Return to new task's code. +; +; 3) Upon entry: +; OSTCBCur points to the OS_TCB of the task to suspend, +; OSTCBHighRdy points to the OS_TCB of the task to resume. +;********************************************************************************************************* + +OSCtxSw + ; SAVE CURRENT TASK'S CONTEXT: + STMFD SP!, {LR} ; Push return address, + STMFD SP!, {LR} + STMFD SP!, {R0-R12} ; Push registers, + MRS R0, CPSR ; Push current CPSR, + TST LR, #1 ; See if called from Thumb mode, + ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, set the T-bit. + STMFD SP!, {R0} + + LDR R0, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP; + LDR R1, [R0] + STR SP, [R1] + + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy; + LDR R1, ?OS_PrioHighRdy + LDRB R2, [R1] + STRB R2, [R0] + + LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy; + LDR R1, ?OS_TCBHighRdy + LDR R2, [R1] + STR R2, [R0] + + LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr; + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;********************************************************************************************************* +; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw() +; +; Note(s) : 1) OSIntCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED. +; +; 2) The pseudo-code for OSCtxSw() is: +; a) OSTaskSwHook(); +; b) OSPrioCur = OSPrioHighRdy; +; c) OSTCBCur = OSTCBHighRdy; +; d) SP = OSTCBHighRdy->OSTCBStkPtr; +; e) Restore the new task's context from the new task's stack, +; f) Return to new task's code. +; +; 3) Upon entry: +; OSTCBCur points to the OS_TCB of the task to suspend, +; OSTCBHighRdy points to the OS_TCB of the task to resume. +;********************************************************************************************************* + +OSIntCtxSw + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy; + LDR R1, ?OS_PrioHighRdy + LDRB R2, [R1] + STRB R2, [R0] + + LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy; + LDR R1, ?OS_TCBHighRdy + LDR R2, [R1] + STR R2, [R0] + + LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr; + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;******************************************************************************************************** +; RESET EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptResetHndlr + ; LR offset to return from this exception: 0. + ; (there is no way to return from a RESET exception). + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_RESET ; Set exception ID to OS_CPU_ARM_EXCEPT_RESET. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; UNDEFINED INSTRUCTION EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptUndefInstrHndlr + ; LR offset to return from this exception: 0. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_UNDEF_INSTR ; Set exception ID to OS_CPU_ARM_EXCEPT_UNDEF_INSTR. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; SOFTWARE INTERRUPT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptSwiHndlr + ; LR offset to return from this exception: 0. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_SWI ; Set exception ID to OS_CPU_ARM_EXCEPT_SWI. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; PREFETCH ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptPrefetchAbortHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_PREFETCH_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_PREFETCH_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; DATA ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptDataAbortHndlr + SUB LR, LR, #8 ; LR offset to return from this exception: -8. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_DATA_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_DATA_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; ADDRESS ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptAddrAbortHndlr + SUB LR, LR, #8 ; LR offset to return from this exception: -8. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_ADDR_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_ADDR_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; INTERRUPT REQUEST EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptIrqHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_IRQ ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; FAST INTERRUPT REQUEST EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptFiqHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; GLOBAL EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 Exception's SPSR +; R2 Old CPU mode +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr + MRS R1, SPSR ; Save CPSR (i.e. exception's SPSR). + + ; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION: + ; SPSR.Mode = SVC : task, + ; SPSR.Mode = FIQ, IRQ, ABT, UND : other exceptions, + ; SPSR.Mode = USR : *unsupported state*. + AND R2, R1, #OS_CPU_ARM_MODE_MASK + CMP R2, #OS_CPU_ARM_MODE_SVC + BNE OS_CPU_ARM_ExceptHndlr_BreakExcept + + +;******************************************************************************************************** +; EXCEPTION HANDLER: TASK INTERRUPTED +; +; Register Usage: R0 Exception Type +; R1 Exception's SPSR +; R2 Exception's CPSR +; R3 Return PC +; R4 Exception's SP +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr_BreakTask + MRS R2, CPSR ; Save exception's CPSR. + MOV R4, SP ; Save exception's stack pointer. + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; SAVE TASK'S CONTEXT ONTO TASK'S STACK: + STMFD SP!, {R3} ; Push task's PC, + STMFD SP!, {LR} ; Push task's LR, + STMFD SP!, {R5-R12} ; Push task's R12-R5, + LDMFD R4!, {R5-R9} ; Move task's R4-R0 from exception stack to task's stack. + STMFD SP!, {R5-R9} + STMFD SP!, {R1} ; Push task's CPSR (i.e. exception SPSR). + + ; if (OSRunning == 1) + LDR R1, ?OS_Running + LDRB R1, [R1] + CMP R1, #1 + BNE OS_CPU_ARM_ExceptHndlr_BreakTask_1 + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting++; + LDRB R4, [R3] + ADD R4, R4, #1 + STRB R4, [R3] + + LDR R3, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP; + LDR R4, [R3] + STR SP, [R4] + +OS_CPU_ARM_ExceptHndlr_BreakTask_1 + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; EXECUTE EXCEPTION HANDLER: + LDR R1, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0); + MOV LR, PC + BX R1 + + ; Adjust exception stack pointer. This is needed because + ; exception stack is not used when restoring task context. + ADD SP, SP, #(14 * 4) + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; Call OSIntExit(). This call MAY never return if a ready + ; task with higher priority than the interrupted one is + ; found. + LDR R0, ?OS_IntExit + MOV LR, PC + BX R0 + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;******************************************************************************************************** +; EXCEPTION HANDLER: EXCEPTION INTERRUPTED +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr_BreakExcept + MRS R2, CPSR ; Save exception's CPSR. + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting++; + LDRB R4, [R3] + ADD R4, R4, #1 + STRB R4, [R3] + + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; EXECUTE EXCEPTION HANDLER: + LDR R3, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0); + MOV LR, PC + BX R3 + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting--; + LDRB R4, [R3] + SUB R4, R4, #1 + STRB R4, [R3] + + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; RESTORE OLD CONTEXT: + LDMFD SP!, {R0-R12, PC}^ ; Pull working registers and return from exception. + + +;********************************************************************************************************* +; POINTERS TO VARIABLES +;********************************************************************************************************* + + DATA + +?OS_Running: + DC32 OSRunning + +?OS_PrioCur: + DC32 OSPrioCur + +?OS_PrioHighRdy: + DC32 OSPrioHighRdy + +?OS_TCBCur: + DC32 OSTCBCur + +?OS_TCBHighRdy: + DC32 OSTCBHighRdy + +?OS_IntNesting: + DC32 OSIntNesting + +?OS_TaskSwHook: + DC32 OSTaskSwHook + +?OS_IntExit: + DC32 OSIntExit + +?OS_CPU_ExceptHndlr: + DC32 OS_CPU_ExceptHndlr + + + END diff --git a/.svn/pristine/29/29f8c8b3e0df2c0627998cd03ee60d1e0fa832f5.svn-base b/.svn/pristine/29/29f8c8b3e0df2c0627998cd03ee60d1e0fa832f5.svn-base new file mode 100644 index 0000000..7de93e3 --- /dev/null +++ b/.svn/pristine/29/29f8c8b3e0df2c0627998cd03ee60d1e0fa832f5.svn-base @@ -0,0 +1,20 @@ +#ifndef __CRC16_H__ +#define __CRC16_H__ + + +#define CRC16_SMALL 0 // +#define CRC16_LARGE 1 // ( ) +#define CRC16_MODEL_TYPE CRC16_LARGE + + +#if (CRC16_MODEL_TYPE==CRC16_LARGE) + extern unsigned short CRC16_large( unsigned char *pBuf, unsigned char ucLength ); + #define CRC16 CRC16_large +#else + extern unsigned short CRC16_small( unsigned char *pBuf, unsigned char ucLength ); + #define CRC16 CRC16_small +#endif + + +#endif // #ifndef __CRC16_H__ + diff --git a/.svn/pristine/2a/2ad7ea9dad193a24e77c8b808d59b35c080186ad.svn-base b/.svn/pristine/2a/2ad7ea9dad193a24e77c8b808d59b35c080186ad.svn-base new file mode 100644 index 0000000..15dbfb3 --- /dev/null +++ b/.svn/pristine/2a/2ad7ea9dad193a24e77c8b808d59b35c080186ad.svn-base @@ -0,0 +1,50 @@ +#ifndef __LCD_H__ +#define __LCD_H__ + +/*! + + ks066, 4 + +*/ + +#define LCD_HOME 0x02 +#define LCD_CLEAR 0x01 +#define LCD_GOTO_LINE_0 0x80 +#define LCD_GOTO_LINE_1 0xC0 +#define LCD_GOTO_LINE_2 0x94 +#define LCD_GOTO_LINE_3 0xD4 +#define LCD_1CYCLE 0 +#define LCD_2CYCLE 1 + + +#define LCD_PORT PORTB + #define D4_pin PB4 + #define D5_pin PB5 + #define D6_pin PB6 + #define D7_pin PB7 + +#define LCD_SET_E_PIN() {FIO2SET_bit.P2_7 = 1;} +#define LCD_CLR_E_PIN() {FIO2CLR_bit.P2_7 = 1;} + +#define LCD_SET_RW_PIN() {FIO2SET_bit.P2_6 = 1;} +#define LCD_CLR_RW_PIN() {FIO2CLR_bit.P2_6 = 1;} + +#define LCD_SET_RS_PIN() {FIO2SET_bit.P2_8 = 1;} +#define LCD_CLR_RS_PIN() {FIO2CLR_bit.P2_8 = 1;} + +#define LCD_OUT_DATA(x) {FIO0PIN &= ~(0x0fL << 19); FIO0PIN |= (((x) & 0xf) << 19);} +#define LCD_IN_DATA() ((FIO0PIN >> 19) & 0x0f) +#define LCD_SET_DATA_IN() {FIO0DIR &= ~(0x0fL << 19);} +#define LCD_SET_DATA_OUT() {FIO0PIN |= (0x0fL << 19);} + + +extern void InitLcd(); +extern void LCD_puts(unsigned char *s, unsigned char n); +extern void LCD_putc(unsigned char c, unsigned char n, unsigned char m); +extern void LCD_clear(void); +extern void LCD_putc_embed(unsigned char c, unsigned char n, unsigned char m); +extern void LCD_cursor_on(void); +extern void LCD_cursor_off(void); +extern void LCD_goto(unsigned char n, unsigned char m); + +#endif //#ifndef __LCD_H__ diff --git a/.svn/pristine/2e/2e6563f943aa76cbc45136183c34e432ce24f25c.svn-base b/.svn/pristine/2e/2e6563f943aa76cbc45136183c34e432ce24f25c.svn-base new file mode 100644 index 0000000..00177b3 --- /dev/null +++ b/.svn/pristine/2e/2e6563f943aa76cbc45136183c34e432ce24f25c.svn-base @@ -0,0 +1,654 @@ +#include +#include "menu.h" +#include "menudesc.h" +#include "data.h" +#include "keyboard.h" +#include "lcd.h" +#include "mode.h" +#include "app_serv.h" +#include "time.h" + +OS_STK MenuTaskStk[MENU_TASK_STK_SIZE]; + +#define STACKPANELSIZE 8 +TMenuStack MenuStack[STACKPANELSIZE]; +CPU_INT08U MenuStackPtr; +CPU_INT08U MenuActiveLine, MenuFirstLine, MenuEditStatus; +TMenuPanel* MenuCurrentPanel; + +CPU_INT08U EditPos, EditStart, EditLen, EditLine; +TVariant32 EditVal, EditMax, EditMin; +TDataDescStruct* EditDesc; +TRTC_Data EditTime; +// +const CPU_INT08U EditTimePos[12] = +{ + 0, 1, + 3, 4, + 6, 7, + 9,10, + 12,13, + 15,16 +}; +CPU_INT08U EditBuf[32]; +#define EDIT_TYPE_NUMBER 0 +#define EDIT_TYPE_ITEMS 1 + +CPU_INT08U refresh_menu = 0; + +void ShowMenuLine(TMenuLine* line_ptr, CPU_INT08U pos) +{ + CPU_INT08U strbuf[32]; + + if (line_ptr->LineType == MENU_LINE_STRING) + { + sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr); + LCD_puts(strbuf, pos); + } + else if (line_ptr->LineType == MENU_LINE_SHOW_DESC) + { + strbuf[0] = ' '; + if ((MenuEditStatus) && (pos == EditLine)) + { + // + if (EditDesc->IsIndex) + { + GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]); + strcat((char*)strbuf, "<"); + strcat((char*)strbuf, (char const*)EditBuf); + strcat((char*)strbuf, ">"); + LCD_puts(strbuf, pos); + } + else + { + GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]); + if (EditDesc->Name) strcat((char*)strbuf, "="); + strcat((char*)strbuf, (char const*)EditBuf); + LCD_puts(strbuf, pos); + } + } + else + { + GetDataFullStr((const TDataDescStruct*)line_ptr->Ptr, &strbuf[1], 0, DATA_FLAG_SYSTEM_INDEX); + LCD_puts(strbuf, pos); + } + } + else if (line_ptr->LineType == MENU_LINE_GOTO_MENU) + { + sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr); + LCD_puts(strbuf, pos); + } + + + +} + +void ClearMenuLine(CPU_INT08U pos) +{ + CPU_INT08U c = 0; + LCD_puts(&c, pos); +} + +void ClearDisplay(void) +{ + LCD_clear(); +} + + +TMenuPanel* GetCurrentMenu(void) +{ + return MenuCurrentPanel; +} + +// +void ShowCurrentMenu(void) +{ + // + CPU_INT08U i, j; + TMenuLine* pLine; + //MenuCurrentPanel->LineNum + + // , 4 + if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC) + { + j=0; + LCD_cursor_off(); + for (i=0; iLineArray[i].pMenuLine; + if (pLine == NULL) break; + ShowMenuLine(pLine, j++); + } + while (jLineArray[0].pMenuLine)->Flags) & MENU_INDEX_LINE) + { + LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0); + } + return; + } + + + // + pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine == NULL) {ClearDisplay(); return;} + ShowMenuLine(pLine, 0); + + // 3 + // MenuFirstLine - + if (MenuActiveLine == 0) MenuFirstLine = 0; + else + { + if (MenuCurrentPanel->LineNum < MENU_LINES_NUMBER) MenuFirstLine = MenuActiveLine-1; + else + { + if (MenuActiveLine < MenuCurrentPanel->LineNum-2) MenuFirstLine = MenuActiveLine-1; + else MenuFirstLine = MenuActiveLine-2; + } + } + + i=MenuFirstLine+1; + j=1; + while((jLineNum)) + { + TMenuLine* pline = (TMenuLine*)MenuCurrentPanel->LineArray[i].pMenuLine; + if (pline == NULL) ClearMenuLine(j); + else ShowMenuLine(pline, j); + i++; + j++; + } + + while(jLineArray[MenuActiveLine+1].pMenuLine)->LineType); + if (linetype == MENU_LINE_STRING) + { + LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1); + } + else if (linetype == MENU_LINE_GOTO_MENU) + { + LCD_putc_embed(SYMB_RIGHT_ARROW, 0, MenuActiveLine-MenuFirstLine+1); + } + else if (linetype == MENU_LINE_SHOW_DESC) + { + TMenuLine* mline = ((TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine); + + if (((const TDataDescStruct*)mline->Ptr)->Desc == DATA_DESC_EDIT) + LCD_putc_embed(SYMB_DESC_MARK, 0, MenuActiveLine-MenuFirstLine+1); + else + LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1); + } + + // + CPU_INT08U lineflags = (((TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine)->Flags); + if (lineflags & MENU_INDEX_LINE) + { + LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0); + } + + // () + if ((MenuEditStatus) && (!EditDesc->IsIndex)) + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + LCD_goto(EditStart+EditPos, MenuActiveLine-MenuFirstLine+1); + } + else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN)) + { + LCD_goto(EditStart+EditTimePos[EditPos], MenuActiveLine-MenuFirstLine+1); + } + LCD_cursor_on(); + } + else + { + LCD_cursor_off(); + } +} + +void RefreshMenu(void) +{ + refresh_menu = 1; +} + +// +CPU_INT08U GetFirstActiveLine(TMenuPanel *menu) +{ + CPU_INT08U line = 0; + CPU_INT08U i = 0; + while (i++ < menu->LineNum) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +// +CPU_INT08U GetNextActiveLine(TMenuPanel *menu, CPU_INT08U recent) +{ + CPU_INT08U line = recent+1; + CPU_INT08U i = recent+1; + while (i++ < menu->LineNum) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +// +CPU_INT08U GetPrevActiveLine(TMenuPanel *menu, CPU_INT08U recent) +{ + CPU_INT08U line = recent+1; + CPU_INT08U i = recent+1; + if (recent == 0) return 0; + while (i--) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +void GoToMenu(const TMenuPanel* Menu) +{ + if (MenuStackPtr >= STACKPANELSIZE) return; + MenuStack[MenuStackPtr].PrevMenu = MenuCurrentPanel; + MenuStack[MenuStackPtr].PrevActiveLine = MenuActiveLine; + MenuStackPtr++; + + MenuCurrentPanel = (TMenuPanel*)Menu; + MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel); + if (Menu->InitFunc) Menu->InitFunc(); + refresh_menu = 1; +} + +void SetMenu(const TMenuPanel* Menu) +{ + MenuCurrentPanel = (TMenuPanel*)Menu; + MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel); + if (Menu->InitFunc) Menu->InitFunc(); + refresh_menu = 1; +} + +void GoToPreviousMenu(void) +{ + if (!MenuStackPtr) return; + --MenuStackPtr; + MenuCurrentPanel = (TMenuPanel*)MenuStack[MenuStackPtr].PrevMenu; + MenuActiveLine = MenuStack[MenuStackPtr].PrevActiveLine; + if (MenuCurrentPanel->InitFunc) MenuCurrentPanel->InitFunc(); + refresh_menu = 1; +} + +void GoToNextMenu(void) +{ + if ((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr) + GoToMenu((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr); +} + +void MenuSprintf(CPU_INT08U* str, CPU_INT08U len, CPU_INT32U Val) +{ + if (EditDesc->Type == DATA_TYPE_ULONG) + { + CPU_INT08U format[6]; + format[0]='%'; + format[1]='0'; + format[2]='0'+len/10; + format[3]='0'+len%10; + format[4]='u'; + format[5]=0; + sprintf((char*)str, (char const*)format, Val); + } + else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN)) + { + GetDataStr(EditDesc, str, 0, DATA_FLAG_SYSTEM_INDEX); + } +} + +// +void EnterEdit(void) +{ + // , 0 - + EditPos = 0; + // + EditDesc = (TDataDescStruct*)(MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->Ptr; + // + EditLine = MenuActiveLine+1-MenuFirstLine; + // + GetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX); + // + TRangeValueULONG* RVal = EditDesc->RangeValue; + memcpy(&EditMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&EditMax, &RVal->Max, sizeof(CPU_INT32U)); + + if (EditDesc->IsIndex) + { + GetDataStr((const TDataDescStruct*)EditDesc, EditBuf, 0, DATA_FLAG_SYSTEM_INDEX); + } + else + { + GetDataNameStr((const TDataDescStruct*)EditDesc, EditBuf); + if (EditDesc->Name) strcat((char*)EditBuf, "="); + EditStart = strlen((char const*)EditBuf)+1; + if (EditDesc->Type == DATA_TYPE_ULONG) + { + sprintf((char*)EditBuf, "%u", RVal->Max); + EditLen = strlen((char const*)EditBuf); + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditLen = 12; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditLen = 4; + } + else + { + EditLen = 0; + } + MenuSprintf(EditBuf, EditLen, EditVal.Val32U); + } + + MenuEditStatus = 1; +} + +// +void EscEdit(void) +{ + MenuEditStatus = 0; +} + +// +void SaveEdit(void) +{ + if (EditDesc->Type == DATA_TYPE_ULONG) + { + if (!EditDesc->IsIndex) + { + sscanf((char const*)EditBuf, "%d", &EditVal.Val32U); + } + SetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX); + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + TRTC_Data rtc; + ScanRTCDateTimeStringRus((char*)EditBuf, &rtc); + if (RTCCheckTime(&rtc) == 0) + { // + CPU_INT32U time; + time = GetSec(&rtc); + SetData(EditDesc, &time, 0, DATA_FLAG_SYSTEM_INDEX); + } + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + int hour, min, hour_min; + sscanf((char*)EditBuf, "%02d:%02d", &hour, &min); + hour_min = hour * 60 + min; + SetData(EditDesc, &hour_min, 0, DATA_FLAG_SYSTEM_INDEX); + } + MenuEditStatus = 0; +} + + +void MenuTask(void *p_arg) +{ + int pause = 0; + + SetMenu(START_MENU); + + while (1) + { + int key=0; + if (GetKbrdEvent(&key) || (++pause >= 1000) || ((pause >= 500) && (MenuEditStatus)) || (refresh_menu != 0)) + { + if (refresh_menu) {refresh_menu = 0; ShowCurrentMenu();} + // + if (!MenuEditStatus) + { // + pause = 0; + if (key) + { + switch (key){ + + case KEY_UP: + //if (MenuActiveLine) MenuActiveLine--; + MenuActiveLine = GetPrevActiveLine(MenuCurrentPanel, MenuActiveLine); + ShowCurrentMenu(); + break; + + case KEY_DOWN: + //MenuActiveLine++; + //if (MenuActiveLine+1 >= MenuCurrentPanel->LineNum) MenuActiveLine--; + MenuActiveLine = GetNextActiveLine(MenuCurrentPanel, MenuActiveLine); + ShowCurrentMenu(); + break; + + case KEY_LEFT: + { + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine->Flags & MENU_INDEX_LINE) + {// - + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Type == DATA_TYPE_ULONG) + { + CPU_INT32U i, min, max; + GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + GetDataMin(desc, &min); + GetDataMax(desc, &max); + i--; + if ((i < min) || (i > max)) i = max; + SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + } + ShowCurrentMenu(); + } + } + break; + + case KEY_RIGHT: + { + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine->Flags & MENU_INDEX_LINE) + {// - + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Type == DATA_TYPE_ULONG) + { + CPU_INT32U i, min, max; + GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + GetDataMin(desc, &min); + GetDataMax(desc, &max); + i++; + if ((i < min) || (i > max)) i = min; + SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + } + ShowCurrentMenu(); + } + } + break; + + case KEY_STOP: + // + GoToPreviousMenu(); + break; + + case KEY_START: + { + if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC) {ShowCurrentMenu();break;} + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine; + if (pLine->LineType == MENU_LINE_SHOW_DESC) + {// , + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Desc == DATA_DESC_EDIT) {EnterEdit(); pause=1000;} + } + else if (pLine->LineType == MENU_LINE_GOTO_MENU) + {// + GoToNextMenu(); + } + } + break; + }//switch (key) + }//if (key) + else + { + ShowCurrentMenu(); + } + } + else//if (!MenuEditStatus) + { // + if (key) + { + switch (key){ + case KEY_UP: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U++; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + EditBuf[EditPos]++; + if (EditBuf[EditPos] > '9') EditBuf[EditPos] = '0'; + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditBuf[EditTimePos[EditPos]]++; + if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0'; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditBuf[EditTimePos[EditPos]]++; + if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0'; + } + } + break; + case KEY_DOWN: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U--; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + EditBuf[EditPos]--; + if (EditBuf[EditPos] < '0') EditBuf[EditPos] = '9'; + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditBuf[EditTimePos[EditPos]]--; + if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9'; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditBuf[EditTimePos[EditPos]]--; + if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9'; + } + } + break; + case KEY_LEFT: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U--; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditPos) EditPos--; + } + break; + case KEY_RIGHT: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U++; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditPos < EditLen-1) EditPos++; + } + break; + case KEY_STOP: + EscEdit(); + break; + case KEY_START: + SaveEdit(); + break; + }//switch (key) + + ShowCurrentMenu(); + }//if (key) + else + { + pause = 0; + ShowCurrentMenu(); + } + }//if (!MenuEditStatus) + + } + } +} + + + +void InitMenu(void) +{ + + MenuStackPtr = 0; + MenuActiveLine = 0; + MenuFirstLine = 0; + MenuEditStatus = 0; + MenuCurrentPanel = NULL; + + memset(&MenuStack, 0, sizeof(TMenuStack)*STACKPANELSIZE); + + OSTaskCreate(MenuTask, (void *)0, (OS_STK *)&MenuTaskStk[MENU_TASK_STK_SIZE-1], MENU_TASK_PRIO); +} + + +void ReInitMenu(void) +{ + OSTaskDel(MENU_TASK_PRIO); + ClearDisplay(); + OSTimeDly(100); + InitMenu(); + OSTimeDly(100); + if (GetMode() == MODE_WORK) SetMenu(WORK_MENU); + else SetMenu(SERVICE_MENU); +} + diff --git a/.svn/pristine/30/30b68ba7b27fcd9ed088a2d416b5e61515861a76.svn-base b/.svn/pristine/30/30b68ba7b27fcd9ed088a2d416b5e61515861a76.svn-base new file mode 100644 index 0000000..6b7477a --- /dev/null +++ b/.svn/pristine/30/30b68ba7b27fcd9ed088a2d416b5e61515861a76.svn-base @@ -0,0 +1,5894 @@ +:1000000018F09FE518F09FE518F09FE518F09FE5C0 +:1000100018F09FE5586FA0B818F09FE518F09FE51D +:10002000B008010000870000108700002087000052 +:1000300034870000000000005C870000708700002B +:1000440008B4024B9C4608BC6047C0468832000096 +:1000540070B598B00600002014900023002214A963 +:10006400B74801F07DFC149800281ED0C748002131 +:10007400017000242406240E0A2C13D200201390AD +:1000840001232406240E220013A9C14801F068FCB0 +:100094001398002804D0BD480078401CBB49087060 +:1000A400641CE7E7BB4801210170CA4800210170C4 +:1000B400C948002101700023002216A9C74801F095 +:1000C4004FFC1698C649884202D1042002F05CFD18 +:1000D40001A800F084FD002801D100F0E8FC01989B +:1000E400401E32D0801E00D18EE1401E00D1D9E1E5 +:1000F400401E00D124E2401E00D179E1801E00D1CF +:1001040045E2401E00D143E2401E00D141E2401EC0 +:1001140000D13FE2401E00D1ACE2401E00D176E2A5 +:10012400401E00D1A7E2401E00D1A2E2401E0128D9 +:1001340000D82CE3801E092800D8D5E20A3800D163 +:10014400E5E0401E00D14DE1C2E702F08BFD02F074 +:10015400FDFFD049086001F0CBF8CF480078401C7F +:10016400CD4908700006000E0A2103F081F8002929 +:100174000DD1CA480078002803D003F098FD002868 +:1001840005D003F022FB002801D103F05DF904F04F +:10019400DFFA02F056FD00289AD103F055FE00283C +:1001A40025D000F08BFE04F00AFDBD4800688021D4 +:1001B40089030143BA48016076480078012812D1C6 +:1001C40085480078002811D105F0FFFB002804D0F1 +:1001D40003220021002005F07DFE06F021F87E4870 +:1001E4000121017002E07C480021017070E7D148D0 +:1001F400007804214843D049085800280DD0CD4840 +:10020400007800F037FD04F0DAFCA548006880218E +:1002140089030143A248016078E05E480078012820 +:100224003ED100F093FD04F0CAFC03F00DF96A48D6 +:10023400007800286AD005F0C8FB002804D0032207 +:10024400BE49BE4805F046FE0120129000201190E0 +:100254000020C043109001F01DFB040011AA12A954 +:10026400B448007800F0CCFE0123B248027810A90B +:10027400CD4801F075FB119860433C214843129925 +:10028400FFF7DEFE10993C225143814202D205F071 +:10029400C7FF01E005F0C5FF4F480021017035E0BC +:1002A4003C48007802281ED17D48006880218903DB +:1002B40001437B48016005F0B3FFBC480078002887 +:1002C40007D001F0F5F8B9480078401EB749087026 +:1002D4001CE03048002101709648007801F018F9BC +:1002E40004F06DFC12E02B48007800280ED16C4815 +:1002F40000688021890301436948016005F090FF8B +:100304008C48007801F004F904F059FCE0E6002080 +:1003140002900024182C15D200200F9001232200F3 +:100324000FA9A34801F01CFB02980F990422624311 +:10033400A04B9A58514340180290641CEAE7C04607 +:1003440028170100234801210170029ACE499A48D6 +:1003540006F068F8CD4804F0A2FC029A0C210020B3 +:1003640003F01AFE00230022C949CA4801F0F8FA32 +:100374000024182C10D20123220004206043C64913 +:1003840009188B4801F0ECFA641CF2E7605600404F +:10039400780C0100625600400023002202A9CD48D7 +:1003A40001F02EFB02F0D2FE03900023002203A9E9 +:1003B400C94801F025FB0A4803900023002203A941 +:1003C400064801F01DFB042002F0DEFB04F0A0F956 +:1003D4007EE6C0466556004066560040C8190100D6 +:1003E40021436587BD480021017004F09EFC6FE63F +:1003F40005F0E8F802F025FC0006000E02000B21CF +:10040400002003F0C9FD63E601200E9000230022C2 +:100414000EA9B34801F0A4FA05F012FF0E99414366 +:100424000D0001F037FA04006419200001F016FAF7 +:10043400AC480078012803D100F088FC04F0BFFB2D +:100444002A0002213B48007803F0A6FD01200D900C +:1004540000200C900020C0430B900CAA0DA9354835 +:10046400007800F0CDFD0123324802780BA94E48F4 +:1004740001F076FA0C9860433C2148430D99FFF74C +:10048400DFFD0B993C225143814201D205F0C8FEA5 +:100494001EE6C0466455004067560040685600405A +:1004A4003CC0FF3F17A805F012FB040001200A908E +:1004B400002009900020C043089009AA0AA91D48F9 +:1004C400007800F09DFD01231A48027808A93648F7 +:1004D40001F046FA01F0DEF90500099829194843AC +:1004E4003C2148430A99FFF7ABFD08993C2251434C +:1004F40081420FD2BF480321017005F066FA00283B +:1005040017D0032005F062FD002812D1012003F06A +:100514001BFC0EE0B7480021017005F056FA0028D4 +:1005240007D0032005F020FD002802D1012003F0AC +:100534000BFCCDE561560040C4530040FFFFFF00B3 +:1005440015A805F0C4FA050001F0A4F90400641923 +:10055400200001F083F963480078012803D100F0FA +:10056400F5FB04F02CFB05F030FA002805D003223B +:100574000021C943C54805F0ADFC2A000121C44847 +:10058400007803F009FD159804F091F8A0E59FE5C3 +:100594009EE59DE502F055FB002803D14F48007805 +:1005A40000280BD094E5C046A80F01006356004014 +:1005B40038190100A85100407454004003F044FC71 +:1005C400002804D000F07AFC04F0F9FA80E54548EC +:1005D400007800281AD1C6480078022816D300F003 +:1005E40031FEAB48007804214843C249085800282A +:1005F40006D0A748007800F03DFB04F0E0FA05E0DF +:10060400A348007800F084FF04F0D9FA60E502F012 +:1006140018FB002803D131480078002800D057E5A2 +:1006240003F012FC002804D000F048FC04F0C7FAE0 +:100634004EE52C48007800281AD1AD4800780228ED +:1006440016D300F0BFFD9248007804214843A9491D +:100654000858002806D08E48007800F00BFB04F000 +:10066400AEFA05E08A48007800F052FF04F0A7FAD9 +:100674002EE52DE52CE502F0E4FA002803D1174815 +:10068400007800280AD023E50C3E010068570100D9 +:100694006855004068190100E850004003F0D4FB9D +:1006A400002804D000F00AFC04F089FA10E50D4893 +:1006B400002101707648007800F02AFF04F07FFAE8 +:1006C40005F083F9002804D003220021002005F05E +:1006D40001FCFDE4F8190100281A010065560040E8 +:1006E400880E010062560040019804214843814964 +:1006F400081848380068002848D001980421484365 +:100704007C49081848380021016001981238000615 +:10071400000E05F0A3FE01980421484383490818FC +:100724004838019904225143D14A5118483909687B +:10073400016001987E49081812380221017001985D +:1007440004214843CA49081848380268032101981B +:1007540012380006000E03F01FFC03F0BBF800285B +:1007640007D000F0A5FE04F02AFAD3480221017054 +:1007740002E0D14800210170D04803210170D04823 +:100784000068802189030143CD480160A0E4CD487D +:100794000078002800D09BE402F053FA002879D0B6 +:1007A400C9480078002800D192E404F09BF8C749B6 +:1007B400884221D103F08EF8002866D003F09FF818 +:1007C40000A9891C1E2006F0E3F903F0ACF8684682 +:1007D4008078002803D06846807803F0C1F802F0DE +:1007E400B5FC02000921002003F0D6FB04F09DFAB9 +:1007F4004BE0C0466456004004F074F8B4498842A3 +:1008040021D103F067F800283FD003F078F800A95D +:10081400491C1E2006F0F1F903F085F8684640787B +:10082400002803D06846407803F09AF802F08EFC62 +:1008340002000821002003F0AFFB04F076FA4E20FA +:1008440003F0AEF821E004F04DF8A24988421CD12F +:1008540003F040F8002818D003F051F869461E2030 +:1008640006F033FA03F05FF868460078002803D0F6 +:100874006846007803F074F802F068FC02000A216C +:10088400002003F089FB04F050FA21E4FFFFFF008D +:100894006156004003F0D8FA002804D000F00EFBA3 +:1008A40004F08DF914E412480078002801D1FFF710 +:1008B4000FFC8148007800283CD18748007800F07C +:1008C40087FF002801D0FFF703FC03F018F802F0BB +:1008D400BBFD002810D503F0B7FA00280CD003F0B4 +:1008E40022F800F0EBFA04F06AF9FFF7F1FBC046D6 +:1008F40060560040C453004003F015F86E480121CF +:10090400017000F023FA04F05AF905F05EF80028AB +:1009140005D003220021C943704805F0DBFA05F035 +:1009240080FC6F4800210170FFF7D2FB7453004034 +:100934005455004060480078012800D0B5E00120FB +:100944000790002006900020059006AA07A9624897 +:10095400007800F055FB00F09DFF0400069860430A +:100964003C2148430799FFF76BFB5B490978042254 +:1009740051433F4A505001235748027805A9A448DF +:1009840000F0EEFF544800780421484338490858E1 +:1009940005993C225143884200D284E005F015F8C1 +:1009A400002804D003220021002005F093FA02F06D +:1009B40091FF002812D048480078042148432C496C +:1009C4000958200003F00EF8002807D102F0BEFBFE +:1009D400020007214048007803F0DEFA22003E4876 +:1009E400007804214843224909583B48007803F021 +:1009F40053FD002000F032FF00200490012336480C +:100A0400027804A9964800F0ABFF049800281DD092 +:100A14003148007804214843924900220A502E4864 +:100A24000078914901220A542B4800780421484354 +:100A3400B64901220A5022480068802189030143F3 +:100A44001F4801601C48002101702CE022480078F6 +:100A540004214843AD4900220A5001231E4802786C +:100A64001D480078042148437E4909187F4801E065 +:100A74009C53004000F074FF174800787A49012223 +:100A84000A5402F027FF002807D000F011FD04F0FB +:100A940096F809480221017002E00748002101701C +:100AA400064805210170FFF713FBFFF711FB012036 +:100AB40006F060FAFFF70CFB6256004063560040F4 +:100AC4003CC0FF3F6556004072560040D05E0100B6 +:100AD4000C5F01003C5F010061560040FFFFFF0016 +:100AE4006456004080B502F075F801F018FA03F07E +:100AF400A7FD00F081FE00F0DDFE05F08DFD8448C9 +:100B04000068844901408248016083480068814943 +:100B140001408148016081480068802189030143C4 +:100B24007E4801607E4800687E4901407C4801603F +:100B34004F4800688021890301434D48016004F057 +:100B44001FFDFA20800006F015FA04F053FF7648E2 +:100B540006F010FA02F0ACFE02F007F902F0F6FA21 +:100B640002000621002003F017FA00230022694640 +:100B74006E4800F0F5FE0023002269466C4800F040 +:100B84003FFF06F0A5FA002803D0192003F0DCF893 +:100B940002E0192003F006F905F063FB65480068DC +:100BA40000280BD14021644807F016F86149086019 +:100BB4000723624A0021624807F054F902F0C6FA9A +:100BC4006049086002F03DF8002803D15E4804F053 +:100BD40096F802E0B14804F092F809BC184710B541 +:100BE40082B004006846002101706A460121514820 +:100BF400006807F043F8010068460078002801D037 +:100C0400002001E02160012016BC08BC1847000048 +:100C1400D80F010010B5040021004648006807F011 +:100C2400C1F810BC08BC184780B59D48002101706C +:100C34009B4800780A2811D200200090012398488C +:100C440002786946974800F08BFE0098002805D189 +:100C540093480078401C92490870E9E709BC18479A +:100C6400381001007453004054550040480F0100EF +:100C74003CC0FF3F10B588B0040004206043234902 +:100C8400085800283DD088480078022810D3012352 +:100C940022006946854800F088FF684607F090FA0C +:100CA4002200521C82A16B46181805F0BBFB03E01E +:100CB400C4A1684605F0B6FB0021684607F0D4FAE3 +:100CC4007C49684605F0AEFB0121684607F0CCFA82 +:100CD4007949684605F0A6FB0221684607F0C4FA84 +:100CE40071480078022804D3B749684605F09AFB96 +:100CF40003E0B4A1684605F095FB0321684607F0BC +:100D0400B3FA08B010BC08BC18470000C453004034 +:100D14000CC002E0FFF3FFFF4CC002E020C0FF3F25 +:100D240030C0FF3FFFFFDFFF10270000380D010038 +:100D3400580E01006C550040644B00407424004080 +:100D44005500000064550040505D010070B58CB042 +:100D54009E4904A805F066FB002104A807F084FA64 +:100D640000F098FD05002A00994904A805F05AFBF3 +:100D7400012104A807F078FA0120039000200290D2 +:100D8400002402AA03A94648007800F039F9029821 +:100D940068433C2148430399FFF752F904002000BB +:100DA4003C21FFF74DF90B001E0020003C21FFF70A +:100DB40047F902003300874904A805F033FB0221F8 +:100DC40004A807F051FA84480078002809D0824822 +:100DD4000078401E80490870804904A805F022FB71 +:100DE40053E0002001900020009001232C48027859 +:100DF40001A97B4800F0B4FD012329480278694623 +:100E0400784800F0ADFD28480078022807D324482C +:100E14000278521C744904A805F004FB03E073A192 +:100E240004A805F0FFFA01983C21484384421DD3ED +:100E34006F4800688021890301436D480160009870 +:100E44003C214843844208D304A807F0B9F969490E +:100E540004AA101805F0E6FA17E004A807F0B0F9A0 +:100E6400654904AA101805F0DDFA0EE0634800682D +:100E74008021890301436148016004A807F0A0F9B7 +:100E8400CB4904AA101805F0CDFA032104A807F0F1 +:100E9400EBF90CB070BC08BC184700000458010002 +:100EA40061560040780C010060560040A80C010017 +:100EB40020256400885201009452010000B589B0D5 +:100EC400012002F09DFF002803D102F0E7FF002873 +:100ED40025D0B84901A805F0A5FA002101A807F01A +:100EE400C3F9B54901A805F09DFA012101A807F04D +:100EF400BBF9012002F084FF002860D0AF4901A8AB +:100F040005F090FA022101A807F0AEF937A101A873 +:100F140005F088FA032101A807F0A6F94FE01A208A +:100F240002F06EFF00281CD0A24901A805F07AFA4D +:100F3400002101A807F098F9A14901A805F072FA67 +:100F4400012101A807F090F928A101A805F06AFA87 +:100F5400022101A807F088F9032101A807F084F908 +:100F64002DE002F0A4FE002829D0924901A805F042 +:100F740059FA002101A807F077F9684600210170A9 +:100F8400AD4901A805F04EFA012101A807F06CF95A +:100F9400684602F0A5FE6846027801A9A74800F059 +:100FA400CAFE022101A807F05FF96846027801A988 +:100FB400A34800F0C0FE032101A807F055F909B0C9 +:100FC40008BC184720000000482501001C3E010011 +:100FD4002C3E01005C250100645600407025010090 +:100FE400D80F0100A80F010060610100000000009B +:100FF40038C0FF3FA0520100AC5201003CC0FF3F8B +:10100400F1B586B00F001600AF480078002802D171 +:101014000020C043C8E0684601F061FE002004904F +:1010240000250123A948027804A9A94800F098FCE6 +:101034000498012806D002280FD0032818D00428C9 +:1010440021D02BE06846C078002803D06846C078D9 +:10105400052801D30120050022E06846C078002855 +:1010640003D06846C078062801D10120050017E0A6 +:101074006846C078052803D06846C078062801D1A0 +:10108400012005000CE06846C078052803D26846B4 +:10109400C078022801D20120050001E000200500EB +:1010A400002004002406240E042C40D22D062D0E0C +:1010B400002D18D0012385480078042148432406D4 +:1010C400240E021903A9834800F04AFC01237F4837 +:1010D4000078042148432406240E021902A97E48FC +:1010E40000F03EFC17E001237848007804214843CF +:1010F4002406240E021903A9784800F031FC0123C8 +:1011040072480078042148432406240E021902A9D7 +:10111400734800F025FC684680780399884204D31C +:10112400684680780299884201D3641CBAE7240691 +:10113400240E042C02D30120C04335E02D062D0ECD +:10114400002D18D001236148007804214843240667 +:10115400240E02193100634800F002FC01235B48AD +:101164000078042148432406240E021939005E48FD +:1011740000F0F6FB17E001235448007804214843AB +:101184002406240E02193100584800F0E9FB01231B +:101194004E480078042148432406240E02193900DD +:1011A400C14800F0DDFB002007B0F0BC08BC1847C4 +:1011B4003C3E0100686101004C3E0100B852010050 +:1011C4005C3E01001CB541480078401C0400240624 +:1011D400240E0A2C0ED20020019001232406240E92 +:1011E400220001A9B14800F0BBFB0198002801D1FD +:1011F400641CECE72406240E0A2C02D23348047043 +:1012040016E0002004002406240E0A2C0ED200202E +:10121400009001232406240E22006946A34800F00E +:101224009FFB0098002801D1641CECE72748047058 +:1012340013BC08BC18470000C4520100D8120100B6 +:10124400081301001CB521480078401E0400240640 +:101254002416002C0ED40020019001232406241609 +:10126400220001A9914800F07BFB0198002801D1DC +:10127400641EECE724062416002C02D413480470E0 +:101284001EE009200400114800782100090609160F +:101294000004001409040914884211DA00200090A3 +:1012A40001232406241622006946804800F058FBD6 +:1012B4000098002802D00548047001E0641EE2E7AB +:1012C40013BC08BC1847000060560040615600403B +:1012D40008100100E8110100181201008811010032 +:1012E400B811010028110100C810010058110100B3 +:1012F40010B500242406240E0A2C00D3D1E02406C1 +:10130400240E7E48005D002806D0022852D009D35E +:10131400032800D19AE0C2E020000006000E05F088 +:1013240004F9BCE02406240E0420604374490858E0 +:1013340000280CD02406240E042060437049085869 +:10134400401E2406240E042161436D4A5050240695 +:10135400240E042060436B490858002829D1240630 +:10136400240E0420604366490858002821D1200037 +:101374000006000E05F072F82406240E04206043D3 +:101384005F492406240E042262435F4B9A580A5094 +:101394002406240E5948022101552406240E042053 +:1013A400604359490A58032120000006000E02F048 +:1013B400F3FD74E02406240E0420604350490858C9 +:1013C40000280CD02406240E042060434C490858FD +:1013D400401E2406240E04216143494A5050240629 +:1013E400240E042060434649085800282DD12000CB +:1013F4000006000E05F099F801232406240E2200AD +:101404002406240E042060433D4909183F4800F097 +:10141400A7FA2406240E04206043394908583C21C5 +:1014240048432406240E04216143354A50502406BF +:10143400240E32480321015501F088FE02000421E4 +:1014440020000006000E02F0A7FD28E02406240E6A +:10145400042060432A49085800280CD02406240E8E +:101464000420604326490858401E2406240E042103 +:101474006143234A50502406240E0420604320492B +:10148400085800280BD12406240E1C4800210155BD +:101494002406240E042060431B4900220A50641CC5 +:1014A40028E710BC08BC1847F8100100780C0100AC +:1014B40000B589B09B49684604F0B4FF0021684632 +:1014C40006F0D2FE9849684604F0ACFF0121684654 +:1014D40006F0CAFE9549684604F0A4FF0221684656 +:1014E40006F0C2FEDA49684604F09CFF0321684610 +:1014F40006F0BAFE09B008BC184700005455004075 +:1015040074530040C45300409C530040780F0100C2 +:1015140030B58DB00500AD480021017000242406CB +:10152400240E0A2C13D200200C9001232406240E2E +:1015340022000CA9AD4800F013FA0C98002804D03E +:10154400A2480078401CA1490870641CE7E79F4842 +:101554000078002820D1A649684604F063FF0021E2 +:10156400684606F081FEA349684604F05BFF01214A +:10157400684606F079FEB749684604F053FF022135 +:10158400684606F071FEB449684604F04BFF032137 +:10159400684606F069FEC1E08C480078012854D101 +:1015A40001200B9000200A900AAA0BA9280000062B +:1015B400000EFFF725FD0A9B0B9AB449684604F018 +:1015C40031FF0021684606F04FFE28000006000E99 +:1015D40000F0FEF800281DD0AD49684604F022FF53 +:1015E4000121684606F040FEAF49684604F01AFF40 +:1015F4000221684606F038FE28000006000E00F0BE +:1016040097F80100684601F0D7FC0321684606F00C +:101614002BFE19E0A549684604F004FF0121684641 +:1016240006F022FEA249684604F0FCFE0221684648 +:1016340006F01AFE002300226946B44800F0B5FA09 +:101644000321684606F010FE68E001232D062D0EE6 +:101654002A006946AE4800F0A8FA684606F0B0FDD4 +:101664002D062D0E2A00521CAAA16B46181804F050 +:10167400D9FE0021684606F0F7FD012009900020FC +:10168400089008AA09A928000006000EFFF7B8FC74 +:10169400089B099A7D49684604F0C4FE0121684606 +:1016A40006F0E2FD28000006000E00F091F8002884 +:1016B4001AD09949684604F0B5FE0221684606F03E +:1016C400D3FD9649684604F0ADFE28000006000EDE +:1016D40000F02EF80400684606F072FD21006A4608 +:1016E400101801F069FC15E08D49684604F09AFE73 +:1016F4000221684606F0B8FD8A49684604F092FE65 +:10170400684606F05DFD00230022694609187F48FB +:1017140000F04BFA0321684606F0A6FD0DB030BC7C +:1017240008BC1847D052010084250100DC52010096 +:101734007CB504002406240E042060437A490E5824 +:101744000020019000200090002501232406240E8F +:10175400220001A9754800F003F901232406240E90 +:1017640022006946724800F0FBF800983C21484387 +:1017740000902406240E6F48005D002805D002283E +:101784000FD003D3032816D01CE01BE000983018B8 +:101794002406240E04216143674A51584018050069 +:1017A40010E000982406240E04216143624A515833 +:1017B4004018050006E02406240E042060435E4918 +:1017C40008580500280076BC08BC1847605600403D +:1017D40000B501000906090E5648405C002801D0F6 +:1017E400012000E0002008BC18470000780C01002C +:1017F4007C3E0100E85201001CB50023002269462A +:101804004E4800F0ADF80023002201A94C4800F036 +:10181400A7F80421684606F0C3FE04000198844238 +:1018240012D0002000900421684606F0B9FE019011 +:10183400002300226946414800F0E2F80023002218 +:1018440001A93F4800F0DCF813BC08BC18470000AD +:101854006C3E010098250100AC2501001CB5040074 +:1018640000940421684606F09BFE019000230022A8 +:101874006946324800F0C4F80023002201A9304828 +:1018840000F0BEF813BC08BC18470000C0250100D6 +:10189400D425010080B5002300226946274800F0C2 +:1018A4005FF800980ABC18478C3E0100E825010047 +:1018B400706101001CB5002300226946214800F034 +:1018C4004FF80023002201A91F4800F049F8042121 +:1018D400684606F065FE04000198844212D01B4855 +:1018E40000900421684606F05BFE0190002300226C +:1018F4006946144800F084F80023002201A9124824 +:1019040000F07EF813BC08BC18470000D80C010096 +:10191400A80C01002025640048250100F4520100B0 +:101924009C3E0100005301009C530040480F0100FD +:10193400780F0100545500407453004028170100EB +:101944005817010088170100B81701005704000058 +:1019540008B4024B9C4608BC6047C046148600008D +:10196400F2B582B0040016001F0000200090E07859 +:1019740000281AD03F063F0E012F0CD16068864222 +:1019840005D3A0696168491E484300900DE0A06931 +:101994007043009009E0002300226946A068FFF725 +:1019A400DFFF0098A16948430090A07800280ED179 +:1019B400002506F023FE050004220098E1680918BA +:1019C40001A806F059FF2800FFF7C2FF0FE0A07836 +:1019D400012809D101AA0421E068009BC018000471 +:1019E400000C06F0F0FF02E00020C04305E00422F2 +:1019F40001A9029806F040FF0020FEBC08BC18476D +:101A0400F8B584B004000F0016000020019020787F +:101A1400012802D10020C0439CE0206900284DD059 +:101A240025690422290003A806F026FF04222900C0 +:101A3400091D02A806F020FF04223900684606F0BA +:101A44001BFF607802280AD102980099884203D3C8 +:101A540000980399884236D20020C0437AE0607827 +:101A640003280AD102980099884203DB009803995D +:101A7400884228DA0020C0436CE0607804280CD146 +:101A84000298009906F0F0FF04D30098039906F039 +:101A9400EBFF18D20020C0435CE06078052812D028 +:101AA4006078072807D10098B421C90088420AD376 +:101AB4000020C0434EE00020C0434BE00422390024 +:101AC400684606F0D9FEE07800281AD06846007C03 +:101AD40001280CD16068864205D3A0696168491E5B +:101AE400484301900DE0A0697043019009E0002390 +:101AF400002201A9A068FFF733FF0198A1694843B8 +:101B04000190A07800280ED1002506F077FD05008D +:101B1400042269460198E368181806F0ADFE28000F +:101B2400FFF716FF0FE0A078012809D16A460421C7 +:101B3400E068019BC0180004000C06F0C8FE02E037 +:101B44000020C04306E06069002802D0606906F006 +:101B5400A3FF002005B0F0BC08BC184770B5050011 +:101B64000C002869002807D02E6904223100091DC1 +:101B7400200006F081FE01E000200400002070BC7B +:101B840008BC184770B505000C002869002806D069 +:101B94002E6904223100200006F06EFE01E00020D0 +:101BA4000400002070BC08BC1847FEB504000E00F9 +:101BB4006846037A019A69462000FFF7D1FE6078EF +:101BC400022836D12020205C00282CD0206900284F +:101BD40018D025690098296888420CD36868009950 +:101BE400884208D3009804214843616A09583000A8 +:101BF40006F058FF5AE069A1300006F053FF0020B8 +:101C0400C04354E02078012808D1009804214843B7 +:101C1400616A0958300006F045FF47E05FA13000D3 +:101C240006F040FF42E0009A5DA1300004F0FAFBA8 +:101C34003CE06078032805D1009A59A1300004F0F3 +:101C4400F1FB33E06078042809D1009806F062FFC4 +:101C540002000B00BC49300004F0E4FB26E060788D +:101C6400052804D10099300001F08EF91EE0607857 +:101C7400062804D10099300001F0C8F916E0607814 +:101C8400072810D100983C21FEF7DAF90F000098DC +:101C94003C21FEF7D5F905003B002A00AB49300092 +:101CA40004F0C0FB02E00020C04300E00020FEBCC2 +:101CB40008BC1847F8B505000C0017001E002100E9 +:101CC400280000F025F8E869002812D02020285CBC +:101CD400002807D0200006F073FA9DA1201806F012 +:101CE4004DFF06E0200006F06BFA9AA1201806F0DA +:101CF40045FF200006F064FA33001B061B0E3A0071 +:101D040021182800FFF751FF0020F2BC08BC184737 +:101D140038B504000D00E069002804D0E16928000A +:101D240006F0C0FE03E01DA1280006F0BBFE002063 +:101D340032BC08BC1847F8B504000D001700202079 +:101D4400205C002804D1002028700020C04321E03A +:101D54006078022804D0002028700020C04319E0D5 +:101D64002069002811D02669306887420AD3706838 +:101D7400B84207D304207843616A0958280006F062 +:101D840091FE06E00020C04304E004A1280006F010 +:101D940089FE0020F2BC08BC1847000000000000C7 +:101DA4002564000038B504000D0001232A00210039 +:101DB4002C312000FFF724FE002032BC08BC184759 +:101DC40070B584B005002E692869002801D100206F +:101DD4008AE00422310002A806F04EFD04223100FC +:101DE400091D01A806F048FDE878002840D0002429 +:101DF4006868844277D20123220069462800FFF7ED +:101E0400AFFD687802280CD101980099884203D369 +:101E140000980299884229D221002800FFF7C2FFC6 +:101E240024E0687803280CD101980099884203DBE8 +:101E340000980299884219DA21002800FFF7B2FFBE +:101E440014E0687804280ED10198009906F00CFE7D +:101E540004D30098029906F007FE07D22100280057 +:101E6400FFF7A0FF02E00020C0433DE0641CBFE791 +:101E74000123002269462800FFF772FD68780228D2 +:101E84000CD101980099884203D3009802998842A2 +:101E940029D200212800FFF785FF24E06878032871 +:101EA4000CD101980099884203DB0098029988427A +:101EB40019DA00212800FFF775FF14E06878042878 +:101EC4000ED10198009906F0CFFD04D30098029931 +:101ED40006F0CAFD07D200212800FFF763FF02E0E5 +:101EE4000020C04300E0002004B070BC08BC1847C8 +:101EF40038B50500E878002809D0002468688442D1 +:101F040009D221002800FFF74DFF641CF6E70021E9 +:101F14002800FFF747FF002032BC08BC184710B563 +:101F24000024042060430C490858002807D00420EA +:101F3400604309490858FFF743FF641CF1E7002098 +:101F440010BC08BC18470000786101000C53010064 +:101F5400200000003D000000C005010038B5050068 +:101F64000C000123220069463448FFF7F9FC2800DD +:101F740006F026F9009B2200521C3149281804F06F +:101F840051FA0123220069462E48FFF7E9FC280094 +:101F940006F016F9009A2C49281804F043FA012394 +:101FA400220069462948FFF7DBFC280006F008F9FF +:101FB4000099281801F000F8280006F001F924A17E +:101FC400281804F02FFA31BC08BC184738B50500AE +:101FD4000C000123220069461E48FFF7C1FC2800BB +:101FE40006F0EEF8009B2200521C1549281804F054 +:101FF40019FA0123220069461748FFF7B1FC2800AB +:1020040006F0DEF8009A1049281804F00BFA0123B0 +:10201400220069461148FFF7A3FC280006F0D0F817 +:102024000099281800F0C8FF280006F0C9F808A194 +:10203400281804F0F7F931BC08BC1847A8150100AA +:10204400BC3D0100781501001C610100D815010098 +:102054000D0A000038160100081601006816010078 +:1020640030B58FB00400AB480068112800DBF8E1FC +:1020740000202070A7480068002815D10AA800F0A5 +:102084002EFEA549200004F0CDF9200006F098F8B2 +:102094000AA9201800F05DFF200006F091F89F497E +:1020A400201804F0BFF9D5E19A480068012834D11A +:1020B4009B49200004F0B6F90023002201A99948A5 +:1020C400FFF74EFC200006F07BF8019A9649201891 +:1020D40004F0A8F90023002201A99448FFF740FC6A +:1020E400200006F06DF8019A9149201804F09AF93D +:1020F4000023002201A98F48FFF732FC200006F0DC +:102104005FF80199201800F057FF200006F058F8F6 +:10211400CEA1201804F086F99CE17E4800680228CC +:1021240007D1200006F04CF8C949201804F07AF9C8 +:1021340090E178480068032834D17949200004F0FC +:1021440071F9002300226946CC48FFF709FC2000FE +:1021540006F036F8009A7449201804F063F9002355 +:1021640000226946C648FFF7FBFB200006F028F86A +:10217400009A6F49201804F055F90023002269469B +:10218400C048FFF7EDFB200006F01AF8009920186C +:1021940000F012FF200006F013F8ACA1201804F0A0 +:1021A40041F957E15B48006804280BD1CB49200072 +:1021B40004F038F9200006F003F8C949201804F0A7 +:1021C40031F947E15348006805280DD10020050086 +:1021D400032D00DB3EE1200005F0F2FF290020186A +:1021E400FFF7BCFE6D1CF3E74A48006806280DD1D2 +:1021F40003200500062D00DB2CE1200005F0E0FFA4 +:1022040029002018FFF7AAFE6D1CF3E74148006877 +:1022140007280DD1062005000A2D00DB1AE1200055 +:1022240005F0CEFF29002018FFF798FE6D1CF3E798 +:102234003848006808280BD1AA49200004F0F2F8B5 +:10224400200005F0BDFFA649201804F0EBF801E1D9 +:102254003048006809280DD100200500032D00DB5B +:10226400F8E0200005F0ACFF29002018FFF7AEFECF +:102274006D1CF3E7274800680A280DD103200500E8 +:10228400062D00DBE6E0200005F09AFF2900201867 +:10229400FFF79CFE6D1CF3E71E4800680B280DD168 +:1022A400062005000A2D00DBD4E0200005F088FF9D +:1022B40029002018FFF78AFE6D1CF3E71548006813 +:1022C4000C2839D1BC49200004F0ACF800230022CA +:1022D40007A9BA48FFF744FB0798002811D120004A +:1022E40005F06EFFB649201804F09CF80948006810 +:1022F400401C0849086007480068401C05490860FC +:10230400A8E0200005F05CFFAE49201804F08AF82C +:10231400A0E0C046D8550040D03D010004030100B0 +:10232400040B010088140100286101005814010005 +:1023340034610100B8140100CC4800680D2821D193 +:102344000020207000200500062D00DB82E0012320 +:102354002A0003A9AB48FFF703FB039800280BD01E +:10236400200005F02DFF039B04216943B24A525813 +:10237400B249201804F056F8200005F021FF03901C +:102384006D1CE1E7B94800680E281CD100202070BC +:10239400062005000C2D5DDA01232A0006A99948C0 +:1023A400FFF7DEFA069800280BD0200005F008FF9E +:1023B400069B04216943A04A5258A049201804F0FE +:1023C40031F86D1CE6E7A94800680F281CD10020ED +:1023D40020700C200500122D3CDA01232A0005A9E7 +:1023E4008848FFF7BDFA059800280BD0200005F0B7 +:1023F400E7FE059B042169438F4A52588F492018F0 +:1024040004F010F86D1CE6E798480068102821D104 +:102414000020207012200500182D1BDA01232A0049 +:1024240004A97848FFF79CFA049800280BD02000F0 +:1024340005F0C6FE049B042169437F4A52587F4934 +:10244400201803F0EFFF6D1CE6E7C0460D0A0000FC +:102454001405010085480068401C84490860002078 +:10246400A6E082480068FF21123188423CDA8C4899 +:102474000068002808D10020C04399E01815010025 +:10248400E8140100481501007848016811390CA8C6 +:1024940001F06CFD00202070744800681138002899 +:1024A40003D18049200003F0BDFF0C98002806D119 +:1024B4006E480068401C6D490860002078E02000E8 +:1024C40005F07EFE0CA9201801F0C8FE67480068DC +:1024D400401C6649086000206AE0C046B40301005D +:1024E40040F6000064040100604800686E498842B8 +:1024F4005CDA00200290002020705C4800686B4980 +:102504004018002803D16A49200003F08BFF0123FF +:10251400564800686549421802A96648FFF720FA40 +:102524000298002806D151480068401C4F490860B1 +:1025340000203DE0200005F043FE5FA1201803F0D9 +:1025440071FF0123494800685849421802A95948B3 +:10255400FFF706FA029908A800F003FE200005F030 +:102564002FFE08A9201800F0F4FC200005F028FE36 +:102574005249201803F056FF200005F021FE0123E4 +:102584003A490968494A8A1821184D48FFF70DFB52 +:10259400200005F015FE4BA1201803F043FF33483B +:1025A4000068401C31490860002001E00020C0435D +:1025B4000FB030BC08BC184764060100681901005C +:1025C40038200100881A010000B58DB02748002189 +:1025D4000160002300223249A148FFF7C1F900231A +:1025E400002269469F48FFF7BBF9009AAB4901A84E +:1025F40003F018FFAA4901A805F09AF90DB008BC28 +:10260400184700003819010010B582B0040068466C +:10261400002101706A460121A248006805F02EFBE2 +:10262400010068460078002801D0002001E0216004 +:10263400012016BC08BC1847A8510040EC1B01003F +:1026440010B504000948006800280AD1074800684A +:10265400401C064908609449200003F0E3FE002072 +:1026640001E00020C04310BC08BC1847D855004006 +:1026740000B58DB00023002269467A48FFF770F94F +:10268400009A8A4901A803F0CDFE77480021016031 +:10269400874901A805F04CF90DB008BC18470000A3 +:1026A400DC550040F806010011020000EFFEFFFFB8 +:1026B4008C070100681301007C202000C064010025 +:1026C400381301000D0A00007CB505007948006844 +:1026D400002819D178480168684600F042FD77491E +:1026E400280003F09FFE280005F06AFD69462818BB +:1026F40000F02FFC280005F063FD71490A68714958 +:10270400281803F08FFEA2E06A48006801281BD154 +:102714006D4800680400002C0AD1280005F050FD23 +:102724006A49281803F07EFE6248642101608EE045 +:102734006749280003F076FE280005F041FD65494D +:10274400281803F06FFE82E05A48006802281ED160 +:102754000020287000200400062C78DA042060434E +:102764005D4908580600002E0BD0280005F028FD0E +:10277400330004216143594A52585949281803F037 +:1027840051FE280005F01CFD0600641CE4E74948DE +:10279400006803281AD100202870062004000C2C9D +:1027A40055DA042060434C4908580600002E0BD02B +:1027B400280005F005FD330004216143474A5258BF +:1027C4004749281803F02EFE641CE8E739480068DE +:1027D40004281AD1002028700C200400122C36DAA8 +:1027E400042060433C4908580600002E0BD0280002 +:1027F40005F0E6FC330004216143384A5258384955 +:10280400281803F00FFE641CE8E72A48006805282E +:102814001AD10020287012200400182C17DA042082 +:1028240060432D4908580600002E0BD0280005F0FF +:10283400C7FC330004216143284A52582849281808 +:1028440003F0F0FD641CE8E70020C04305E01948EC +:102854000068401C17490860002076BC08BC184773 +:10286400C80D010098190100D855004000B58DB07D +:102874000023002269461B48FFF772F8009A1A49A0 +:1028840001A803F0CFFD0B4800210160174901A8FE +:1028940005F04EF80DB008BC18470000101C0100EC +:1028A40065200000D4550040542001007020010030 +:1028B40045260000D8550040E4550040E43D0100A1 +:1028C400E0550040F83D010068550040A41E010099 +:1028D40064060100881A0100E8500040A851004035 +:1028E400EC1B0100981901008C200100CD2600008A +:1028F400F1B58CB000200190642004F03BFB04F09F +:1029040073FE002827D10023002201A9A348FFF762 +:1029140027F8019800281AD004F07FFE002803D17C +:102924009F480221016006E004F08CFE002802D1D9 +:102934009B480121016004F0CBFB002803D019203F +:1029440001F002FA06E0192001F02CFA02E09448A2 +:1029540000210160CEE7924800210160002300229B +:1029640001A98E48FEF7FCFF0198002802D104F06B +:102974002AFEBFE708A8FFF747FE002800D1B7E00A +:10298400089801285BD0022800D187E0032800D1F1 +:10299400ABE00428AED10023002269468148FEF74B +:1029A400DFFF009880498842A4D1002300227F4998 +:1029B4007F48FEF7D5FF002300227E497E48FEF7BC +:1029C400CFFF00200500032D14DA00200400032C9F +:1029D4000ADAFFF74BFF0600002E05D0FA2080002C +:1029E40004F0C8FA641CF2E7032C03DB04F070FB68 +:1029F4006D1CE8E7032D08DB00220F21002001F005 +:102A0400CBFA042000F0C0F818E000200090002366 +:102A1400002269466348FEF7F3FF0023002269465B +:102A24006348FEF7EDFF0023002269466248FEF783 +:102A3400E7FF00220E21002001F0AEFA5AE7002041 +:102A44000500032D14DA00200400032C0ADAFFF732 +:102A5400BBFD0600002E05D0FA20800004F08AFA9F +:102A6400641CF2E7032C03DB04F032FB6D1CE8E783 +:102A7400032D05DB00220F21002001F08DFA0CE06C +:102A840000220E21002001F087FA01F007FE002346 +:102A940000224A494A48FEF7B3FF2BE7002005000D +:102AA400032D14DA00200400032C0ADAFFF7E0FDFA +:102AB4000600002E05D0FA20800004F05BFA641CA6 +:102AC400F2E7032C03DB04F003FB6D1CE8E7032DA2 +:102AD40005DB00220F21002001F05EFA04E0002251 +:102AE4000E21002001F058FA04E704F0F1FA01E79E +:102AF400344804F03FFA0023002202A93248FEF7CA +:102B04002FFF0023002203A93048FEF729FF039872 +:102B14003C21FDF795FA079003983C21FDF790FAC4 +:102B24000F000023002206A92548FEF719FF029989 +:102B340004A800F016FB069909A800F012FB04A8EB +:102B440080780799884200D2D4E604A84078B84235 +:102B540000D2CFE609A8007904A9097988420CD1EA +:102B640009A8807904A98979884206D109A84079FD +:102B740004A94979884200D1BCE6012000F004F898 +:102B84000E4802990160B5E610B504002100104812 +:102B9400006805F007F910BC08BC1847380D01009F +:102BA400E8550040C819010021436587E0550040FD +:102BB400F8190100E4550040281A0100EC550040C2 +:102BC400480C010010270000F8130100280E010032 +:102BD400D455004010B5002405F010FD04002F4822 +:102BE40000682F4901402D4801602E4800682C4997 +:102BF40001402C4801602C4800682C4901402A48B7 +:102C040001602B48006829490140294801602000DF +:102C1400FEF79EFE012004F0ADF905F0EFFC040080 +:102C240024480068400203D523480021017002E0D3 +:102C34002148012101702000FEF78AFE10BC08BC67 +:102C4400184738B5002505F0D9FC05001A48007866 +:102C540004002800FEF77CFE20000006000E32BCB3 +:102C640008BC184710B513480068400202D500207C +:102C7400040001E0012004000F4800782406240E1B +:102C8400844206D00C4804700620FDF7C3FF0120DF +:102C940000E0002010BC08BC184700000CC002E093 +:102CA400FFCFFFFF4CC002E020C0FF3FFFFFBFFF8C +:102CB40030C0FF3F34C0FF3F7456004010B5B048E9 +:102CC40000684007400F04002000C00702D501201F +:102CD400FDF7A0FFAA48046010BC08BC184738B52B +:102CE4000400002505F08AFC050071480068207086 +:102CF40070480068607070480068A0706F48006891 +:102D0400E0706F48006820716E4800686071A648E2 +:102D140000683030A0712800FEF71AFE31BC08BCF0 +:102D2400184738B50400002505F068FC0500207834 +:102D34005F49086060785F490860A0785E49086070 +:102D4400E0785E49086020795D49086060795D49F2 +:102D54000860A079FA21C9004018A7490860280032 +:102D6400FEF7F6FD31BC08BC184710B500248548B1 +:102D74000068802189000143824801608B48006813 +:102D84008B4901408948016005F038FC04009B48E8 +:102D940011210160092005F062FFC00B401E854926 +:102DA4000860092005F05BFF82490968491C8022FC +:102DB40012025143401A924908607B4800689149C5 +:102DC400884208D33C480068182804D27648006832 +:102DD4008D49884214D38948002101607248894989 +:102DE40001603848082101603548082101603248F3 +:102DF400072101602F4800210160804811210160F2 +:102E0400924893490160934800689349014091486E +:102E14000160924807210160914880218901016085 +:102E24009048002101609048FF2101608F480121F2 +:102E340001602000FEF78CFD10BC08BC184730B5BB +:102E440085B005000C00A079039060790290207988 +:102E54000190207800906378A278B949280003F0A3 +:102E6400E1FA05B030BC08BC184730B58BB005009A +:102E74000C0004A8039005A8029006A8019007A8D6 +:102E8400009008AB09AAAE49280006F075FB049827 +:102E9400A07105986071069820710998A07008982F +:102EA4006070079820700BB030BC08BC1847000055 +:102EB400204002E0244002E0284002E0304002E0EA +:102EC4002C4002E0384002E010B50400A078182835 +:102ED40002D30020C04339E060783C2802D30120AB +:102EE400C04333E020783C2802D30220C0432DE0C5 +:102EF40060790D2802D26079012802D20420C043EF +:102F040024E0A079642802D30520C0431EE0A07900 +:102F1400042100F0ADF900290BD16079022808D111 +:102F24002079002802D020791E280ED30320C04324 +:102F34000CE02079002805D060798249085C217969 +:102F4400884202D20320C04300E0002010BC08BC29 +:102F5400184730B585B005000C00207803906078E0 +:102F64000290A0780190207900906379A279764943 +:102F7400280003F057FA05B030BC08BC184700001D +:102F8400004002E0C4C01FE030B583B004000D006F +:102F94002900684600F0E5F869462000FFF74FFF76 +:102FA40037BC08BC184700003C4002E0A8C11FE041 +:102FB400FFFFF3FF804002E0F1B582B00E00300065 +:102FC4003C2100F055F93C2100F052F90D0030008D +:102FD4003C2100F04DF90F003000E121090100F01F +:102FE40047F9040000972B0022009849029803F047 +:102FF40019FAF7BC08BC18473C4002E0084002E05C +:10300400844002E0DA07000035080000F1B582B020 +:103014000E0030003C2100F02BF93C2100F028F98F +:103024000D0030003C2100F023F90F003000E121B5 +:10303400090100F01DF9040000972B0022008449C7 +:10304400029803F0EFF9F7BC08BC184734F1FFFF0E +:10305400C12C00000CF0FFFFFFDFFFFF34F2FFFF85 +:1030640010F0FFFF404002E0104002E00C4002E09C +:10307400F8B504000D00A079462801D3754801E095 +:10308400FA20C000A1790E183604360C0C207043C7 +:10309400617947180D3F2D062D0E052D3BD03604C2 +:1030A400360C711EFF206E30414300913604360CFD +:1030B400701E042100F0DCF80099081861790222DE +:1030C4005143654A515A4018217940180700360483 +:1030D400360C3000042100F0CBF8002903D16079CC +:1030E400032800D37F1C2D062D0E042D13D0182089 +:1030F4004743A0783F182D062D0E032D0BD03C20FE +:10310400474360783F182D062D0E022D03D03C2036 +:10311400474320783F183800F2BC08BC1847000029 +:1031240010B5040002212000FFF7A2FF4B4940180C +:103134003C2148432178401810BC08BC18470000C3 +:10314400C41E01006C520100E41E010000B583B0EE +:103154006846FFF7C4FD6846FFF7E2FF03B008BC0A +:10316400184770B504000D00002628003C49FCF700 +:1031740067FF06003000001D0721FCF761FFE170C6 +:103184003848854204D338482D180020A07101E046 +:103194004620A071FF206E300600A079042100F0C3 +:1031A40067F8002901D0002000E00120FF216E31E2 +:1031B40046182B484643B54204D3AD1BA079401CA6 +:1031C400A071EAE7012060716079022809D1A07931 +:1031D400042100F04DF8002901D0002002E0012074 +:1031E40000E000206179214A515C0E181C484643D6 +:1031F400B54204D3AD1B6079401C6071E4E728003C +:103204001749FCF71DFF401C207128001449FCF7E6 +:1032140017FF0D002800E1210901FCF711FFA07040 +:103224002800E1210901FCF70BFF0D0028003C21D7 +:10323400FCF706FF607028003C21FCF701FF0D003D +:103244002800207070BC08BC184700004C520100D4 +:103254005C5201006C070000A8200100C0BF45C2F9 +:103264008051010080436D3880BC92C76C520100CC +:103274007847C046802411E200106142402032E0C9 +:103284006800001A010050E1020051231800003ABE +:103294000030A0E3200851E10118A091103083927E +:1032A400200451E10114A09108308392200251E1DD +:1032B4000112A09104308392200151E10111A091E7 +:1032C40002308392A00051E18110A09101308392D9 +:1032D400010050E0A110A0E1001061E20130D3E24E +:1032E4004A0000DA010090E00100403020C063E2AF +:1032F4008CF18FE0010011E1A718000A010050E1F0 +:103304000010A0310000A0330010A0231EFF2FE105 +:103314008000B1E0010040308000B1E001004030A5 +:103324008000B1E0010040308000B1E00100403095 +:103334008000B1E0010040308000B1E00100403085 +:103344008000B1E0010040308000B1E00100403075 +:103354008000B1E0010040308000B1E00100403065 +:103364008000B1E0010040308000B1E00100403055 +:103374008000B1E0010040308000B1E00100403045 +:103384008000B1E0010040308000B1E00100403035 +:103394008000B1E0010040308000B1E00100403025 +:1033A4008000B1E0010040308000B1E00100403015 +:1033B4008000B1E0010040308000B1E00100403005 +:1033C4008000B1E0010040308000B1E001004030F5 +:1033D4008000B1E0010040308000B1E001004030E5 +:1033E4008000B1E0010040308000B1E001004030D5 +:1033F4008000B1E0010040303013A0E1110320E06F +:103404000000A0E002C0A0E31C0380E11EFF2FE146 +:10341400013093E201009030010040300010A0E13F +:103424000300A3E01EFF2FE104402DE90000602209 +:1034340093FFFFEB8220B0E10010614200006022A4 +:103444000440BDE81EFF2FE170B588B000230022C0 +:1034540004A9A048FEF784FA0498002801D10020AA +:1034640033E103F0C1FD04000600A01B06F098F848 +:103474009949884200DB1EE1642003F07BFD03F0E0 +:10348400B3FD040003F04AFA05000120C04385425D +:1034940008D19248002101701A2000F055FC002048 +:1034A400C04312E10020C0438542DED001AA8C490A +:1034B400012003F030FB00281DD068460079002865 +:1034C4000ED068460079002803D06846007900F0E1 +:1034D40047FA8248012101701A2000F063FC07E0DA +:1034E40000F02EFA7D48002101701A2000F02CFC17 +:1034F4000120C043E9E07948012101701A2000F05D +:1035040051FC022276490B3101A8801C05F0B4F964 +:103514006846C088800605D4A12000F021FA022064 +:10352400C043D2E0A12000F03BFA6B2000F038FA4F +:103534006B48807B401E07D0401E0BD0401E0FD02E +:10354400401E012816D916E06B2000F009FA03206A +:10355400C043BAE06B2000F003FA0420C043B4E097 +:103564006B2000F0FDF901A9012003F0CCFC05203B +:10357400C043AAE079E75A48407B002811D00128CB +:1035840012D0022813D0032814D004286BD00528A5 +:103594006CD006286ED0082870D00C2800D189E0A1 +:1035A40089E000F0CDF986E000F0CAF983E000F08C +:1035B400C7F980E00023002202A9BC48FEF7D0F935 +:1035C400029802282CD101A91E2003F04AFB684668 +:1035D40000794B2819D16846007900F0C1F9FFF74A +:1035E400B5FD02000A21002000F0D6FC01A91E202E +:1035F40003F06BFB68460079002833D068460079F5 +:1036040000F0AEF90720C0435FE068460079002867 +:1036140028D06846007900F0A3F90820C04354E09C +:103624000298012815D101A91E2003F0E6FAFFF73C +:103634008DFD02000821002000F0AEFC68460079F0 +:1036440000280FD06846007900F08AF90920C043A9 +:103654003BE00298002805D14E2000F081F90A20B1 +:10366400C04332E027E000F06BF924E04F2000F083 +:1036740077F920E0C02000F073F91CE006AA0020CE +:10368400002103C2083A03A80021016001A80090A8 +:10369400AA4B03AA06A9012003F0E0FB68460079BF +:1036A400002806D06846007900F05AF90A20C04381 +:1036B4000BE000E0D9E6A01B05F072FF0649884242 +:1036C40001DA002001E00020C04308B070BC08BC4F +:1036D40018470000B80E010010270000685600408B +:1036E400445300407CB50023002201A9AB48FEF7F7 +:1036F40037F900F004F90198002857D00620050096 +:10370400002D1BD404206843B249085806F064F81D +:103714000A200400642003F02DFC03F0FFF80600E7 +:10372400002E03D00020C043864200D102E0641E74 +:10373400002CEFD1002C01D16D1EE1E7002D0AD53C +:103744001A2000F001FBA4480021017000F0EBF8FE +:103754000020C04336E06A46A049012003F0DBF9AB +:10376400002819D068460078002808D068460078F8 +:10377400002811D06846007800F0F2F80CE000F060 +:10378400DFF89548002101701A2000F0DDFA00F0FE +:10379400CAF80120C04315E08F48012101701A20A6 +:1037A40000F000FB00F0BFF800200BE08A48002185 +:1037B400017000F0C5F81A2000F0F4FA00F0B3F834 +:1037C4000220C04376BC08BC18477CB50023002205 +:1037D40001A97248FEF7C4F800F091F80198002896 +:1037E40054D006200500002D18D4042068437949DC +:1037F400085805F0F1FF0220040003F08FF80600DA +:10380400002E03D00020C043864200D102E0641E93 +:10381400002CF2D1002C01D16D1EE4E7002D0AD555 +:103824001A2000F091FA6C480021017000F07BF836 +:103834000020C04336E06A466849012003F06BF972 +:10384400002819D068460078002808D06846007817 +:10385400002811D06846007800F082F80CE000F0EF +:103864006FF85D48002101701A2000F06DFA00F035 +:103874005AF80120C04315E05748012101701A206D +:1038840000F090FA00F04FF800200BE052480021BD +:10389400017000F055F81A2000F084FA00F043F8A3 +:1038A4000220C04376BC08BC1847000098160100EB +:1038B40080B54B480068002804D1012006F09EF82A +:1038C40047490860FFF70EFF002801D1FFF7BCFD50 +:1038D40009BC184738B5002404F090FE04003E48A3 +:1038E4000078012802D10120050001E00020050034 +:1038F4002000FEF72DF8280032BC08BC184780B51C +:103904006A4601213648006806F0A1F86846007846 +:10391400002806D0012003F02DFB6846007800281B +:10392400EED109BC184780B5C82003F023FB2C480E +:10393400006806F0F9F809BC1847000038230100B4 +:1039440010B51B242406240EAA2C06D2200000063F +:10395400000E00F027FA641CF4E710BC08BC1847FA +:1039640010B504002406240E002C14D000200006F8 +:10397400000E8F280FD20006000EC049095C2406F1 +:10398400240EA14205D11B300006000E00F0DCF924 +:1039940001E0401CEBE710BC08BC1847B80E01005E +:1039A40010B5040000200006000E8F280FD2000678 +:1039B400000EB249095C2406240EA14205D11B3035 +:1039C4000006000E00F0EEF901E0401CEBE710BC2D +:1039D40008BC1847581F0100685600404453004073 +:1039E400AC550040F2B58CB005000C98FA21890062 +:1039F40048433C21FCF724FB002108AA03C2083AEF +:103A04006420684300210AAA03C2083A280006F089 +:103A1400C5F80022B04B06F0CBF80022AF4B06F0FD +:103A2400C7F806000F000C9806F0B8F802000B0067 +:103A34003000390006F0BAF906F056FB06AA03C2B4 +:103A4400083A05A80021016000200490FFF757FF01 +:103A5400FFF7FAFC002804D5FFF765FF6320C04395 +:103A6400ECE00020040003AA0021012003F064F923 +:103A740000281AD06846007B002804D06846007BE2 +:103A8400FFF76EFF07E0FFF75BFFA6480021017018 +:103A94001A2000F059F92406240E002C04D0FFF754 +:103AA40042FF0020C043C9E0641C2406240E002CFD +:103AB40008D0FFF7C9FC0028D5D0FFF734FFC72092 +:103AC400C043BBE00023002204A99748FDF748FF48 +:103AD4000498002836D10020040003A802909348DB +:103AE400019005A80090002306AA08A9012003F06C +:103AF4005BF900281AD06846007B002804D0684689 +:103B0400007BFFF72DFF07E0FFF71AFF8548002130 +:103B140001701A2000F018F92406240E002C04D099 +:103B2400FFF701FF0120C04388E0641C2406240E33 +:103B3400002C4DD0FFF788FC0028CED0FFF7F3FE11 +:103B44007B487BE00498012842D10020040008AAA5 +:103B5400FA208000002103C2083A6420684300214F +:103B640006AA03C2083A03A802907248019005A865 +:103B74000090002306AA08A9012003F015F90028E3 +:103B84001AD06846007B002804D06846007BFFF703 +:103B9400E7FE07E0FFF7D4FE6248002101701A2017 +:103BA40000F0D2F82406240E002C04D0FFF7BBFE4C +:103BB4000220C04342E0641C2406240E002C07D0DB +:103BC400FFF742FC0028C2D0FFF7ADFE5A4835E0AB +:103BD4000020040003A80090584B05AA0AA901205C +:103BE40003F03CF900281AD06846007B002804D072 +:103BF4006846007BFFF7B4FE07E0FFF7A1FE4948E3 +:103C0400002101701A2000F09FF82406240E002CD5 +:103C140004D0FFF788FE0320C0430FE0641C240691 +:103C2400240E002C07D0FFF70FFC0028D2D0FFF79A +:103C34007AFE414802E0FFF776FE00200DB0F0BCAA +:103C440008BC184710B5040000200006000E8F2899 +:103C54000FD20006000E0949095C2406240EA14275 +:103C640005D11B300006000E00F0CAF802E0401C2B +:103C7400EBE7002010BC08BC184700002008010036 +:103C840000B5010000200006000E8F280CD20006AB +:103C9400000E2B4A125C0906090E8A4202D1000664 +:103CA400000E02E0401CEEE7002008BC184738B5BF +:103CB400002400252D062D0E462D09D22D062D0E8D +:103CC4002048405DFFF7BEFF204304006D1CF1E770 +:103CD400200032BC08BC18470000594000004E4088 +:103CE40070B5040000250020207000263606360E2C +:103CF400462E13D23606360E1248805DFFF7A2FF19 +:103D04000500002D08D03606360E0E48805DFFF7FC +:103D1400B7FF1B30207001E0761CE7E7280070BC79 +:103D240008BC184768560040C8160100502301001B +:103D3400D4FEFFFFAC4E010070FEFFFF38230100EC +:103D440020080100380A0100F0B583B00400002502 +:103D540004F054FC05002406240E20002021FFF763 +:103D640087FA04214843BA49009001912406240E9D +:103D740020002021FFF77CFA04214843B4490E585F +:103D840001272406240E20002021FFF771FA8F401A +:103D94003743019900980F502800FDF7D9FDF7BC6F +:103DA40008BC1847F0B583B00400002504F026FCD5 +:103DB40005002406240E20002021FFF759FA0421CF +:103DC4004843A349009001912406240E2000202199 +:103DD400FFF74EFA042148439D490E580127240653 +:103DE400240E20002021FFF743FA8F40BE4301999F +:103DF40000980E502800FDF7ABFDF7BC08BC18472F +:103E0400F8B506000024002504F0F8FB050036068A +:103E1400360E30002021FFF72BFA042148438C4949 +:103E24000858009001273606360E30002021FFF78F +:103E34001FFA8F40009807403C002800FDF788FDDA +:103E44002000F2BC08BC184738B500240025002027 +:103E54000090002300226946B648FDF781FD04F076 +:103E6400CDFB05000098002808D1FFF720FF204370 +:103E740004001A20FFF7C4FF204304000120FFF7C9 +:103E8400BFFF204304002800FDF762FD002C01D091 +:103E9400012000E0002032BC08BC18470020704715 +:103EA40010B502242406240E192C06D22000000684 +:103EB400000EFFF777FF641CF4E710BC08BC18473A +:103EC400F1B582B000270026002500200400FF2C55 +:103ED4001BD86A46082108206043974BC018000489 +:103EE400000C04F070FD0098002804D00098002114 +:103EF400C943884201D1270007E00098A84202D3B1 +:103F0400009805002600641CE1E7FF2C06D9300068 +:103F1400401C80214900FCF793F80F00FFF716F9C5 +:103F24000090029801906A46082108207843824B49 +:103F3400C0180004000C04F0CAFCF7BC08BC184705 +:103F440038B505000C00FF2C02D90020C0430AE05C +:103F54002A00082108206043774BC0180004000C95 +:103F640004F031FD002032BC08BC184738B5050008 +:103F74000C00FF2C02D90020C0430AE02A000A21C9 +:103F84000A2060436D4BC0180004000C04F01BFDB4 +:103F9400002032BC08BC1847F7B584B000270026BF +:103FA400002500200400FF2C1BD86A460A210A20A1 +:103FB4006043624BC0180004000C04F004FD009838 +:103FC400002804D000980021C943884201D1270069 +:103FD40007E00098A84202D3009805002600641C5C +:103FE400E1E7FF2C06D93000401C80214900FCF792 +:103FF40027F80F00FFF7AAF8009068466946097C85 +:10400400417268466946097D0172069801906A46C4 +:104014000A210A207843494BC0180004000C04F01C +:1040240056FC07B0F0BC08BC184780B500228021BC +:104034000901414804F089FC09BC184780B50022F5 +:10404400A02109013D4804F080FC09BC1847000088 +:104054001454004038B504000D002D062D0E280020 +:1040640001281AD002281DD0032820D0042823D0E8 +:10407400062826D0072829D008282CD009282FD094 +:104084000A2832D00B2835D00C2838D00D283BD044 +:104094000E2843D00F283CD045E06149200002F0AF +:1040A400C1F944E05F49200002F0BCF93FE05E49F9 +:1040B400200002F0B7F93AE05C49200002F0B2F9BE +:1040C40035E05B49200002F0ADF930E059492000A9 +:1040D40002F0A8F92BE05849200002F0A3F926E0E9 +:1040E4005649200002F09EF921E05549200002F0D3 +:1040F40099F91CE05349200002F094F917E0524961 +:10410400200002F08FF912E05049200002F08AF9F1 +:104114000DE04F49200002F085F908E04D492000E8 +:1041240002F080F903E04CA1200002F07BF931BCDD +:1041340008BC1847E80E0100CE070000CE0F0000AF +:1041440038B504000D002D062D0E280001281AD0C4 +:1041540002281DD0032820D0042823D0062826D0E6 +:10416400072829D008282CD009282FD00A2832D093 +:104174000B2835D00C2838D00D283BD00E2843D03E +:104184000F283CD045E0B249200002F04BF944E04E +:10419400B049200002F046F93FE0AF49200002F0A8 +:1041A40041F93AE0AD49200002F03CF935E0AC4970 +:1041B400200002F037F930E0AA49200002F032F979 +:1041C4002BE0A949200002F02DF926E0A7492000A0 +:1041D40002F028F921E0A649200002F023F91CE0AE +:1041E400A449200002F01EF917E0A349200002F0C0 +:1041F40019F912E0A149200002F014F90DE0A049D8 +:10420400200002F00FF908E09E49200002F00AF9AC +:1042140003E09D49200002F005F931BC08BC1847B1 +:10422400605601006C560100785601008456010066 +:10423400905601009C560100BC4E0100CC4E01007A +:1042440044380100DC4E0100A8560100EC4E010088 +:10425400583801006C380100EDE5F2007CB504002B +:104264000D00287A002800D1EBE0280005F07AFF41 +:1042740001006846FEF775FF84A1200002F0D2F821 +:10428400200003F09DFF69462018FEF762FE20001F +:1042940003F096FF297A2018FFF752FF287A0128A5 +:1042A40002D0287A022816D1200003F089FF6A7A06 +:1042B400521C7749201802F0B5F8200003F080FF63 +:1042C40006002800001D05F04DFF02007149A019E9 +:1042D40002F0A8F8ADE0287A032815D1200003F0F5 +:1042E4006FFF6A7A521C6A49201802F09BF820007A +:1042F40003F066FF06002800001D05F033FF0100EF +:10430400A019FEF759FE94E0287A042810D1200061 +:1043140003F056FF6A7A521C5D49201802F082F8B5 +:10432400200003F04DFFC5A1201802F07BF880E0C7 +:10433400287A062807D1200003F042FFBFA12018E5 +:1043440002F070F875E0287A072809D1200003F0FC +:1043540037FF6A7A521C4E49201802F063F868E06D +:10436400287A082807D1200003F02AFFB3A12018D7 +:1043740002F058F85DE0287A092807D1200003F0FC +:104384001FFFAEA1201802F04DF852E0287A0A2847 +:1043940007D1200003F014FFA8A1201802F042F86E +:1043A40047E0287A0B2815D12800001D05F0DAFE15 +:1043B400002807D1200003F003FFD349201802F09E +:1043C40031F836E0200003F0FBFED049201802F05B +:1043D40029F82EE0287A0C280DD1200003F0F0FEF5 +:1043E40006002800001D05F0BDFE0200D649A019F4 +:1043F40002F018F81DE0287A0D280DD1200003F0F2 +:10440400DFFE06002800001D05F0ACFE0200CFA16F +:10441400A01902F007F80CE0287A0E2802D0287AB6 +:104424000F2806D1200003F0CBFE84A1201801F050 +:10443400F9FF200003F0C4FEDAA1201801F0F2FF16 +:1044440003E0D949200001F0EDFF73BC08BC184714 +:104454008038010094380100A8380100BC380100FC +:10446400FC4E0100D03801006823010080230100C4 +:10447400041E0100E4380100F8380100982301000B +:10448400241E0100441E01000C3901007C20200080 +:10449400B45601003064010070B5A6B004000E00EB +:1044A400150002AA04212406240E04206043CB2311 +:1044B400DB00C0180004000C04F085FA01AA0421F2 +:1044C4002406240E04206043D023DB00C01800041B +:1044D400000C04F078FA6A4604212406240E042011 +:1044E4006043D523DB00C0180004000C04F06BFA11 +:1044F4000298401C0290019880190190009840197C +:10450400009002AA04212406240E04206043CB2335 +:10451400DB00C0180004000C04F0D9F901AA04213E +:104524002406240E04206043D023DB00C0180004BA +:10453400000C04F0CCF96A4604212406240E04205D +:104544006043D523DB00C0180004000C04F0BFF95D +:1045540002AA0421DA20C00004F035FA01AA0421D9 +:10456400924804F030FA6A460421DB20C00004F0CB +:104574002AFA0298401C0290019880190190009830 +:104584004019009002AA0421DA20C00004F09FF927 +:1045940001AA0421854804F09AF96A460421DB2023 +:1045A400C00004F094F903AA8621E820C00004F0B6 +:1045B4000AFA2406240E0420604303A90858401C68 +:1045C4002406240E0421614303AA50502406240E19 +:1045D4000420604303A90818806A80192406240E65 +:1045E4000421614303AA511888622406240E04207E +:1045F400604303A90818006D40192406240E042101 +:10460400614303AA511808652198401C21902298FF +:1046140080192290239840192390842103A803F041 +:10462400BFFF03A98431088003AA8621E820C000C3 +:1046340004F04DF926B070BC08BC18470000000017 +:1046440010B5A2B06A468621E820C00004F0BBF988 +:104654008421684603F0A4FF04006846843000887F +:104664002404240C844215D086220021684605F0D7 +:104674008BFD8421684603F093FF694684310880EA +:104684006A468621E820C00004F021F900F006F80B +:1046940000F03EF822B010BC08BC184780B50022D8 +:1046A4008421CB20C00004F050F909BC184710B590 +:1046B40082B00400182C23D26A46042104206043EB +:1046C4003B4BC0180004000C04F07DF90098401C1A +:1046D40000906A46042104206043354BC01800044E +:1046E400000C04F0F4F86A460421324804F06BF933 +:1046F4000098401C00906A4604212E4804F0E7F814 +:1047040013BC08BC1847000038640100C0560100FF +:1047140010B582B00020009000200400182C0BD2A9 +:104724006A46042104206043214BC0180004000C95 +:1047340004F0CDF8641CF1E76A4604211D4804F036 +:10474400C6F813BC08BC1847406401002575000076 +:1047540070B50024AA2C1CDA20002021FEF788FD65 +:104764000421484314490D58012620002021FEF756 +:104774007FFD8E402E40002E09D120000006000E41 +:10478400FFF73EFB002802D02000FFF799FB641CD2 +:10479400E0E720220949084804F06EF870BC08BC20 +:1047A400184700000D0A00000C4F0100D406000059 +:1047B400DC0600003C070000345400401454004060 +:1047C40030B589B005000C00287800280BD16A6840 +:1047D40046A1684601F026FE21000906090E684636 +:1047E40005F08EFF66E02878022855D1684620211E +:1047F40001703F480078002840D03E4800782406E5 +:10480400240E84423AD13C480068203000780028C5 +:1048140018D06946491C38480068FDF779FA37A171 +:10482400684604F0ABF93649684604F0A7F935A1A7 +:10483400684604F0A3F921000906090E684605F04C +:104844005FFF37E06946491C2B480068FDF760FAB2 +:10485400294800681C3005F085FC002803D02AA1F3 +:10486400684604F08BF92649684604F087F921006C +:104874000906090E684605F043FF1BE000230022E9 +:104884006946491C6868FDF715FA21000906090EF6 +:10489400684605F035FF0DE0287801280AD16A68DA +:1048A40012A1684601F0BEFD21000906090E684602 +:1048B40005F026FF09B030BC08BC184710B582B01B +:1048C400040068460021017021000906090E6846AB +:1048D40005F016FF13BC08BC184780B505F07BFF34 +:1048E40009BC1847B84800687047000020257300C9 +:1048F4006C56004070560040C85500403C00000013 +:10490400545400403E0000003D000000F8B5AE489D +:104914000068407A01283BD10020040005F069FFBB +:10492400002005002D062D0E042D14D22D062D0E6B +:1049340004206843A449096809680858009000984D +:10494400002808D021000906090E0098FFF738FF57 +:10495400641C6D1CE6E72406240E042C06D22000F9 +:104964000006000EFFF7AAFF641CF4E796480068EF +:10497400006800684078800709D50022122185204C +:1049840005F015FF00221321842005F010FF13E128 +:104994008D4800680068006800900098002802D1E3 +:1049A400FFF79BFF08E100210098FFF709FF874804 +:1049B4000078002803D18648002101701DE0824858 +:1049C4000068007A042805D280480078401E804997 +:1049D400087012E07D4800787B490968097A891ECD +:1049E400884205DA79480078401E7949087004E065 +:1049F40076480078801E7649087075480078401C17 +:104A04000500012004002406240E042C1FD26E4845 +:104A14000068007A2D062D0E854218D22D062D0E23 +:104A2400042068436849096809680E58002E05D1B6 +:104A340020000006000EFFF741FF05E021000906F3 +:104A4400090E3000FFF7BCFE6D1C641CDBE7240676 +:104A5400240E042C06D220000006000EFFF72EFFC1 +:104A6400641CF4E75948007804214843564909680E +:104A740009680818406806783606360E002E0CD1F0 +:104A84005248007852490978421A521C1206120EF2 +:104A94000021DF2005F08BFE3AE03606360E012EAB +:104AA4000CD14A4800784A490978421A521C120625 +:104AB400120E0021132005F07AFE29E03606360E88 +:104AC400022E25D141480078042148433E49096813 +:104AD4000968081847687868007800280CD13B48B2 +:104AE40000783B490978421A521C1206120E002122 +:104AF400842005F05CFE0BE03448007834490978E2 +:104B0400421A521C1206120E0021DF2005F04FFE3D +:104B14002D480068006800684778B80709D5002266 +:104B24001221852005F043FE00221321842005F084 +:104B34003EFEA048007800283CD09F480068203002 +:104B44000078002836D19C4800684078022811D1AA +:104B54001E4800781E490978411A491C0906090EA5 +:104B640096480078964A127880180006000E05F0E0 +:104B7400EDFD1CE0904800684078052804D08E487C +:104B840000684078072812D1104800781049097845 +:104B9400411A491C0906090E88480078884A127887 +:104BA400A94B9A5C80180006000E05F0CFFD05F0B5 +:104BB40019FE01E005F01DFEF1BC08BC1847A3482E +:104BC4000121017070470000B85500406A5600404A +:104BD4006B56004010B501000020002213001A009B +:104BE400521C0C7A1B061B0EA3420CD21206120E88 +:104BF400042353430C68E3581C78012C02D01C781E +:104C0400022CEBD11000401E0006000E10BC08BCA4 +:104C1400184730B502000800401C0B005B1C1C0048 +:104C240023005B1C157A2406240EAC420CD21B060E +:104C34001B0E04245C4315682C592578012D02D0E1 +:104C44002578022DEBD11800401E0006000E30BC62 +:104C540008BC184730B503000C00641C0A00521C41 +:104C64000906090E002901D1002015E01000421E9A +:104C74000006000E00280CD01206120E0420504329 +:104C84001D6828580578012D02D00578022DEDD134 +:104C94001400601E0006000E30BC08BC184710B596 +:104CA40004006B480078082826D269480078082157 +:104CB40048436849684A12680A50654800780821E0 +:104CC40048436449081865490978017160480078C7 +:104CD400401C5F490870604804605F480068FFF743 +:104CE40079FF5E4908706068002802D0606803F0AC +:104CF400D3FE56480121017010BC08BC184710B5FA +:104D040004005548046054480068FFF763FF5349A2 +:104D140008706068002802D0606803F0BDFE4B484C +:104D24000121017010BC08BC184780B548480078C0 +:104D3400002822D046480078401E4549087044485F +:104D440000780821484343490858434908604048CB +:104D54000078082148433F49081800793F49087002 +:104D64003D4800684068002804D03B48006840681B +:104D740003F092FE35480121017009BC184780B543 +:104D84003648007804214843A54909680968081889 +:104D94004068806800280BD03048007804214843DC +:104DA4009F4909680968081840688068FFF777FF19 +:104DB40009BC18476C560040C85500406E56004068 +:104DC4006D5600407CB505000C001600954800683F +:104DD4004078022823D16846252101706846302195 +:104DE40041702406240E20000A21FEF741FA3030D7 +:104DF400694688702406240E20000A21FEF738FA3A +:104E040030316846C17068467521017168460021D9 +:104E1400417132006946280001F004FB10E081482A +:104E240000684078052804D07E4800684078072848 +:104E340006D10023002229007A480068FCF7B5FE59 +:104E440073BC08BC18470000D856010071560040D6 +:104E54006956004008520040B85500406A56004068 +:104E640010B571480021017070480078042148434E +:104E74006B4909680968081840684068694908600E +:104E84006A480078401C6A490978401A69490870E0 +:104E940000230022684963480068FCF761FD61480B +:104EA4000068103005F05EF9040004222100634814 +:104EB40003F0E2FC04222100091D614803F0DCFC3C +:104EC4005848006820300078002807D000230022CA +:104ED4005C4954480068FCF768FE45E0594951486C +:104EE4000068FCF715FF4F4800681C3005F03AF9DC +:104EF400002803D054A1534803F040FE514803F066 +:104F04005FF9401C514908704648006840780228FF +:104F14000ED12000001D05F025F902004CA14948DE +:104F240001F080FA474803F04BF94A49087014E04D +:104F34003C4800684078052803D146480C2101709C +:104F44000BE0384800684078072803D14148042121 +:104F5400017002E03F4800210170374802683D4873 +:104F640001783848FFF72EFF3B480121017010BC3F +:104F740008BC1847384800210170704700B587B055 +:104F8400284800684078022812D12648006820305A +:104F94000078002804D1284A30A12A4804F0ECFA09 +:104FA4000023002224491F480068FCF729FD31E052 +:104FB4001C4800684078052814D104A92148FDF74D +:104FC40054FF04A8FDF780FF002823D104A8FEF7AE +:104FD400A7F803900023002203A912480068FCF7F5 +:104FE4000FFD17E00F4800684078072812D101AB85 +:104FF40002AA1B49134804F0BFFA02983C21484313 +:105004000199401800900023002269460548006871 +:10501400FCF7F6FC10480021017007B008BC1847E3 +:10502400B8550040C85500406D5600406A560040CF +:105034006B56004070560040BC550040C4550040BB +:10504400C0550040545400403D0000006E560040DE +:10505400257500006F5600406C5600402564000022 +:10506400CC560100F0B58FB0070000246848FFF764 +:1050740046FE0020029002A805F0D4FE002810D1BC +:10508400641CFA20800084420BDAFA204000844237 +:1050940003DB60480078002803D15F4800780028CB +:1050A400E7D05D480078002804D05B4800210170F7 +:1050B400FFF72CFC57480078002800D0B7E0002008 +:1050C40004000298002800D1AEE0029804281FD002 +:1050D400CFD306284BD005D308280ED076D3092881 +:1050E40077D0C6E7C3480178C3480068FFF7B2FD2C +:1050F400C0490870FFF70AFCBBE7BE480178BE4808 +:105104000068FFF786FDBB490870FFF7FFFBB0E7B7 +:10511400B9480068006806687078800726D5756805 +:105124006878022820D10023002201A92800FCF776 +:1051340017FC0EA92800FCF725FD08A92800FCF798 +:105144000DFD0198401E019001980E99884203D3E9 +:1051540008980199884201D20898019000230022FE +:1051640001A92800FCF74CFCFFF7D0FB81E7A2481B +:105174000068006806687078800726D575686878C6 +:10518400022820D10023002269462800FCF7E8FB0E +:1051940007A92800FCF7F6FC0DA92800FCF7DEFCA3 +:1051A4000098401C009000980799884203D30D98FA +:1051B4000099884201D20798009000230022694692 +:1051C4002800FCF71DFCFFF7A1FB52E7FFF7ADFD3C +:1051D4004FE789480068407A012802D1FFF796FB1F +:1051E40047E78448007804214843834909680968EB +:1051F400081845682878022810D16E68307800288D +:1052040011D1FFF72DFEFA20800004000BE0C04608 +:105214002C5701006C560040715600402878012834 +:1052240001D1FFF7ACFD24E7FFF770FB21E70298FB +:10523400002800D199E10298042800D122E100D28B +:1052440090E1062800D151E108D3082800D18DE06F +:1052540000D282E1092800D182E183E1C5480068D7 +:1052640020300078002823D006A9C2480068FCF743 +:1052740089FC0CA9BF480068FCF770FCBE480068B4 +:10528400401CBD490860BC4800680699884204D3A4 +:105294000C98B9490968884202D2B7480699016056 +:1052A400B5480268B549B3480068FCF744FD5CE0C2 +:1052B400B04800684078022814D1C0480078AF494B +:1052C400085C401CBD490978AC4A5054BB4800787E +:1052D400AA49085C3A2848D3B8480078A74930223C +:1052E4000A5442E0A3480068407805281CD1B3481A +:1052F4000078B349085CA149085C401CAF490978AF +:10530400AF4A515C9D4A5054AC480078AC49085CA3 +:105314009A49085C3A2828D3A8480078A849085C28 +:10532400964930220A5420E09248006840780728C1 +:105334001BD1A2480078A249085C9049085C401C33 +:105344009E4909789E4A515C8C4A50549B48007887 +:105354009B49085C8949085C3A2806D39748007839 +:105364009749085C854930220A54FBE0814800686B +:1053740020300078002823D00BA97E480068FCF771 +:1053840001FC05A97B480068FCF7E8FB7A48006843 +:10539400401E79490860784800680B99884204D314 +:1053A400059875490968884202D2734805990160D5 +:1053B4007148026871496F480068FCF7BCFC60E002 +:1053C4006C4800684078022818D17C4800786B4902 +:1053D400085C401E79490978684A50547748007837 +:1053E4006649085C30284CD27448007863493922F5 +:1053F4000A5446E06A560040B85500405D480068CB +:10540400407805281CD16D4800786D49085C5B49DB +:10541400085C401E69490978694A515C574A5054EE +:10542400664800786649085C5449085C302828D2EC +:10543400624800786249085C504939220A5420E0E5 +:105444004C480068407807281BD15C4800785C49C8 +:10545400085C4A49085C401E58490978584A515C1E +:10546400464A5054554800785549085C4349085CFD +:10547400302806D2514800785149085C3F49392206 +:105484000A546FE03B48006820300078002823D09D +:105494000AA938480068FCF775FB04A93548006878 +:1054A400FCF75CFB34480068401E3349086032480E +:1054B40000680A99884204D304982F4909688842ED +:1054C40002D22D48049901602B4802682B492948CF +:1054D4000068FCF730FC08E038480078002804D065 +:1054E40036480078401E354908703BE02148006882 +:1054F40020300078002823D003A91E480068FCF758 +:1055040041FB09A91B480068FCF728FB1A480068FE +:10551400401C19490860184800680399884204D35C +:10552400099815490968884202D213480399016011 +:105534001148026811490F480068FCF7FCFB0BE0B6 +:105544001E4800782D490978491E884204DA1B4810 +:105554000078401C1949087004E0FFF70BFD01E0D6 +:10556400FFF70CFDFFF7D2F983E500200400FFF7F5 +:10557400CDF97EE5C8550040BC5500405454004068 +:1055840080B51F48002101701E48002101701E488B +:10559400002101701D48002101701D480021016097 +:1055A400402200211B4804F0EFFD0B231A4A00217E +:1055B4001A4802F057FC09BC184700006D56004019 +:1055C400D856010080B50B2002F016FDFFF785F9CF +:1055D400642001F0CFFCFFF7D3FF642001F0CAFC84 +:1055E400FDF72FFB002803D10D48FFF788FB02E0ED +:1055F4000C48FFF784FB09BC184700006F560040B5 +:10560400695600406A5600406B5600406C56004094 +:10561400B855004008520040741E00406950000014 +:10562400505D01000458010030B583B0050000242A +:10563400B74800210160B748012101700120FEF73D +:10564400B1FB0220FEF7AEFB962001F093FC002391 +:10565400002201A9BA48FCF783F9AE480078012872 +:105664001ED10198002809D1AA4801210170012006 +:10567400FEF798FB0220FEF795FBE5E700F062F9E0 +:10568400002803D00120FEF75FFBDDE70120FEF7D1 +:1056940089FB0220FEF786FB9E48002101700CE086 +:1056A4000198002809D19B48012101700120FEF7CF +:1056B40079FB0220FEF776FBC6E76946032000F07B +:1056C400D5FB002800D133E12406240E002C08D099 +:1056D40068460078422804D0002004001D20FBF70F +:1056E40099FA684600781038052822D9C01F042882 +:1056F4001FD9401F20D025385DD0401E5FD0401EEA +:1057040069D0401E6BD0401E6DD0801E6FD009380A +:10571400042800D8A4E01538022800D8A0E01B38DB +:1057240000D1D0E0401E00D19EE0401E00D1F3E045 +:10573400F5E0FEF7B5FBF4E00220FEF733FB684624 +:105744004078602812D0612814D062280ED06428D2 +:1057540014D0652816D0662818D067281AD068286F +:105764001CD069281ED06C2820D023E00320FEF72B +:10577400EBFA1FE00420FEF7E7FA1BE00520FEF732 +:10578400E3FA17E00620FEF7DFFA13E00720FEF73E +:10579400DBFA0FE00820FEF7D7FA0BE00920FEF74A +:1057A400D3FA07E00A20FEF7CFFA03E00B20FEF756 +:1057B400CBFAFFE7B5E00C20FEF7C6FAB1E0240609 +:1057C400240E002C06D11C20FBF724FAFEF768FBFC +:1057D40001200400A5E00E20FEF7B6FAA1E00F2098 +:1057E400FEF7B2FA9DE01020FEF7AEFA99E06846A3 +:1057F400407850280ED0512810D0522812D0532867 +:1058040014D0542816D0652818D066281AD06728D2 +:105814001CD01EE01120FEF797FA1AE01220FEF7C2 +:1058240093FA16E01320FEF78FFA12E01420FEF725 +:105834008BFA0EE01520FEF787FA0AE01620FEF731 +:1058440083FA06E01720FEF77FFA02E01820FEF73D +:105854007BFA0120FEF778FA2E480121017060E0FE +:105864000220FEF771FA5CE003220021002000F020 +:1058740031FB002802D10120FEF766FA6846407821 +:10588400182814D22248006805F0FAFA69464978C3 +:105894000C225143984A515805F0FCFA05F04EFB8E +:1058A4001B490860684640789449086005E0184838 +:1058B400002101609148182101600520FBF7AAF935 +:1058C400FEF7EEFA2DE068464078182814D2104806 +:1058D400006805F0D5FA694649780C225143864A96 +:1058E400515805F0D7FA05F029FB094908606846C4 +:1058F40040788249086005E00548002101607F483E +:10590400182101600420FBF785F9FEF7C9FA08E0C5 +:1059140038560040740A0040FEF7C2FA01E0FEF770 +:10592400BFFA0120FEF73EFA7548002101708BE6AC +:105934000120FEF709FA72480121017084E6000093 +:10594400080D010010B5C82001F014FB002004006C +:10595400182C06DA042060436A4900220A50641CA9 +:10596400F6E700F083F8032000F04EFA002802D195 +:105974000020C04326E06049032000F065FB0028B6 +:1059840002D10120C0431DE000200400182C0BDAD2 +:105994000C2060435849085805F0D0FA04216143AB +:1059A400584A5050641CF1E703220021002000F003 +:1059B40091FA002802D10220C04303E0504800219C +:1059C4000170002010BC08BC184738B5002402F050 +:1059D40015FE04004A480078002802D10120050081 +:1059E40001E0002005002000FBF7B2FF280032BCD4 +:1059F40008BC184710B59620800105F0DFFA002492 +:105A040002F0FCFD040040480068404901403E4863 +:105A140001603F4800683D4901403D4801603D4800 +:105A24000068102101433B4801603B480068102195 +:105A340088433949086039480068102101433748D0 +:105A440001602000FBF784FF3548006800280AD174 +:105A5400012003F0D3FF324908600623314A0021B4 +:105A6400314802F0FFF910BC08BC184780B500F0BB +:105A740013F82A4800681021014328480160642073 +:105A840001F078FA29480068102101432748016091 +:105A940000F016F809BC184780B56A460121204871 +:105AA400006803F0D4FF68460078002806D001207F +:105AB40001F060FA684600780028EED109BC184766 +:105AC40080B51748006804F02FF809BC184770B572 +:105AD4000400002502F092FD0500154806681448EC +:105AE400002101600548006820602800FBF730FFB2 +:105AF400300070BC08BC184744480040700A00409D +:105B0400740A0040A851004010C002E0FFFCFFFFEF +:105B140050C002E040C0FF3F50C0FF3F5CC0FF3FA9 +:105B240034560040743000402D56000058C0FF3FEA +:105B34003856004008B4024B9C4608BC6047C04637 +:105B4400C0B1000030B50200AE4B08001206120EC0 +:105B5400504000252C002404240C082C0BD2C5072B +:105B640004D50004000C4008584002E00004000C76 +:105B74004008641CEFE70004000C30BC08BC184764 +:105B8400F8B507000026B878002801D0BC7803E0F7 +:105B940038790002797944180025A01E854208DA74 +:105BA40031000904090C785DFFF7CCFF06006D1C79 +:105BB400F3E730000004000CF2BC08BC1847F0B551 +:105BC40083B005000E000020C04307000024012C10 +:105BD40050DA0620009005F0A1FAA878002807D131 +:105BE4002879000269794118280005F0C3F903E017 +:105BF400A978280005F0BEF9E878002802D0E878F2 +:105C0400FF2802D10020070035E0962252000099B7 +:105C1400300005F0BEF900282AD03078022803D0DD +:105C24000120C043070023E0B078002801D0B078F9 +:105C340003E070793179090240180099401A019003 +:105C44000198012811DB962252000199009830181E +:105C540005F09FF9002802D0002007000AE0022086 +:105C6400C043070005F05AFA02E00020070001E0F3 +:105C7400641CACE73800FEBC08BC1847F7B5040048 +:105C8400A078002801D0A77803E020790002617988 +:105C940047186846007960702000FFF771FF05001F +:105CA400E019801E29000170E019401E2900090432 +:105CB400090C090A017081492000FFF780FF0600E2 +:105CC400002E27D1E078002824D0E078FF2821D0C6 +:105CD4007A488078002811D0784880787749081865 +:105CE400801E007805002D042D0C744880787349BB +:105CF4000818401E007800022D1801E0002005005D +:105D04006E48FFF73DFF2D042D0CA84202D003205E +:105D1400C04306000298694901603000FEBC08BC1B +:105D24001847F0B585B007000E00FFF7B5FE002454 +:105D3400032C60DA6A4631000906090E3800FFF7C1 +:105D44009DFF050068460221017101A806218170AA +:105D540001A80021C170002D33D10098C07800281B +:105D640007D100988078062803D1FFF7A9FE280000 +:105D740044E00098C078FF280ED100988078062867 +:105D84000AD14F480068002833D04D480068000409 +:105D9400000C01F0EFF82CE001A80021C1706A4664 +:105DA40031000906090E01A8FFF768FF444800689E +:105DB400002805D0424800680004000C01F0DAF81D +:105DC40019E00020C043854213D001A8FF21C1700F +:105DD4006A4631000906090E01A8FFF74FFF38484B +:105DE4000068002805D0364800680004000C01F063 +:105DF400C1F8641C9CE7FFF763FE280005B0F0BC03 +:105E040008BC1847088400001CB5040068462D49E6 +:105E14000CC90CC008390838062269462A4802F021 +:105E24002BFD21000906090E2748FFF77AFF010020 +:105E3400002917D12148C07802001206120E002A48 +:105E44000ED01206120E302A04D020480423DB435D +:105E5400036003E01D480523DB430360002002E0E8 +:105E6400012000E0002016BC08BC184730B583B000 +:105E740005000C00684616490CC90CC008390838DE +:105E840006226946104802F0F7FC29000906090EAB +:105E94000D48FFF746FF0100002907D10748C078E5 +:105EA4002070064800796070012004E00020207012 +:105EB4000020607000203EBC08BC184764490040C4 +:105EC400680A004040610100644A00406055004097 +:105ED40048610100FEB505000C00160068465849EB +:105EE4008CC98CC00C390C382800000C6946087128 +:105EF4002800000A6946487168462900817120001B +:105F0400000C6946C8712000000A69460872684698 +:105F1400210041720C226946484802F0ADFC310070 +:105F24000906090E4548FFF7FCFE0100002917D1B8 +:105F34004448C07802001206120E002A0ED012063F +:105F4400120E302A04D03C480423DB43036003E0F0 +:105F540039480523DB430360002002E0012000E010 +:105F64000020FEBC08BC18471CB5040068469649CE +:105F74000CC90CC008390838062269462F4802F0BB +:105F84007BFC21000906090E2C48FFF7CAFE01001C +:105F9400002917D12B48C07802001206120E002ADD +:105FA4000ED01206120E302A04D089480423DB4393 +:105FB400036003E086480523DB430360002002E01E +:105FC400012000E0002016BC08BC184710B5C0B082 +:105FD400040068467D4980225200FFF7ABFD802211 +:105FE40052006946154802F047FC21000906090ED3 +:105FF4001248FFF796FE0100002917D11148C07816 +:1060040002001206120E002A0ED01206120E302AB8 +:1060140004D06F480423DB43036003E06C4805238A +:10602400DB430360002002E0012000E0002040B0D8 +:1060340010BC08BC1847000060550040644A00408A +:106044007C52010064490040F1B586B00E0003A8FB +:1060540060490CC90CC008390838062203A95E48F7 +:1060640002F00AFC6846017E5B48FFF75AFE009086 +:106074000098002800D0A2E05848C078302819D1F0 +:1060840056488078062815D151480521C943016036 +:106094000025182D0CDA0C2068430021315050A142 +:1060A4000C2068433018001D02F0FCFC6D1CF0E766 +:1060B400002085E00020040048488078401F844286 +:1060C40062DA20000521FDF7D3F805000C204543D2 +:1060D40042480019C07804F0D3FE705103223F48AF +:1060E4000119091D01A805F0C1F801A80021C1701A +:1060F40001A90D0020000521FDF7BAF80C21484341 +:106104003018001D290002F0CDFC34480019C07974 +:1061140000061BD5002531480019C0794006400E01 +:1061240085422FDA20000521FDF7A2F807000C2094 +:10613400474320000521FDF79BF80C2148433058C4 +:10614400284905F0E3F8F0516D1CE4E700252348E5 +:106154000019C0794006400E854213DA200005215B +:10616400FDF786F807000C20474320000521FDF7C2 +:106174007FF80C21484331581A4805F0ADF9F05125 +:106184006D1CE4E7641D97E7782C16DA20000521DE +:10619400FDF76EF80C2148430021315010A10D0089 +:1061A40020000521FDF764F80C2148433018001D38 +:1061B400290002F077FC641DE6E7012000E00020DE +:1061C40007B0F0BC08BC184750610100380001005A +:1061D4006055004058610100644A00406449004031 +:1061E400000000000000204110B582B004006420CB +:1061F40000F0C0FE0023002269466B48FBF7B0FBA9 +:106204000098002807D000F00DF80028EFD00320F4 +:10621400FAF700FDEBE700F003F800F011F8E6E709 +:106224007047704738B5002402F0E8F904005F486D +:1062340005682000FBF78CFB280032BC08BC18471B +:1062440038B5002402F0DAF90400584805685748C4 +:10625400002101602000FBF77BFB280032BC08BC56 +:10626400184780B551480021016000F02EF808233A +:106274004F4A00214F4801F0F5FD09BC184700B50D +:106284004D4800684C49FF220A60C1061BD54B49A2 +:106294000968090213D54A4909684A4A12688A1AE0 +:1062A400494B9A420FD3474A12688A1A474B9A427B +:1062B40009D23E4A1268521C3C4B1A6003E0414921 +:1062C4003F4A12680A6008BC184770B5002402F0FF +:1062D40095F904003E4800688021090401433C48C4 +:1062E40001603C4800683C490140802000020843AA +:1062F4003849086039480068C02109020143374819 +:106304000160374800683449014035480160354828 +:106314000068354901403348016034480068324917 +:10632400014032480160172002F099FC0600300059 +:106334002F49F9F785FE05002E480068032188439C +:106344002C4908602B4800680C21884329490860BF +:10635400681E29490860294800210160284807214E +:106364000160284800210160274803210160264874 +:106374000121016025480068254901402348016046 +:1063840024482549016025480A21016024488021C8 +:10639400090501600848FF2101602000FBF7D8FAD5 +:1063A40070BC08BC18470000580E0100745500402A +:1063B400742A0040ED610000004007E014C0FF3F74 +:1063C4002C4007E07855004099080000282300007D +:1063D400C4C01FE0ACC11FE0FF3FFFFF04C002E0E8 +:1063E40044C002E000C0FF3FFFFF7FFF10C0FF3F3B +:1063F400A0860100704007E00C4007E0144007E06D +:10640400284007E03C4007E0044007E00CF0FFFFB1 +:10641400FFFFFFF76CF1FFFF836200006CF2FFFFE8 +:1064240010F0FFFF0CB41CB5040004A801900A008E +:10643400009401AB6946084878441C3005F0FCF828 +:10644400009900220A70002801D40098001B02B0B1 +:10645400019910BC03B008474326000000B5664903 +:106464000988012282400A4363490A800006000E1B +:1064740000280ED002281BD012D3042827D01FD303 +:10648400062832D02AD308283ED035D3092843D051 +:1064940049E05A49096804220A4358490A6042E01B +:1064A40057490968802292000A4355490A603AE034 +:1064B40053490968802252000A4351490A6032E074 +:1064C4004F49096880220A434D490A602BE04C4930 +:1064D400096840220A434A490A6024E04849096895 +:1064E40020220A4346490A601DE0454909681022F2 +:1064F4000A4343490A6016E042490968802252056A +:106504000A4340490A600EE03F49096880221205A7 +:106514000A433D490A6006E03B4909688022520566 +:106524000A4339490A6008BC184700B5324909884A +:10653400012282409143304A11800006000E002857 +:106544000ED002281BD012D3042827D01FD306282C +:1065540032D02AD308283ED035D3092843D049E085 +:106564002A49096804220A4328490A6042E0284962 +:106574000968802292000A4325490A603AE02449C6 +:106584000968802252000A4321490A6032E0204906 +:10659400096880220A431E490A602BE01C490968E5 +:1065A40040220A431A490A6024E019490968202252 +:1065B4000A4317490A601DE01549096810220A4375 +:1065C40013490A6016E013490968802252050A43F8 +:1065D40010490A600EE0B1490968802212050A4395 +:1065E400AE490A6006E0AD490968802252050A43B3 +:1065F400AA490A6008BC18474056004058C0FF3FEB +:1066040018C0FF3F98C0FF3F38C0FF3F5CC0FF3F4A +:106614001CC0FF3F9CC0FF3F10B5002401F0EEFFFB +:1066240004009F480068302188439D4908609D48C4 +:106634000068302188439B4908609B480068042116 +:1066440001439948016099480068042188439749A7 +:106654000860974800680421014395480160954803 +:106664000068954901409348016094480068924944 +:1066740001409248016092480068802189000143EA +:106684008F4801608F4800688F4901408D48016040 +:106694008E4800688021890001438C480160854848 +:1066A40000688B4901408348016084480068884938 +:1066B400014082480160824800688021490001430A +:1066C4007F4801607F480068824901407D4801603D +:1066D4007E4800688021490001437C480160754878 +:1066E40000687D49014073480160744800687A4934 +:1066F400014072480160724800688021014370487B +:10670400016070480068802188436E4908606F48C2 +:106714000068802101436D480160664800686F4944 +:10672400014064480160654800686C490140634861 +:106734000160634800684021014361480160614889 +:106744000068402188435F49086060480068402130 +:1067540001435E480160574800686149014055485B +:106764000160564800685E4901405448016054483D +:1067740000682021014352480160524800682021EA +:1067840088435049086051480068202101434F481C +:106794000160484800685349014046480160474841 +:1067A400006850490140454801604548006810218F +:1067B400014343480160434800681021884341492C +:1067C400086042480068102101434048016046487F +:1067D400006846490140444801604548006843490F +:1067E4000140434801604348006880214905014352 +:1067F4004048016040480068404901403E4801600B +:106804003F4800688021490501433D4801603D48F7 +:1068140000683D4901403B4801603C4800683A49F2 +:1068240001403A4801603A48006880210905014363 +:1068340037480160374800683749014035480160EE +:1068440016480068802109050143144801602D4859 +:106854000068264901402B4801602C480068234900 +:1068640001402A4801602A48006880214905014303 +:1068740027480160274800682049014025480160F5 +:10688400064800688021490501430448016020004E +:10689400FBF75EF810BC08BC184700003CC0FF3F83 +:1068A40010C002E050C002E040C0FF3F50C0FF3FB4 +:1068B4005CC0FF3F00C002E0FFFFF3FF40C002E006 +:1068C40000C0FF3F10C0FF3FFFFDFFFF1CC0FF3FA4 +:1068D400FFFFFCFFFFFEFFFFFF3FFFFFFFCFFFFFB8 +:1068E400FFF3FFFFFFFCFFFF24C002E0FFFFFFFCFC +:1068F40064C002E080C0FF3F90C0FF3FFFFFFFEF96 +:106904009CC0FF3F0CC002E0FFFF3FFF4CC002E011 +:1069140020C0FF3F30C0FF3FFFFFFFF710B582B03C +:10692400052003F029F86921684603F035F80400CE +:10693400002C02D10120C0430EE0684600781528DF +:1069440001D1002008E068460078062802D1002022 +:10695400C04301E00120C04316BC08BC184780B501 +:10696400052003F009F86921684603F015F80028AA +:1069740002D10120C0430EE068460078152801D1F9 +:10698400002008E068460078062802D10020C043B1 +:1069940001E00120C0430ABC1847F1B582B00F00E2 +:1069A400140002F005FE022002F0E6FF2000401C65 +:1069B4000006000E02F0E0FF2000401C05006846BF +:1069C400007A02F0D9FF29006846057A4D4020007C +:1069D400441E0006000E002807D0387802F0CCFFD1 +:1069E40028003D7845407F1CF1E728000006000E92 +:1069F40002F0C2FF6921684602F0CEFF002802D1EE +:106A04000020C04321E068460078152815D10026EF +:106A1400642E18DA692000F0ADFAFFF7A0FF010038 +:106A2400002901D1002010E00020C043814201D19F +:106A3400761CEDE70020C04307E06846007806288E +:106A440001D1002001E00020C043FEBC08BC18476F +:106A5400F4B582B007000E000020386000203070CA +:106A64000299684602F098FF002802D10020C04332 +:106A74004EE068460078022802D00020C04347E078 +:106A84006921684602F088FF002802D10020C04333 +:106A94003EE068460078002802D10020C04337E079 +:106AA4006846007805000A222D062D0E2900364876 +:106AB40002F08FFF002802D10020C04328E00A2101 +:106AC400684602F069FF002802D10020C0431FE09D +:106AD4002C0000200006000E2D062D0EA84207D221 +:106AE40022000006000E28490C5C5440401CF1E7CB +:106AF400684600782406240E844202D00020C04355 +:106B040006E0062002F038FF1F4838603570002088 +:106B1400FEBC08BC184731B582B00D00140000203B +:106B24002070042202A91120FFF737FF002802D0A9 +:106B34000020C04325E0154A01A96846FFF788FFF5 +:106B4400002802D00020C0431BE000984078207049 +:106B540068460079302802D00020C04311E0009834 +:106B64000078112803D100984078002802D0002032 +:106B7400C04306E02E220099891C280001F07CFE07 +:106B840000203EBC08BC1847644C00408813000039 +:106B940011B583B00C00042203A94020FFF7FDFEC9 +:106BA400002802D00020C04322E0624A01A96846BE +:106BB400FFF74EFF002802D00020C04318E00098E1 +:106BC4004078207068460079032802D00020C04332 +:106BD4000EE000980078402803D1009840780028FF +:106BE40002D00020C04303E0524800F0C3F9002063 +:106BF40004B010BC08BC1847000011B583B00C00E9 +:106C0400042203A94120FFF7C8FE002802D0002077 +:106C1400C04322E0474A01A96846FFF719FF00284C +:106C240002D00020C04318E00098407820706846E5 +:106C34000079032802D00020C0430EE000980078B9 +:106C4400412803D100984078002802D00020C04396 +:106C540003E0384800F08EF9002004B010BC08BCF2 +:106C6400184711B583B00C00042203A9C620FFF70E +:106C740094FE002802D00020C04322E02D4A01A93E +:106C84006846FFF7E5FE002802D00020C04318E064 +:106C940000984078207068460079032802D00020CC +:106CA400C0430EE000980078C62803D100984078CD +:106CB400002802D00020C04303E0642000F05AF909 +:106CC400002004B010BC08BC184711B583B00C00F8 +:106CD400042203A9C720FFF760FE002802D0002089 +:106CE400C04322E0134A01A96846FFF7B1FE002819 +:106CF40002D00020C04318E0009840782070684615 +:106D04000079032802D00020C0430EE000980078E8 +:106D1400C72803D100984078002802D00020C0433F +:106D240003E0044800F026F9002004B010BC08BCBD +:106D3400184700008813000031B582B00D0014001C +:106D4400042202A9894801F097FD884805710522AB +:106D540086498D20FFF721FE002802D00020C04381 +:106D64001FE0834A01A96846FFF772FE002802D09B +:106D74000020C04315E000984078207068460079F0 +:106D8400032802D00020C0430BE0009800788D282F +:106D940003D100984078002802D00020C04300E0CE +:106DA40000203EBC08BC1847FBB582B017000A9E01 +:106DB4000B9D0C9C042202A96C4801F05DFD052288 +:106DC40003996A48001D01F057FD05223900674800 +:106DD400093001F051FD65486946097C817304223C +:106DE400310062480F3001F047FD282200215F483E +:106DF400133003F0C9F929005C48133001F052FE46 +:106E04003B225A498020FFF7C8FD002802D0002009 +:106E1400C0431FE0564A01A96846FFF719FE00283F +:106E240002D00020C04315E00098407820706846E6 +:106E34000079032802D00020C0430BE000980078BA +:106E4400802803D100984078002802D00020C04355 +:106E540000E0002005B0F0BC08BC1847F1B582B0D2 +:106E64000E0015001F00089C042202A93F4801F0EF +:106E740003FD052231003D48001D01F0FDFC1122F7 +:106E840000213A48093003F07FF9042229003748E9 +:106E94001A3001F0F1FC2822002134481E3003F09E +:106EA40073F939003148463001F0FCFD46222F4980 +:106EB4008520FFF772FD002802D00020C0431FE0A8 +:106EC4002B4A01A96846FFF7C3FD002802D0002021 +:106ED400C04315E00098407820706846007908287F +:106EE40002D00020C0430BE000980078852803D12D +:106EF40000984078002802D00020C04300E0002021 +:106F0400FEBC08BC184711B583B00C0000202070EB +:106F1400042203A9B020FFF740FD002802D000207E +:106F2400C0431FE0124A01A96846FFF791FD0028FB +:106F340002D00020C04315E00098407820706846D5 +:106F44000079032802D00020C0430BE000980078A9 +:106F5400B02803D100984078002802D00020C04314 +:106F640000E0002004B010BC08BC1847644C00408A +:106F74008813000070B50400002623480078012817 +:106F84002FD22404240C012C2BD301F037FB060050 +:106F94001E4800683030007805002D062D0E1C4870 +:106FA400405D1A4909683131097888432D062D0E50 +:106FB400174948552D062D0E1548405D002808D167 +:106FC4001448007811490968323109788843114915 +:106FD40008700E48006844853000FAF7B9FC05F0E3 +:106FE400E9FC70BC08BC184738B5002501F006FB65 +:106FF40005000948006804002800FAF7A9FC2000ED +:1070040032BC08BC184700007556004004560040C6 +:10701400FC550040795600401C56004080B56A4635 +:1070240001217948006802F012FD684600780028C2 +:1070340003D00120FFF79EFFF1E709BC184780B594 +:107044007148006802F070FD09BC184710B50400CF +:10705400207800280CD005F022FE002803D101205E +:10706400FFF788FFF7E7207805F02CFE641CEFE7B4 +:1070740010BC08BC1847F2B504000025FF2D21DC24 +:10708400009E05F0F9FD00280AD1002E03D100204E +:107094002070002019E00120FFF76CFF761EF0E756 +:1070A40005F0C2FD0100002903D500202070002056 +:1070B4000BE0080007002770641C6D1C3F063F0EA0 +:1070C4000A2FDBD1002020700120F2BC08BC184735 +:1070D40038B5002501F092FA05007C4800210170C2 +:1070E4007B48002101602800FAF732FC00230022CB +:1070F40069467848FAF734FC009800286DD0764841 +:107104000068764901407448016075480068734915 +:1071140001407348016073480068802149040143B9 +:107124007048016070480068704901406E48016011 +:107134006F4800688021490401436D480160FA20CA +:107144008000FFF717FF6B48006880214904014362 +:10715400684801606848FFF70DFFE120400205F030 +:107164007BFE29480068002804D1012002F046FC77 +:1071740025490860FFF752FF60496148FFF752F95B +:10718400FA2189005E4800F0CDF80400002C02D0FA +:10719400FFF755FF23E05B495948FFF743F9FA210C +:1071A4008900574800F0BEF80400002C02D0FFF715 +:1071B40046FF14E0FFF743FF01F020FA05004448BE +:1071C400012101602800FAF7C3FBFA208000FFF7D1 +:1071D400D1FE00F03DF9040001E0002004004A481B +:1071E400006800280BD10821484800F0F5FC464906 +:1071F40008601C23464A0021464800F033FE200064 +:1072040032BC08BC18470000CC550040F8B5060055 +:107214000F00FFF703FF05F0E5FC3A003E4938484C +:10722400FFF700F93648FFF711FF3C493448FFF7F0 +:1072340022FF002804D1FFF702FF0020C04341E0F1 +:1072440036492F48FFF717FF002804D1FFF7F7FE50 +:107254000020C04336E0002004002406240EA02CA5 +:107264002DD22748002101702C492548FFF703FF40 +:10727400002804D1FFF7E3FE0020C04322E02849A0 +:107284001F4805F0C7FE002819D01D4800F098FFDC +:10729400002814D01A480500194800F091FF00286E +:1072A40004D1FFF7CCFE0020C0430BE0287800286F +:1072B400D3D0287830706D1C761C641CF6E7FFF779 +:1072C400BEFE0020F2BC08BC18470000004000408D +:1072D400D0550040380D010004C002E0FFFFFCFF60 +:1072E40044C002E000C0FF3F10C0FF3FFFFFFFFEAD +:1072F4001CC0FF3F18C0FF3F60EA0000A864010003 +:1073040044420040F8600100D455004094540040C9 +:1073140074160040F5280000FC5101008813000099 +:10732400B064010070B504000E0005F05BFC2000A1 +:10733400FFF78CFE052005002800451E00281AD002 +:1073440031002000FFF797FE002811D03E492000AD +:1073540005F060FE002801D100200EE03B4920002A +:1073640005F058FE002802D10120C04305E0E3E700 +:107374000020C04301E00220C04370BC08BC184791 +:10738400F8B504000E00170005F02CFC00200500E1 +:10739400B5420CDA05F083FC002803D10120FFF785 +:1073A400E9FDF7E7605D05F08DFC6D1CF0E7052055 +:1073B40005002800451E00281AD039002000FFF7D8 +:1073C4005AFE002811D02049200005F023FE002891 +:1073D40001D100200EE01D49200005F01BFE00280D +:1073E40002D10120C04305E0E3E70020C04301E0EF +:1073F4000220C043F2BC08BC1847000070B504006A +:107404000E0005F0EFFB2000FFF720FE052005002D +:107414002800451E0006000E002810D03100200070 +:10742400FFF729FE002807D091A1200005F0F2FD06 +:107434000028EDD0002004E00020C04301E0022039 +:10744400C04370BC08BC1847B0640100B8640100B4 +:10745400FEB50027002000908648019001F0CEF888 +:107464000090C748002101700098FAF771FA0120D2 +:1074740006003606360E182E00D386E03606360E83 +:1074840031000198FFF7C2FE00287CD100200400DF +:107494002406240E0B2C73D22406240E08206043E9 +:1074A4007549085800F08CFE0500684600210172F9 +:1074B4002800451E00280DD02406240E0820604311 +:1074C4006D490858405D0199495D8842F0D068468D +:1074D400012101726846007A00284FD12406240E47 +:1074E400082060436449085800F06AFE01990918AD +:1074F4002406240E082060435F4A1018406801F0F7 +:10750400D1FA00200500402D33DA2406240E082089 +:107514006043594908184068405D002829D0240672 +:10752400240E08206043544908184068405D0D2823 +:1075340009D12406240E082060434F4908184068E6 +:107544000021415515E02406240E082060434A49D1 +:1075540008184068405D0A2809D12406240E082032 +:1075640060434549081840680021415501E06D1CFD +:10757400C9E738000127A740074301E0641C87E7F7 +:10758400C820FFF7F7FC761C73E7012006000020F3 +:1075940004002406240E0B2C09D20120A0403840FC +:1075A400002802D10020060001E0641CF1E701F08C +:1075B40025F80090724806700098FAF7C9F900207F +:1075C400FEBC08BC184710B5002401F017F80400ED +:1075D4006B48002101706B48002101602000FAF71C +:1075E400B7F910BC08BC184738B50024002501F0D1 +:1075F40005F8040062480078002805D06148006856 +:10760400002801D0012005002000FAF7A1F9280084 +:107614000006000E32BC08BC184738B5002400250B +:1076240000F0ECFF040057480068002801D0012056 +:1076340005002000FAF78CF928000006000E32BC81 +:1076440008BC184738B50024002500F0D7FF040013 +:107654009C480078002801D0012005002000FAF79A +:1076640077F928000006000E32BC08BC1847000059 +:107674000D0A0000644D00403809010010B50024D3 +:107684003F480078002802D10020C04375E0FFF78E +:10769400C5FC8D498D48FEF7C5FE8D498B48FFF723 +:1076A40041FE002815D08B498848FEF7BBFE8A4965 +:1076B4008648FFF737FEFA204000FFF75BFC200006 +:1076C4000400641C0028E4D0FFF7B9FC0420C04384 +:1076D40053E082497D48FEF7A5FE7D497B48FFF7CC +:1076E40021FE002804D0FFF7AAFC0520C04344E093 +:1076F4007B4A40327B497548FEF794FE74497348CF +:10770400FFF710FE002804D0FFF799FC0620C043C1 +:1077140033E0734A803274496C48FEF783FE6C4947 +:107724006A48FFF7FFFD002804D0FFF788FC072014 +:10773400C04322E06D4A6E496448FEF773FE644913 +:107744006248FFF7EFFD002804D0FFF778FC08201B +:10775400C04312E0674A68495C48FEF763FE5C492F +:107764005A48FFF7DFFD002804D0FFF768FC092022 +:10777400C04302E0FFF763FC002010BC08BC1847BC +:1077840000400040D055004010B500244D4800781A +:10779400002802D10020C04390E0FFF73FFC574986 +:1077A4004A48FEF73FFE4A494848FFF7BBFD002818 +:1077B40014D048494548FEF735FE47494348FFF78A +:1077C400B1FD4F48FFF7D6FB20000400641C0028DD +:1077D400E5D0FFF734FC1820C0436FE049493B482B +:1077E400FEF720FE3A493948FFF79CFD002804D0F3 +:1077F400FFF725FC1920C04360E043493348FEF7F6 +:1078040011FE33493148FFF78DFD002804D0FFF7FE +:1078140016FC1A20C04351E03C4A3D492B48FEF770 +:1078240001FE2B492948FFF77DFD002804D0FFF70E +:1078340006FC1B20C04341E0364A37492348FEF783 +:10784400F1FD23492148FFF76DFD002804D0FFF71F +:10785400F6FB1C20C04331E0304A31491B48FEF797 +:10786400E1FD1B491948FFF75DFD002804D0FFF72F +:10787400E6FB1D20C04321E02A491448FEF7D2FD4F +:1078840013491248FFF74EFD002804D0FFF7D7FB39 +:107894001E20C04312E0244A24490C48FEF7C2FDCE +:1078A4000B490A48FFF73EFD002804D0FFF7C7FB49 +:1078B4001F20C04302E0FFF7C2FB002010BC08BC3D +:1078C4001847000000400040901F0100444200405F +:1078D400881300000461010030750000AC1F010032 +:1078E400403D00402824010040240100803E004027 +:1078F40058240100403E004070240100C81F0100CC +:1079040010270000E41F010088240100803F00408C +:1079140000200100C03E0040A0240100003F0040C0 +:10792400B8240100D0240100C03F00401C20010005 +:10793400F3B585B00026F64395480078002802D1B7 +:107944003120C04320E1FFF799FE0600002E01D04C +:10795400300019E1FFF718FF0600002E01D03000B7 +:1079640012E1FFF75BFB8B4A8B498C48FEF75AFD0B +:107974008B498A48FFF7D6FC002804D0FFF75FFB49 +:107984003220C04300E1874A87498448FEF74AFD14 +:1079940083498248FFF7C6FC002804D0FFF74FFB59 +:1079A4003320C043F0E0059A80497C48FEF73AFD55 +:1079B4007B497A48FFF7B6FC002804D0FFF73FFB69 +:1079C4003420C043E0E07A497448FEF72BFD79493E +:1079D4007248FFF7A7FC002804D0FFF730FB3520DE +:1079E400C043D1E06E48FFF7C5FA73496B48FEF710 +:1079F40019FD70496948FFF795FC002804D0FFF78A +:107A04001EFB3620C043BFE06A496448FFF733FBDE +:107A1400002804D1FFF713FB3720C043B4E06549C5 +:107A24005E48FFF728FB002804D1FFF708FB382045 +:107A3400C043A9E06149594805F0ECFA002802D096 +:107A44003920C043A0E05E480700FA208000FFF719 +:107A540091FA3800069905F019FB002848D138003E +:107A640000F0AEFB05000024AC42F2DA2A1B5549B3 +:107A74004A48FEF7D7FC4F494848FFF7BFFC0028A7 +:107A840003D03A20C043060070E002A8009001AB86 +:107A940003AA4D49414801F06FFD0398029901433F +:107AA400002906D1281B0199884202DB019800288D +:107AB40003D13B20C043060058E03E4A01993800F8 +:107AC400FFF75EFC002803D03C20C04306004DE0D5 +:107AD40038493248FFF7CFFA002803D13D20C0438C +:107AE400060043E0019824183220FFF743FABBE76D +:107AF40036492A48FEF796FC2E492848FFF712FC1F +:107B0400002803D03E20C04306002FE02949234823 +:107B1400FFF7B1FA002803D13F20C043060025E057 +:107B240024491E48FFF7A7FA002803D14020C04388 +:107B340006001BE02649194805F06CFA002803D01A +:107B44004120C043060011E019491448FEF76AFCBD +:107B540018491248FFF7E6FB002803D04220C0432F +:107B6400060003E0FFF76BFA00200DE010490B4814 +:107B7400FEF758FC1748FFF7FDF90E490748FFF7D1 +:107B8400D1FBFFF75CFA300007B0F0BC08BC184723 +:107B940000400040403F0040E824010044420040CF +:107BA40088130000403D0040002501001825010015 +:107BB4000461010030750000106101000C520100E5 +:107BC400644D00401C520100A83D01002C520100EC +:107BD4003C52010010270000F2B5070000266C4853 +:107BE4000078012801D3002045E000F007FD0600DD +:107BF40068480068040067480068002804D06548A5 +:107C040000684068634908603000F9F7A1FE002C61 +:107C140030D000F0F3FC06005F4800680500002D3A +:107C24001ED05D485C490968096801603000F9F7B5 +:107C34008FFE6F6068460088042148433818A860A6 +:107C4400EF602F6168460088A8820020E882022045 +:107C54002070002020816560200004F0EDFD09E023 +:107C64004C48006860604B4804603000F9F770FECF +:107C7400002004002000F2BC08BC1847F3B581B012 +:107C84001400002642480078012803D30220207003 +:107C9400002079E041480078012803D30D202070AA +:107CA400002071E000F0AAFC06000198406805007D +:107CB400E88A012815D328690100091D2961006893 +:107CC4000700E88A401EE8822869A968884201D131 +:107CD400686828613000F9F73BFE00202070380006 +:107CE40052E02F4800682C300078042101432C48CE +:107CF40000682C3001702A4800682D300021017082 +:107D040027480068694609894185019804F01EFDE9 +:107D14003000F9F71DFE04F04DFE00F06FFC060084 +:107D24001F4800682D300078002816D068461C498A +:107D340009682D3109780170019804F049FD30007B +:107D4400F9F706FE68460078022802D00A2020705F +:107D540001E00E202070002016E011480068006A3F +:107D640007000F480068002101620D4800682C30AC +:107D7400002101700A4800680021C1613000F9F750 +:107D8400E7FD002020703800FEBC08BC1847000046 +:107D940075560040F4550040185600407656004091 +:107DA40004560040F2B5070000253878022801D0B7 +:107DB400012031E000F022FC0500B87A00280DD043 +:107DC400002304220099380004F061FC0600280016 +:107DD400F9F7BEFD04F0EEFD00201DE07868040014 +:107DE400E08AA18A884204D32800F9F7B1FD1E2055 +:107DF40012E0E0680100091DE16000990160E08A79 +:107E0400401CE082E068A168884201D16068E060BB +:107E14002800F9F79DFD0020F2BC08BC184770B596 +:107E240060210E4804F0BAFD0C4805000B481830D8 +:107E34000600002004002404240C032C04D22E6029 +:107E440018351836641CF6E70020286004480349F6 +:107E5400016070BC08BC1847000000004851004095 +:107E640018560040F3B585B017001D00002400F03B +:107E7400C5FB04005F480078012804D32000F9F70B +:107E840067FD3C2047E02D062D0E04206843584929 +:107E9400085800283BD12D062D0E04206843544970 +:107EA40001220A502000F9F753FD00233A000699F5 +:107EB400059805F0F5F80390002002900020019049 +:107EC4000020009000230022039928000006000EE1 +:107ED40004F0E2FD06003606360E002E06D1A74851 +:107EE400007801280FD104F065FD0CE000F086FB5A +:107EF40004002D062D0E042068433D4900220A503B +:107F04002000F9F725FD30000006000E03E02000F4 +:107F1400F9F71EFD282007B0F0BC08BC1847F7B5D8 +:107F240084B01E00109D002400F068FB040031485A +:107F34000078012804D32000F9F70AFD3C2052E020 +:107F44003606360E0420704329490858002846D1C5 +:107F54003606360E04207043254901220A502000BB +:107F6400F9F7F6FC2A001204120C0E990D9800F091 +:107F740019F92B001B041B0C069A0599049805F0AB +:107F84008FF803902D042D0C02950F9801900E98F4 +:107F940000906846038E0D9A039930000006000E87 +:107FA40004F07AFD07003F063F0E002F06D1734808 +:107FB400007801280FD104F0FDFC0CE000F01EFB5A +:107FC40004003606360E04207043094900220A5084 +:107FD4002000F9F7BDFC38000006000E03E0200085 +:107FE400F9F7B6FC282007B0F0BC08BC184700001D +:107FF400044F004075560040F1B582B00026604839 +:108004000078012801D34020B4E06846007A1F2894 +:1080140001D13E20AEE000F0F1FA06006846007A95 +:10802400FF2805D16846574909682E31097801723D +:108034006846007A04214843534908580400002C38 +:1080440004D13000F9F784FC432093E0012C04D1DF +:108054003000F9F77DFC3D208CE03020205C0500E9 +:108064002D062D0E4948405D3121615C88432D0663 +:108074002D0E464948552D062D0E4448405D0028D6 +:1080840006D1434800783221615C88434049087036 +:10809400E0690700002F15D02D062D0E7819C07A3F +:1080A4003121615C88432D062D0E7919C8722D0685 +:1080B4002D0E7819C07A002804D1B87A3221615C77 +:1080C4008843B872606A00900098002802D0009833 +:1080D40005F078F8002060852C20002121542D2003 +:1080E400002121542B480078FF2804D02948007827 +:1080F400401C284908703000F9F72AFC04F0C6FA3D +:1081040000F07CFA060023480078012804D32148B3 +:108114000078401E1F490870200004F0BFFF1E486D +:108124000078401E1C4908706846007A04214843C0 +:10813400154900220A50A069002806D1606900216F +:10814400816160691549086005E0A0696169416160 +:108154006069A16981611248006860611048046027 +:108164003000F9F7F5FB05480078012801D104F047 +:1081740021FC0020FEBC08BC184700007A560040D1 +:108184007556004004560040044F0040FC55004022 +:1081940079560040765600407B5600401056004009 +:1081A4000856004000B5D30708D5930706D5002923 +:1081B40004D0491E00230360001DF8E708BC1847DB +:1081C4007847C046013080E2001FB0E10300000A96 +:1081D4000110D0E4000051E3FAFFFF1A0A0000EA9C +:1081E400002090E528C09FE50C1052E00210D1E178 +:1081F4008C0311E10420B005FAFFFF0A0110D0E45A +:10820400000051E30110D014FCFFFF1A030050E0FA +:108214001EFF2FE101010101574800210160704751 +:10822400B54800210160704700B5B44800780028C3 +:1082340003D152480021016002E0B04800210170DE +:1082440008BC18474D480068042148434C4908605D +:10825400AA48012101707047474800210160704716 +:108264004548002101607047F1B582B00F003F0618 +:108274003F0E002F05D0022F09D005D3032F09D0BC +:108284000BE09F48060009E09E48060006E09E4871 +:10829400060003E0B048060000E02CE00298040069 +:1082A4002078202801D1641CFAE714222021300010 +:1082B40001F06AFF2000FFF783FF0500142D09DA9F +:1082C4000921009128000221FAF7D2FF0099081A27 +:1082D400002804D52100300000F0E4FB0BE021006D +:1082E4000C0028000221FAF7C3FF4142701809303C +:1082F400210000F0D7FBF7BC08BC184780B5002369 +:10830400002269469548F9F72BFB0098002804D110 +:10831400FCF70BFD9248FCF7C2FC92480021017067 +:1083240009BC184780B51420FEF724FE8D480121AE +:10833400017009BC184730B583B08B480021016037 +:10834400002500200400FF2C0CD821006846FBF710 +:10835400F7FD0098A84203D3009805008248046002 +:10836400641CF0E7002D03D18048FCF7C8FCFFE74C +:1083740037BC08BC18470000A05500407C5500409D +:108384008055004010B50400207A002800D1A7E0F1 +:10839400217A7748FBF75EFE207A012802D0207A02 +:1083A400022813D17248FFF70BFF627A521C7149FD +:1083B4006F4B1818FEF736F82000001D01F0D2FEAE +:1083C40002006D496D48FEF72DF891E0207A0328EC +:1083D40012D16748FFF7F4FE627A521C6549644B78 +:1083E4001818FEF71FF82000001D01F0BBFE010065 +:1083F4006248FAF7E1FD7BE0207A04280ED15C485C +:10840400FFF7DEFE627A521C5A49594B1818FEF7E0 +:1084140009F85BA15948FEF705F869E0207A0628B7 +:1084240004D157A15548FDF7FDFF61E0207A0728E4 +:1084340006D1627A521C53495048FDF7F3FF57E0C6 +:10844400207A082804D14EA14C48FDF7EBFF4FE0F9 +:10845400207A092804D14AA14848FDF7E3FF47E000 +:10846400207A0A2804D146A14448FDF7DBFF3FE007 +:10847400207A0B280FD12000001D01F073FE002884 +:1084840004D141493D48FDF7CDFF31E03F493B4828 +:10849400FDF7C8FF2CE0207A0C2809D12000001D2C +:1084A40001F060FE02003A493448FDF7BBFF1FE0CB +:1084B400207A0D2809D12000001D01F053FE02008E +:1084C40034A12E48FDF7AEFF12E0207A0E2802D028 +:1084D400207A0F280CD12AA12848FDF7A3FF07E032 +:1084E4002D492348FDF79EFF2B492448FDF79AFFA9 +:1084F40010BC08BC18470000A85500407356004043 +:10850400B4540040CC540040E45400403EB52348E9 +:108514000021016000250024FF2C0CD821006846AE +:10852400FBF724FD0098A84203D3009805001B48DC +:108534000460641CF0E7002D03D10C48FCF7DFFB5A +:1085440007E0164801686846FBF710FD6846FFF728 +:1085540019FF37BC08BC1847FC540040B80E010092 +:108564006C5F01007256004090550040A457010012 +:108574001455004048640100506401002C5500402B +:1085840000000000E456010058640100F0560100A8 +:108594006064010025750000686401009455004082 +:1085A40070B50200FF24FF200D00691E2D062D0E5C +:1085B400002D16D0157865402B00521C1B061B0E8F +:1085C40002255D430C4E755B2D042D0C2D0A454090 +:1085D4002C001B061B0E02255D43074E755B28000D +:1085E400E2E72406240E24020006000E20430004C1 +:1085F400000C70BC08BC184738FE00007847C04621 +:1086040000000FE1C01080E301F021E11EFF2FE123 +:1086140000F021E11EFF2FE1D3F021E348029FE5A2 +:108624000FE0A0E110FF2FE124029FE50110A0E379 +:108634000010C0E528029FE5000090E500D090E519 +:1086440004009DE400F06FE1FFDFFDE800402DE948 +:1086540000402DE9FF1F2DE900000FE101001EE39A +:108664002000801301002DE9F0019FE5001090E542 +:1086740000D081E5F0019FE50FE0A0E110FF2FE1BC +:10868400D0019FE5D0119FE50020D1E50020C0E591 +:10869400C8019FE5C8119FE5002091E5002080E511 +:1086A40000D092E50100BDE800F06FE1FFDFFDE8D6 +:1086B400B4019FE50FE0A0E110FF2FE194019FE5D5 +:1086C40094119FE50020D1E50020C0E58C019FE5D1 +:1086D4008C119FE5002091E5002080E500D092E513 +:1086E4000100BDE800F06FE1FFDFFDE8FF5F2DE969 +:1086F4000E30A0E10000A0E3200000EAFF5F2DE9B6 +:108704000E30A0E10100A0E31C0000EAFF5F2DE9A8 +:108714000E30A0E10200A0E3180000EA04E04EE2FB +:10872400FF5F2DE90E30A0E10300A0E3130000EA8F +:1087340008E04EE2FF5F2DE90E30A0E10400A0E363 +:108744000E0000EA08E04EE2FF5F2DE90E30A0E1E2 +:108754000500A0E3090000EA04E04EE2FF5F2DE912 +:108764000E30A0E10600A0E3040000EA04E04EE2BB +:10877400FF5F2DE90E30A0E10700A0E3FFFFFFEA51 +:1087840000104FE11F2001E2130052E31F00001A02 +:1087940000200FE10D40A0E1D3F021E308002DE912 +:1087A40000402DE9E01F2DE9E003B4E8E0032DE9E2 +:1087B40002002DE998109FE50010D1E5010051E376 +:1087C4000600001A9C309FE50040D3E5014084E296 +:1087D4000040C3E584309FE5004093E500D084E584 +:1087E40002F02FE188109FE50FE0A0E111FF2FE1D7 +:1087F40038D08DE2D3F021E370009FE50FE0A0E1D3 +:1088040010FF2FE10100BDE800F06FE1FFDFFDE89C +:1088140000200FE1D3F021E348309FE50040D3E589 +:10882400014084E20040C3E502F02FE140309FE5BF +:108834000FE0A0E113FF2FE1D3F021E324309FE503 +:108844000040D3E5014044E20040C3E502F02FE1DB +:10885400FF9FFDE87A560040775600407856004066 +:10886400045600400C560040755600401FD10000CD +:10887400DBC40000FB8C000070B504000D00160082 +:1088840032002900200002F085FC200070BC08BCE6 +:10889400184710B50400002004F08AFD06210020CA +:1088A40004F0AAFC002004F093FD10BC08BC184797 +:1088B40010B50400002004F07BFD0421002004F026 +:1088C4009BFC002004F084FD10BC08BC1847F8B5DC +:1088D40004000E00170004F08BFD20000004000CBF +:1088E400FFF7D7FF002004F063FD0221002004F00D +:1088F40083FC21000904090C090A0906090E002059 +:1089040004F07AFC21000906090E002004F074FC2E +:10891400002005002D042D0C3604360CB54207D278 +:108924002D042D0C795D002004F066FC6D1CF1E72C +:10893400002004F04DFD20000004000CFFF7B8FFF8 +:1089440004F06AFDF1BC08BC1847F8B504000E0039 +:10895400170004F04DFD20000004000CFFF799FF00 +:10896400002004F025FD0221002004F045FC210034 +:108974000904090C090A0906090E002004F03CFC4C +:1089840021000906090E002004F036FC0020050031 +:108994002D042D0C3604360CB54207D239000906D5 +:1089A400090E002004F028FC6D1CF1E7002004F0FF +:1089B4000FFD20000004000CFFF77AFF04F02CFDEB +:1089C400F1BC08BC1847F8B504000E00170004F009 +:1089D4000FFD20000004000CFFF76AFF002004F0E4 +:1089E400E7FC0321002004F007FC21000904090C22 +:1089F400090A0906090E002004F0FEFB21000906FD +:108A0400090E002004F0F8FB002005002D042D0CB5 +:108A14003604360CB54208D2FF21002004F0ECFBEA +:108A24002D042D0C78556D1CF0E7002004F0D0FCCB +:108A340004F0F2FCF1BC08BC184710B40168001D36 +:108A440000290FD00268436882180830DC0702D579 +:108A54004C46641E1B191468121D1C601B1D091F43 +:108A6400F9D1EBE710BC70477847C04640C7A0E394 +:108A740080007CE181007C911EFF2F8101C080E198 +:108A84008CC0B0E10100002A010050E11EFF2FE17B +:108A9400000051111EFF2FE100470268531C0360C0 +:108AA400117070477847C04601402DE9013020E03D +:108AB400030013E30E00001A030010E30400000A8D +:108AC4000130D1E40130C0E4000033E3F9FFFF1AC0 +:108AD4000C0000EA34C09FE5002091E50C3052E020 +:108AE4000230D3E18C0313E1042080040420B10597 +:108AF400F9FFFF0A0130D1E40130C0E4000033E3A0 +:108B04000130D114FBFFFF1A0140BDE81EFF2FE125 +:108B1400010101017847C0460010A0E1810EA0E1E7 +:108B240040C7A0E381007CE10200003A7018810391 +:108B34000010E0131EFF2FE181005CE10A00009A9F +:108B440081C0B0E11EFF2F01801401E2E01581E233 +:108B54008CC3A0E18CC0B0E1401941E2FCFFFF5A94 +:108B64008C0AA0E1AC1581E01EFF2FE1C111A0E148 +:108B74007014C1E3E01581E21EFF2FE102001378B7 +:108B8400002B03D0521C1378002BFBD10B781370ED +:108B9400002B02D0521C491CF8E7704708B4024B62 +:108BA4009C4608BC6047C0468832000008B4024BAB +:108BB4009C4608BC6047C046C8D4000080B500F09D +:108BC40067F900F00BFA00F049FA00F0DBFA00F064 +:108BD40017F909BC1847FEB5854800688007800F5F +:108BE400002803D0022807D003D309E081480400F9 +:108BF40008E08148040005E080200002040001E050 +:108C04007C4804007D480068800118D57B480068D2 +:108C14008004800C401C029078480068000C000717 +:108C2400000F401C01900299009120000199FFF768 +:108C3400B5FF00994143022041430D0000E02500A7 +:108C44008C4800680006000E401C06002800310015 +:108C5400FFF7A4FF07003800FEBC08BC184770B536 +:108C64000600FFF7B8FF04003606360E3000002871 +:108C74000F2808D9103803281ED9401F06281BD9ED +:108C8400083819D033E07C48006802217143C84099 +:108C94008007800F0500002D02D12000800827E006 +:108CA400012D01D1200023E0022D02D12000400833 +:108CB4001EE02000C0081BE0C048006831001039E5 +:108CC40002225143C8408007800F0500002D02D1C5 +:108CD400200080080CE0012D01D1200008E0022DC5 +:108CE40002D12000400803E02000C00800E000207A +:108CF40070BC08BC1847F1B582B00298062802D0AF +:108D0400029807280ED1FF20C04300680190019803 +:108D1400002806D00198FFF7BFFEFF20C0430121C1 +:108D240001605DE0554800680068040002995448F9 +:108D340004F0A4FB00906168524804F09FFB00908B +:108D4400A168514804F09AFB0090E1684F4804F090 +:108D540095FB009021699A4804F090FB00906169AA +:108D6400984804F08BFB0090A169974804F086FBB7 +:108D74000090E169954804F081FB0090216A9448D1 +:108D840004F07CFB0090616A924804F077FB009049 +:108D9400A16A914804F072FB0090E16A9F4804F0D4 +:108DA4006DFB0090216B9E4804F068FB0090616BA2 +:108DB4009C4804F063FB009021009B4804F05EFB98 +:108DC4000700A16B994804F059FB0600E16B984831 +:108DD40004F054FB05002168964804F04FFBFEE7BD +:108DE400F7BC08BC1847C0480021C943016070475C +:108DF4000CC11FE000093D00001BB70088C01FE044 +:108E040038B58D480068102188438B4908608B4829 +:108E14008B4901608B48102101600120FFF71FFF7F +:108E240005002800FA218900FFF7B8FE0400AF48C6 +:108E340002210160AD4800210160834800210160E6 +:108E4400601E824908608248032101608148002134 +:108E54000160814800210160A4480121016031BC06 +:108E640008BC184780B5A248FF21016003F08CFBC1 +:108E740009BC184704C11FE0A8C11FE00456004004 +:108E8400801B0100AC3E0100BC3E0100CC3E010051 +:108E9400F8B500240B2000900020070003200500F3 +:108EA4000520060093480068800111D504F0F8FA03 +:108EB400040091480068022188438F4908608F4864 +:108EC400AA2101608D48552101602000FFF76EFE44 +:108ED40004F0E6FA040088480068012188438649C2 +:108EE40008608648AA210160844855210160200059 +:108EF400FFF75CFE824800681021884380490860BF +:108F04007F480068202101437D4801607C48006857 +:108F1400012101437A480160794800684006FBD585 +:108F240078480121016004F0BBFA04000098390478 +:108F34000143754801607148AA2101606F485521B9 +:108F440001602000FFF732FE04F0AAFA04006A4828 +:108F5400006801210143684801606848AA21016052 +:108F64006648552101602000FFF720FE6748056030 +:108F7400674806605F4800684001FBD5654866495C +:108F840001600E486549016004F08AFA04005A48F9 +:108F9400006802210143584801605848AA21016031 +:108FA4005648552101602000FFF700FE5148006833 +:108FB4008001FBD5F1BC08BC18470000ACC11FE020 +:108FC400DC3E0100EC3E0100FC3E01000C3F0100D0 +:108FD4001C3F01002C3F01003C3F010010B5FFF78E +:108FE400FAFD0400D348002101604D48844202D2B6 +:108FF4004C48012101604C48844202D24948022174 +:1090040001604948844202D3464803210160C948AB +:109014000221016010BC08BC184700004C3F01004D +:109024005C3F01006C3F01007C3F01008C3F01006C +:109034009C3F0100AC3F01000CF0FFFF10F1FFFF6B +:10904400698E000010F0FFFF104000E0184000E0BF +:10905400144000E0284000E03C4000E03348002198 +:109064000160334800210160324800210160324828 +:109074000021016031480021016031480021016074 +:109084003048002101603048002101602F48002150 +:1090940001602F48002101602E48002101602E4804 +:1090A400002101602D48002101602D48002101604C +:1090B4002C48002101602C48002101602B4800212C +:1090C40001602B48002101602A48002101602A48E0 +:1090D4000021016029480021016029480021016024 +:1090E400CA4800210160704714F0FFFF044000E00B +:1090F400004000E088C01FE080C01FE08CC01FE07B +:10910400A0C11FE00CC11FE084C01FE004C11FE028 +:1091140008C11FE0A8C11FE0AAAAAAAAAAA8AA2255 +:10912400002D310104C01FE0005A6202088002E0F1 +:10913400188002E000C0FF3F20C0FF3F40C0FF3F57 +:1091440060C0FF3F80C0FF3F10C0FF3F30C0FF3F03 +:1091540050C0FF3F70C0FF3F90C0FF3F00C002E01F +:1091640004C002E008C002E00CC002E010C002E04B +:1091740014C002E018C002E01CC002E020C002E0FB +:1091840024C002E046480021C9430160FF20C043D7 +:10919400002101604748002101604B484B490160B0 +:1091A4004B4850490160504854490160544855495E +:1091B400016059485949016059485F4901605F4855 +:1091C4006349016063486449016068486849016013 +:1091D40068486D4901606D48714901607148724980 +:1091E400016076487649016076487B4901607B4896 +:1091F4007F4901607F488049016085488549016055 +:1092040085488A4901608A488E4901608E488F49A1 +:1092140001609348934901609348984901609848D4 +:109224009C4901609C489D490160A148A149016095 +:10923400A148A6490160A648AA490160AA48AB49C9 +:109244000160AF48AF490160AF48B4490160B44818 +:10925400B8490160B848B9490160704700B5FEE7F4 +:1092640080B5BB4800210160FFF7F8FF09BC18472F +:1092740080B5B74801210160FFF7F0FF09BC18472A +:1092840080B5B34802210160FFF7E8FF09BC184725 +:1092940080B5AF4803210160FFF7E0FF09BC184720 +:1092A40014F0FFFF80B5AA4804210160FFF7D6FF40 +:1092B40009BC184720F0FFFF80B5A54805210160CF +:1092C400FFF7CCFF09BC184700F1FFFF65920000CF +:1092D40004F1FFFF80B59E4806210160FFF7BEFF41 +:1092E40009BC18477592000008F1FFFF80B5984843 +:1092F40007210160FFF7B2FF09BC184785920000FF +:109304000CF1FFFF9592000080B59148082101609F +:10931400FFF7A4FF09BC184710F1FFFFA992000052 +:1093240014F1FFFF80B58A4809210160FFF796FF19 +:1093340009BC184700C01FE0BD92000018F1FFFFF0 +:1093440080B583480A210160FFF788FF09BC1847EC +:10935400D99200001CF1FFFFF192000080B57C4817 +:109364000B210160FFF77AFF09BC184720F1FFFFCA +:109374000D93000024F1FFFF80B575480C210160B6 +:10938400FFF76CFF09BC18472993000028F1FFFF81 +:1093940080B56F480D210160FFF760FF09BC1847D5 +:1093A400459300002CF1FFFF6193000080B56848ED +:1093B4000E210160FFF752FF09BC184730F1FFFF8F +:1093C4007D93000034F1FFFF80B561480F210160F7 +:1093D400FFF744FF09BC18479593000038F1FFFFDD +:1093E40080B55B4810210160FFF738FF09BC1847BE +:1093F400B19300003CF1FFFFCD93000080B55448C9 +:1094040011210160FFF72AFF09BC184728C002E0B8 +:1094140040F1FFFFE593000044F1FFFF80B54C48A5 +:1094240012210160FFF71AFF09BC184701940000DC +:1094340048F1FFFF80B5464813210160FFF70EFF96 +:1094440009BC1847219400004CF1FFFF3994000037 +:1094540080B53F4814210160FFF700FF09BC18479D +:1094640050F1FFFF5594000054F1FFFF80B53848D8 +:1094740015210160FFF7F2FE09BC18477194000042 +:1094840058F1FFFF80B5324816210160FFF7E6FE70 +:1094940009BC1847899400005CF1FFFFA594000003 +:1094A40080B52B4817210160FFF7D8FE09BC184787 +:1094B40060F1FFFFC194000064F1FFFF80B5244810 +:1094C40018210160FFF7CAFE09BC1847D9940000AF +:1094D40068F1FFFF80B51E4819210160FFF7BEFE49 +:1094E40009BC1847F59400006CF1FFFF11950000CA +:1094F40080B517481A210160FFF7B0FE09BC184770 +:1095040070F1FFFF2995000074F1FFFF80B510484A +:109514001B210160FFF7A2FE09BC18474595000016 +:1095240078F1FFFF80B50A481C210160FFF796FE21 +:1095340009BC1847599500007CF1FFFF69950000AC +:1095440080B503481D210160FFF788FE09BC184758 +:109554007055004080B507481E210160FFF77EFE6C +:1095640009BC184780B503481F210160FFF776FE48 +:1095740009BC1847705500400DB400B582B004A86A +:1095840000900A006B4603A9034878440A3003F0AC +:10959400B3FF029906B00847218700001EFF2FE1A0 +:1095A40000B5002802D541420800FFE708BC18476F +:1095B40010B50024FFF722F8040000207A4908803F +:1095C4007A4908807A49088000207A4908807A49D3 +:1095D40008807A4908807A480068022188437849DB +:1095E40008607848062101602000F8F7B1F910BC42 +:1095F40008BC184738B50025FFF700F8050000241B +:10960400E4436E480088012815D36C480088401E46 +:109614006A490880684800886B49085C0400664809 +:109624000088401C64490880634800888021F9F759 +:109634001FFE614801802800F8F78AF9200032BC37 +:1096440008BC184770B505000026FEF7D7FF0600D2 +:1096540000245748008840283CD2554800880028F8 +:109664001FD15A480078800602D55948057034E065 +:109674004F480088401C4E4908804B480088554993 +:109684000D5449480088401C4749088046480088D2 +:109694004021F9F7EDFD44480180A648032101600B +:1096A4001BE043480088401C414908803E4800882C +:1096B40048490D543C480088401C3B4908803A48BE +:1096C40000884021F9F7D4FD3748018099480321E7 +:1096D400016002E00020C04304003000F8F738F9CC +:1096E400200070BC08BC184738B53648006805002F +:1096F4002D062D0E6D086D076D0F2D062D0E022DF6 +:1097040024D132480078C0074BD52C4800888028E3 +:1097140017D2284800882C492D4A12780A54254823 +:109724000088401C23490880224800888021F9F7DA +:109734009FFD2048018021480088401C1F49088063 +:109744002FE068462249097801702AE02D062D0E83 +:10975400012D1FD116480088012817D3134800880B +:109764001C49085C1A49087010480088401C0F49BD +:1097740008800E4800884021F9F77AFD0B480180E3 +:109784000B480088401E0A4908800AE00C48012161 +:10979400016006E068460E49097801700B480078BC +:1097A400040031BC08BC18474A56004048560040E3 +:1097B4004C560040505600404E5600405256004011 +:1097C40004C000E008C000E0844F004014C000E082 +:1097D40000C000E088520040F1B584B00026FEF7D6 +:1097E4000DFF06000320FFF73AFA0190019800F0FC +:1097F400D5F90022504B00F0D9FA04000D0004986A +:1098040000F0CCF902000B002000290000F0CEFA91 +:1098140004F0F2FB02900298FFF77CF902000B00BF +:109824000020464904F040FC04F0E0FC07006846D0 +:1098340039004170684639000904090C090A0170AD +:109844003F4800688021490401433D48016039488C +:10985400002101603B48062101603B480021016072 +:109864003A48802101703A48694649780170314884 +:1098740069460978016037481021016033480021A6 +:1098840001703248007803210143304801702F48A9 +:109894000078FB2101402D48017026480121016018 +:1098A4002D48006830218843102101432A48016073 +:1098B40029480068C02188434021014326480160AB +:1098C40026480068302188432449086023480068FA +:1098D400C0218843214908602148006804210143CC +:1098E4001F4801601E480068082188431C4908601D +:1098F4001C480068042101431A48016019480068A3 +:109904000821014317480160174800684021884333 +:109914001549086015481649016016484021016040 +:10992400FFF746FE3000F8F713F805B0F0BC08BCAA +:109934001847000004C000E0000030400000E03F91 +:10994400C4C01FE008C000E020C000E00CC000E07C +:1099540000C000E028C000E000C002E040C002E017 +:1099640000C0FF3F10C0FF3F0CF0FFFF18F1FFFFE6 +:10997400ED96000010F0FFFF10B504002000000673 +:10998400000EFFF75FFE002803D00120FDF7F2FA76 +:10999400F4E710BC08BC1847F8B507000C00002514 +:1099A4000026F643002E0ED5FFF724FE0600002EF7 +:1099B40009D50120FDF7DEFA280005006D1C84425C +:1099C400F0D2002002E0300038700120F2BC08BC64 +:1099D400184770B504000D0016002800451E002825 +:1099E40008D031002000FFF7D7FF641C0028F4D111 +:1099F400002000E0012070BC08BC184770B50400CA +:109A0400002661480078012801D300201CE0FEF7FD +:109A1400F5FD06005D48006805005C480068002804 +:109A240004D05A4800684068584908603000F7F785 +:109A34008FFF002D07D0032028702C810020686040 +:109A4400280002F0F9FE280070BC08BC1847F2B5E3 +:109A54000500140000262878032802D00120207075 +:109A64005FE049480078012802D30220207058E0C2 +:109A740047480078012802D30D20207051E0FEF7FA +:109A8400BDFD06002889012808D32889401E2881A5 +:109A94003000F7F75DFF0020207042E03D48006889 +:109AA4002C300078012101433A4800682C300170C1 +:109AB400384800682D300021017036480068694636 +:109AC40009884185280002F041FE3000F7F740FF85 +:109AD40002F070FFFEF792FD06002E4800682D305C +:109AE4000078002814D02B4800682D300078070037 +:109AF400280002F06DFE3000F7F72AFF3F063F0E04 +:109B0400022F02D00A20207001E00E20207008E00D +:109B1400204800680021C1613000F7F719FF0020D8 +:109B24002070F1BC08BC184770B5040000252078EB +:109B3400032801D0012023E0FEF760FD0500A07A90 +:109B440000280DD0002301220021200002F09FFDF7 +:109B540006002800F7F7FCFE02F02CFF00200FE0BF +:109B640020890D49884207D02089401C2081280083 +:109B7400F7F7EEFE002003E02800F7F7E9FE3220B5 +:109B840070BC08BC1847000075560040F4550040EE +:109B94007656004004560040FFFF00007847C04658 +:109BA4000010B0E14214A013AE11001A1EFF2FE101 +:109BB4007847C046B0402DE9037021E0807407E285 +:109BC400FF40A0E3704E84E321CA14E0235A14102A +:109BD40004003C11040035112500000A05C08CE086 +:109BE400843AC3E1403983E38115A0E1801481E321 +:109BF400A05A81E180E5A0E10210A0E19E0282E08A +:109C0400000050E30000A0E39521A0E00010A0E3D1 +:109C1400932EA1E001208213010090E00010A0E344 +:109C24000110A1E09305A1E040CE4CE20156B0E161 +:109C34000200002A8220B0E10000B0E00110B1E08F +:109C440001C0BCE23E0000DAA050B0E18024D2E2C0 +:109C54000000B0E20C1AB1E0401941E2071081E1C2 +:109C64000C00005A041A87410000A043B040BDE82C +:109C74001EFF2FE1235A04E004003CE104003511E7 +:109C84002300000A81E090E183E092110300001AAE +:109C94000710A0E10000A0E3B040BDE81EFF2FE1E3 +:109CA4000C001CE105C08CE01200001A050015E14F +:109CB400F6FFFF0A0116B0E10010A0010000A003A6 +:109CC40014504502201A91E10006A0E105C0A0E16C +:109CD4000300004A01C04CE28000B0E10110B1E091 +:109CE400FBFFFF5A00E0A0E10150A0E1843AC3E188 +:109CF400403983E3BFFFFFEA01C04CE28220B0E1B8 +:109D04000330A3E0400913E3FAFFFF0A01C08CE229 +:109D1400B4FFFFEA81E090E183E092110010E003D8 +:109D24008059A0E3830075E10310A081810075913F +:109D3400D8FFFF8A041A87E10000A0E3B040BDE821 +:109D44001EFF2FE101C07CE220505CE2080000AA63 +:109D540020506CE2020012E1A220A0E10120821353 +:109D6400102592E1300CA0E1110580E1311CA0E145 +:109D7400080000EA35005CE3C4FFFFCA20C065E2C6 +:109D8400802092E13025A0E1012082133105A0E179 +:109D9400112C92E10010A0E38024D2E20000B0E292 +:109DA4000710B1E0B040BDE81EFF2FE17847C04680 +:109DB400F0002DE9037021E0807407E2FF40A0E386 +:109DC400704E84E321CA14E0235A141004003C1199 +:109DD40004003511A700000A05C04CE001C04CE2A4 +:109DE400C064E0E3014506E0204B84E10005A0E106 +:109DF400033506E0223B83E10225B0E10210A0E333 +:109E04001F00000A026050E00340D4E0403483E3C2 +:109E14000400002A01C04CE28660B0E10440A4E0E2 +:109E2400026096E00340B4E08660B0E10440A4E040 +:109E3400020056E10350D4E0026046200540A02110 +:109E44000110B1E0F7FFFF3A800EA0E38660B0E1B5 +:109E54000440A4E0020056E10350D4E0026046202E +:109E64000540A0210000B0E0F7FFFF3A8660B0E1B2 +:109E74000440A4E0026056E00350D4E0060016015A +:109E8400300000EA034054E0403483E30200002A37 +:109E940001C04CE28000B0E18440A3E0003063E202 +:109EA400000010E11100000A401E81E3000090E070 +:109EB4008440B3E0034044300110A1E0000090E08E +:109EC4008440B3E0034044300110A1E0000090E07E +:109ED4008440B3E0034044300110A1E0000090E06E +:109EE4008440B3E0034044300110B1E0F2FFFF3A94 +:109EF400844093E0034044300110A1E0844093E0A7 +:109F0400034044300110A1E0844093E00340443016 +:109F14000110B1E0F8FFFF3A800EA0E3844093E023 +:109F2400034044300000A0E0844093E00340443008 +:109F34000000A0E0844093E0034044300000B0E01F +:109F4400F5FFFF3A844093E08044A0230040A0330F +:109F540040448413810A80E1A115A0E140CE9CE233 +:109F64000D0000DAA020B0E18024D4E20000B0E2C9 +:109F74000C1AB1E0400971E3071081E10100004AC5 +:109F8400F000BDE81EFF2FE1FF1687E3701481E3A4 +:109F94000000A0E3F000BDE81EFF2FE1401981E3BB +:109FA40001C07CE220505CE2080000AA20506CE270 +:109FB400040014E1A440A0E101408413104594E19D +:109FC400300CA0E1110580E1311CA0E1080000EA99 +:109FD40034005CE30B0000CA20C065E2804094E1D9 +:109FE4003045A0E1014084133105A0E1114C94E116 +:109FF4000010A0E38044D4E20000B0E20710B1E016 +:10A00400F000BDE81EFF2FE10000A0E30710A0E16F +:10A01400F000BDE81EFF2FE10C001CE10700001A50 +:10A02400050015E10C00001A01C04CE28000B0E10B +:10A034000110A1E0400911E3FAFFFF0A01C08CE21C +:10A0440001C08CE28220B0E10330A3E0400913E3B5 +:10A05400FAFFFF0A02C04CE260FFFFEA015085E20A +:10A064008000B0E10110A1E0400911E3FAFFFF0A0A +:10A0740000C065E259FFFFEA235A04E004003CE112 +:10A08400040035110B00000A816090E18360921195 +:10A09400E0FFFF1A816090E10000A0E30710A0E157 +:10A0A400041A8111F000BDE81EFF2F1183C092E154 +:10A0B4000010E0031EFF2FE18069A0E30000A0E38D +:10A0C400810076E183007691810076010010E0231F +:10A0D4000200002A830076E10710A001041A871108 +:10A0E400F000BDE81EFF2FE17847C04681C0B0E113 +:10A0F4001800002AACCAA0E140CE4CE201C09CE2A8 +:10A104001400004A20005CE3060000AA1FC06CE2B1 +:10A114008115A0E1801481E3A00A81E1300CA0E163 +:10A124000010A0E31EFF2FE13FC07CE28115A0E1F7 +:10A13400801481E3A01A81E18005A0E1300CA051D4 +:10A14400710C2050311CA051010020500000E0434C +:10A154000010E0431EFF2FE10000A0E30010A0E385 +:10A164001EFF2FE17847C0460330D0E50220D0E53A +:10A174000110D0E50000D0E5032482E1010480E170 +:10A18400020880E11EFF2FE170B504000D001600E7 +:10A194002A003100200004F08DF8200070BC08BCB7 +:10A1A4001847310000B50100481E002905D00021E0 +:10A1B4000529F8DAC046491CFAE708BC184710B567 +:10A1C40004002406240EC02C05D32406240E66485D +:10A1D4000019C038047865480068F021C9030143B8 +:10A1E4006248016062480068802149000143604878 +:10A1F40001605F480068802101435D480160954823 +:10A20400006840210143934801600120FFF7CAFF21 +:10A214005648006857490140544801605348006853 +:10A2240021000906090E09090906090EC90401439A +:10A234004E4801600120FFF7B5FF86480068802181 +:10A244000143844801600120FFF7ACFF48480068DF +:10A2540080210143464801600120FFF7A3FF4348E2 +:10A2640000684449014041480160404800682406B0 +:10A27400240E2107090FC90401433C480160012051 +:10A28400FFF790FF73480068802101437148016023 +:10A294006420FFF787FF10BC08BC184710B5040002 +:10A2A40032480068F021C903014330480160304856 +:10A2B40000688021490001432D4801602C48006852 +:10A2C400802101432A48016062480068402101431B +:10A2D400604801600120FFF765FF244800682549B4 +:10A2E4000140224801602148006821000906090E46 +:10A2F40009090906090EC90401431C48016001202B +:10A30400FFF750FF53480068802101435148016022 +:10A314000120FFF747FF16480068802101431448D5 +:10A3240001600120FFF73EFF104800681149014019 +:10A334000E4801600D4800682406240E2107090F09 +:10A34400C9040143094801600120FFF72BFF41487C +:10A354000068802101433F4801606420FFF722FF29 +:10A3640010BC08BC18470000C40A010014C0FF3F19 +:10A3740058C0FF3FFFFF87FF38B505000C009C481D +:10A384000068F021C903014399480160314800681D +:10A394008021490001432F480160964800688021CC +:10A3A4000143944801602B48006840210143294837 +:10A3B40001600120FFF7F6FE8D4800688E490140D8 +:10A3C4008B4801608A48006829000906090E0909BA +:10A3D4000906090EC9040143854801600120FFF7FD +:10A3E400E1FE1C480068802101431A4801602406EC +:10A3F400240E012C2AD10120FFF7D4FE7D480068E9 +:10A40400802101437B4801600120FFF7CBFE78489F +:10A4140000687949014076480160754800682D0656 +:10A424002D0E2907090FC904014371480160012059 +:10A43400FFF7B8FE07480068802101430548016022 +:10A444000120FFF7AFFE0220FCF794FD31BC08BCED +:10A45400184700005CC0FF3F10B50024FEF7CEF89B +:10A464000400664800686649014064480160634826 +:10A4740000686449014061480160604800686249BD +:10A4840001405E480160614800685D4901405F48E1 +:10A4940001605E4800685B4901405C4801605B48BC +:10A4A40000685949014059480160594800688021B1 +:10A4B4004900014356480160554800688021014322 +:10A4C40053480160524800684021014350480160EC +:10A4D40050480068504901404E4801604D480068AA +:10A4E400802188434B4908604A48006840218843DA +:10A4F4004849086049480068C021884347490860C2 +:10A5040046480068464901404448016043480068A1 +:10A514004449014041480160404800683A490140CB +:10A524003E48016040480068C02188433E490860B5 +:10A534003D4800683A4901403B4801603A48006898 +:10A544003849014038480160374800682E490140C5 +:10A5540035480160354800688021090301433348C8 +:10A564000160324800688021490301432F4801609B +:10A574002E4800688021890301432C4801602B4840 +:10A5840000688021C9030143284801602848006805 +:10A5940028490140264801602548006826490140B1 +:10A5A4002348016022480068244901402048016092 +:10A5B4001F480068224901401D4801602148006885 +:10A5C400802101431F4801601E4800684021014367 +:10A5D4001C4801601B480068802149000143194858 +:10A5E40001602000F7F7B4F910BC08BC184700005C +:10A5F40014C0FF3F58C0FF3FFFFF87FF10C002E0B9 +:10A60400FFFFFCFFFF3FFFFFFFCFFFFF50C002E053 +:10A6140040C0FF3F50C0FF3FFFFEFFFF04C002E009 +:10A62400FFFCFFFFFFF3FFFF44C002E000C0FF3F59 +:10A6340010C0FF3FFFFFF7FFFFFFEFFFFFFFDFFF4C +:10A64400FFFFBFFF5CC0FF3F80B5FFF705FF1E2083 +:10A65400FCF790FC00213020FFF78EFE2820FFF746 +:10A66400A1FD00213020FFF787FE2820FFF79AFD87 +:10A6740000213020FFF780FE2820FFF793FD002102 +:10A684002020FFF779FE2820FFF78CFD01212820E8 +:10A69400FFF772FE01210820FFF76EFE0121012061 +:10A6A400FFF76AFE01210620FFF766FE01210C2058 +:10A6B400FFF762FE09BC184710B504002406240EF7 +:10A6C400002C05D0022C0DD007D3032C0FD013E09F +:10A6D40001218020FFF750FE0FE00121C020FFF789 +:10A6E4004BFE0AE001219420FFF746FE05E001211C +:10A6F400D420FFF741FE00E0FFE710BC08BC184778 +:10A7040070B505000C0020000006000EFFF7D4FF12 +:10A7140000200600287800280CD028780A2809D0C0 +:10A724003606360E142E05D22878FFF748FD6D1C28 +:10A73400761CEFE73606360E142E04D22020FFF7DF +:10A744003EFD761CF6E770BC08BC184738B504001B +:10A754000D002D062D0E002D05D0022D13D00AD389 +:10A76400032D18D01FE00121200080380006000EC0 +:10A77400FFF702FE18E00121200040380006000E19 +:10A78400FFF7FAFD10E0012120006C380006000EEE +:10A79400FFF7F2FD08E0012120002C380006000E2E +:10A7A400FFF7EAFD00E0FFE731BC08BC184770B5CD +:10A7B40005000C00160031000906090E20000006F1 +:10A7C400000EFFF7C3FF28000006000EFFF766FD2A +:10A7D40070BC08BC184780B501210120FFF7CCFDEF +:10A7E40009BC184780B501210F20FFF7C5FD09BC3E +:10A7F400184780B501210C20FFF7BEFD09BC18479E +:10A8040080B5D8480068D8490140D6480160D54889 +:10A814000068D6490140D3480160D5480068D5494D +:10A824000140D3480160D4480068CF490140D24870 +:10A834000160D1480068CD490140CF480160CF484C +:10A844000068CC490140CD480160CD4800688021B2 +:10A8540049050143CA480160C948006880210905C7 +:10A864000143C7480160C74800688021C904014307 +:10A87400C4480160C4480068C4490140C24801603A +:10A88400C1480068C2490140BF480160C14800682E +:10A89400C1490140BF480160C04800683021884375 +:10A8A400BE490860BD480068C0218843BB490860B0 +:10A8B400AF480068BA490140AD480160B948006832 +:10A8C40030218843B7490860B6480068C0218843EE +:10A8D400B4490860A9480068B1490140A74801602B +:10A8E400B1480068B1490140AF480160AE48006812 +:10A8F400AF490140AC480160A2480068AD4901403D +:10A90400A0480160AC480068A8490140AA48016019 +:10A91400A9480068A6490140A74801609D4800680D +:10A92400A44901409B4801609C480068A349014038 +:10A934009A4801609B480068A04901409948016019 +:10A94400994800689E490140974801609A48006808 +:10A954009B49014098480160904800689049014033 +:10A964008E4801608F4800688D4901408D48016020 +:10A974008D4800688F4901408B4801608E4800680B +:10A984008C4901408C480160844800688D4901402D +:10A9940082480160834800688A4901408148016017 +:10A9A40081480068884901407F4801608248006806 +:10A9B400854901408048016078480068800080082B +:10A9C4007649086077480068800080087549086007 +:10A9D400754800684000400873490860764800687C +:10A9E40040004008744908605E4800686C490140B2 +:10A9F4005C48016060480068694901405E48016044 +:10AA04005F4800686B4901405D4801605E4800682A +:10AA1400684901405C480160604800686B49014036 +:10AA24005E4801605F480068684901405D48016014 +:10AA34005D480068664901405B4801605E48006803 +:10AA4400634901405C480160464800684949014047 +:10AA5400444801604848006846490140464801604E +:10AA6400474800684C490140454801604648006831 +:10AA7400494901404448016048480068554901403B +:10AA84004648016047480068524901404548016012 +:10AA94004548006850490140434801604648006801 +:10AAA4004D490140444801604C4800680C218843EA +:10AAB4004A4908604A4800680C21884348490860AC +:10AAC4002F480068022188432D4908602E480068F9 +:10AAD400022188432C490860424800683D490140EE +:10AAE40040480160404800683A4901403E480160DE +:10AAF4003E4800683E4901403C4801603D480068CA +:10AB04003B4901403B480160364800681749014011 +:10AB140034480160344800681449014032480160F7 +:10AB240032480068344901403048016031480068C7 +:10AB3400314901402F480160B74800210160B748FE +:10AB4400006800280BD10421B548FDF745F8B34946 +:10AB540008600923BF4A0021BF48FDF783F909BCF7 +:10AB64001847C04604C002E0FFFFFFFCFFFF3FFFA1 +:10AB74001CC002E0FFFFCFFF44C002E05CC002E063 +:10AB840000C0FF3F60C0FF3F10C0FF3FFFFFFFEF6B +:10AB9400FFFFFFF770C0FF3FFFFFFFFB0CC002E0A9 +:10ABA400FFFFF3FF4CC002E020C0FF3FFFFFFBFFAD +:10ABB400FFFFF7FFFFFFFFFD30C0FF3FFFFCFFFF7C +:10ABC400FFFFEFFFFF3FFFFFFFFF7FFFFFFFFCFFE4 +:10ABD400FFFFFFFEFFFFFFF3FFFFFFDF00C002E008 +:10ABE40040C002E010C002E050C002E040C0FF3F9D +:10ABF400FFDFFFFF50C0FF3FFFF7FFFFF8B507007F +:10AC040000241120FCF7B6F90020050093480068E1 +:10AC140080214905014391480160914800688021E1 +:10AC2400090501438E4801608E4800688021C904EB +:10AC340001438C4801600120FCF79CF98A480068B4 +:10AC4400800102D428000225054388480068400397 +:10AC540002D428000425054384480068000302D474 +:10AC64002800082505437E480068802149050143E2 +:10AC74007B480160794800688021090501437748D1 +:10AC84000160784800688021C90401437548016067 +:10AC94000120FCF76FF974480068800102D4280091 +:10ACA4001025054371480068400302D4280020257C +:10ACB40005436E480068000302D42800402505437C +:10ACC400674800688021490501436548016064487C +:10ACD40000688021090501436148016064480068F7 +:10ACE4008021C9040143624801600120FCF742F954 +:10ACF4005D480068800102D42800802505435B4834 +:10AD04000068400303D4280080256D00054357489C +:10AD14000068000303D428008025AD000543534890 +:10AD24000068C00203D428008025ED0005434F4885 +:10AD34000068800103D4280080252D0105434B4879 +:10AD44000068000203D4280080256D0105434748AC +:10AD54000068002803D428008025AD010543454838 +:10AD64000068800103D428008025ED0105433F4895 +:10AD74000068C00103D4280080252D0205433D4806 +:10AD84000068400103D4280080256D02054337483C +:10AD94000068800003D428008025AD0205433548AF +:10ADA4000068800703D428008025ED02054332485B +:10ADB4000068800403D4280080252D0305432E4811 +:10ADC4000068000503D4280080256D030543AC42C8 +:10ADD40020D1114800686840002819D00026152E9B +:10ADE40016D20D4800680121B140014000290DD15F +:10ADF4000120B0402840002808D0310007480068EE +:10AE0400FCF7D0FF3000C01DF5F704FF761CE6E721 +:10AE1400014805602C00F4E6B4550040B0550040EC +:10AE24004455004010B582B004006846002101700A +:10AE34006A46012111480068FCF720FF01006846BA +:10AE44000078002801D0002001E02160012016BC18 +:10AE540008BC18473C3D004001AC00001CC0FF3F4B +:10AE640018C0FF3F78C0FF3F74C0FF3F34C0FF3FAE +:10AE74007CC0FF3F14C0FF3F54C0FF3FB0550040AB +:10AE84007847C0469D10A0E3000050E32D0D001A42 +:10AE94001EFF2FE17847C046010030E180142142B3 +:10AEA4003F0D004A01C050E00C0040300C108130CE +:10AEB400FF20A0E3A0CB02E0A13B12E002003C1182 +:10AEC4008024A0E31300000A03C04CE018005CE3F4 +:10AED4001EFF2FC1011482E1A03BA0E1000482E126 +:10AEE400310C90E00200C031A000822119C06CE254 +:10AEF400521CC1E1001C91E12004A0E102C0D1E098 +:10AF0400830BA0E04037A0E3800073E11EFF2F31E4 +:10AF1400420400E01EFF2FE1FF005CE31EFF2F014F +:10AF24008114B0E10C001C11A10480001EFF2F014C +:10AF3400170053E3E7FFFFDA1EFF2FE17847C0460F +:10AF440080C0B0E10800002A2CCCA0E17FC05CE204 +:10AF54000500004A1FC07CE20004A0E1800480E3F5 +:10AF6400300CA0510000E0431EFF2FE10000A0E3DD +:10AF74001EFF2FE138B505000C002000441E0028F8 +:10AF840004D0287800F0BBF86D1CF6E731BC08BC8F +:10AF9400184770B504000D0016002800451E00284F +:10AFA40008D03100200000F0C0F8641C0028F4D15F +:10AFB400002000E0012070BC08BC1847F1B584B043 +:10AFC4000026FDF71BFB06000420FDF748FE019058 +:10AFD4000198FEF7E3FD00225F4BFEF7E7FE040055 +:10AFE4000D000498FEF7DAFD02000B002000290092 +:10AFF400FEF7DCFE03F000F802900298FDF78AFDEC +:10B0040002000B000020554903F04EF803F0EEF85F +:10B014000700684639004170684639000904090C84 +:10B02400090A01704E480068102101434C48016030 +:10B034004C48802101704C486946497801704B485E +:10B044006946097801604A48102101604548002199 +:10B0540001704848002101704748002101604748B9 +:10B06400006801210143454801603E4800780321FE +:10B0740001433C4801703B480078FB2101403948BA +:10B0840001703A48002101603D480068032188436B +:10B09400022101433A480160394800680C21884381 +:10B0A400082101433648016036480068032188437B +:10B0B40034490860334800680C21884331490860EA +:10B0C40031480068012101432F4801602E4800687F +:10B0D400022188432C4908602C480068012101435F +:10B0E4002A48016029480068022101432748016079 +:10B0F4003000F6F72DFC05B0F0BC08BC184710B5BD +:10B10400040023480078800603D40120FBF732FFB3 +:10B11400F7E71548047010BC08BC184717480068C6 +:10B124000221014315480160704770B505000C0009 +:10B13400002617480078C00707D40120FBF71AFF40 +:10B14400761CB442F5D2002003E00748007828704A +:10B15400012070BC08BC1847000030400000E03FEC +:10B16400C4C01FE00C0001E0000001E0040001E0A5 +:10B17400280001E0100001E0200001E0080001E0E7 +:10B1840010C002E050C002E040C0FF3F50C0FF3F8B +:10B19400140001E07847C046030011E30400000AEC +:10B1A400012052E20130D1240130C024F9FFFF8A8A +:10B1B4001EFF2FE1030010E31200001A102052E2D8 +:10B1C4000500003A30002DE93810B1E8102052E2B1 +:10B1D4003810A0E8FBFFFF2A3000BDE8823EB0E152 +:10B1E4000810B1280810A028043091440430804489 +:10B1F400822FB0E1B220D1200130D144B220C0204E +:10B204000130C0441EFF2FE1042052E21000003A36 +:10B21400010010E30600001A043091E4042052E215 +:10B22400B230C0E06338A0E1B230C0E0F9FFFF2AD9 +:10B23400070000EA043091E4042052E20130C0E443 +:10B244006334A0E1B230C0E06338A0E10130C0E46F +:10B25400F7FFFF2A04208232012052E20130D12478 +:10B264000130C024FBFFFF8A1EFF2FE17847C04650 +:10B2740001402DE9040052E30D00003A030011E3FC +:10B284001800001A7CE09FE5003091E503C010E24D +:10B294000700001A042052E2AEC3432003C0CC21AD +:10B2A4000C001E21043080040430B105F8FFFF0AAD +:10B2B400042092E2020012E10800000A0130D1E405 +:10B2C400012052E20130C0E4030013110130D11413 +:10B2D400FAFFFF1A0210B0E10020A0E3F80B001BF4 +:10B2E4000140BDE81EFF2FE10130D1E4012052E20C +:10B2F4000130C0E4010053E3030011E3F9FFFF8AC6 +:10B30400DFFFFF2AF2FFFFEA808080807847C04693 +:10B31400FF30A0E3A0CB13E0A12B131003003C11DA +:10B32400030032112F00000A02C04CE08024A0E385 +:10B33400013020E0023003E0011482E1000482E1E4 +:10B344002021A0E12111A0E1400FA0E3012052E05F +:10B3540001C04C3282208130822071E00220813091 +:10B364000000A0E0822071E0022081300000A0E013 +:10B37400822071E0022081300000A0E0822071E090 +:10B38400022081300000B0E0F2FFFF3A7FC09CE26F +:10B39400090000DA802F92E1A000A0E18014D2E23B +:10B3A4008C0BB0E080087053030080E11EFF2F5126 +:10B3B400FF00A043800B83411EFF2FE102C07CE20B +:10B3C400400780E319005CE3040000CA20106CE22B +:10B3D400102192E18014D2E2300CA3E01EFF2FE191 +:10B3E4000300A0E11EFF2FE14027A0E3800072E1EB +:10B3F400810072310B00003A800072E10400003ACF +:10B40400810072E10000E023800411E38004204203 +:10B414001EFF2FE1810072E10000E0130100200013 +:10B42400800400021EFF2FE180C0B0E181C0B01192 +:10B434000700001A80C0B0E1010020E0800400E2AF +:10B44400830B80111EFF2F1181C0B0E10000E003C7 +:10B454001EFF2FE1A0CB13E01500001AA1CB13E0CF +:10B46400013020E0803403E20900001A0004A0E166 +:10B4740000C0A0E38000B0E101C04C52FCFFFF5AC1 +:10B484000114A0E18110B0E101C08C52FCFFFF5A0D +:10B49400AAFFFFEA00C06CE20004A0E18000B0E172 +:10B4A40001C04C52FCFFFF5A0114A0E1801481E357 +:10B4B400A2FFFFEA013020E0803403E20114A0E19E +:10B4C4008110B0E101C08C52FCFFFF5A0004A0E1DE +:10B4D400800480E399FFFFEA7847C046FF20A0E399 +:10B4E400A0CB12E0A13B121002003C110200331168 +:10B4F4001500000A012020E003C08CE08034A0E3A2 +:10B50400011483E1000483E1913080E0802402E2AD +:10B514008010B0E18000A0317FC0DCE2360000BAC8 +:10B52400A330A0E1003C93E12004A0E18014D3E225 +:10B534008C0BB0E080087053000082E11EFF2F5195 +:10B54400FF00A043800B82411EFF2FE1A13B02E0DC +:10B5540002003CE1020033111A00000A8020B0E12D +:10B564008120B0110200001A010020E0800400E2F2 +:10B574001EFF2FE1012020E0802402E20C001CE1E8 +:10B584000900001A030013E12400000A03C0A0E12B +:10B594000004B0E18000B0E101C04C52FCFFFF5A4E +:10B5A4000114A0E1801481E3D6FFFFEA0114B0E1A5 +:10B5B4008110B0E101C04C52FCFFFF5A0004A0E12D +:10B5C400800480E3CFFFFFEA8030B0E18130B01126 +:10B5D4000000E0034037A0E3810073E10100A08193 +:10B5E400800073911EFF2F81010020E0800400E29F +:10B5F400820B80E11EFF2FE10020A0E308C07CE263 +:10B6040020005CE3050000CA20106CE2A330B0E126 +:10B61400103193E18014D3E2300CA2E01EFF2FE13D +:10B624000200A0E11EFF2FE108B4024B9C4608BCB7 +:10B634006047C046A0E50000F0B5A3B002ACA0602E +:10B64400002016001D00E16002E0206B761C401C07 +:10B6540020633178002904D1206B23B0F0BC08BCEE +:10B664001847252908D10020A061E06120626062AA +:10B67400A062E06200210CE0E068A26802F022FF10 +:10B68400E0600028E1D10020C043E6E70120084340 +:10B694000100761C30782028F8D023280AD02B28E3 +:10B6A40004D02D2804D0302806D007E00220EEE78D +:10B6B4000420ECE70820EAE71020E8E72A280DD167 +:10B6C4002868021D2A600068A063002804D542424D +:10B6D40008000421A2630143761C14E00020A06347 +:10B6E4000AE0A26B274B9A4205D093009A185200A5 +:10B6F40080183038A063761C30780200303A120685 +:10B70400120E0A2AEDD330782E2803D00020C0432D +:10B7140060631EE0761C30782A2805D12868761CE0 +:10B72400021D2A600068F3E7002060630AE0626B90 +:10B73400144B9A4205D093009A185200801830385E +:10B744006063761C30780200303A1206120E0A2A20 +:10B75400EDD3A18731780A487844243002F0B4FE4E +:10B76400002801D03078761C3E216054605C682843 +:10B774000AD13078682810D13E2062210BE0C046FF +:10B78400AC6D0000FFFFFF7F6C2806D130786C2879 +:10B7940003D13E2071212154761C12A860613378B4 +:10B7A4001800253827D01C3800D185E0001F022856 +:10B7B40000D881E0133800D1A8E009387CD0801E7D +:10B7C40000D14DE1401E00D1F1E0401E022873D9A2 +:10B7D400001F00D1EBE0401F3BD0401E00D195E09C +:10B7E400401E25D0C01E0DD0801E00D18EE0C01E8C +:10B7F40000D18BE03EE1A1692522481CA06112A87A +:10B80400425444E12868011D29600068626B20618C +:10B81400002A02D5FCF7D4FC08E0002102F066FE01 +:10B82400002802D02169401A00E0606BE0612EE13B +:10B834002868011D296002680020C04310400021CF +:10B8440002AA03C212A82061782102A800F0A6F976 +:10B854001DE13E20205C622827D068280FD06A288A +:10B864001BD06C2804D0712817D074280ED07A28E5 +:10B874002868011D2960216B0068016007E12868C0 +:10B88400011D2960216B0068018000E12868011D09 +:10B894002960216B00680160F9E02A68101D2860A6 +:10B8A400206B1268C11703C2F1E02868011D2960EA +:10B8B400216B00680170EAE03E20205C4C28286877 +:10B8C400C01D07218843010028600831296003C88E +:10B8D40002AA03C2002902D5A1692D2209E0A08F82 +:10B8E400810702D5A1692B2203E0C00705D5A16910 +:10B8F4002022481CA06112A84254A06912A9081869 +:10B904002061190002A800F0E3F9C0E03E20225CA7 +:10B914006C2A01D1286811E0712A09D1286807210D +:10B92400C01D8843010028600831296003C809E06C +:10B9340028686A2A02D1C01D0721F2E7011D296087 +:10B944000068002102AF682A03C706D102A803C811 +:10B9540002AA00210004000C10E0622A06D102A809 +:10B9640003C802AA00210006000E07E0742A01D0D1 +:10B974007A2A04D102A803C802AA002103C23C20E7 +:10B98400205C000766D502A803C8002901D100285D +:10B9940060D02020184378285CD1A16912A83022F5 +:10B9A4004254491C481CA06112A8435452E03E2052 +:10B9B400205C62280CD0682811D06A2821D06C2819 +:10B9C40029D071281DD0742816D07A280ED027E0EB +:10B9D4002868011D296000680006001624E0286814 +:10B9E400011D29600068000400141DE02868011D81 +:10B9F40029600068002118E02868011D296000689A +:10BA040012E028680721C01D88430100286008311E +:10BA1400296003C809E02868011D2960006803E063 +:10BA24002868011D29600068C11702AA03C2002901 +:10BA340002DAA1692D2209E0A08F810702D5A1694C +:10BA44002B2203E0C00705D5A1692022481CA06170 +:10BA540012A84254A06912A9081820611900F4E63A +:10BA6400A169481CA0612868021D2A60006812AA06 +:10BA740050540CE0A1692522481CA06112A842542C +:10BA8400002B04D0A169481CA06112A84354A06BE8 +:10BA9400A169761C401A616A401AE169401AA16AD8 +:10BAA400401A216A401AE16A401A01903C20205C45 +:10BAB400400710D4684620210170019801280ADB50 +:10BAC400019F0122694602A800F0ACFC002800D0C6 +:10BAD400D9E57F1EF5D1A26912A902A800F0A2FC43 +:10BAE400002800D0CFE5676A684630210170012F35 +:10BAF40009DB0122694602A800F094FC002800D06A +:10BB0400C1E57F1EF5D1E269216902A800F08AFC33 +:10BB1400002800D0B7E5A76A684630210170012FDC +:10BB240009DB0122694602A800F07CFC002800D051 +:10BB3400A9E57F1EF5D1E0692169226A091802A8E6 +:10BB440000F070FC002800D09DE5E76A68463021CB +:10BB54000170012F09DB0122694602A800F062FC92 +:10BB6400002800D08FE57F1EF5D13C20205C4007E3 +:10BB740000D46EE56846202101700198012800DA9E +:10BB840067E5019F0122694602A800F04BFC0028EA +:10BB940000D078E57F1E00D15BE5F3E7F2B506003F +:10BBA400706984B002906846007C6F2801D1082730 +:10BBB40008E06846007C20210143782901D00A2747 +:10BBC40000E0102703CE6A463C24083E03C26A46BE +:10BBD400127C642A03D06A46127C692A09D100299E +:10BBE40007DA684603C800220023121A6D468B4107 +:10BBF4000CC5684603C800290FD100280DD1706B0D +:10BC040000280AD1082F3BD1305D000738D50298AF +:10BC140030213B303B24017032E0684603C83A00CF +:10BC2400FB17641EFFF700FD30321206120E3A2A8B +:10BC340003D36846007C513812180298FB1702554A +:10BC4400684603C83A00FFF7EFFC6A4603C2684639 +:10BC540003C8002901D1002804D0029930690919C8 +:10BC64008842DAD3082F0BD13C20305C000707D57B +:10BC74000298005D302803D00298641E30210155DB +:10BC84003C20001BF061029909193161716B8842F3 +:10BC940006DA081A0D497062B08F0140B18710E0CE +:10BCA40000290ED53C21715C14220A40102A08D1C7 +:10BCB400B16BB269891A726A891A0C1A012C00DBF9 +:10BCC400746205B0F0BC08BC18470000EFFF000028 +:10BCD400F3B503C891B002AA07AD03C212A8007855 +:10BCE400202101436846017061290CD01198406BF2 +:10BCF400002802D51198062104E004D1672902D155 +:10BD04001198012141631198AD4A4168080D104012 +:10BD140090422BD1080318D111980068002814D13F +:10BD240011980321C16112A8007861380006000E41 +:10BD34001A2847D3254878449230009011980099E6 +:10BD440000690322FFF726FA17E211980321C16163 +:10BD540012A8007861380006000E1A282ED31C4958 +:10BD640079446C31119803220069EBE7010018D182 +:10BD7400119802F09BFC012813DB00270020694680 +:10BD84000978612931D11199302209690A70119A0F +:10BD9400491C4B1C136112AA1278612A1ED1782205 +:10BDA4001DE01199874A49680A4087491143119A4D +:10BDB40051608649471A0020C043E0E705497944A9 +:10BDC4001231CFE7044878440E30B6E774670000B8 +:10BDD40068670000606700006467000058220A700A +:10BDE4001199119A8969891C9161002803D1002451 +:10BDF40068468480B5E168460078612800D0A2E0F6 +:10BE04001198446B002C01D5212400E0641C03C864 +:10BE14006A462404241403C202A803C8661C002230 +:10BE2400002302F067FC684603C802AA02D28023FA +:10BE34001B06594003C2381F6946888007AF68460D +:10BE440000217F1C0177012E31DB02A803C80022E8 +:10BE5400002302F06DFC2AD21C2102A802F086FC09 +:10BE640002A803C802F0C2F9F61F0500012E09DB7F +:10BE740002F0EEF902000B0002A803C802F008FD6C +:10BE840002AA03C2FF1D072004E029077F1E090F31 +:10BE940039702D11012D01DB401EF6D5401E03D44F +:10BEA4007F1E00213970F9E7FF1D012ECDDA07A8A6 +:10BEB400401C07AD391A6D1CA14200DA0C002404A1 +:10BEC400241437D42000884206DA07A909184978CF +:10BED400082901D30F2100E0002107AA121801E06C +:10BEE400641E521E1378401E8B42F9D00F2904D1D0 +:10BEF40007A909184A78521C4A70002806D56846D2 +:10BF04008088694607AD001D641C888024042414BD +:10BF1400601E0FD429180A7830321206120E3A2AFB +:10BF240003D312AB1B783A3BD2180A70401E491E49 +:10BF34000028F0D51198406B002800D411E1119825 +:10BF4400611E41630DE102A803C80022002302F030 +:10BF5400D1FB06D202A803C880231B0602AA5940BB +:10BF640003C2884888493F043F1447433800F7F721 +:10BF74007FF96946888004200D5E84490720421BAE +:10BF84000020012A24DB140002AAC0CA02AA03C2A8 +:10BF9400E00707D502A803C832003B00FDF708FEFE +:10BFA40006000F0002A80CC8641002A803C8FDF71D +:10BFB400FFFD02AA002C03C2EAD102A8C0C02BE0F4 +:10BFC400FF070000FFFF0F800000E03FFE030000BA +:10BFD4006F4F544204AA002603C2002C14D0E00779 +:10BFE40007D504A803C832003B00FDF7E1FD0600B5 +:10BFF4000F0004A80CC8641004A803C8FDF7D8FDFA +:10C0040004AA002C03C2EAD102A803C832003B00F0 +:10C01400FDF7CCFE02AA03C268460078662801D167 +:10C024000A3500E006251198406B40190490142845 +:10C0340001DB132004906846302107AC0177641CAF +:10C044000498012841DB02A803C802F01BFD083450 +:10C0540005940500042428000A21FCF79FFD0E0026 +:10C0640028000A21FCF79AFD050005983036401E89 +:10C074000690067028000A21FCF790FD0E002800A7 +:10C084000A21FCF78BFD050006983036401E05900A +:10C094000670641EDFD1059C0498083408380490A7 +:10C0A4000128CDDB02A803C802F0ECFCFDF776FD05 +:10C0B40002000B0002A803C802F0EAFB354B002281 +:10C0C400FDF776FD02AA03C2BDE707A9497807A8D0 +:10C0D400401C07AD201A6D1C30296A4608D16946F8 +:10C0E40089886D1C401E491E918029783029F6D01C +:10C0F40069460978662903D10421515E491C06E08A +:10C1040069460978652901D1012100E00021119ACD +:10C11400526B541824042414A04200DA04002404AA +:10C1240024141ED42100814204DA685C352801D32A +:10C13400392000E030206A1800E0641E521E137893 +:10C14400491E8342F9D0392802D1685C401C6854E6 +:10C15400002906D56846808869466D1E401C641C0B +:10C16400888069460420085E23041B14009012A8EA +:10C17400017811982A0000F00FF813B0F0BC08BC45 +:10C184001847000097750000A086010000002440B5 +:10C194000000F03F84D79741F6B587B004000E9FA6 +:10C1A400666B1D00012D02DAACA001250890202049 +:10C1B400084366280CD0672800D085E003213F049B +:10C1C400C9433F148F4200DA83E0B74200DB80E0CA +:10C1D4007F1C66280BD03C20205C000702D4B542AB +:10C1E40000DA2E003F043F14F61B00D50026236915 +:10C1F400E1693F0458183F14012F24DA491C302206 +:10C204000270012E03DA3C20205C000702D52E20A8 +:10C214005854491C7842E161864200DA77423F046F +:10C224003F147842F619A062AE4200DA35002D04BC +:10C234002D142562E06908992A001818FEF7AAFF50 +:10C24400701BE062D6E0BD4216DA08992A00FEF7B8 +:10C25400A1FFE069791B4019E061A162012E03DAB4 +:10C264003C21615C090705D521692E220A54206A04 +:10C27400401C2062E662BDE008993A00FEF78AFF9E +:10C28400E069ED1BC119E161012E03DA3C20205C59 +:10C29400000704D5481CE06120692E2242542D0475 +:10C2A4002D14AE4200DA350008982369C119E069FB +:10C2B4002D042D142A001818FEF76CFFE0694019AC +:10C2C400E061701BA06295E06129684614D1702179 +:10C2D40015E0B54204DA3C20205C000700D42E00AF +:10C2E400761E00D500266846007F6728684601D17F +:10C2F400652104E0452102E0412901D15021017763 +:10C30400089AE16912782369481C5A540899491C0F +:10C314000091012E03DA3C21615C090702D52E212C +:10C324001954401CE061012E11DB6D1E2D042D14E7 +:10C33400AE4200DA350000992D042D142A00181895 +:10C34400FEF728FFE0694019E061701BA062E06914 +:10C3540021693F0408186946097F0170401C3F1495 +:10C3640004D42B210170401C089005E02D2101709C +:10C37400401C0890380047423F0400253F1403AE98 +:10C38400012F0FDB0A22390001A802F09BFB02985F +:10C394006D1C3070019F761C3F043F14012FF1DAAD +:10C3A400022D0BDA6846007F20210143652905D15F +:10C3B4000898302101700898401C0890002D06D17F +:10C3C4000898302101700898401C08900CE0012D59 +:10C3D4000ADB6D1E089903A8405D30300870089888 +:10C3E400401C0890012DF4DAE1692269089851187B +:10C3F400401A20623C20205C1421014010290DD1F8 +:10C40400A069E1694018A16A4018216A4018E16AEC +:10C414004018A16B884201DA081A606209B0F0BCC6 +:10C4240008BC184770B506000C0015000020002D4C +:10C4340011D02178F068B26802F044F8F060002866 +:10C4440007D0306B641C401C306300206D1EF0D19B +:10C4540001E00020C04370BC08BC18473000320023 +:10C4640008B4024B9C4608BC6047C04614860000D2 +:10C4740008B4024B9C4608BC6047C046B486000022 +:10C4840008B4024B9C4608BC6047C0461C860000AA +:10C4940008B4024B9C4608BC6047C0465086000066 +:10C4A40080B500F0F5FD00F0FDF900F013FA00F09E +:10C4B4004BFA00F0D4F900F05FFE02F015FBFBF735 +:10C4C400AEFC00F029FA02F041FB00F0E5FD02F0B9 +:10C4D40075FC09BC184710B500246548007801288C +:10C4E40034D1FCF78BF8040062480078012804D3A7 +:10C4F40060480078401E5F4908705E480078002854 +:10C5040021D15D48007800281DD100F084FA5B48F1 +:10C5140000785B490978884215D05848007804218E +:10C524004843584908585849086057480068406BC0 +:10C53400401C554909684863A4480068401CA34945 +:10C544000860FFF795FF2000FFF78AFF10BC08BCC6 +:10C55400184780B546480078002813D100F05BFAEC +:10C564004748464909780170444800780421484303 +:10C574004449085844490860AD4843490968016082 +:10C58400FFF77EFF09BC184770B5002600F0C7FD11 +:10C59400FCF734F80600A7480068401CA549086069 +:10C5A4003000FFF75DFF3248007801285DD1BC48B8 +:10C5B4000078002803D0022807D003D30BE0012021 +:10C5C40005000DE0002005000AE001200500B44844 +:10C5D4000121017004E001200500B148002101702F +:10C5E4002D062D0E002D40D0B948006804002E20E1 +:10C5F400205C1F2839D0FCF701F80600608D002864 +:10C604002ED0608D401E60850004000C002827D1C8 +:10C614002C20205C3721084209D02C20205CC82122 +:10C6240001402C2021542D200121215402E02D20F1 +:10C63400002121542C20205C000711D4B548007837 +:10C644003221615C0143B34801703020205CD14940 +:10C65400085C3121615C01433020205CCD4A1154D7 +:10C6640064693000FFF7FCFEC1E770BC08BC1847E2 +:10C674007A56004075560040765600407856004081 +:10C6840077560040044F00400C5600407047FFB5F9 +:10C6940001008E7AAB4FBE5D330001269E4035000B +:10C6A4001B061B0ECE18F67AA64FBE5D6F463E7073 +:10C6B40001266F463F78BE4034001B061B0EDE0089 +:10C6C4006F463F78F61930001B061B0ECE18F67A1B +:10C6D400A6431B061B0ECF18FE721B061B0ECE189C +:10C6E400F67A002E02D18E7AAE438E720006000EC8 +:10C6F40004264643A84FBE5932000026568500261C +:10C70400D661019E16622D266F463F7B97552C26D7 +:10C71400965D6F463F7ABE432C27D6552C26965DF0 +:10C72400002E0DD17B4E36782E437A4F3E701B0679 +:10C734001B0E984EF65C26431B061B0E954FFE54AB +:10C744000006000E04B0F0BC08BC184700B5384A17 +:10C754001268D061364A1268303212781100090624 +:10C76400090E8C4A525C324B1B6831331B789A4356 +:10C774000906090E874B5A540906090E854A525C6C +:10C78400002A08D1634A1278294B1B6832331B787C +:10C794009A43604B1A70264A126830321278821813 +:10C7A400D27A234B1B6831331B781343204A126817 +:10C7B400303212788218D372827A1D4B1B6832335E +:10C7C4001B781343837208BC18470000F0550040DF +:10C7D40000B5174A12683032127811000906090EA2 +:10C7E4004218D27A124B1B6831331B789A430906DC +:10C7F400090E4318DA720906090E4218D27A002A81 +:10C8040006D1827A0A4B1B6832331B789A438272B0 +:10C81400074A12682D3200231370054A12682C321D +:10C8240000231370024A12680023D36108BC18471E +:10C83400045600401C56004000B5002383720300D8 +:10C844000B33190000231A001206120E042A04D214 +:10C8540000230B70491C521CF6E708BC184770B53E +:10C86400A0217E4800F09AF87C4805007B481030EF +:10C874000600002004002404240C092C06D2002005 +:10C8840028706E6010351036641CF4E700202870A0 +:10C894000020686072487149016070BC08BC184788 +:10C8A4007C5600406F48002101606F4800210170F0 +:10C8B4006E48002101706E48002101706D4800210E +:10C8C40001706D48002101606C48002101607047CF +:10C8D4001056004000B50F4A002313702D4A100073 +:10C8E400002211000906090E042904D20022027054 +:10C8F400401C491CF6E7624A00231370614A002376 +:10C904001370614A00231360AC4A0023136008BC0F +:10C91400184700007956004000B585B00320049004 +:10C9240000200390802002905848019058480090BD +:10C934001F23584A0021A248FBF7F1FA05B008BCAE +:10C94400184700003801010070B59921C9009D48BD +:10C9540000F024F88021104800F020F899480500E0 +:10C96400984848300600002004002406240E102CA9 +:10C9740004D26E6148354836641CF6E700206861CD +:10C9840091480021016091488E49016070BC08BC47 +:10C9940018470000FC550040044F004000B509044E +:10C9A400090C012904D300220270401C491EF6E739 +:10C9B40008BC184710B50024FBF720FE04002A48E1 +:10C9C4000078002821D12948007800281DD100F0E2 +:10C9D40022F82C4800782A490978884215D0294839 +:10C9E4000078042148437A490858274908602648B2 +:10C9F4000068406B401C2449096848631E4800686D +:10CA0400401C1D490860FFF743FD2000FFF728FD87 +:10CA140010BC08BC18476F4909786F4A515C08007C +:10CA24000006000EC1000006000E6C4A125C6A4B40 +:10CA34009A5C8918134A1170704738B504000025B0 +:10CA4400FBF7DCFD05000D480068401C0B4908603D +:10CA54002800FFF705FD00F022FBF1E7644E0040DB +:10CA6400F45500401C560040755600407656004070 +:10CA74007B5600407A560040F05500400056004076 +:10CA840077560040785600400C560040444400401D +:10CA9400FFFF000040460040FEB504000A9F002648 +:10CAA400FBF7ACFD0600494800680500002D7DD069 +:10CAB4006869464908603000FFF7D2FC0098286096 +:10CAC4002E202C542C20002129542D2000212954BF +:10CAD40000206885099868600898E8600198A86053 +:10CAE4002F8268460089688233200021295430202F +:10CAF40021000906090EC908295401203021695C66 +:10CB04008840322168542F206107490F295401209D +:10CB14002F21695C8840312168540020E86100209D +:10CB2400686200202862002068630020E863002017 +:10CB3400A8630020286400206864280000F0EEFA4E +:10CB4400280000F0AAFAFBF759FD06002406240E7B +:10CB5400042060431E490D501B4800686861002092 +:10CB6400A86119480068002802D017480068856148 +:10CB740015480560174800783221695C014315485F +:10CB840001703020285C1549095C3120285C084379 +:10CB94003021695C114A505411480078401C1049F6 +:10CBA40008703000FFF75CFC002003E03000FFF762 +:10CBB40057FC4220FEBC08BC184700000456004045 +:10CBC4003FCA00007830004010560040085600402C +:10CBD400044F00407956004038010100FC550040E4 +:10CBE4007B56004010B50024FBF708FD040000202C +:10CBF4008D4908808D4908808D49088000208D4921 +:10CC040008808D4908808D4908808D48006802217C +:10CC140088438B4908608B48062101602000FFF798 +:10CC24001FFC10BC08BC184738B50025FBF7E6FC10 +:10CC340005000024E44381480088012815D37F4877 +:10CC44000088401E7D4908807B4800887E49085C36 +:10CC5400040079480088401C774908807648008899 +:10CC64008021F6F705FB744801802800FFF7F8FBE4 +:10CC7400200032BC08BC184738B50024FBF7BEFCC2 +:10CC8400040000256D480088012801D30120050017 +:10CC94002000FFF7E5FB280032BC08BC184738B574 +:10CCA4000024FBF7ABFC0400002561480088402801 +:10CCB40001D2012005002000FFF7D2FB280032BC7E +:10CCC40008BC184770B505000026FBF797FC060062 +:10CCD40000245748008840283CD255480088002842 +:10CCE4001FD15A480078800602D55948057034E0AF +:10CCF4004F480088401C4E4908804B4800885549DD +:10CD04000D5449480088401C47490880464800881B +:10CD14004021F6F7ADFA44480180A9480321016097 +:10CD24001BE043480088401C414908803E48008875 +:10CD340048490D543C480088401C3B4908803A4807 +:10CD440000884021F6F794FA374801809C48032173 +:10CD5400016002E00020C04304003000FFF780FBC4 +:10CD6400200070BC08BC184738B536480068050078 +:10CD74002D062D0E6D086D076D0F2D062D0E022D3F +:10CD840024D132480078C0074BD52C48008880282D +:10CD940017D2284800882C492D4A12780A5425486D +:10CDA4000088401C23490880224800888021F6F727 +:10CDB4005FFA2048018021480088401C1F490880F0 +:10CDC4002FE068462249097801702AE02D062D0ECD +:10CDD400012D1FD116480088012817D31348008855 +:10CDE4001C49085C1A49087010480088401C0F4907 +:10CDF40008800E4800884021F6F73AFA0B48018073 +:10CE04000B480088401E0A4908800AE00C480121AA +:10CE1400016006E068460E49097801700B48007805 +:10CE2400040031BC08BC1847565600405456004014 +:10CE3400585600405C5600405A5600405E5600402A +:10CE4400048007E0088007E004500040148007E0F5 +:10CE5400008007E0C8520040F1B584B00026FBF71B +:10CE6400CDFB06001820FBF7FAFE01900198FCF7B1 +:10CE740095FE0022534BFCF799FF04000D00049823 +:10CE8400FCF78CFE02000B0020002900FCF78EFF4B +:10CE940001F0B2F802900298FBF73CFE02000B008E +:10CEA4000020494901F000F901F0A0F907006846A3 +:10CEB40039004170684639000904090C090A0170F7 +:10CEC40042480068802149040143404801603C48CD +:10CED400002101603E48062101603E4800210160B6 +:10CEE4003D48802101703D486946497801703448C5 +:10CEF4006946097801603A481021016036480021EA +:10CF040001703548007803210143334801703248E9 +:10CF14000078FB210140304801702948012101605B +:10CF240030480068304901408020400308432D49BF +:10CF340008602C4800682D4901408020C003084344 +:10CF4400284908602A4800682749014028480160A8 +:10CF540027480068254901402548016025480068A4 +:10CF64008021C90001432348016022480068224906 +:10CF7400014020480160214800688021C900014324 +:10CF84001E4801601D4800688021090101431B48B7 +:10CF940001601B4800681B490140194801601A4898 +:10CFA4001A4901601A48802149050160FFF71AFEF9 +:10CFB4003000FFF755FA05B0F0BC08BC1847000074 +:10CFC400048007E0000030400000E03FC4C01FE0E0 +:10CFD400088007E0208007E00C8007E0008007E07D +:10CFE400288007E000C002E0FFFFCFFFFFFF3FFF04 +:10CFF40040C002E000C0FF3FFFF7FFFF10C0FF3F4B +:10D004000CF0FFFFFFFFFFEF70F1FFFF6DCD00009D +:10D0140010F0FFFF7847C046003021E0030013E31F +:10D024001100001A002FB0E10500000A0120D0E42D +:10D034000130D1E4010052E303005221F8FFFF0A5A +:10D044000E0000EA3CC09FE5002090E5003091E529 +:10D05400030052E10C3042000230C3018C0313017F +:10D064000420B0050430B105F8FFFF0A0120D0E424 +:10D074000130D1E4010052E303005221FAFFFF0A18 +:10D08400030052E01EFF2FE10101010108473300B4 +:10D094002B480021018070477047704770477047E4 +:10D0A40070B5040010006608760035000560001FA6 +:10D0B400244E0660001F244E0660001F234E0660A7 +:10D0C400001F234E0660001F224E0660001F224EE2 +:10D0D4000660001F214E0660001F214E0660001FDF +:10D0E400204E0660001F204E0660001F1F4E066083 +:10D0F400001F1F4E0660001F1E4E0660001F0160C9 +:10D104002600F60703D5001F3326066002E0001F41 +:10D114001326066070BC08BC18477047704780B57A +:10D1240007480088401C0649088005480088642890 +:10D1340004D303480021018001F0FCFC09BC18471A +:10D144004656004014141414121212121111111123 +:10D15400101010100909090908080808070707072B +:10D164000606060605050505040404040303030373 +:10D17400020202020101010170B53C210F48FFF7D0 +:10D184000DFC0E4805000D480C300600002004007C +:10D194002404240C042C06D2002028706E600C3564 +:10D1A4000C36641CF4E700202870002068600448F2 +:10D1B4000249016070BC08BC1847000008530040D5 +:10D1C400F855004030B545682B0005682C00002B4D +:10D1D40007D1C5682A005460002C06D0002565607C +:10D1E40003E01C60002C00D06360856829000025E2 +:10D1F4004D6230BC08BC184700B502008A480906D5 +:10D20400090E016089480068C006FBD4864800689E +:10D214000006000E08BC184780B5854800688021C8 +:10D2240089030143824801608248006882490140C1 +:10D234008020C00008437F4908608048006880005F +:10D2440080088021090601437C4801607C4800680D +:10D25400032188437A490860794800680C2188438F +:10D2640008210143764801607548006830218843ED +:10D2740020210143724801607248006880008008E0 +:10D284008021090601436F4801606F48006803214B +:10D2940088436D4908606C4800680C218843082164 +:10D2A40001436948016068480068302188432021AF +:10D2B4000143654801606548006865490140634869 +:10D2C40001606448006880214902014361480160AB +:10D2D400614800688021490201435F4801605B485E +:10D2E40000688021090201435848016057480068DA +:10D2F4008021890201435548016054480068802117 +:10D30400C902014351480160544800680F21884311 +:10D314000721014351480160504800683021884387 +:10D324004E4908604D480068402188434B490860D5 +:10D334004A48006880218843484908604748006893 +:10D34400474901408020400008434449086045485B +:10D35400006801218843434908604248006802216B +:10D364000143404801603F480068042188433D4927 +:10D3740008603C480068082188433A4908603A48F4 +:10D384000068FF2188430221014337480160374880 +:10D3940000210160364800210160364800680028F9 +:10D3A40004D10120FCF72AFB3249086009BC184764 +:10D3B40000B501000906090E002906D12E480068AF +:10D3C4008022520202432C480260002008BC184705 +:10D3D40000B501000906090E002906D11E4800689F +:10D3E4008022520202431C480260002008BC1847F5 +:10D3F40080B56A4601211F480068FCF728FB68468F +:10D404000078002806D00120F9F7B4FD68460078BA +:10D414000028EED109BC184780B516480068FCF70F +:10D4240083FB09BC18470000088006E00C8006E076 +:10D43400C4C01FE0ACC11FE0FFF3FFFF00C002E067 +:10D4440004C002E040C002E044C002E010C0FF3F5C +:10D45400FFFFFEFF00C0FF3F18C0FF3F008006E053 +:10D46400FF00FFFF048006E0108006E0148006E061 +:10D47400248006E0305600401CC0FF3F0EB400B5C7 +:10D4840082B003A9009102006B460121034878444D +:10D494000A30FEF7D1F8029906B00847254C00007F +:10D4A4007847C04600000FE1C01080E301F021E19D +:10D4B40000100FE1C01001E2C00051E3F9FFFF1AB0 +:10D4C4001EFF2FE100F021E11EFF2FE180B50300D4 +:10D4D4005869401E58611969491C0028196106D40D +:10D4E40058681B680122002101F01EFD01E00020A4 +:10D4F400C0430ABC18470000F0B58BB001900291FC +:10D5040018680027FF43002601AC3D000390266104 +:10D51400E2601CE02069019B401C2061029801220A +:10D52400002101F001FD010009390529F2D3202869 +:10D53400F0D02169491EB842216105D0019B010048 +:10D544000298002201F0F0FCE068401CE060E06812 +:10D5540001780B00093B052BDCD32029DAD0002904 +:10D5640007D1002D00DA002528000BB0F0BC08BC60 +:10D574001847252907D1401CE06001782A291CD1CD +:10D58400401CE0601AE0019B009020690122401CCD +:10D5940020610298002101F0C7FC009909788842B3 +:10D5A400D2D02169491EB8422161DAD0019B010021 +:10D5B4000298002201F0B8FCD3E700212020215476 +:10D5C400A6610BE0A1697B08994205D08B0059182C +:10D5D400490051183039A161401CE060E0680278CC +:10D5E400110030390A29EDD3E76101782AA000F04F +:10D5F4006BFF002804D0E0680178401CE06000E084 +:10D60400002121202154205C682806D1E06801789B +:10D6140068290DD12121622207E06C2808D1E06835 +:10D6240001786C2904D121217122401C6254E060EC +:10D63400E06801781AA000F047FF002819D120699A +:10D64400019B401C206102980122002101F06CFC26 +:10D65400010009390529F2D32028F0D02169491E97 +:10D66400B842216105D0019B01000298002201F01B +:10D674005BFC01A800F018F8012803DA002D00D59E +:10D6840073E771E7002D00D500252220205C0028D7 +:10D6940000D159E76D1C57E7686A6C747A4C000036 +:10D6A40063436E5B0000000010B5040022200021DB +:10D6B4002154E068007825385FD01C3825D0001F3D +:10D6C400022822D913381CD0C01E70D0801F1CD051 +:10D6D400801E12D0401E14D0401E022815D9001FEF +:10D6E4000FD0401F15D0401E01280AD9001F42D078 +:10D6F400801E06D0C01E04D05BE0200000F05DF860 +:10D7040058E0200000F046F954E0200000F050FA00 +:10D7140050E02020205C00282BD12120205C6228AE +:10D724000BD0682818D06A280ED06C281BD071281A +:10D734000AD0742817D07A2815E0A068011DA160CA +:10D7440021690068017014E0A268101DA0602069BE +:10D754001268C11703C20CE0A068011DA160216911 +:10D764000068018005E0A068011DA16021690068CE +:10D77400016001201EE00121BFE720690122401C55 +:10D7840020616068236801F0CFFB2528F1D022696D +:10D794000021521EC9438842226106D02368010039 +:10D7A4006068002201F0C0FB0021080002E0C943C8 +:10D7B400A3E7002010BC08BC1847F2B5040084B0ED +:10D7C400002003900498002600282CD5E068401C13 +:10D7D400E06001785E2904D1411CE1600078029088 +:10D7E40000E00296E06801785D2900D1401C5D21CB +:10D7F40000F06AFE002804D1002005B0F0BC08BC8B +:10D804001847E168421A00920191E06000980328E9 +:10D8140009DB821E01982D21401C00F067FE0028C0 +:10D8240001D001200390A069012805DA049800289A +:10D8340001D0574800E0012060612020205C0028CE +:10D844000CD1A068011DA160076807E03D7022208B +:10D854002654E0697F1C401EE06102262000FFF789 +:10D8640035FE00210500C943884278D00498012878 +:10D8740017DB28000938052801D3202D65D120693C +:10D884000022401E206160682368290001F04CFBDF +:10D894000498002801D0022E6FD0022E63D10120FB +:10D8A400ABE7002851D50398002810D10298009ABC +:10D8B400002806D10198290000F018FE0028DED0C7 +:10D8C40005E00198290000F011FE0028D7D1039843 +:10D8D40000283AD00299019A2806000E00290099DE +:10D8E40021D106E0984202DB937883422DDAD21CE0 +:10D8F400C91E032908D353782D2B1378F2D0834201 +:10D9040023D0521C491EF4E70029B8D0137883426F +:10D914001BD0521C491EF7E7984202DB93788342DE +:10D92400ADDAD21CC91E03290DD353782D2B1378DD +:10D93400F2D08342A3D0521C491EF4E713788342E9 +:10D944009DD0521C491E0029F8D12020205C0028BB +:10D9540083D1E0690126002800D077E78FE72069AA +:10D96400401E206194E7F00704D40020C0438542A0 +:10D9740000D041E70020C0433FE72020205C00287E +:10D984008DD1E069002800D136E70020387086E7A1 +:10D99400FFFFFF7FF0B50400A06989B0012800DA19 +:10D9A4008248606101AE2000FFF790FD05002B2D39 +:10D9B40001D02D2D06D168460571761C2000FFF795 +:10D9C40085FD0500684600210170E0680078642840 +:10D9D40001D0752801D10A270EE0692801D100275A +:10D9E4000AE06F2801D1082706E0702803D020211F +:10D9F4000143782900D11027302D28D16846012110 +:10DA040001702000FFF762FD202101430906050093 +:10DA1400090E782917D1002F01D0102F07D1102714 +:10DA24002000FFF753FD0500684600210170302DEA +:10DA340011D12000FFF74AFD05006846012101705D +:10DA4400302D0CD1F5E7002FF1D10827EFE7002F97 +:10DA540016D10A2714E068460078002810D0302038 +:10DA64003070761C0CE001A81F30864201D235705C +:10DA7400761C2000FFF72AFD05006846012101708D +:10DA84000020C04385421FD02906090E612901D315 +:10DA9400573909E0412901D3373905E030390906FE +:10DAA400090E0A2900D3FF2109063806090E000EC3 +:10DAB4008142D8D320690022401E20616068236817 +:10DAC400290001F031FA02E02069401E2061684615 +:10DAD4000078002808D101A8864203D10020C04361 +:10DAE40085425FD000205DE0002030702020205C63 +:10DAF400002856D1E0680178642901D0692929D128 +:10DB04003A00002101A801F06DFA22220123A35456 +:10DB14002122A25C622A0BD0682A15D06A2A0DD071 +:10DB24006C2A39D0712A09D0742A35D07A2A33E084 +:10DB3400A268131DA3601268107032E0A268131D5E +:10DB4400A360126803C22CE0A268131DA3601268CC +:10DB5400108026E03A00002101A801F00BFB2222EC +:10DB64000123A354E2681278702A15D02122A25C02 +:10DB7400622ADDD0682AE7D06A2A07D06C2A0BD043 +:10DB8400712ADBD0742A07D07A2A05E0A268131D13 +:10DB9400A360126803C204E0A268131DA3601268A4 +:10DBA4001060012009B0F0BC08BC1847FFFFFF7FDC +:10DBB400F0B50700B86995B0012800DA1A48786111 +:10DBC40004AC3800FFF782FC0500002001902B2DE7 +:10DBD40001D02D2D06D168460574641C3800FFF76A +:10DBE40075FC050068460A21417000210170302D42 +:10DBF40029D13800FFF76AFC2021014309060500FA +:10DC0400090E782912D0684601210170302D00D008 +:10DC1400F4E03800FFF75AFC050068460121017062 +:10DC2400302D00D0EDE0F4E7FFFFFF7F30202070BF +:10DC340078206070A41C3800FFF748FC0500684693 +:10DC440010214170E2E7202028430006000E6E28D0 +:10DC54006ED1684641706E262670641C3800FFF74A +:10DC640035FC2021014309060500090E612915D060 +:10DC740038690021401EC9438D42386100D087E1D4 +:10DC84006846007800283FD104A8844200D086E189 +:10DC94000020C043854200D081E1A9E161202070C9 +:10DCA400641C3800FFF712FC20210143090605001B +:10DCB400090E6E29DCD13800FFF708FC050028287E +:10DCC4000DD038690021401EC9438D42386119D0F6 +:10DCD40078683B680022290001F026F912E0380038 +:10DCE400FFF7F4FB0100050061391A29F7D301009D +:10DCF40041391A29F3D330380A28F0D35F2DEED0F6 +:10DD0400292DB5D12670641C002020702020385C99 +:10DD1400002800D06BE1684640780B2800D340E12E +:10DD2400019A002104A801F0F9FA02AA03C244E10D +:10DD3400692869D16846417069202070641C3800E4 +:10DD4400FFF7C4FB2021014309060500090E6E29D3 +:10DD54008ED16E202070641C3800FFF7B7FB2021A1 +:10DD6400014309060500090E662900D080E7380042 +:10DD7400FFF7ACFB2021014309060500090E6929C0 +:10DD84000DD038690021401EC9438D42386132D01C +:10DD940078683B680022290001F0C6F82BE03800BF +:10DDA400FFF794FB2021014309060500090E6E29A3 +:10DDB40000D05DE73800FFF789FB20210143090605 +:10DDC4000500090E692900D052E73800FFF77EFBF1 +:10DDD4002021014309060500090E742900D047E7F4 +:10DDE4003800FFF773FB2021014309060500090EE3 +:10DDF400792900D03CE76620207084E70078002869 +:10DE040002D030202070641C002609E00198401CD8 +:10DE140001903800FFF75AFB0500684601210170A4 +:10DE24000020C043854224D02806000E612801D377 +:10DE3400573809E0412801D3373805E03038000667 +:10DE4400000E0A2800D3FF20694649780006000E18 +:10DE5400884205D2242ED9DA2570641C761CD8E7B2 +:10DE64002E2D06D12E202070641C3800FFF72EFBC7 +:10DE74000500002E23D1302D0BD10198401E0190B6 +:10DE84003800FFF723FB0500684601210170302D9F +:10DE9400F3D00198002812D5302020700198641C1A +:10DEA400401C01900BE0242E02DA2570641C761CC1 +:10DEB4003800FFF70BFB05006846012101700020C4 +:10DEC400C043854215D02806000E612801D3573877 +:10DED40009E0412801D3373805E030380006000E48 +:10DEE4000A2800D3FF20694649780006000E8842BC +:10DEF400D9D368460078002800D1B9E66946497844 +:10DF0400202028430A2905D10006000E652800D0E8 +:10DF1400AEE604E00006000E702800D0A8E62570E6 +:10DF2400641C3800FFF7D2FA05002B2D01D02D2DEB +:10DF340005D12570641C3800FFF7C8FA050068464F +:10DF440000210170302D0BD13800FFF7BFFA050016 +:10DF5400684601210170302DF6D030202070641CF9 +:10DF64002800002630380A2802D381E6082E02DA77 +:10DF74002570641C761C3800FFF7A8FA0500684673 +:10DF840001210170280030380A2800D370E6EDE73B +:10DF940078683B680022290000F0C6FF70E6002084 +:10DFA40026E00022002104A801F0B8F902AA03C265 +:10DFB4000198810002A800F0D9FB222001213954E4 +:10DFC4002120385C6C2807D1B868011DB96002684B +:10DFD40002A803C803C20AE04C28F5D0BC68201D7F +:10DFE400B86002A803C800F007F82168086001209F +:10DFF40015B0F0BC08BC18477847C04680C9A0E3F8 +:10E0040081007CE12500008AE1CFA0E170C45CE2DC +:10E0140080095C230900003A8CC0B0E1FF055C3341 +:10E024001A00002A2CC1B0E10CC2A0E16CC0A0E12E +:10E034008011B0E18014D1E2A00EACE01EFF2FE10C +:10E044008115A0E1A01A81E18005B0E101108113DE +:10E05400801481E3CC0AA0E1090060E2210050E3CE +:10E064000800002A8CCF80E120C06CE2110CB0E1E2 +:10E074008004D0E220C06CE2310CA0E180C40CE248 +:10E084000C00A0E01EFF2FE18C0FA0E11EFF2FE18A +:10E094007F04A0E3800880E30C0F80E11EFF2FE1E2 +:10E0A4000000E0E31EFF2FE17847C04650002DE951 +:10E0B40003C031E080342342F901004A024050E0B9 +:10E0C4000360D1E00300002A040050E00610D1E010 +:10E0D400042092E00630B3E080C9A0E381007CE133 +:10E0E4008340DC308044A0E32B00002A21CAA0E155 +:10E0F400236A4CE0350056E3370000CA833584E1D7 +:10E10400A335A0E1811584E1C115A0E1200056E307 +:10E11400080000BA206056E20220B0117346A0E164 +:10E12400334624E001408413330690E00010B1E24A +:10E134000800002A0B0000EA7246A0E13226A0E1A2 +:10E14400024024E0732622E0332622E0020090E01D +:10E154003316B1E00300003AA110B0E16000B0E171 +:10E164006440B0E101408423401981E2A020B0E181 +:10E174008024D4E20000B0E20C1AA1E05000BDE813 +:10E1840080C9A0E381007CE11EFF2F310000A0E3E1 +:10E19400211AA0E1011AA0E11EFF2FE181007CE118 +:10E1A4000F00002A836092E10B00000A81005CE109 +:10E1B4000600008A21CAA0E10430C3E101604CE2F8 +:10E1C400340056E3CEFFFFDA5000BDE81EFF2FE116 +:10E1D4008034C3E3020090E00310B1E05000BDE8D6 +:10E1E4001EFF2FE15000BDE81EFF2FE17847C04617 +:10E1F40081C0A0E1ACCAA0E140CE4CE201C09CE2E7 +:10E204000C00004A1FC07CE20C00004A8110B0E1FF +:10E214000115A0E1801481E3A00A81E1300CA0E1A2 +:10E22400000010E18004A043000060221EFF2F21A3 +:10E23400010040421EFF2FE10000A0E31EFF2FE17A +:10E24400800411E38004E0538004A0431EFF2FE107 +:10E254007847C0460010B0E11EFF2F010000604265 +:10E26400C214A0434214A053400B50E30008A03151 +:10E2740040174132400750E30004A0318018413276 +:10E28400400550E30002A03140184132400450E3FD +:10E294000001A03180194132800450E38000A03194 +:10E2A40040194132C01941E2A01581E0800AA0E181 +:10E2B4001EFF2FE17847C046022CB0E1222482E100 +:10E2C400222882E1010080E0033010E20400000A09 +:10E2D400031051E01100003A833FB0E10120604592 +:10E2E400B22060210230A0E110402DE902C0A0E17B +:10E2F40002E0A0E1101051E20C502029FCFFFF8A3B +:10E30400811EB0E10C002029042020450111B0E158 +:10E31400B2206021012060451040BDE81EFF2FE1BE +:10E32400031091E001206015020011E30120601543 +:10E334001EFF2FE1000050E39D10A0E3401F814326 +:10E34400000070421EFF2F01400B50E30008A03173 +:10E3540010104132400750E30004A031081041324C +:10E36400400550E30002A03104104132400450E360 +:10E374000001A03102104132800450E38000A0313A +:10E384000110413200CCB0E12004A0E180C4DCE201 +:10E39400810BA0E01EFF2FE1010030E18014214237 +:10E3A400BFF2FF4A000051E180C420828004218230 +:10E3B4000C10A0814037A0E3800073E18100533149 +:10E3C4002B00002AA0CBA0E1A13BDCE00800003A2E +:10E3D4008024A0E3011482E11800008A800471E023 +:10E3E4000600003AA004B0E1A010B0218C0BA0E01C +:10E3F4001EFF2FE1010050E01EFF2F018004B0E159 +:10E404000120A0E3012082528000B051FCFFFF5A9A +:10E414008000A0E1A004A0E16C34A0E1023C53E040 +:10E42400E30080801EFF2F81800880E343CCA0E1BD +:10E43400833FA0E101C06CE2300C83E11EFF2FE1B9 +:10E44400180053E31EFF2FC13123A0E1121371E022 +:10E4540001208233800472E08000A03100C0CCE24D +:10E46400802BB0E1A004A0E18014D2E28C0BA0E0E8 +:10E474001EFF2FE1800073E10E00002A8120B0E12D +:10E484000900000AA0CBA0E1A13B4CE0020053E349 +:10E49400040000BA8114A0E18024A0E3170053E330 +:10E4A400E8FFFFDA1EFF2FE1A20040E08030B0E178 +:10E4B4000000A0031EFF2FE1810073E10000E023B0 +:10E4C4001EFF2FE1104734007847C0460020D0E5F6 +:10E4D400FF1001E2010052E3020031E10120F08566 +:10E4E400FBFFFF8A0000A0131EFF2FE17847C04600 +:10E4F400FF1001E2030010E30500000A012052E2CC +:10E504001C00003A0130D0E4030031E1F8FFFF1AA7 +:10E51400160000EA082052E20E00003A042082E2CB +:10E5240030002DE9011481E1011881E14CC09FE51F +:10E53400043090E4042052E201302320AC43432011 +:10E544000340C4210C001421F8FFFF0A3000BDE889 +:10E55400FF1001E2040050E2082092E20130D0E40E +:10E56400012052E203003121FBFFFF8A0100A013C6 +:10E57400010050E21EFF2FE10000B0E31EFF2FE177 +:10E584008080808080C413E20100005A002072E27F +:10E594000030E3E241C03CE00E00001A01C093E108 +:10E5A4001B00001A00502DE90210A0E134D3FFEB48 +:10E5B4000120A0E10010A0E30030A0E30050BDE87A +:10E5C4001EFF2FE10130A0E10020A0E10010A0E334 +:10E5D4000000A0E31EFF2FE100502DE90100003AE6 +:10E5E400000070E20010E1E2EBFFFFEB0050BDE839 +:10E5F4008CC0B0E10200003A000070E20010E1E2D9 +:10E604000C001CE11EFF2F51002072E20030E3E2F7 +:10E614001EFF2FE1020050E103C0D1E0E8FFFF3A02 +:10E6240003C092E13F03000A30002DE900C0A0E3DB +:10E63400022092E00330B3E00300002A030051E11A +:10E644000200500101C08C22F8FFFF2A6330B0E1C0 +:10E654006220A0E18054A0E320405CE23544A02184 +:10E664000050A023355CA0310040A033010000EA33 +:10E67400A330B0E16220A0E1020050E103C0D1E088 +:10E68400020040200C10A0210440B4E00550B5E085 +:10E69400F6FFFF3A0020A0E10130A0E10400A0E170 +:10E6A4000510A0E13000BDE81EFF2FE1104B70B44F +:10E6B40001004A684C6880200006024001201C408A +:10E6C4004C6002D10C68002C0DD04D680C686E00B3 +:10E6D400E50F35434D6064000C60401EEC02F4D538 +:10E6E4004C6823404B604B681A434A6070BC7047C7 +:10E6F400FFFF0F007847C04680C9A0E381007CE19A +:10E7040083007C911EFF2F8101C083E18CC090E1C6 +:10E714000CC092E10200002A030051E10200500102 +:10E724001EFF2FE101005311000052011EFF2FE1D3 +:10E734007847C04680C9A0E381007CE183007C91D6 +:10E744001EFF2F8103C081E18CC090E10CC092E1D7 +:10E754000200002A010053E1000052011EFF2FE1D4 +:10E7640003005111020050011EFF2FE1F8B5444E81 +:10E77400040060680D00000D3040B04209D16068AB +:10E78400000302D12068002801D0022074E0012097 +:10E7940072E0010006D12000FFF788FF012801DBA9 +:10E7A400002069E0012D0CDB311A8D4209D3606829 +:10E7B400002802D53349002001E00020310503C4BC +:10E7C400E5E74142A94207DA61682F4A28180A405E +:10E7D4000005104360604DE06368626880210906AB +:10E7E4001B03401E1B0BCE0A2D181E4328000A4093 +:10E7F400002335306660352802D362602360CFE79A +:10E8040028001E260025F643B04204DA666825680F +:10E81400266020306360434211D0266867686D1E0D +:10E82400AD412020ED43C01AED0F864035432668E4 +:10E834008740DE40374327606068D8406060606886 +:10E84400104360601148854204D28D420CD1207877 +:10E85400C00709D52068401C20602068002803D127 +:10E864006068401C606005E06068904202D12068E6 +:10E87400002895D00020C043F2BC08BC1847C0460D +:10E88400FF0700000000F0FFFFFF0F800100008081 +:10E894007847C04650002DE903C031E0803423425C +:10E8A40005FEFF4A024050E00360D1E00400002A64 +:10E8B400806426E2040050E00610D1E0042092E0D7 +:10E8C4000630B3E080C9A0E381007CE18340DC3002 +:10E8D4008044A0E35500002A21CAA0E1236A4CE049 +:10E8E400360056E34F0000CA010056E3280000CA70 +:10E8F4000CCAA0E1833584E1A23A83E18225A01108 +:10E904000225A001A330A001811584E1A01A81E1B0 +:10E91400800572E00310D1E01600004A0010A00147 +:10E924000000A0030060A0132060A00301001101F7 +:10E934003C00000A0300004A016086E2000090E007 +:10E944000110B1E0FBFFFF5AECCFA0E186CA5CE006 +:10E954000160DCE3ECC0A0E10600008A806976E295 +:10E96400A66AA0E180C40CE23006A0E1710620E0B2 +:10E974003116A0E1010020E0A005B0E1810A80E1A8 +:10E984008014C1E3A040B0210000B0E2A115ACE0C6 +:10E99400240000EA833584E1A335A0E1811584E1F4 +:10E9A400A115A0E1200056E3080000DA206056E239 +:10E9B4000220B0117346A0E1334624E001408413E1 +:10E9C400004074E23306D0E00010C1E2080000EA1F +:10E9D4007246A0E13226A0E1024024E0732622E040 +:10E9E4003336A0E1032022E0004074E20200D0E0CC +:10E9F4000310C1E0400911E30500001A01C04CE214 +:10EA04008C2AB0E10200000A8440B0E10000B0E0CA +:10EA14000110A1E04019C1E3A030B0E18034D4E298 +:10EA24000000B0E20C1AA1E05000BDE81EFF2FE187 +:10EA340081007CE10F00002A8034C3E3836092E10B +:10EA44000900000A8CC0A0E181005CE10400008A96 +:10EA540021CAA0E101604CE2340056E3CEFFFFDAA4 +:10EA6400F0FFFFEA020050E00310D1E0816090E182 +:10EA74000010A003EBFFFFEA83007C010010E023F9 +:10EA8400E8FFFFEA7847C04681C0B0E10A00002AE7 +:10EA9400ACCAA0E140CE4CE201C09CE20600004AB0 +:10EAA4001FC07CE28115A0E1801481E3A00A81E10A +:10EAB400300CA0510000E0431EFF2FE10000A0E352 +:10EAC4001EFF2FE17CB504000E0015003000290064 +:10EAD400F4F7CEFB45430090701B0190684603C8D1 +:10EAE40003C476BC08BC184738B564211048FDF748 +:10EAF40055FF0F480400002005002D042D0C042DA3 +:10EB04000AD22D042D0C1420684309490818143026 +:10EB1400606014346D1CF0E7002060600348044911 +:10EB2400016031BC08BC18470000000014560040C6 +:10EB34008450004010B596480068FAF7F5FF0400C9 +:10EB440020000006000E10BC08BC184770B59021C8 +:10EB540089009248FDF722FF40219148FDF71EFFEE +:10EB64008E4805008D48243006000020040024044B +:10EB7400240C0F2C09D26420287021200021295450 +:10EB8400EE6024352436641CF1E7642028702120CB +:10EB9400002129540020E8608248002101607D485A +:10EBA400002101807C481021018055487B49016087 +:10EBB4000120FAF723FF7C4908600020FAF71EFFC2 +:10EBC4007349086000F003F870BC08BC184700B52E +:10EBD40085B00320049000200390802002907348A5 +:10EBE4000190734800901D23724A00217248F9F77E +:10EBF40096F905B008BC1847FCB504000D002120A7 +:10EC0400032121542D062D0E012D05D1E0696549FE +:10EC14000968401860610DE0A069002805D1E06929 +:10EC2400604909684018606104E0A0695D490968A9 +:10EC3400401860616846009060690821F9F7AEFFEA +:10EC44000098818068468088082148435449081800 +:10EC540007003868002805D13C600020E0600120EE +:10EC6400B88007E0386806003C60E6603461B88824 +:10EC7400401CB88000202061F3BC08BC1847FCB5D8 +:10EC840004006846009060690821F9F787FF00983E +:10EC94008180684680880821484341490818070054 +:10ECA4003868A04207D1E06805003D60002D0AD015 +:10ECB4000020286107E020690500E0680600EE6096 +:10ECC400002E00D035612120012121540020E06074 +:10ECD40000202061B888401EB880F3BC08BC1847E7 +:10ECE40080B56A46002130480068FAF7B0FE09BCD6 +:10ECF400184780B52C480068FAF716FF09BC184776 +:10ED04002C560040F1B582B001AA002120480068C9 +:10ED1400FAF79DFEFFF7E4FF22480068401C2149F2 +:10ED24000860204800680821F9F738FF0F003F0405 +:10ED34003F0C082078431A4908180090009800688E +:10ED44000400002C20D0E0680600164800686169C1 +:10ED5400884217D1606805002800002803D0A16804 +:10ED6400200000F0E3FA2000FFF789FF2020205C58 +:10ED7400022804D101212000FFF73EFF02E02120F8 +:10ED8400022121543400DCE7FFF7B3FFBCE70000A5 +:10ED9400285600404456004042560040044000407B +:10EDA400485200402056004024560040444600404B +:10EDB400FDFF00004048004009ED00002D49080017 +:10EDC4002D4908002D4908002D4908002D49080047 +:10EDD4002D4908002D4908002D4908002D49080037 +:10EDE4002D4908002D4908002D4908002D49080027 +:10EDF4002D4908002D4908002D4908002D49080017 +:10EE04002D4908002D4908002D4908002D49080006 +:10EE14002D4908002D4908002D4908002D490800F6 +:10EE24002D4908002D4908002D4908002D490800E6 +:10EE34002D4908002D4908002D4908002D490800D6 +:10EE44002D4908002D4908002D4908002D490800C6 +:10EE54002D4908002D4908002D4908002D490800B6 +:10EE64002D4908002D4908002D4908002D490800A6 +:10EE74007047C04638650100306501003A650100FD +:10EE84003C6501003E6501004065010042650100EA +:10EE94004465010046650100486501004A650100BA +:10EEA4004C6501004E65010050650100526501008A +:10EEB4005465010056650100586501005A6501005A +:10EEC4005C6501005E65010060650100626501002A +:10EED4006465010066650100686501006A650100FA +:10EEE4006C6501006E6501007065010072650100CA +:10EEF4007465010076650100786501007A6501009A +:10EF04007C6501007E650100806501008265010069 +:10EF14008465010086650100886501008A65010039 +:10EF24008C650100A06501001847F2B506001F00BA +:10EF340082B0002901D168460290340000E0641CCC +:10EF44002078010009390529F9D32028F7D00500D4 +:10EF54002D2D01D02B2D01D1641C00E02B2502990D +:10EF6400200000F045F8029A1268944201D1029AF6 +:10EF74001660029A1268964203D1002911D1002822 +:10EF84000FD12B2D03D180231B06994209D22D2D9D +:10EF940019D1802301221B06994214D301D890422F +:10EFA40011D300F0C5F922210160002F01D0012006 +:10EFB40038602D2D03D18021002009060EE00020A9 +:10EFC400C04341080AE02D2D04D100220023121A67 +:10EFD4008B4101E002000B001000190003B0F0BCEB +:10EFE40008BC184780B50023FFF79FFF0CBC1847E7 +:10EFF400FDB50D0086B0002B01D000211960069CE0 +:10F0040000E0641C2078010009390529F9D320287F +:10F01400F7D02D2801D02B2803D169460870641C31 +:10F0240002E068462B2101700798002803D40128C8 +:10F0340001D0252806DB002D01D006982860002089 +:10F0440000218FE001280BDB102818D1207830280C +:10F0540015D1607820210143782910D1A41C0EE039 +:10F064002078302801D00A2008E06078202101436C +:10F07400782902D110200790F0E708200790039424 +:10F084002078302803D1641C20783028FBD0002657 +:10F094000027029404A8C0C06846C04638A101965F +:10F0A400417014E004A9C0C1079A69464978D3178E +:10F0B400401A0006000E01903000019E3900360609 +:10F0C40000F03EF9360E002736184F41641C2178B3 +:10F0D400080041381A2800D22031079A28A0FFF7E7 +:10F0E40005FA0028DED10398A042A4D0079902981B +:10F0F4002DA2515C201A401A25D4012817DA019A4E +:10F1040000231206120E3900B01A99418F420ED311 +:10F1140001D886420BD3079AD317FCF785FA02006D +:10F124000B0004A803C88B4201D182420BD000F02B +:10F13400FFF8222101600898002801D00121016014 +:10F144000AA6C0CE09E0684600782D2805D1002023 +:10F154000021801BB94106000F00002D00D02C6057 +:10F164003000390009B0F0BC08BC1847FFFFFFFFAE +:10F17400FFFFFFFF80B50023FFF73AFF0CBC1847E1 +:10F184003031323334353637383961626364656619 +:10F194006768696A6B6C6D6E6F7071727374757683 +:10F1A4007778797A0000000000004129211C1917A2 +:10F1B4001615141312121111111010100F0F0F0F36 +:10F1C4000E0E0E0E0E0E0E0D0D0D0D0D0D0000008B +:10F1D400FDB588B004000D0008A800F0BDF80821B2 +:10F1E400014001910A99002901D000220A600821F6 +:10F1F4008843012836D108990220009004AB2A00E4 +:10F20400200000F03DF9040004D102AA00200021EE +:10F2140003C21DE00598FFF71BF802AA03C2022CE3 +:10F2240016DB04AD0835641E394B02A803C800225E +:10F23400FAF7BEFC060028680F00FFF709F8320051 +:10F244003B00FEF731FF02AA03C22D1D641EEBD161 +:10F25400099804990A9B421802A803C800F036FAD8 +:10F2640002AA48E0022837D10899009004AB2A008A +:10F27400200000F003FB040004D102AA00200021B6 +:10F2840003C21DE00598FEF7E3FF02AA03C2022CA5 +:10F2940016DB04AD0835641E1E4B02A803C8002209 +:10F2A400FAF786FC060028680F00FEF7D1FF32004B +:10F2B4003B00FEF7F9FE02AA03C22D1D641EEBD12A +:10F2C400049902A8FFF752FA0A9B099A02A803C8F4 +:10F2D40000F0FCF902AA0EE0032803D10E4902AAA9 +:10F2E400002008E0042802AA03D10020C0434108FA +:10F2F40001E00020002103C20198000602A803C80F +:10F3040002D08022120651400BB0F0BC08BC184752 +:10F3140065CDCD410000B0410000F07F80B50023F1 +:10F32400FFF756FF0CBC18471EFF2FE12847350096 +:10F33400024880B500F0ACFB0ABC18473C560040BC +:10F344007847C04690030CE091C22CE0920081E023 +:10F354000C1081E01EFF2FE1F8B4020010680B00CE +:10F36400009001000020002500E0491C0C782600D4 +:10F37400093E052EF9D3202CF7D02D2C01D10825D8 +:10F3840001E02B2C00D1491C0E7820272024374380 +:10F394006E2F28D1491C0D782543612D04D1491CB9 +:10F3A4000D782C436E2C01D0009918E0491C0C00F8 +:10F3B40025780420282D12D1641C25782E003700CE +:10F3C400613F1A2FF8D33700413F1A2FF4D3303E50 +:10F3D4000A2EF1D35F2DEFD0292D00D1611C002B13 +:10F3E4004AD0196048E0692F28D1491C0E78264379 +:10F3F4006E2E04D1491C0E782643662E01D0009946 +:10F40400EDE70320491C28430D782543692DE6D1F7 +:10F414004E1C357825436E2DE1D1761C3578254375 +:10F42400692DDCD1761C35782543742DD7D1761C13 +:10F4340035782C43792CD2D1711CD0E7302E19D1D8 +:10F4440048780443782C15D1881C03782E2B00D1DE +:10F45400401C00780300613B062B06D30300413BAC +:10F46400062B02D330380A2802D20220891C02E07B +:10F47400012000E0012028431160F2BC70473600EF +:10F48400F5B590B017980E00C1001C0000250818AF +:10F494002E2800DB2D202560656001953178302908 +:10F4A40005D10121761C019131783029F9D000274A +:10F4B40004A905E02268521C22600122761C0192F4 +:10F4C40032781300303B0A2B05D2B842F2DB303AD3 +:10F4D400CA557F1CF1E72E2A00D1761C002F0BD1D0 +:10F4E4003178302908D12168761C491E2160012118 +:10F4F400019131783029F6D031780A00303A0A2A5D +:10F504000CD2B84206DB04AA3039D15521687F1CDD +:10F51400491E21600121761C0191EDE7B84215DAFC +:10F5240004A909180A78052A03D3491E0A78521C2B +:10F534000A700700206807E004A8C019401E00787C +:10F5440000280AD120687F1E401C2060012FF3DAB6 +:10F55400002F02D1684605740127019800285CD069 +:10F564000920009038000921F3F782FE0920401A8F +:10F5740000900921F3F77CFE0295002900D00125B3 +:10F58400012F1FDB029804A9085C0921039000984D +:10F59400F3F76EFE002904D103996D1CA8002150D5 +:10F5A40008E0A800201801688A005118039A49004D +:10F5B400891801600098401C00900298401C029039 +:10F5C400B842DFDB307820210143652925D100963C +:10F5D400761C30782B2801D02D2801D1761C00E030 +:10F5E4002B200023002109E0134B994204DA8B00FD +:10F5F4005918490051183039761C01233278170004 +:10F60400303F0A2FF0D32D2801D108004142206851 +:10F6140040182060002B00D1009E1198002805D0CE +:10F624000198002800D1109E11980660280012B09D +:10F63400F0BC08BC1847C04600E1F5057C204B61CE +:10F644006E616C207C2044656E65672C2072756247 +:10F654002E207C205365616E736F76207C204E6172 +:10F664007261626F746B6120683A6D3A730D0A00BF +:10F67400000000006749F8B5040060681600000D3A +:10F684001F000840884201D100250EE0010004D18A +:10F694002000FFF70BF80128F6DA61685E4A0A4099 +:10F6A4005E49114361605E49451A03CC32003B0058 +:10F6B400083CFAF77DFA03C4083C29040914200025 +:10F6C400FFF754F8F2BC08BC18470000FBB514005F +:10F6D4001F0082B0002C06D002A803C80022002319 +:10F6E40000F0D8F905D102A803C805B0F0BC08BCE5 +:10F6F400184747496A46002003C2002C4AD5604295 +:10F704000400C0464BA608250EE0E00709D568466C +:10F7140003C802000B0003CE083EFAF749FA6A4612 +:10F7240003C2640808366D1E002C01D0002DECD1F4 +:10F7340003983849000D0840884201D100250EE0A5 +:10F74400010004D102A8FEF7B1FF0128F6DA0399FB +:10F75400314A0A403149114303913149451A02A8FB +:10F7640003C86A460CCAFAF721FB02AA03C2290499 +:10F77400091402A8FEF7FAFF050036D5002CB2D012 +:10F7840028A20CCA02A8FFF775FF05002DD5641E38 +:10F79400F6D1A8E7012C28DB26A60825E00709D521 +:10F7A400684603C802000B0003CE083EFAF700FACD +:10F7B4006A4603C2641008366D1E012C01DB002D5D +:10F7C400ECD168460CC8FFF755FF05000DD5012C98 +:10F7D40089DB16A20CCA02A8FFF74CFF050004D56A +:10F7E400641E012C00DA7EE7F3E72D042D1402D009 +:10F7F400012D00D077E7FFF79BFD22210160002F48 +:10F8040000D170E738680121014339606BE70000DB +:10F814000000F03FFF070000FFFF0F800000E03F03 +:10F82400FE030000436FAC642806C80A3CBF737F24 +:10F83400DD4F1575000000000000244000000000AA +:10F8440000005940000000000088C3400000000090 +:10F8540084D797410080E03779C34143176E05B5DB +:10F86400B5B89346F5F93FE9034F384D321D30F9E9 +:10F874004877825A3CBF737FDD4F1575F5B58DB05F +:10F8840014980C00C1001E000027081A00902428B8 +:10F8940001DB2320009037607760019720783028BF +:10F8A40005D10120641C019020783028F9D0C0468D +:10F8B4006BA00025029005E03068401C30600120F8 +:10F8C400641C01902178162265A0FEF70FFE002823 +:10F8D4000AD00099A942EFDB0299401A66A1085C9C +:10F8E40004A948556D1CEAE720782E2800D1641C31 +:10F8F400002D0BD12078302808D13068641C401EBC +:10F9040030600120019020783028F6D0217816222A +:10F9140053A0FEF7EBFD002810D00099A94209DBA3 +:10F924004FA1401A54A1085C04A9485530686D1CC5 +:10F93400401E30600120641C0190E7E70098A84253 +:10F9440015DA04A908180178082903D3401E0178A0 +:10F95400491C01703068009D07E004A84019401E4E +:10F96400007800280AD130686D1E401C3060012DDB +:10F97400F3DA002D02D1684607740125306880004F +:10F984003060019800285AD00720009028000721F1 +:10F99400F3F76EFC0720401A00900721F3F768FC88 +:10F9A4000297002900D00127012D1DDB029804A92C +:10F9B400085C072103900098F3F75AFC002904D14E +:10F9C40003997F1CB800315006E0039AB800301840 +:10F9D40001680901891801600098401C0090029890 +:10F9E400401C0290A842E1DB2078202101437029C9 +:10F9F40025D10094641C20782B2801D02D2801D116 +:10FA0400641C00E02B200023002109E0134B9942E1 +:10FA140004DA8B005918490051183039641C012349 +:10FA240022781500303D0A2DF0D32D2801D108008D +:10FA34004142306840183060002B00D1009C0E9881 +:10FA4400002805D00198002800D10D9C0E98046070 +:10FA540038000FB0F0BC08BC1847000000E1F50501 +:10FA64003031323334353637383961626364656630 +:10FA740041424344454600000001020304050607D1 +:10FA840008090A0B0C0D0E0F0A0B0C0D0E0F0000CB +:10FA9400704737007847C046020050E11EFF2F111F +:10FAA40003C081E18CC090E11EFF2F01030051E1EE +:10FAB4001EFF2F1180C9A0E381007CE10C003C31C2 +:10FAC4001EFF2FE180B5002000900023002269462C +:10FAD4006448F1F745FF0098002811D0F7F79DFD21 +:10FAE400002803D1B4480221016006E0F7F7AAFD1B +:10FAF400002802D1B048012101600320F3F744F843 +:10FB040009BC1847704700B5B34800680021C943D1 +:10FB1400884207D0B04800689349096804225143D9 +:10FB2400884207D29048006804214843C01CAA496F +:10FB340008600EE0A84800688B490968491C042243 +:10FB44005143884205D38848006804214843A249A8 +:10FB5400086008BC184710B50024A04800680028B5 +:10FB640010D0042060439E490858002807D0042080 +:10FB740060439B490858F2F7BBF9641CF1E79748C6 +:10FB84000021016010BC08BC18477047704700B5DD +:10FB9400944800680021C943884203D19148FF2159 +:10FBA400016006E08F480068FF2802D98D480021D3 +:10FBB400016008BC1847E0B58B4800680021C943C0 +:10FBC400884203D18848FF21016006E08648006826 +:10FBD400FF2802D9844800210160834801686846EF +:10FBE400F4F7C4F96846F8F7CDFB0FBC184700B525 +:10FBF40083B07E4801686846F3F7B3FA6846F3F7C2 +:10FC040090F80FBC184780B579480068002806D0E2 +:10FC1400F4F70BFAF4F712FA75480021016009BCF5 +:10FC2400184780B573480068002804D0F4F736FDFF +:10FC340070480021016009BC184700B583B0002357 +:10FC4400002201A96C48F1F78BFE042101A8F8F702 +:10FC5400A7FC00900023002269466848F1F7D0FE13 +:10FC64000FBC1847380D010080B5002300226946F7 +:10FC74006148F1F775FEF4F735FE6149884214D105 +:10FC8400009860490968884209D05E4802680D21DD +:10FC94000020F4F781F95C48F5F701F861E0F5F725 +:10FCA40044F85A48F4F7FBFF5BE0F4F71BFE5849AD +:10FCB400884219D1009853490968884209D05148AB +:10FCC40002680D210020F4F767F94F48F4F7E7FFC5 +:10FCD40047E0424801210160FFF73DFFF5F725F8B1 +:10FCE4004C48F4F7DCFF3CE0F4F7FCFD4A49884259 +:10FCF40019D1009843490968884209D041480268EB +:10FD04000D210020F4F748F93F48F4F7C8FF28E034 +:10FD1400384801210160FFF784FFF5F706F83F48F2 +:10FD2400F4F7BDFF1DE0F4F7DDFD3D49884218D12D +:10FD3400009834490968884209D0324802680D2184 +:10FD44000020F4F729F93048F4F7A9FF09E028481E +:10FD540001210160FFF757FFF4F7E7FF3148F4F79B +:10FD64009EFF09BC184700007C55004000B583B0D5 +:10FD7400244800682C4988421CD122480021016093 +:10FD84002A48009004216846F8F70AFC01900023F1 +:10FD9400002269461848F1F733FE0023002201A926 +:10FDA4001648F1F72DFEF4F7C0FFF4F7BEFF17482D +:10FDB400F4F775FF0FBC1847E855004080B51C48A0 +:10FDC4000068002805D00220F2F7DEFE1848002162 +:10FDD400016009BC1847000080550040845500406C +:10FDE400C005010090550040945500406455004002 +:10FDF400985500409C55004088170100B817010031 +:10FE0400105B0100A0550040805D0100A05B010073 +:10FE1400705B0100BC5D010088580100EC5D0100CD +:10FE2400B85801001C5E0100CD6CAC005704000002 +:10FE3400A4550040000005800F800A001B801E00AE +:10FE440014001180338036003C00398028002D8056 +:10FE540027802200638066006C00698078007D80C2 +:10FE640077807200500055805F805A004B804E00AE +:10FE740044004180C380C600CC00C980D800DD8026 +:10FE8400D780D200F000F580FF80FA00EB80EE000E +:10FE9400E400E180A000A580AF80AA00BB80BE0082 +:10FEA400B400B180938096009C00998088008D8076 +:10FEB40087808200838186018C01898198019D81DC +:10FEC40097819201B001B581BF81BA01AB81AE01C6 +:10FED400A401A181E001E581EF81EA01FB81FE013A +:10FEE400F401F181D381D601DC01D981C801CD812E +:10FEF400C781C201400145814F814A015B815E0196 +:10FF040054015181738176017C01798168016D818D +:10FF140067816201238126012C01298138013D81F9 +:10FF240037813201100115811F811A010B810E01E5 +:10FF340004010181038306030C03098318031D8351 +:10FF440017831203300335833F833A032B832E0335 +:10FF540024032183600365836F836A037B837E03A9 +:10FF640074037183538356035C03598348034D839D +:10FF740047834203C003C583CF83CA03DB83DE0305 +:10FF8400D403D183F383F603FC03F983E803ED83FD +:10FF9400E783E203A383A603AC03A983B803BD8369 +:10FFA400B783B203900395839F839A038B838E0355 +:10FFB40084038183800285828F828A029B829E02CF +:10FFC40094029182B382B602BC02B982A802AD82C5 +:10FFD400A782A202E382E602EC02E982F802FD8231 +:10FFE400F782F202D002D582DF82DA02CB82CE021D +:0CFFF400C402C182438246024C024982D2 +:020000040001F9 +:1000000058025D8257825202700275827F827A02A4 +:100010006B826E0264026182200225822F822A0294 +:100020003B823E0234023182138216021C02198284 +:1000300008020D820782020202000636000000005C +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000010002000100BB +:1001400003000100020001000400010002000100A0 +:10015000030001000200010005000100020001008F +:100160000300010002000100040001000200010080 +:10017000030001000200010006000100020001006E +:100180000300010002000100040001000200010060 +:10019000030001000200010005000100020001004F +:1001A0000300010002000100040001000200010040 +:1001B000030001000200010007000100020001002D +:1001C0000300010002000100040001000200010020 +:1001D000030001000200010005000100020001000F +:1001E0000300010002000100040001000200010000 +:1001F00003000100020001000600010002000100EE +:1002000003000100020001000400010002000100DF +:1002100003000100020001000500010002000100CE +:1002200003000100020001000400010002000100BF +:10023000030001000200010000C09FE51CFF2FE148 +:10024000FD02010000502DE9FAFFFFEB0020A0E1C4 +:10025000000092E50030E0E3030050E10400000AF2 +:100260000210A0E10200A0E3563412EF0000A0E368 +:10027000000082E5040092E5030050E10400000A5A +:10028000041082E20200A0E3563412EF0000A0E363 +:10029000040082E50140BDE81EFF2FE110402DE97A +:1002A00010D04DE20040A0E1E2FFFFEB0020A0E112 +:1002B000040192E7010070E30B00001A34108FE292 +:1002C00000108DE5000054E30010A0030410A013FB +:1002D00004108DE50310A0E308108DE50D10A0E1DA +:1002E0000100A0E3563412EF040182E710D08DE242 +:1002F0001040BDE81EFF2FE13A74740000487047BB +:10030000600A00400D0A0D0A2D2D2D2D2D2D2D2DAD +:100310002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D +:100320002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DFD +:100330002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DED +:100340002D2D2D2D2D0D0A53746174697374696BF5 +:1003500061206F6273686179612E204B6F726F74D8 +:100360006B69652073636865746368696B692E0DDA +:100370000A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DD0 +:100380002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9D +:100390002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8D +:1003A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D0D0AC0 +:1003B000000000000D0A2D2D2D2D2D2D2D2D2D2D64 +:1003C0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D5D +:1003D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4D +:1003E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3D +:1003F0002D2D2D0D0A53746174697374696B61201E +:10040000706F206B616E616C616D2E204B6F726F2F +:10041000746B69652073636865746368696B692EC2 +:100420000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2D3F +:100430002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DEC +:100440002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDC +:100450002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0DEC +:100460000A0000000D0A2D2D2D2D2D2D2D2D2D2DA9 +:100470002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DAC +:100480002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9C +:100490002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8C +:1004A0002D2D2D0D0A53746174697374696B61206D +:1004B000706F206B616E616C616D2E20446C696E93 +:1004C0006E79652073636865746368696B692E0D66 +:1004D0000A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6F +:1004E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3C +:1004F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2C +:100500002D2D2D2D2D2D2D2D2D2D2D2D2D2D0D0A5E +:10051000000000000D0A2D2D2D2D2D2D2D2D2D2D02 +:100520002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DFB +:100530002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DEB +:100540002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDB +:100550002D2D2D0D0A53746174697374696B6120BC +:100560006F6273686179612E20446C696E6E796583 +:100570002073636865746368696B690D0A2D2D2D9E +:100580002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9B +:100590002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8B +:1005A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7B +:1005B0002D2D2D2D2D2D2D2D2D2D0D0A0000000062 +:1005C000180F0100B80B0100780C0100080D0100A4 +:1005D000380D0100B80E0100580E0100480F01004F +:1005E000780F0100A80F0100D80F010008100100CA +:1005F0006810010098100100C8100100F8100100F7 +:10060000281101005811010088110100B8110100E2 +:10061000E8110100181201004812010078120100CF +:10062000A8120100F813010028140100880E01002F +:10063000C8160100A80C01008817010098190100D4 +:10064000680D0100C80D0100F80D0100280E010021 +:10065000A8180100D818010038100100D80C0100BA +:10066000000000000D0A2D2D2D2D2D2D2D2D2D2DB1 +:100670002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DAA +:100680002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9A +:100690002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8A +:1006A0002D2D2D0D0A4B757075726F707269656D09 +:1006B0006E696B2E0D0A2D2D2D2D2D2D2D2D2D2DF1 +:1006C0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D5A +:1006D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4A +:1006E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3A +:1006F0002D2D2D0D0A0000000D0A2D2D2D2D2D2D37 +:100700002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D19 +:100710002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D09 +:100720002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DF9 +:100730002D2D2D2D2D2D2D0D0A5A6875726E616C83 +:1007400020736F62797469790D0A2D2D2D2D2D2D51 +:100750002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DC9 +:100760002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DB9 +:100770002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DA9 +:100780002D2D2D2D2D2D2D0D0A0000000D0A2D2DA6 +:100790002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D89 +:1007A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D79 +:1007B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D69 +:1007C0002D2D2D2D2D2D2D2D2D2D2D0D0A5A6875EC +:1007D000726E616C206F736869626F6B0D0A2D2DEC +:1007E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D39 +:1007F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D29 +:100800002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D18 +:100810002D2D2D2D2D2D2D2D2D2D2D0D0A000000D2 +:100820000102030405060708090A0B111213141527 +:10083000161718191A1B1C1D1F20212223242528D6 +:100840003335363738393A3C3E3F404142434445E0 +:100850004647484A4B4C4D4E4F50515253545657B1 +:1008600058595B5C5D5E5F60616263646566676882 +:10087000696A6B6C6D6E6F70717273747576777870 +:10088000797A7B7C7D7E7F80818283848586878860 +:10089000898A8B8C8D8E8F9091929394A0A1A2A324 +:1008A000A4A5A6A7A8A9AAB0B1B2C0C1C2C3C400DA +:1008B00000000FE11F00C0E3130080E300F021E11E +:1008C00054D09FE51F00C0E31B0080E300F021E14E +:1008D00048D09FE51F00C0E3170080E300F021E14E +:1008E0003CD09FE51F00C0E3110080E300F021E150 +:1008F00030D09FE51F00C0E3120080E300F021E14B +:1009000024D09FE51F00C0E31F0080E300F021E139 +:1009100018D09FE518009FE510FF2FE1805B004095 +:10092000D05C0040E05C0040C05C0040805C004067 +:10093000805A0040581C0100BC600100403D00404E +:10094000C8600100803D0040AC510100C03D004046 +:10095000D4600100003E0040E0600100403E0040E5 +:10096000EC600100803E0040BC510100C03E0040F0 +:10097000943D0100003F0040CC510100403F004049 +:10098000DC510100803F0040EC510100C03F0040BD +:1009900010402DE940109FE50F1081E03C1081E2EE +:1009A00038409FE50F4084E0344084E2040051E188 +:1009B0000700000A002091E5040081E2011082E0B6 +:1009C0000FE0A0E111FF2FE10010A0E1040051E1D0 +:1009D000F7FFFF1A1040BDE81EFF2FE104130000CF +:1009E0002413000080B5F8F700FAFBF75BFD052340 +:1009F000044A00210448F7F737FAFBF7ACFD09BCBD +:100A0000184700003C3900400D0A010010B50400F1 +:100A1000F8F7D6F8FA208000F6F7AEFAF9F716FEE6 +:100A2000F9F7F0FEFCF7FAFBF0F75EF8FA20800029 +:100A3000F6F7A2FAFAE738000102060A0B111314BE +:100A400017181A1C1D1F232438393A3C3E3F4041D9 +:100A500042434447484C4E51525354575B64676A73 +:100A60006B70717475767778797B808182838788E3 +:100A7000898A8BA0A1A3A4A5A6A7A8A9C2C4000087 +:100A800010402DE910D04DE20230A0E100008DE5CC +:100A900004108DE50040A0E108308DE50120A0E3C1 +:100AA0000D10A0E10500A0E3563412EF000043E072 +:100AB0000410A0E10000A0E110D08DE21040BDE8DC +:100AC0001EFF2FE141A042A1E045A3A4A5034BA72F +:100AD0004D484FA8504354A9AA58E1ABACE2ADAE83 +:100AE00002AFB0B161B2B3B4E365B6B7B8B9BABBDF +:100AF000BCBD6FBE7063BF79E478E5C0C1E6C2C318 +:100B0000C4C5C6C77C20567365676F2064656E6573 +:100B1000672C207275622E207C20567365676F20CB +:100B20007365616E736F76207C20567365676F20E6 +:100B30006E617261626F746B6120683A6D3A732006 +:100B40000D0A000030402DE90CD04DE20140A0E13B +:100B50000250A0E10100A0E3CFFDFFEB00008DE516 +:100B600004408DE508508DE50D10A0E10500A0E3DF +:100B7000563412EF000045E00CD08DE23040BDE865 +:100B80001EFF2FE1000051E30000A0030000001A47 +:100B90001EFF2FE100502DE9010050E30200501329 +:100BA0000100001AE6FFFFEB000000EAB3FFFFEBD5 +:100BB0000240BDE81EFF2FE100020000000000001F +:100BC000000000007C550040286201000000000089 +:100BD00000000000F854010001000000A0090040DE +:100BE0000100000000000000000200000000000002 +:100BF000000000007C550040286201000000000059 +:100C0000000000002C4E010001000000A00900407F +:100C100001000000000000000002000000000000D1 +:100C2000000000007C550040286201000000000028 +:100C3000000000000455010001000000A009004070 +:100C400001000000000000000002010000000000A0 +:100C500000000000D6190000E06201000000000062 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000201010A00000066 +:100C8000B80B010004000000306201000000000009 +:100C9000040000001055010001000000100A00408F +:100CA0000000000000000000000201010A00000036 +:100CB000B80B0100F40000004862010000000000D1 +:100CC000040000001C55010001000000E009004084 +:100CD0000000000000000000000201000000000011 +:100CE00000000000E619000058620100000000004A +:100CF000000000006062010001000000180A0040CE +:100D000000000000000000000002010000000000E0 +:100D1000000000001C0600007862010000000000D6 +:100D2000040000003455010001000000200A0040CA +:100D300001000000010000000002010000000000AE +:100D4000000000002406000090620100C9FA0000C3 +:100D5000040000009862010001000000280A004021 +:100D6000010000000000000000020100000000007F +:100D70000000000040060000A0620100000000002A +:100D8000040000004055010001000000300A00404E +:100D9000010000000000000001020000000000004F +:100DA00000000000E85500400000000000000000C6 +:100DB00000000000A862010001000000EC090040F2 +:100DC000010000000000000000020100000000001F +:100DD0000000000048060000A062010000000000C2 +:100DE000040000003C4E010001000000300A0040F9 +:100DF00001000000000000000002010000000000EF +:100E0000000000004C060000A0620100000000008D +:100E1000040000004C55010001000000300A0040B1 +:100E200001000000000000000007010000000000B9 +:100E30000000000050060000B06201000000000049 +:100E400000000000B8620100000000000000000087 +:100E50000100000009000000000201000000000085 +:100E60000000000020060000C062010009FB000035 +:100E7000040000005855010001000000380A00403D +:100E8000010000000000000000020100000000005E +:100E90000000000034060000C862010000000000ED +:100EA0000000000064550100000000000000000088 +:100EB000010000000100000000020100000000002D +:100EC0000000000028060000D062010000000000C1 +:100ED000040000001065010001000000400A00400D +:100EE00001000000000000000002010000000000FE +:100EF000000000003C060000D86201000000000075 +:100F0000040000004C4E010001000000480A0040AF +:100F10000100000000000000010200010A000000C2 +:100F2000B80B0100EC530040E0620100000000003B +:100F300004000000705501000000000000000000E7 +:100F40000100000000000000000201010A00000092 +:100F5000B80B01002C000000E86201000000000056 +:100F6000040000005C4E01000000000000000000D2 +:100F7000010000001E000000000201010A00000044 +:100F8000B80B010054000000F062010000000000F6 +:100F900004000000303801000000000000000000E4 +:100FA0000100000003000000000201010A0000002F +:100FB000B80B01007C000000F86201000000000096 +:100FC000040000007C55010000000000000000004B +:100FD0000100000014000000000201010A000000EE +:100FE000B80B0100A4000000006301000000000035 +:100FF000040000008855010000000000000000000F +:101000000100000005000000000201010A000000CC +:10101000B80B0100CC0000000863010000000000D4 +:10102000040000009455010001000000C8090040C0 +:101030000100000000000000000201010A000000A1 +:10104000B80B0100EA190000306301000000000045 +:1010500004000000A055010001000000F809004054 +:10106000000000000000000000020000000000007E +:101070000000000080550040386301000BFB0000B9 +:1010800000000000A365010001000000F807004017 +:10109000010000000000000000020000000000004D +:1010A0000000000080550040386301000BFB000089 +:1010B00000000000A3650100010000009C08004042 +:1010C00001000000000000000002010128000000F3 +:1010D000681001003C0400004063010000000000B3 +:1010E00004000000AC5501000000000000000000FA +:1010F000000000000F0000000002010128000000B5 +:10110000981001009C0300004863010000000000EB +:1011100004000000B85501000000000000000000BD +:10112000000000000F000000000201012800000084 +:10113000681001007C050000506301000000000001 +:10114000040000006C4E01000000000000000000E0 +:101150000000000001000000000201012800000062 +:1011600098100100DC04000058630100000000003A +:10117000040000007C4E01000000000000000000A0 +:101180000000000001000000000201012800000032 +:10119000981001001C0100006063010000000000C5 +:1011A00004000000C4550100000000000000000021 +:1011B0000000000000000000000201012800000003 +:1011C00098100100BC0100006863010000000000ED +:1011D0000400000070630100000000000000000037 +:1011E00001000000180000000002010128000000BA +:1011F000681001005C02000078630100000000003C +:1012000004000000D05501000000000000000000B4 +:1012100000000000000000000002010128000000A2 +:1012200068100100FC020000806301000000000063 +:1012300004000000886301000000000000000000BE +:101240000100000018000000000200000000000083 +:101250000000000088550040906301008FFB0000F3 +:10126000000000009863010001000000500A0040E7 +:10127000010000000000000000020000000000006B +:10128000000000008C5500409063010091FB0000BD +:1012900000000000A863010001000000500A0040A7 +:1012A000010000000000000000020000000000003B +:1012B0000000000090550040B063010093FB000067 +:1012C00000000000DC5501000000000000000000EC +:1012D0000100000000000000010201010001000007 +:1012E000A8120100D2070000B8630100000000004E +:1012F00008000000000000000100000000000040A5 +:1013000000000000000000000102010100010000D7 +:10131000A8120100D2070000B8630100000000001D +:10132000080000000000000001000000A8020040CA +:1013300000000000000000000102010100010000A7 +:10134000A8120100D2070000B863010000000000ED +:1013500008000000000000000100000050050040EF +:101360000000000000000000010501010001000074 +:10137000A8120100CE0700000000000000000000DD +:101380000800000000000000000000000000000055 +:10139000000000000000000000020000000000004B +:1013A0000000000094550040C0630100BBFB00003A +:1013B00000000000E85501000000000000000000EF +:1013C0000100000000000000010501010001000013 +:1013D00098130100CE0F0000000000000000000084 +:1013E0000A000000000000000000000000000000F3 +:1013F00000000000000000000105000000000000E7 +:1014000000000000645500400000000000000000E3 +:1014100000000000000000000000000000000000CC +:1014200000000000000000000005000000000000B7 +:10143000000000006455004000000000F3FB0000C5 +:10144000000000000000000000000000000000009C +:101450000000000000000000010201000000000088 +:1014600000000000D00600000000000000000000A6 +:1014700000000000C8630100000000000000000040 +:101480000000000000000000010201000000000058 +:1014900000000000D806000000000000000000006E +:1014A00000000000F45501000000000000000000F2 +:1014B0000000000000000000010601000000000024 +:1014C00000000000D4060000000000000000000042 +:1014D00000000000D06301000000000000000000D8 +:1014E00000000000000000000102010000000000F8 +:1014F00000000000B807000000000000000000002D +:1015000000000000C86301000000000000000000AF +:1015100000000000000000000102010000000000C7 +:1015200000000000C00700000000000000000000F4 +:1015300000000000F4550100000000000000000061 +:101540000000000000000000010601000000000093 +:1015500000000000BC0700000000000000000000C8 +:1015600000000000D0630100000000000000000047 +:101570000000000000000000010201010A0000005C +:10158000E80B010058060000000000000000000009 +:1015900004000000C863010000000000000000001B +:1015A0000000000000000000010201010A0000002C +:1015B000E80B0100A8060000000000000000000089 +:1015C00004000000F45501000000000000000000CD +:1015D0000000000000000000010601010A000000F8 +:1015E000E80B010080060000000000000000000081 +:1015F00004000000D06301000000000000000000B3 +:101600000000000000000000010201010A000000CB +:10161000E80B01004007000000000000000000008F +:1016200004000000C863010000000000000000008A +:101630000000000000000000010201010A0000009B +:10164000E80B01009007000000000000000000000F +:1016500004000000F455010000000000000000003C +:101660000000000000000000010601010A00000067 +:10167000E80B010068070000000000000000000007 +:1016800004000000D0630100000000000000000022 +:101690000000000000000000000201000000000047 +:1016A000000000002C060000D863010000000000CC +:1016B000040000000056010001000000040A004080 +:1016C0000100000001000000000201000000000015 +:1016D0000000000038060000E06301000000000088 +:1016E00004000000E863010001000000580A004007 +:1016F00000000000010000000002010000000000E6 +:101700000000000030060000F86301000000000047 +:1017100004000000A4650100010000006C0A004004 +:1017200000000000000000000002010000000000B6 +:1017300000000000C60700000000000000000000DC +:101740000000000000000000000000000000000099 +:101750000000000000000000000201000000000086 +:1017600000000000CA0700000000000000000000A8 +:101770000000000000000000000000000000000069 +:101780000000000000000000000201000000000056 +:1017900000000000CE190000006401003FFC0000C2 +:1017A00000000000185601000000000000000000CA +:1017B00000000000570400000002010000000000CB +:1017C00000000000D219000000000000000000002E +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000002000000000000F7 +:1017F00000000000A0550040006401006DFC0000E6 +:101800000000000018560100000000000000000069 +:1018100000000000000000000002000000000000C6 +:1018200000000000A0550040006401006DFC0000B5 +:10183000000000002456010000000000000000002D +:101840000000000000000000000200000000000096 +:1018500000000000A05500400864010071FD000078 +:101860000000000010640100000000000000000003 +:101870000000000000000000000200000000000066 +:1018800000000000A0550040006401006DFC000055 +:1018900000000000305601000000000000000000C1 +:1018A0000000000000000000000200000000000036 +:1018B00000000000A4550040A0620100C1FD00002E +:1018C000040000003C56010001000000480A0040EE +:1018D0000100000000000000000200000000000005 +:1018E00000000000A855004018640100000000003E +:1018F000000000008C4E0100010000004009004083 +:1019000001000000000000000102000118000000BA +:10191000D8180100A851004000000000000000009D +:10192000040000009C4E01000000000000000000C8 +:10193000000000000000000001020101180000008A +:10194000D8180100DC0600000000000000000000C4 +:1019500004000000206401000000000000000000FE +:101960000000000000000000010201000000000073 +:10197000000000003C070000000000000000000024 +:1019800000000000485601000000000000000000B8 +:101990000000000000000000000201000000000044 +:1019A0000000000054060000286401000000000050 +:1019B000000000005456010000000000000000007C +:1019C0000100000000000000000201000100000012 +:1019D00000000000DA190000000000000000000014 +:1019E00004000000000000000000000000000000F3 +:1019F00000000000000000000002010001000000E3 +:101A000000000000DE1900000000000000000000DF +:101A100004000000000000000000000000000000C2 +:101A200000000000000000000002010001000000B2 +:101A300000000000E21900000000000000000000AB +:101A40000400000000000000000000000000000092 +:101A50000000000000000000145A0100205A01009C +:101A60002C5A0100385A0100445A0100505A010012 +:101A70005C5A0100685A0100745A0100805A010042 +:101A80008C5A0100000000007C2020202020204EE5 +:101A90006F6D696E616C2C207275622E2020202083 +:101AA000207C20202020204B6F6C69636865737454 +:101AB000766F0D0A0000000038B500250400ED43E4 +:101AC000AC420AD06846047001226946012000F049 +:101AD00009F8012801D1200000E0280032BC08BC30 +:101AE000184739007847C04600502DE9000050E300 +:101AF0000100004A22FCFFEB000000EA0000A0E326 +:101B00000240BDE81EFF2FE14B726974696368658E +:101B1000736B617961206F736869626B61206B75AB +:101B20007075726F707269656D6E696B610000002F +:101B30004E656B72697469636865736B6179612066 +:101B40006F736869626B61206B757075726F70720C +:101B500069656D6E696B610010B400210268001D3B +:101B6000002A0BD00368001DDC0702D54C46641E1A +:101B70001B1919601B1D121FFBD1EFE710BC70472A +:101B80000A4350555F41524D5F45584345505449B3 +:101B90004F4E2023256420747261707065642E0A94 +:101BA000000000004F736869626B61207376796191 +:101BB0007A692063206B757075726F707269656DDC +:101BC0006E696B6F6D000000567962726F73206BE7 +:101BD000757075727920707269207472616E73709D +:101BE0006F727469726F766B650000007C20202034 +:101BF0002020202531336420202020207C2020201C +:101C00002020253131642020202020200D0A0000D2 +:101C10005265706F72742066726F6D20736F6C61A5 +:101C20007269756D20646576696365206964202535 +:101C3000642E000000C09FE51CFF2FE17D1C010009 +:101C400000C09FE51CFF2FE1E509010000C09FE5F2 +:101C50001CFF2FE1811C01000100A0E3F4FFFFEB5A +:101C6000000050E349FBFF1B0000A0E3F3FFFFEB84 +:101C7000F5FFFFEB030000EBFDFFFFEA01207047DB +:101C800080B500F011F8C04600502DE96CF9FFEB6B +:101C90002620A0E3802B82E30210A0E11800A0E33D +:101CA000563412EFFBFFFFEA7847C0460070B0E100 +:101CB0000700B0E1F3FFFFEBFDFFFFEA03000800C0 +:101CC0001968002A02D1491E196070470878002857 +:101CD00002D10020C0437047481C18600878704744 +:101CE00079FEFFFF084C0000780A00400000000069 +:101CF0004F6DFFFF780A0000B4480000000000406C +:101D000000000000567962726F73206B75707572F7 +:101D10007920706F206D61672E6461746368696BF0 +:101D200075000000567962726F73206B7570757262 +:101D30007920706F206964656E746966696B616390 +:101D400069690000567962726F73206B75707572E5 +:101D50007920706F207665726966696B6163696965 +:101D600000000000567962726F73206B7570757297 +:101D70007920706F206F70742E6461746368696B72 +:101D800075000000567962726F73206B7570757202 +:101D90007920706F20656D6B2E6461746368696B68 +:101DA000750000004F736869626B6120736B6F721E +:101DB0006F737469207472616E73702E6D6F746FBF +:101DC000726100004F736869626B61206D656861C4 +:101DD0006E697A6D6176797261766E6976616E6927 +:101DE000796100004F736869626B61204652203050 +:101DF0007843334F736869626B61204652203078B4 +:101E000043340000207C20205065636861742720E3 +:101E10006F74636865746120697A206275666572A3 +:101E200061200000207C20204F736869626B612074 +:101E30006F74707261766B6920652D6D61696C20BD +:101E400000000000207C2020452D6D61696C206F12 +:101E500074707261766C656E6F20757370657368EF +:101E60006E6F2000B4590100C0590100CC59010027 +:101E7000E4590100D8590100F0590100FC59010052 +:101E800000000000C05C0100CC5C0100D85C0100D7 +:101E9000E45C0100F05C0100FC5C0100085D0100F5 +:101EA000000000004B757075726F707269656D6E21 +:101EB000696B2062796C20707573742E0D0A0D0A9F +:101EC00000000000253032643A253032643A253073 +:101ED000326420253032642F253032642F25303291 +:101EE000640000003230253032642F253032642FF8 +:101EF0002530326420253032643A253032643A2568 +:101F000030326400567962726F73206B757075722F +:101F10007920706F207A617072657475000000001E +:101F20004F736869626B61207374656B65726E6F65 +:101F3000676F206D6F746F72610000004F73686986 +:101F4000626B6120737679617A692073206D6F64AA +:101F5000656D6F6D0000000060090000C012000098 +:101F600080250000004B00000096000000E100000A +:101F700000C201003C5C0100485C0100545C0100AF +:101F8000605C01006C5C0100785C010000000000F6 +:101F900041545E534943533D302C636F6E54797006 +:101FA000652C47505253300D0A00000041545E53D7 +:101FB0004943533D302C696E616374544F2C223277 +:101FC00030220D0A0000000041545E534953533D36 +:101FD000302C737276547970652C22536D74702294 +:101FE0000D0A000041545E534953533D302C616C3F +:101FF0007068616265742C2231220D0A00000000B5 +:1020000041545E534953533D302C6164647265738F +:10201000732C222573220D0A0000000041545E53E8 +:102020004953533D302C746370506F72742C2225C9 +:1020300073220D0A000000004B757075726F70728C +:1020400069656D6E696B20707573742E0D0A0D0ACB +:102050000000000054657374206D657373616765DB +:102060002066726F6D20736F6C617269756D2E00E2 +:1020700054657374206D6573736167652E204465C4 +:10208000766963652069642025642E00496E63616A +:1020900073736174696F6E2E204465766963652081 +:1020A00069642025642E0000000000001F003B0032 +:1020B0005A0078009700B500D400F30011013001F8 +:1020C0004E01000038B505000C002000FFF7F4FCBD +:1020D000A04200D00025280032BC08BC18472300CD +:1020E000EA2FEF3A3531682DEEF8E8E1EAE020F129 +:1020F000EAEEF02E00000000D4D03A3041682DF412 +:10210000EEF0ECE0F220E4E0EDEDFBF50000000085 +:10211000D4D03A3042682DEDE5E8F1EFF02EFFF72C +:10212000E5E9EAE000000000D4D03A3137682DCE6E +:10213000F8E8E1EAE020EDEEECE5F0E00000000078 +:10214000D4D03A3232682DCDE5E2E5F0EDE0FF2063 +:10215000E4E0F2E000000000D4D03A3446682DCD2F +:10216000E5E2E5F0EDFBE920EFE0F0EEEBFC00004E +:10217000D4D03A3634682DD4CF20EEF2F1F3F2F118 +:10218000F2E2F3E5F2000000D4D03A3844682DCEF4 +:10219000F2F0E8F6E0F2E5EBFCEDFBE90000000010 +:1021A000D4D03A3933682DC2EEF1F1F2E0EDEEE22F +:1021B000EBE5EDE8E5000000EDE0EAEEEFEBE5ED44 +:1021C000E8FF20EFEE20EDE0EBEEE3E0EC000000B6 +:1021D000EDE0EAEEEFEBE5EDE8E9203220E220F178 +:1021E000ECE5EDE500000000EDE0EAEEEFEBE5EDFB +:1021F000E8E9203320E220F1ECE5EDE50000000005 +:10220000EDE0EAEEEFEBE5EDE8E9203420E220F145 +:10221000ECE5EDE500000000E7EDE0F7E5EDE8E5D1 +:1022200020E220EFEEEBE520E4EBE8EDFB00000020 +:10223000E4E8E0EFE0E7EEEDE020E8F2EEE3E020B6 +:10224000F7E5EAE000000000EFEE20E2EEE7E2F062 +:10225000E0F2E0EC20EFEEEAF3EFEEEA000000003F +:10226000EBE8ECE8F220EEEFE5F0E0F6E8E920E25A +:1022700020F7E5EAE5000000CDE5EAEEF0F02EF407 +:10228000EEF0ECE0F220EAEEECE0EDE4FB00000022 +:10229000CDE5E2E5F0EDFBE520E4E0F2E020E8202A +:1022A000E2F0E5ECFF200000CDE5F220E7E0EFF002 +:1022B000EEF8E5EDEDFBF520E4E0EDEDFBF52000BB +:1022C000567962726F73206B757075727920706FBA +:1022D00020646C696E6500005A616D696E2076201D +:1022E0006B757075726F707269656D6E696B650084 +:1022F0004F736869626B61207472616E73702E6DCA +:102300006F746F72610000004F736869626B6120C7 +:102310006D61676E2E6461746368696B61000000B3 +:102320004F736869626B6120656D6B2E64617463C5 +:1023300068696B6100000000D1EFE0F1E8E1EE2098 +:10234000E7E020EFEEEAF3EFEAF3212121000000BD +:10235000D3F1EBF3E3E820F1EEEBFFF0E8FF2C2004 +:10236000ECE8ED2E00000000207C20205065636822 +:10237000617427205A2D6F746368657461200000B2 +:10238000207C20205065636861742720582D6F746D +:102390006368657461200000207C20204E657665AE +:1023A000726E6979207061726F6C272000000000E6 +:1023B000C8570100D4570100E0570100EC57010055 +:1023C000F8570100000000001C58010028580100C7 +:1023D00034580100405801004C5801000000000032 +:1023E000A45A0100B05A0100BC5A0100C85A0100A9 +:1023F000D45A010000000000AC5B0100B85B010092 +:10240000C45B0100D05B0100DC5B01000000000048 +:10241000F45B0100005C01000C5C0100185C010031 +:10242000245C01000000000041545E534943533DC9 +:10243000302C646E73312C222573220D0A000000AB +:1024400041545E534943533D302C7061737377643C +:102450002C222573220D0A0041545E534943533DFB +:10246000302C61706E2C222573220D0A00000000B2 +:1024700041545E534943533D302C757365722C2291 +:102480002573220D0A00000041545E534953533D09 +:10249000302C636F6E49642C2230220D0A0000003C +:1024A00041545E534953533D302C757365722C2251 +:1024B0002573220D0A00000041545E534953533DD9 +:1024C000302C7061737377642C222573220D0A00FF +:1024D00041545E534953533D302C736D41757468BC +:1024E0002C2231220D0A000041545E534953533DC2 +:1024F000302C736D46726F6D2C222573220D0A00ED +:1025000041545E534953533D302C736D5263707484 +:102510002C222573220D0A0041545E534953533D2A +:10252000302C736D5375626A2C222573220D0A00BC +:10253000686A6C747A4C00006E616E004E414E0009 +:10254000696E6600494E4600C2DBC1C5D0C8D2C51F +:1025500020C4D02ECAC0CDC0CB000000CEEFEBE02F +:10256000F7E5EDEE2025643A2530326400000000E6 +:10257000CFD0C5C2DBD8C5CDCE20CCC0CAD12EC2EB +:10258000D02E0000CFCECB62C7CEC2C0CDC8C520F2 +:10259000D3D1CBD3C3CEE900D0C0C1CED2C020CDE1 +:1025A000C5C2CEC7CCCEC6CDC0000000212121219E +:1025B000212121212121212121212121210000006E +:1025C000D6C5CDC0202564F0F3E12E2F2564ECE8BC +:1025D000ED2E0000C0CFCFC0D0C0D220D0C0C1CE21 +:1025E000D2C0C5D200000000C4CBDF20CDC0D7C010 +:1025F000CBC020D0C0C1CED2DB000000CAC0CD2EDF +:102600003120CFC5D02E3120C2DBD52E00000000F6 +:10261000CAC0CD2E3120CFC5D02E3220C2DBD52E60 +:1026200000000000CAC0CD2E3120CFC5D02E3320EF +:10263000C2DBD52E00000000CAC0CD2E3120CFC590 +:10264000D02E3420C2DBD52E00000000CAC0CD2E13 +:102650003220CFC5D02E3120C2DBD52E00000000A5 +:10266000CAC0CD2E3220CFC5D02E3220C2DBD52E0F +:1026700000000000CAC0CD2E3220CFC5D02E33209E +:10268000C2DBD52E00000000CAC0CD2E3220CFC53F +:10269000D02E3420C2DBD52E00000000CAC0CD2EC3 +:1026A0003320CFC5D02E3120C2DBD52E0000000054 +:1026B000CAC0CD2E3320CFC5D02E3220C2DBD52EBE +:1026C00000000000CAC0CD2E3320CFC5D02E33204D +:1026D000C2DBD52E00000000CAC0CD2E3320CFC5EE +:1026E000D02E3420C2DBD52E00000000CAC0CD2E73 +:1026F0003420CFC5D02E3120C2DBD52E0000000003 +:10270000CAC0CD2E3420CFC5D02E3220C2DBD52E6C +:1027100000000000CAC0CD2E3420CFC5D02E3320FB +:10272000C2DBD52E00000000CAC0CD2E3420CFC59C +:10273000D02E3420C2DBD52E00000000CAC0CD2E22 +:102740003520CFC5D02E3120C2DBD52E00000000B1 +:10275000CAC0CD2E3520CFC5D02E3220C2DBD52E1B +:1027600000000000CAC0CD2E3520CFC5D02E3320AA +:10277000C2DBD52E00000000CAC0CD2E3520CFC54B +:10278000D02E3420C2DBD52E00000000CAC0CD2ED2 +:102790003620CFC5D02E3120C2DBD52E0000000060 +:1027A000CAC0CD2E3620CFC5D02E3220C2DBD52ECA +:1027B00000000000CAC0CD2E3620CFC5D02E332059 +:1027C000C2DBD52E00000000CAC0CD2E3620CFC5FA +:1027D000D02E3420C2DBD52E00000000CAC0CD2E82 +:1027E0003720CFC5D02E3120C2DBD52E000000000F +:1027F000CAC0CD2E3720CFC5D02E3220C2DBD52E79 +:1028000000000000CAC0CD2E3720CFC5D02E332007 +:10281000C2DBD52E00000000CAC0CD2E3720CFC5A8 +:10282000D02E3420C2DBD52E00000000CAC0CD2E31 +:102830003820CFC5D02E3120C2DBD52E00000000BD +:10284000CAC0CD2E3820CFC5D02E3220C2DBD52E27 +:1028500000000000CAC0CD2E3820CFC5D02E3320B6 +:10286000C2DBD52E00000000CAC0CD2E3820CFC557 +:10287000D02E3420C2DBD52E00000000CAC0CD2EE1 +:102880003920CFC5D02E3120C2DBD52E000000006C +:10289000CAC0CD2E3920CFC5D02E3220C2DBD52ED6 +:1028A00000000000CAC0CD2E3920CFC5D02E332065 +:1028B000C2DBD52E00000000CAC0CD2E3920CFC506 +:1028C000D02E3420C2DBD52E00000000CAC0CD2E91 +:1028D000313020CFC5D02E3120C2DBD52E000000F4 +:1028E000CAC0CD2E313020CFC5D02E3220C2DBD58C +:1028F0002E000000CAC0CD2E313020CFC5D02E33DF +:1029000020C2DBD52E000000CAC0CD2E313020CF32 +:10291000C5D02E3420C2DBD52E000000CAC0CD2E7B +:102920003120CFC5D02E3120C1D3C42E00000000ED +:10293000CAC0CD2E3120CFC5D02E3220C1D3C42E57 +:1029400000000000CAC0CD2E3120CFC5D02E3320CC +:10295000C1D3C42E00000000CAC0CD2E3120CFC587 +:10296000D02E3420C1D3C42E00000000CAC0CD2E0A +:102970003220CFC5D02E3120C1D3C42E000000009C +:10298000CAC0CD2E3220CFC5D02E3220C1D3C42E06 +:1029900000000000CAC0CD2E3220CFC5D02E33207B +:1029A000C1D3C42E00000000CAC0CD2E3220CFC536 +:1029B000D02E3420C1D3C42E00000000CAC0CD2EBA +:1029C0003320CFC5D02E3120C1D3C42E000000004B +:1029D000CAC0CD2E3320CFC5D02E3220C1D3C42EB5 +:1029E00000000000CAC0CD2E3320CFC5D02E33202A +:1029F000C1D3C42E00000000CAC0CD2E3320CFC5E5 +:102A0000D02E3420C1D3C42E00000000CAC0CD2E69 +:102A10003420CFC5D02E3120C1D3C42E00000000F9 +:102A2000CAC0CD2E3420CFC5D02E3220C1D3C42E63 +:102A300000000000CAC0CD2E3420CFC5D02E3320D8 +:102A4000C1D3C42E00000000CAC0CD2E3420CFC593 +:102A5000D02E3420C1D3C42E00000000CAC0CD2E19 +:102A60003520CFC5D02E3120C1D3C42E00000000A8 +:102A7000CAC0CD2E3520CFC5D02E3220C1D3C42E12 +:102A800000000000CAC0CD2E3520CFC5D02E332087 +:102A9000C1D3C42E00000000CAC0CD2E3520CFC542 +:102AA000D02E3420C1D3C42E00000000CAC0CD2EC9 +:102AB0003620CFC5D02E3120C1D3C42E0000000057 +:102AC000CAC0CD2E3620CFC5D02E3220C1D3C42EC1 +:102AD00000000000CAC0CD2E3620CFC5D02E332036 +:102AE000C1D3C42E00000000CAC0CD2E3620CFC5F1 +:102AF000D02E3420C1D3C42E00000000CAC0CD2E79 +:102B00003720CFC5D02E3120C1D3C42E0000000005 +:102B1000CAC0CD2E3720CFC5D02E3220C1D3C42E6F +:102B200000000000CAC0CD2E3720CFC5D02E3320E4 +:102B3000C1D3C42E00000000CAC0CD2E3720CFC59F +:102B4000D02E3420C1D3C42E00000000CAC0CD2E28 +:102B50003820CFC5D02E3120C1D3C42E00000000B4 +:102B6000CAC0CD2E3820CFC5D02E3220C1D3C42E1E +:102B700000000000CAC0CD2E3820CFC5D02E332093 +:102B8000C1D3C42E00000000CAC0CD2E3820CFC54E +:102B9000D02E3420C1D3C42E00000000CAC0CD2ED8 +:102BA0003920CFC5D02E3120C1D3C42E0000000063 +:102BB000CAC0CD2E3920CFC5D02E3220C1D3C42ECD +:102BC00000000000CAC0CD2E3920CFC5D02E332042 +:102BD000C1D3C42E00000000CAC0CD2E3920CFC5FD +:102BE000D02E3420C1D3C42E00000000CAC0CD2E88 +:102BF000313020CFC5D02E3120C1D3C42E000000EB +:102C0000CAC0CD2E313020CFC5D02E3220C1D3C482 +:102C10002E000000CAC0CD2E313020CFC5D02E33BB +:102C200020C1D3C42E000000CAC0CD2E313020CF29 +:102C3000C5D02E3420C1D3C42E00000031436836E5 +:102C400030682DE2FBE1F02EEAF3EFFEF0FB00002E +:102C50003143683631682DE2FBE1F02EEAF3EFFEF6 +:102C6000F0FB00003143683634682DE2FBE1F02EC2 +:102C7000EAF3EFFEF0FB00003143683635682DE2E1 +:102C8000FBE1F02EEAF3EFFEF0FB00003143683683 +:102C900036682DE2FBE1F02EEAF3EFFEF0FB0000D8 +:102CA0003143683637682DE2FBE1F02EEAF3EFFEA0 +:102CB000F0FB00003143683638682DE2FBE1F02E6E +:102CC000EAF3EFFEF0FB00003143683639682DE28D +:102CD000FBE1F02EEAF3EFFEF0FB00003143683633 +:102CE00043682DE2FBE1F02EEAF3EFFEF0FB00007B +:102CF000EA2FEF3A3433682DE7E0ECE8ED20E220EC +:102D000000000000EA2FEF3A3533682DEEF8E8E1D5 +:102D1000EAE020ECE5F52E00EA2FEF3A3637682D91 +:102D2000EEF8E8E1EAE020E5ECEA2E00D4D03A3013 +:102D300031682DEDE5E8F1EFF0E0E2E5ED000000AF +:102D4000D4D03A3032682DEEF2F1F3F2F1F2E2F340 +:102D5000E5F20000D4D03A3033682DEEF2F1F3F210 +:102D6000F1F2E2F3E5F20000D4D03A3034682DED10 +:102D7000E5EAEEF0F02EEF2DF0FB0000D4D03A3073 +:102D800036682DD4CF20E220F0E5E6E8ECE500003F +:102D9000D4D03A3037682DEDE5EAEEF0F02EEF2D85 +:102DA000F0FB0000D4D03A3131682DEDE520E2E2AD +:102DB000E5E4E5EDE0000000D4D03A3132682DE7DB +:102DC000E0E2EEE4F1EAEEE900000000D4D03A31AE +:102DD00033682DF2E5EAF3F9E0FF20E4E0F2E000E9 +:102DE000D4D03A3138682DCEF8E8E1EAE020E4E0CA +:102DF000F2FB0000D4D03A3139682DCDE5F220E461 +:102E0000E0EDEDFBF5000000D4D03A3141682DCE65 +:102E1000EEF8E8E1EAE020D4CF000000D4D03A3167 +:102E200042682DC7E0E2EEE4F1EAEEE900000000BE +:102E3000D4D03A3144682DCFEEE2F0E5E6E4E5ED9A +:102E4000E0000000D4D03A3146682DCEF2F1F3F222 +:102E5000F1F2E2F3E5F20000D4D03A3230682DCF3F +:102E6000E5F0E5EFEEEBEDE5EDE8E500D4D03A3244 +:102E700031682DCEF8E8E1EAE020F1F3ECECFB005C +:102E8000D4D03A3233682DCDE5F220E7E0EFE8F117 +:102E9000E8000000D4D03A3238682DC220D4CF20C8 +:102EA000E1EEEBE5E5000000D4D03A3333682DCDF8 +:102EB000E5EAEEF0F0E5EAF2EDFBE500D4D03A33D6 +:102EC00035682DCDE5EAEEF0F0E5EAF2EDFBE9003C +:102ED000D4D03A3336682DCDE5EAEEF0F0E5EAF2EB +:102EE000EDFBE500D4D03A3338682DCEF8E8E1EABE +:102EF000E020E220CFC7D300D4D03A3339682DC2C6 +:102F0000EDF3F2F0E5EDEDFFFF000000D4D03A3331 +:102F100041682DCFE5F0E5EFEEEBEDE5EDE8E500FE +:102F2000D4D03A3345682DCFE5F0E5EFEEEBEDE593 +:102F3000EDE8E500D4D03A3346682DCFE5F0E5EF73 +:102F4000EEEBEDE5EDE8E500D4D03A3430682DCF76 +:102F5000E5F0E5EFEEEBEDE5EDE8E500D4D03A3451 +:102F600031682DCFE5F0E5EFEEEBEDE5EDE8E500BE +:102F7000D4D03A3432682DCFE5F0E5EFEEEBEDE555 +:102F8000EDE8E500D4D03A3433682DCFE5F0E5EF35 +:102F9000EEEBEDE5EDE8E500D4D03A3434682DCF22 +:102FA000E5F0E5EFEEEBEDE5EDE8E500D4D03A3401 +:102FB00036682DCDE520F5E2E0F2E0E5F200000014 +:102FC000D4D03A3437682DCFE5F0E5EFEEEBEDE500 +:102FD000EDE8E500D4D03A3438682DCFE5F0E5EFE0 +:102FE000EEEBEDE5EDE8E500D4D03A3441682DCEC6 +:102FF000F2EAF0FBF220F7E5EA000000D4D03A3420 +:1030000042682DC1F3F4E5F020F7E5EAE0000000A6 +:10301000D4D03A3443682DCFE5F0E5EFEEEBEDE5A3 +:10302000EDE8E500D4D03A3530682DC8E4E5F2206B +:10303000EFE5F7E0F2FC0000D4D03A3531682DCF4F +:10304000E5F0E5EFEEEBEDE5EDE8E500D4D03A355F +:1030500032682DCFE5F0E5EFEEEBEDE5EDE8E500CC +:10306000D4D03A3533682DCFE5F0E5EFEEEBEDE562 +:10307000EDE8E500D4D03A3534682DCFE5F0E5EF42 +:10308000EEEBEDE5EDE8E500D4D03A3542682DCF22 +:10309000E5F0E5EFEEEBEDE5EDE8E500D4D03A350F +:1030A00045682DCDE5EAEEF0F0E5EAF2EDE0FF004F +:1030B000D4D03A3630682DCFE5F0E5EFEEEBEDE514 +:1030C000EDE8E500D4D03A3631682DCFE5F0E5EFF4 +:1030D000EEEBEDE5EDE8E500D4D03A3632682DCFE1 +:1030E000E5F0E5EFEEEBEDE5EDE8E500D4D03A36BE +:1030F00033682DCFE5F0E5EFEEEBEDE5EDE8E5002B +:10310000D4D03A3635682DCDE520F5E2E0F2E0E5A1 +:10311000F2000000D4D03A3636682DCFE5F0E5EF66 +:10312000EEEBEDE5EDE8E500D4D03A3637682DCE8C +:10313000F8E8E1EAE020F1E2FFE7E800D4D03A362F +:1031400038682DCDE520F5E2E0F2E0E5F200000080 +:10315000D4D03A3639682DCFE5F0E5EFEEEBEDE56A +:10316000EDE8E500D4D03A3642682DCDE5F220F7FF +:10317000E5EAEEE2EEE90000D4D03A3643682DCD20 +:10318000E5F220EAEEEDF2F02E000000D4D03A365F +:1031900044682DCDE520F5E2E0F2E0E5F200000024 +:1031A000D4D03A3645682DCFE5F0E5EFEEEBEDE50E +:1031B000EDE8E500D4D03A3646682DCFE5F0E5EFEE +:1031C000EEEBEDE5EDE8E500D4D03A3730682DCFF1 +:1031D000E5F0E5EFEEEBEDE5EDE8E500D4D03A37CC +:1031E00032682DCAEEECE0EDE4E020EDE5000000F1 +:1031F000D4D03A3733682DCAEEECE0EDE4E020EDB0 +:10320000E5000000D4D03A3734682DCEF8E8E1EA82 +:10321000E020CEC7D3000000D4D03A3738682DC79D +:10322000E0ECE5EDE020CFCE00000000D4D03A374E +:1032300039682DC7E0ECE5EDE020D4CF00000000B8 +:10324000D4D03A3743682DCDE520F1EEE2EFE0E44B +:10325000E0E5F200D4D03A3746682DCFE5F0E5EF4F +:10326000EEEBEDE5EDE8E500D4D03A3834682DCF4B +:10327000E5F0E5EFEEEBEDE5EDE8E500D4D03A382A +:1032800035682DCFE5F0E5EFEEEBEDE5EDE8E50097 +:10329000D4D03A3836682DCFE5F0E5EFEEEBEDE52A +:1032A000EDE8E500D4D03A3837682DCFE5F0E5EF0A +:1032B000EEEBEDE5EDE8E500D4D03A3838682DCFF7 +:1032C000E5F0E5EFEEEBEDE5EDE8E500D4D03A38DA +:1032D00039682DCFE5F0E5EFEEEBEDE5EDE8E50043 +:1032E000D4D03A3841682DCFE5F0E5EFEEEBEDE5CF +:1032F000EDE8E500D4D03A3842682DCFE5F0E5EFAF +:10330000EEEBEDE5EDE8E500D4D03A3845682DCD9B +:10331000F3EBE5E2EEE920E8F2EEE300D4D03A394F +:1033200030682DCFEEEBE520EFF0E5E22E00000057 +:10333000D4D03A3932682DCDE0EBEEE6E5EDE8E5A4 +:1033400000000000D4D03A4130682DCEF8E8E1EA20 +:10335000E020F1E2FFE7E800D4D03A4133682DCD18 +:10336000E5EAEEF0F0E5EAF2EDEEE500D4D03A4120 +:1033700034682DC0E2E0F0E8FF20DDCACBC70000D2 +:10338000D4D03A4135682DC0E2E0F0E8FF20CAD140 +:1033900000000000D4D03A4141682DCFE5F0E5EFC0 +:1033A000EEEBEDE5EDE8E500D4D03A4332682DCF01 +:1033B000F0E5E2FBF8E5EDE8E5000000D4D03A43A3 +:1033C00033682DCDE5F1EEE2EFE0E4E5EDE8E50070 +:1033D000D4D03A4334682DCDE5F1EEE2EFE0E4E5F8 +:1033E000EDE8E500EAF3EFFEF0EEEFF0E8E5ECEDF6 +:1033F000E8EAEEEC00000000EFEE20E8E4E5EDF294 +:10340000E8F4E8EAE0F6E8E800000000EFEE20EE7D +:10341000EFF2E8F72EE4E0F2F7E8EAF3200000002C +:10342000EFEE20E5ECEAEEF1F22EE4E0F2F7E8EA66 +:10343000F3000000F1F2E5EAE5F0EDEEE3EE20EC5A +:10344000EEF2EEF0E0000000F2F0E0EDF1EFEEF071 +:10345000F22EECEEF2EEF0E000000000D4CF312CC2 +:10346000D4CF3220E8EBE820F7E0F1FB00000000C9 +:10347000E7E0EFF0EEF8E5EDEDFBF520E4E0EDED53 +:10348000FBF50000EDEEECE5F020F3E6E520E2E2EE +:10349000E5E4E5ED00000000ECE5EDFCF8E520E4F6 +:1034A000E0F2FB20E220D4CF00000000EFEEF1EBD1 +:1034B000E5E4EDFFFF20E7E0EFE8F1FC00000000AD +:1034C000EFE0ECFFF2FC20F0E5E3E8F1F2F0EEE2F1 +:1034D00000000000E4E5EDE5E6EDEEE3EE20F0E5CA +:1034E000E3E8F1F2F0E0000032F520F1E1EEE9ED81 +:1034F000FBF520E7E0EFE8F1E5E90000EFE0F0E0C0 +:10350000ECE5F2F0FB20E220EAEEECE0EDE4E50091 +:10351000EDE0EAEEEFEBE5EDE8FF20E220F1ECE58F +:10352000EDE50000EDE5E2E5F0EDFBE920F0E5E397 +:103530002EEDEEECE5F00000EDE0EAEEEF2EEFEE22 +:1035400020F1E5EAF6E8FFEC00000000EDE0EAEE2D +:10355000EF2EEFEE20F1EAE8E4EAE0EC00000000F4 +:10356000E4E8E0EFE0E7EEEDE020F1EAE8E4EEEA9F +:1035700000000000E4E8E0EFE0E7EEEDE020EEEF31 +:10358000EBE0F2FB00000000E4E8E0EFE0E7EEED46 +:10359000E020EEEFEBE0F2FB20320000E4E8E0EFA9 +:1035A000E0E7EEEDE020EEEFEBE0F2FB2033000091 +:1035B000E4E8E0EFE0E7EEEDE020EEEFEBE0F2FB39 +:1035C00020340000ECE5EDFCF8E520E8F2EEE3E065 +:1035D00020F7E5EAE0000000EDE0EBE8F7EDEEF1C2 +:1035E000F2E820E220EAE0F1F1E50000EEEFE5F09C +:1035F000E0F6E8FF20EDE5E2EEE7ECEEE6EDE000D8 +:10360000EDE0EAEEEF2EEFEE20EDE0EBEEE3E0ECA6 +:1036100000000000E1E5E7EDE0EB2EF1F3ECECE07B +:1036200020E1EEEBFCF8E500EFF0E5E2FBF1E8EB82 +:10363000E020323420F7E0F1E0000000EDE0EAEEB7 +:10364000EFEBE5EDE8E920E220F1ECE5EDE5000047 +:10365000EEF8E8E1EAE020EAEEEB2DE2E020F1EC22 +:10366000E5ED0000EAEEECE0EDE4FB20EFF0EEE447 +:10367000EEEBE6E5EDE8FF00EEF2EAF0FBF220E427 +:10368000F0F3E3E8EC20EEEF2E000000E4E8E0EFDA +:10369000E0E7EEEDE020EDE0E4E1E0E2EEEA00005C +:1036A000E4E8E0EFE0E7EEEDE020EAEEEB2DE2E02B +:1036B00000000000E4E8E0EFE0E7EEEDE020EEF2ED +:1036C000E4E5EBE000000000E4E5EDE5E320EFEEEB +:1036D00020EDE0EBEEE3E0EC00000000EFEE20E296 +:1036E000FBEFEBE0F2E520E220F1ECE5EDE5000098 +:1036F000EFEE20E2EEE7E2F0E0F2E0EC20EFF0EEB9 +:10370000E4E0E600EFEE20E2EDE5F1E5EDE8FE2095 +:10371000E220F1ECE5EDE500EFEE20EDE0E4E1E0A4 +:10372000E2EAE0EC20E220F7E5EAE500EFEE20F146 +:10373000EAE8E4EAE0EC20E220F7E5EAE500000050 +:10374000E8F2EEE320F1EAE8E4EAE820E220F7E537 +:10375000EAE50000F0E0E7ECE5F020E220EDE0F142 +:10376000F2F0EEE9EAE0F500E3F0E0EDE8F6F32050 +:10377000EFEEEBFF20EFE5F7E0F2E800CEC7D32055 +:10378000EFF0EEF8EBEE20F3F1EFE5F8EDEE0000F0 +:10379000E2F0E5EC2EF0E5F1F3F0F120DDCACBC765 +:1037A00000000000CFE5F0E5EFEEEBEDE5EDE8E53C +:1037B00020EAEEEB2DE2E000CFE5F0E5EFEEEBEDF9 +:1037C000E5EDE8E520F1F3ECECFB0000D3E6E520C5 +:1037D000E0EAF2E8E2E8E7E8F0EEE2E0EDE000003F +:1037E000E8F2EEE3EEE220F7E5EAE020E820DDCAC9 +:1037F000CBC700004B617373657461207A61706F91 +:103800006C6E656E610000004B61737365746120BE +:103810006F74737574737476756574004F7368692B +:10382000626B6120737679617A6920732046520059 +:10383000CFE0F3E7E020EFEEF1EBE52CECE8ED2E46 +:1038400000000000CFE5F7E0F2FC20EEF2F72EE8F2 +:10385000E720E1F3F42E0000CEF8E8E1EAE020EE04 +:10386000F2EFF02E652D6D61696C0000452D6D61E4 +:10387000696C20EEF2EFF02EF3F1EFE5F8EDEE00DB +:10388000207C2020566E6573656E61206B757075A7 +:1038900072612000207C2020566E6573656E792051 +:1038A0006D6F6E6574792000207C20204E61636806 +:1038B000616C6F207365616E73612000207C202035 +:1038C0004B6F6E65F1207365616E736120000000BF +:1038D000207C2020506563686174272063686563DD +:1038E0006B612000207C2020536D656E6120726525 +:1038F0006A696D6120000000207C2020496E6361B0 +:10390000737361636979612000000000207C2020CE +:103910004E657420736F62797469796120000000CC +:10392000C2E2EEE420ECE0F1F2E5F02DEFE0F0EEA3 +:10393000EBFF00002D2D2D2D2D2D2D2D2D2D2D2D81 +:103940002D2D2D2D2D2D2D002D2D2D2D2D2D2D2DD4 +:103950002D2D2D2D2D2D2D2D2D2D2D00FC56010025 +:103960000857010014570100205701000000000013 +:103970002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D77 +:103980002D2D2D002020202020C2CDC8CCC0CDC898 +:10399000C52020202020000020202020C8CDCAC023 +:1039A000D1D1C0D6C8DF2020202000003857010028 +:1039B00044570100505701005C570100000000000F +:1039C00074570100805701008C570100985701007F +:1039D00000000000D1C5D0C2C8D120E2E5F02ECF52 +:1039E000CE2030332E323500CEF7E8F1F2EAE02077 +:1039F000F1F2E0F2E8F1F2E8EAE80000D1D2C0D258 +:103A0000C8D1D2C8CAC820C2C2C5C4C8D2C5000065 +:103A100020C6D3D0CDC0CBCEC220C2C2C5C4C8D26E +:103A2000C5000000C4580100D0580100DC58010056 +:103A3000E858010000000000005901000C59010085 +:103A4000185901002459010000000000CACED0CE50 +:103A5000D2CAC8C520D1D7C5D2D7C8CAC8000000AD +:103A60003C590100485901005459010060590100B6 +:103A700000000000C4CBC8CDCDDBC520D1D7C5D256 +:103A8000D7C8CAC800000000785901008459010055 +:103A9000905901009C59010000000000D3F1F2E0B0 +:103AA000EDEEE2EAE020EFE0F0EEEBFF00000000D8 +:103AB000D3F1F2E0EDEEE2EAE020E2F0E5ECE5ED54 +:103AC000E80000002020C2C2C5C4C8D2C520D2C5AB +:103AD000CAD3D9C8E900000020CDC0D1D2D0CEC50C +:103AE000CA20C2C2C5C4C8D2C5000000CDC0D1D250 +:103AF000D0CEE9CAC820CCCECDC5D2CECFD02E00F4 +:103B000020CDC0D1D2D0CEE9CAC820CCCEC4C5CC3D +:103B1000C0000000205D01002C5D0100385D010047 +:103B2000445D01000000000020CDE5E2E5F0EDFB82 +:103B3000E920EFE0F0EEEBFC00000000745D010016 +:103B40005C5D0100685D0100745D01000000000023 +:103B5000202020D3F1F2E0EDEEE2EBE5EDFB2020BA +:103B6000000000008C5D0100985D0100A45D010073 +:103B7000B05D010000000000E05D0100C85D0100D3 +:103B8000D45D0100E05D010000000000105E010056 +:103B9000F85D0100045E0100105E010000000000FD +:103BA000CFD0CED1CCCED2D020C6D3D0CDC0CBCEEC +:103BB000C2000000CEF7E8F1F2EAE020E6F3F0ED13 +:103BC000E0EBEEE200000000285E0100345E010040 +:103BD000405E01004C5E0100000000005A2DEEF234 +:103BE000F7E5F220E8E720E1F3F4E5F0E00000007B +:103BF000645E0100705E01007C5E0100885E010071 +:103C000000000000CDE0EFE5F7E0F2E0F2FC20F18B +:103C1000F3F2EEF7EDFBE900EEF2F7E5F220E1E575 +:103C2000E720E3E0F8E5EDE8FF3F0000C4C02D53D6 +:103C30005441525420202053544F502DCDC5D20012 +:103C4000A05E0100AC5E0100B85E0100C45E010030 +:103C500000000000CDE0EFE5F7E0F2E0F2FC20F13B +:103C6000F3F2EEF7EDFBE900EEF2F7E5F220F120DA +:103C7000E3E0F8E5EDE8E5EC3F000000DC5E010084 +:103C8000E85E0100F45E0100005F0100000000003A +:103C9000205A2DCED2D7C5D2DB20C8C720C1D3D45D +:103CA000C5D0C000CDE0EFE5F7E0F2E0F2FC20F196 +:103CB000F3F2EEF7EDFBE50020EEF2F7E5F2FB2084 +:103CC000E8E720E1F3F4E5F0E03F0000185F0100D1 +:103CD000245F0100305F0100C45E010000000000AD +:103CE000EFE5F7E0F2FC20EDE5E2EEE7ECEEE6EDE5 +:103CF000E0000000785F0100845F0100905F010038 +:103D00009C5F010000000000B45F0100C05F010083 +:103D1000CC5F0100D85F010000000000D3D1D2C009 +:103D2000CDCEC2CAC020C2D0C5CCC5CDC80000000F +:103D30002020CEC1D9C0DF20D1D2C0D2C8D1D2C8B4 +:103D4000CAC00000CAEEF0EEF2EAE8E520F1F7E5BD +:103D5000F2F7E8EAE8000000C4EBE8EDEDFBE5204F +:103D6000F1F7E5F2F7E8EAE80000000020D1D2C060 +:103D7000D22DCAC020CFCE20CAC0CDC0CBC0CC006F +:103D8000806001008C60010098600100A460010067 +:103D9000000000005B736D74705F70617373776F08 +:103DA00072645D3D000000005E534953573A202580 +:103DB000642C2025642C2025640000007C20202514 +:103DC00032642020207C2025313164200000000056 +:103DD00053797374656D6E6F65207672656D796168 +:103DE0003A2000005672656D796120696E636173D7 +:103DF00073616369693A20000D0A0D0A53756D6D90 +:103E000061202564207275622E0D0A002020D1D316 +:103E1000CCCCC020257520F0F3E12E00C2EDE5F1F9 +:103E2000E8F2E520E4E5EDFCE3E80000CFF0E8EDA2 +:103E3000FFF2EE20256420F0F3E12E00CDC5C4CEC4 +:103E4000D1D22EC4C5CDC5C300000000CAD3CFDE79 +:103E5000D0CECFD0C8C5CCCDC8CAC000CDC5D22029 +:103E6000D1C2DFC7C820D120D4D00000C2CEC762E3 +:103E7000CCC8D2C520D7C5CA00000000CDC5D2200D +:103E8000C2CACBDED7C5CDCDDBD50000C4CE20D194 +:103E9000CBC5C42ED1C5C0CDD1C03A00C2DBC1C58F +:103EA000D0C8D2C520CAC0CDC0CB0000523020201F +:103EB0003A203078253038780A000000523120202E +:103EC0003A203078253038780A000000523220201D +:103ED0003A203078253038780A000000523320200C +:103EE0003A203078253038780A00000052342020FB +:103EF0003A203078253038780A00000052352020EA +:103F00003A203078253038780A00000052362020D8 +:103F10003A203078253038780A00000052372020C7 +:103F20003A203078253038780A00000052382020B6 +:103F30003A203078253038780A00000052392020A5 +:103F40003A203078253038780A000000523130208D +:103F50003A203078253038780A000000523131207C +:103F60003A203078253038780A000000523132206B +:103F70003A203078253038780A000000535020204D +:103F80003A203078253038780A0000004C52202042 +:103F90003A203078253038780A000000504320203D +:103FA0003A203078253038780A00000043505352C8 +:103FB0003A203078253038780A000000EEF8E8E141 +:103FC000EAE020F1E2FFE7E820F10000EEF8E8E1A6 +:103FD000EAE020F0E0E1EEF2FB000000EA2FEF3A29 +:103FE0003431682DEAE0F1F1E5F2E000EA2FEF3A32 +:103FF0003432682DEAE0F1F1E5F2E000EA2FEF3A21 +:104000003434682DE7E0ECE8ED000000EA2FEF3AE9 +:104010003435682DEFEEEFFBF2EAE000EA2FEF3ADD +:104020003530682DEEF8E8E1EAE00000EA2FEF3ADB +:104030003532682DEEF8E8E1EAE00000EA2FEF3AC9 +:104040003534682DEAE0F1F1E5F2E000EA2FEF3ACD +:104050003635682DEEF8E8E1EAE00000EA2FEF3AA5 +:104060003636682DEEF8E8E1EAE00000D4D03A30C8 +:1040700038682DEAEEECE0EDE4E00000D4D03A3010 +:1040800039682DEDE5EAEEF0F02E0000D4D03A319B +:1040900035682DD1ECE5EDE000000000D4D03A31D8 +:1040A00036682DD1ECE5EDE000000000D4D03A32C6 +:1040B00034682DCEE1EBE0F1F2FC0000D4D03A33CD +:1040C00037682DCAEEECE0EDE4E00000D4D03A33DE +:1040D00043682DDDCACBC73A00000000D4D03A3483 +:1040E00035682D43F3ECECE000000000D4D03A3406 +:1040F00044682DC2EDEEF1E8ECE0FF00D4D03A3494 +:1041000045682DD1ECE5EDE000000000D4D03A3553 +:1041100036682DCDE5F220E4EEEA2E00D4D03A3513 +:1041200037682DDDCACBC73A00000000D4D03A353D +:1041300038682DCEE6E8E4E0EDE8E500D4D03A3585 +:1041400039682DC4EEEAF3ECE5EDF200D4D03A354F +:1041500043682DCFEEEDE8E6E5EDEE00D4D03A353C +:1041600044682DD2E0E1EBE8F6E00000D4D03A3527 +:1041700046682DCEF2F0E8F62E000000D4D03A3694 +:1041800041682DCEF8E8E1EAE0000000D4D03A37EB +:1041900031682DCEF8E8E1EAE0000000D4D03A37EB +:1041A00035682DCEF8E8E1EAE0000000D4D03A37D7 +:1041B00036682DCFF0E8EDF2E5F03A00D4D03A378A +:1041C00037682DCFF0E8EDF2E5F03A00D4CF3A377A +:1041D00041682DCFEEEBE520EDE50000D4D03A3775 +:1041E00042682DCEF8E8E1EAE0000000D4D03A378A +:1041F00044682DCDE5E2E5F0EDFBE900D4D03A3797 +:1042000045682DCDE5E2E5F0EDEEE500D4D03A3895 +:1042100030682DCEF8E8E1EAE0000000D4D03A386A +:1042200031682DCEF8E8E1EAE0000000D4D03A3859 +:1042300032682DCEF8E8E1EAE0000000D4D03A3848 +:1042400033682DCEF8E8E1EAE0000000D4D03A3837 +:1042500043682DCEF2F0E8F62E000000D4D03A38B4 +:1042600046682DCAE0F1F1E020EDE500D4D03A39FE +:1042700031682DC2FBF5EEE420E7E000D4D03A39F6 +:1042800034682DC8F1F7E5F0EFE0ED00D4D03A4105 +:1042900032682DDDCACBC73A20000000D4D03A41A5 +:1042A00036682DC8F1F7E5F0EFE0ED00D4D03A41E3 +:1042B00038682DC7CACBC73A00000000D4D03A41B5 +:1042C00039682DDDCACBC73A00000000D4D03A428D +:1042D00030682DDDCACBC73A00000000D4D03A4286 +:1042E00031682DDDCACBC73A00000000D4D03A4275 +:1042F00032682DDDCACBC73A00000000D4D03A4363 +:1043000030682DCAEEEDF2F0EEEBFC00D4D03A436B +:1043100031682DDDCACBC73A00000000EAF3EFFE9A +:10432000F0EEEFF0E8E5ECEDE8EAE000EFEE20EC8F +:10433000E0E32EE4E0F2F7E8EAF30000EFF0E82033 +:10434000F2F0E0EDF1EFEEF0F22E0000EFEE20E201 +:10435000E5F0E8F4E8EAE0F6E8E82000EAF3EFFE4A +:10436000F0EEEFF0E8E5ECEDE8EAE500E2FBF0E086 +:10437000E2EDE8E2E0EDE8FF00000000E220EAEE16 +:10438000ECE0EDE4E520EA20D4CF0000E2FBE2EE31 +:10439000E4E020E4E0EDEDFBF5000000E220EAEED1 +:1043A000ECE0EDE4E520D4CF00000000E4EBE8ED24 +:1043B000E020EAEEECE0EDE4FB200000EDEEECE5C1 +:1043C000F020EDE520E2E2E5E4E5ED00EFEEE2F0DD +:1043D000E5E6E42E20E7E0EFE8F1FC00E0EAF22E6B +:1043E000EFE5F0E5EFEEEBEDE5EDE000EDE520EFDC +:1043F000EEE4E4E5F0E62ED4D0000000EEF8E8E1CB +:10440000EAE020CFCE20D4D000000000EFF0E5E4B9 +:104410002EEAEEECE0EDE4FB00000000EDE0EFF052 +:10442000FFE6E5EDE8E5203234C20000EDE520EEE0 +:10443000EFF0E5E4E5EBE5EDE0000000EFF0E8206B +:10444000F3ECEDEEE6E5EDE8E8000000E4E8E0EF8F +:10445000E0E7EEEDE020F6E5EDFB0000E4E5EDE55C +:10446000E320E220F1E5EAF6E8E80000E4E5EDE526 +:10447000E320EFEE20EDE0EBEEE3F300EDE5F220DC +:10448000E8ECEFF3EBFCF1EEE2000000F0E5E4E035 +:10449000EAF2E8F0F3E5F2F1FF000000EEE1EEF001 +:1044A000F3E4EEE2E0EDE8FF00000000E8F2EEE306 +:1044B00020EDE0E4E1E0E2EAE8000000F4E8F1EAFF +:1044C000E0EBE8E7E8F0EEE2E0EDE000F1EEF1F23B +:1044D000EEFFEDE8E520DDCACBC70000E220F1EEFB +:1044E000F1F2E0E2E520DDCACBC70000E4E0F2FB38 +:1044F00020E820E2F0E5ECE5EDE80000F1F3F2EE73 +:10450000F7EDFBE920EEF2F7E5F20000EDEEECE569 +:10451000F0EEE220F1ECE5ED000000005A616D697B +:104520006E2076206B61737365746500506F7079CF +:10453000746B61206F626D616E6100004F7368691A +:10454000626B61206F7074696B6900004F736869FA +:10455000626B612046522030783031004F736869B9 +:10456000626B612046522030783032004F736869A8 +:10457000626B612046522030783033004F73686997 +:10458000626B612046522030783034004F73686986 +:10459000626B612046522030783035004F73686975 +:1045A000626B612046522030783036004F73686964 +:1045B000626B612046522030783037004F73686953 +:1045C000626B612046522030783038004F73686942 +:1045D000626B612046522030783039004F73686931 +:1045E000626B612046522030783041004F73686919 +:1045F000626B612046522030783042004F73686908 +:10460000626B612046522030783131004F73686907 +:10461000626B612046522030783132004F736869F6 +:10462000626B612046522030783133004F736869E5 +:10463000626B612046522030783134004F736869D4 +:10464000626B612046522030783135004F736869C3 +:10465000626B612046522030783136004F736869B2 +:10466000626B612046522030783137004F736869A1 +:10467000626B612046522030783138004F73686990 +:10468000626B612046522030783139004F7368697F +:10469000626B612046522030783141004F73686967 +:1046A000626B612046522030783142004F73686956 +:1046B000626B612046522030783143004F73686945 +:1046C000626B612046522030783144004F73686934 +:1046D000626B612046522030783146004F73686922 +:1046E000626B612046522030783230004F73686927 +:1046F000626B612046522030783231004F73686916 +:10470000626B612046522030783232004F73686904 +:10471000626B612046522030783233004F736869F3 +:10472000626B612046522030783234004F736869E2 +:10473000626B612046522030783235004F736869D1 +:10474000626B612046522030783238004F736869BE +:10475000626B612046522030783333004F736869B2 +:10476000626B612046522030783335004F736869A0 +:10477000626B612046522030783336004F7368698F +:10478000626B612046522030783337004F7368697E +:10479000626B612046522030783338004F7368696D +:1047A000626B612046522030783339004F7368695C +:1047B000626B612046522030783341004F73686944 +:1047C000626B612046522030783343004F73686932 +:1047D000626B612046522030783345004F73686920 +:1047E000626B612046522030783346004F7368690F +:1047F000626B612046522030783430004F73686914 +:10480000626B612046522030783431004F73686902 +:10481000626B612046522030783432004F736869F1 +:10482000626B612046522030783433004F736869E0 +:10483000626B612046522030783434004F736869CF +:10484000626B612046522030783435004F736869BE +:10485000626B612046522030783436004F736869AD +:10486000626B612046522030783437004F7368699C +:10487000626B612046522030783438004F7368698B +:10488000626B612046522030783441004F73686972 +:10489000626B612046522030783442004F73686961 +:1048A000626B612046522030783443004F73686950 +:1048B000626B612046522030783444004F7368693F +:1048C000626B612046522030783445004F7368692E +:1048D000626B612046522030783446004F7368691D +:1048E000626B612046522030783530004F73686922 +:1048F000626B612046522030783531004F73686911 +:10490000626B612046522030783532004F736869FF +:10491000626B612046522030783533004F736869EE +:10492000626B612046522030783534004F736869DD +:10493000626B612046522030783536004F736869CB +:10494000626B612046522030783537004F736869BA +:10495000626B612046522030783538004F736869A9 +:10496000626B612046522030783539004F73686998 +:10497000626B612046522030783542004F7368697F +:10498000626B612046522030783543004F7368696E +:10499000626B612046522030783544004F7368695D +:1049A000626B612046522030783545004F7368694C +:1049B000626B612046522030783546004F7368693B +:1049C000626B612046522030783630004F73686940 +:1049D000626B612046522030783631004F7368692F +:1049E000626B612046522030783632004F7368691E +:1049F000626B612046522030783633004F7368690D +:104A0000626B612046522030783634004F736869FB +:104A1000626B612046522030783635004F736869EA +:104A2000626B612046522030783636004F736869D9 +:104A3000626B612046522030783637004F736869C8 +:104A4000626B612046522030783638004F736869B7 +:104A5000626B612046522030783639004F736869A6 +:104A6000626B612046522030783641004F7368698E +:104A7000626B612046522030783642004F7368697D +:104A8000626B612046522030783643004F7368696C +:104A9000626B612046522030783644004F7368695B +:104AA000626B612046522030783645004F7368694A +:104AB000626B612046522030783646004F73686939 +:104AC000626B612046522030783730004F7368693E +:104AD000626B612046522030783731004F7368692D +:104AE000626B612046522030783732004F7368691C +:104AF000626B612046522030783733004F7368690B +:104B0000626B612046522030783734004F736869F9 +:104B1000626B612046522030783735004F736869E8 +:104B2000626B612046522030783736004F736869D7 +:104B3000626B612046522030783737004F736869C6 +:104B4000626B612046522030783738004F736869B5 +:104B5000626B612046522030783739004F736869A4 +:104B6000626B612046522030783741004F7368698C +:104B7000626B612046522030783742004F7368697B +:104B8000626B612046522030783743004F7368696A +:104B9000626B612046522030783744004F73686959 +:104BA000626B612046522030783745004F73686948 +:104BB000626B612046522030783746004F73686937 +:104BC000626B612046522030783830004F7368693C +:104BD000626B612046522030783831004F7368692B +:104BE000626B612046522030783832004F7368691A +:104BF000626B612046522030783833004F73686909 +:104C0000626B612046522030783834004F736869F7 +:104C1000626B612046522030783835004F736869E6 +:104C2000626B612046522030783836004F736869D5 +:104C3000626B612046522030783837004F736869C4 +:104C4000626B612046522030783838004F736869B3 +:104C5000626B612046522030783839004F736869A2 +:104C6000626B612046522030783841004F7368698A +:104C7000626B612046522030783842004F73686979 +:104C8000626B612046522030783843004F73686968 +:104C9000626B612046522030783844004F73686957 +:104CA000626B612046522030783845004F73686946 +:104CB000626B612046522030783846004F73686935 +:104CC000626B612046522030783930004F7368693A +:104CD000626B612046522030783931004F73686929 +:104CE000626B612046522030783932004F73686918 +:104CF000626B612046522030783933004F73686907 +:104D0000626B612046522030783934004F736869F5 +:104D1000626B612046522030784130004F736869E1 +:104D2000626B612046522030784131004F736869D0 +:104D3000626B612046522030784132004F736869BF +:104D4000626B612046522030784133004F736869AE +:104D5000626B612046522030784134004F7368699D +:104D6000626B612046522030784135004F7368698C +:104D7000626B612046522030784136004F7368697B +:104D8000626B612046522030784137004F7368696A +:104D9000626B612046522030784138004F73686959 +:104DA000626B612046522030784139004F73686948 +:104DB000626B612046522030784141004F73686930 +:104DC000626B612046522030784230004F73686930 +:104DD000626B612046522030784231004F7368691F +:104DE000626B612046522030784232004F7368690E +:104DF000626B612046522030784330004F736869FF +:104E0000626B612046522030784331004F736869ED +:104E1000626B61204652203078433200D3F1EBF3CD +:104E2000E3E820F1EEEBFFF0E8FF0000CACED02E61 +:104E3000D1D72ECAC0CDC0CB00000000CEF2EFF01B +:104E40002EE6F3F0EDE0EBFB00000000C8E3EDEE32 +:104E5000F0E8F02EEEF82ED4D0000000CFE0F3E71B +:104E6000E020E4EE2CF1E5EA2E000000C7E020E2AD +:104E7000F0E5ECFF2CECE8ED2E000000C7E020E2AE +:104E8000F0E5ECFF2CECE8ED2E000000202020CD1A +:104E9000CECCC8CDC0CB202300000000C7EDE0F78A +:104EA000E5EDE8E52CF0F3E12E000000D3F1EBF3A3 +:104EB000E3E820F1EEEBFFF0E8FF0000CFE5F7E0DC +:104EC000F2FC205A2DEEF2F7E5F2E000CFE5F7E034 +:104ED000F2FC20582DEEF2F7E5F2E000D1ECE5ED22 +:104EE000E020F0E5E6E8ECE000000000CDE5E2E5DA +:104EF000F0EDFBE920EFE0F0EEEBFC00207C202061 +:104F0000566B6C756368656E696520006E6574200C +:104F10007A61706973690D0A00000000D6E5EDFB47 +:104F200020E220E1F3E4EDE800000000D6E5EDFB2F +:104F300020E220E2FBF5EEE4EDFBE5002020C8E4F2 +:104F4000E5F220EFF0EEE2E5F0EAE0002020EEE10D +:104F5000EEF0F3E4EEE2E0EDE8FF21002020202077 +:104F6000C220E6F3F0EDE0EBE5000000202020E7B2 +:104F7000E0EFE8F1E5E920EDE5F200002020202057 +:104F8000D1D2C0D2C8D1D2C8CAC00000D1F7E5F290 +:104F9000F7E8EAE820EAF3EFFEF00000202020C462 +:104FA000CBDF20CED7C8D1D2CAC8000064580100D8 +:104FB000705801007C58010000000000202020C42F +:104FC000CBDF20CED7C8D1D2CAC800009458010088 +:104FD000A0580100AC580100000000002020202053 +:104FE000CDC0D1D2D0CEE9CAC8000000CEE1EEF0EB +:104FF000F3E4EEE2E0EDE8E500000000D1E1F0EEE0 +:10500000F120EDE0F1F2F0EEE5EA0000EC5A0100EB +:10501000F85A0100045B010000000000C2C2C5C4D0 +:10502000C8D2C520CCC0D1D2C5D02D002020202090 +:10503000C4CBDF20D1C1D0CED1C000004C5B010079 +:10504000585B0100645B0100000000002020C2C228 +:10505000C5C4C8D2C520CDCEC2DBE900202020CEF9 +:10506000C1CED0D3C4CEC2C0CDC8C500CCEEEDE514 +:10507000F2EEEFF0E8E5ECEDE8EA0000202020CDCC +:10508000C0D1D2D0CEE9CAC820D4D000905C0100F3 +:105090009C5C0100A85C0100000000002020202092 +:1050A00020CEF8E8E1EAE0200000000020202020E7 +:1050B000E7E0E2EEE4F1EAE8E5200000202020202D +:1050C00020E7EDE0F7E5EDE8FF00000020202020DC +:1050D000EFE0F0E0ECE5F2F0EEE20000202020202E +:1050E000D1F2E0F2E8F1F2E8EAE00000202020202E +:1050F00020EEF7E8F9E5EDE0000000002020202098 +:1051000020C6F3F0EDE0EBFB200000002020202083 +:1051100020EEF7E8F9E5EDFB00000000C6F3F0ED46 +:10512000E0EB20EEF8E8E1EEEA000000C6F3F0ED77 +:10513000E0EB20F1EEE1FBF2E8E900002020202086 +:105140002020CED2D7C5D2DB0000000020202020B6 +:1051500020582DCED2D7C5D200000000202020201C +:10516000205A2DCED2D7C5D200000000202020D456 +:10517000D020EEF2EAEBFEF7E5ED0000485F01001B +:10518000545F0100605F010000000000206001002A +:105190002C60010038600100000000005060010038 +:1051A0005C60010068600100000000005B61705FEE +:1051B00070617373776F72645D3D00005B736D7433 +:1051C000705F757365725D3D000000005B736D7408 +:1051D000705F6D61696C5D3D000000005B736D7414 +:1051E000705F7365727665725D3D00005B736D7410 +:1051F000705F706F72745D3D0000000041542B437E +:105200004D47523D25640D0A000000005E5349538E +:10521000573A20302C20310D0A00000041545E53D3 +:105220004953573D302C25640D0A000041545E530C +:105230004953573D302C302C310D0A005E534953F1 +:10524000573A20302C20320D0A00000025303264FD +:105250003A253032643A25303264000025643A251C +:105260003032643A2530326400000000001F1C1FF9 +:105270001E1F1E1F1F1E1F1E1F00000002000C34D9 +:105280000000000000000000CEC6C8C4C0CDC8C5E4 +:1052900000000000C2CACBDED7C5CDC8DF000000C9 +:1052A000CCC0CAD12ED1C5C0CDD10000C0CFCF2E29 +:1052B000C3CED2CEC2000000CDC5D220D1C2DFC73E +:1052C000C8000000CED8C8C1CAC020D4D000000099 +:1052D000D1CFC0D1C8C1CE20C7C00000CFCEC6C07C +:1052E000CBD3E9D1D2C00000CAC0CDC0CBCEC22141 +:1052F00000000000CED1D2C0CBCED1623A20000057 +:10530000C820CDC0C6CCC8D2C5200000253032642C +:105310003A25303264000000CEF82EEAEEEDF42E8D +:1053200000000000CDE5F220F1E2FFE7E800000018 +:10533000D4D03A3035682DEDE5F20000D4D03A31C2 +:1053400034682DD4CF000000D4D03A3143682DC545 +:10535000F1F2FC00D4D03A3235682DCDE5F20000F0 +:10536000D4D03A4131682DDDCACBC700D4D03A4100 +:1053700037682DDDCACBC700EFF0E820E7E0ECE8A6 +:10538000EDE50000EFEE20E7E0EFF0E5F2F30000DE +:10539000EFEE20E4EBE8EDE500000000E7E0EFEEE3 +:1053A000EBEDE5EDE0000000EEF2F1F3F2F1F2E2F8 +:1053B000F3E5F200E220EAE0F1F1E5F2E5000000B9 +:1053C000ECE0E32EE4E0F2F7E8EAE000F1E2FFE7E8 +:1053D000E820F120D4D00000EDE520EFEEE4E42E4B +:1053E000D4CF0000EFE0ECFFF2E820D4CF000000C3 +:1053F000EBE8F6E5EDE7E8FF00000000EFE5F0E59B +:10540000EFEEEBEDE5EDE000F3E6E520EEF2EAF09D +:10541000FBF2E000EDE520EEF2EAF0FBF2E0000046 +:10542000E0EAF2E8E2E8E7E0F6E8E800EFE0F0E0E2 +:10543000ECE5F2F000000000EFE0F0E0ECE5F2F067 +:10544000FB000000E8F2EEE3E020F7E5EAE0000010 +:10545000EFE5F0E5EFEEEBEDE5ED0000E4EBFF202E +:10546000EFEEE2F2EEF0E000EEEFE5F0E0F6E8FF5E +:1054700000000000E8F2EEE320F7E5EAE0000000BB +:10548000EEF2F0E5E7F7E8EAE0000000EFEEE4E432 +:10549000E5F0E62E00000000EDE5F220F1E8E3ED96 +:1054A000E0EBE000F4EEF0ECE0F220E4E0F2FB00F0 +:1054B000F1E2FFE7E820F120D4CF0000EDE0EBE8D7 +:1054C000F7EDEEF1F2E80000EFEE20EFF0EEE4E0B1 +:1054D000E6E0EC00EFEE20EFEEEAF3EFEAE0EC00BE +:1054E000EDE0EFF0FFE6E5EDE8FF00004E6574202B +:1054F0006F736869626B690020202020CAC0CDC02C +:10550000CB000000C4CB2ED1D72ECAC0CDC0CB005B +:10551000D1EEF1F2EEFFEDE8E5000000CDE0E7E2CC +:10552000E0EDE8E500000000D3F1F2F0EEE9F1F281 +:10553000E2EE0000CAF3EFFEF0EEEFF02DEA00001D +:10554000CEEFEEE22EEEE120EEF82E00CEF72EE6C4 +:10555000F3F0EDE0EBFB0000CCEEEDE5F2EEEFF06A +:105560002DEA0000D0F3E12E2FE8ECEF2E00000032 +:10557000C2F02EF0E0E1EEF2FB000000546D617825 +:105580002CECE8ED2E000000546D696E2CECE8ED7B +:105590002E000000C2FBF5EEE4EDFBE53A00000052 +:1055A000CEF2EBEEE62EF1F2E0F0F200D6E5EDE021 +:1055B0002CF0F3E12E000000D6E5EDE02CF0F3E155 +:1055C0002E000000CDE0F7E0EBEE2CF7000000002D +:1055D000CDE0F7E0EBEE2CF700000000C7E0EFE8CD +:1055E000F1FC202300000000C7E0EFE8F1FC2023DD +:1055F00000000000C4E5EDFCE3E82CF0F3E12E0030 +:10560000C7E0EAF02EF1ECE5EDFB0000EAEEEB2D51 +:10561000E2EE2AF6E5EDE0002020CFC0D0CECB624E +:105620000000000020202020CFC0D0CECB620000A0 +:10563000202020CFC0D0CECB62000000CEF2EFF011 +:105640002EF2E5F1F2000000C2F1E5E3EE20EAF30C +:10565000EFFEF000494420F3F1F22DE2E0000000FB +:10566000C2ED2EEAF3EFFEF0E0200000C2ED2EECDA +:10567000EEEDE5F2FB200000CDE0F72EF1E5E0EDE8 +:10568000F1E02000CAEEED2EF1E5E0EDF1E02000C2 +:10569000C2EAEBFEF7E5EDE8E5000000CFE5F7E054 +:1056A000F2FC20F7E5EAE000C8EDEAE0F1F1E0F60F +:1056B000E8FF00006B616E616C2025642000000033 +:1056C0006E617374726F696B610000002530326423 +:1056D0003A25303264000000000103040607090A7D +:1056E0000C0D0F10EAE0EDE0EB2025640000000057 +:1056F000EDE0F1F2F0EEE9EAE00000000000000069 +:105700003439010000000000000000003C4F01009F +:1057100000000000000000004C4F010000000000ED +:105720000000000048390100000000005C39010061 +:1057300000000000040100000000000070390100BA +:10574000000000000000000084390100000000009B +:105750000000000098390100000000000000000077 +:105760007454004000000000AC390100000000004B +:105770000401000000000000A56501000000000019 +:10578000000000005C4F010000000000000000006D +:105790006C4F01000000000000000000A665010041 +:1057A00000000000C03901000000000004010000FA +:1057B000CDE0F1F2F0EEE9EAE8000000D1F2E0F22B +:1057C000E8F1F2E8EAE0000000010000D43901004D +:1057D0000000000001000000B0570100085A01005D +:1057E00001000000BC5701005858010001000000F2 +:1057F00070640100585E010001000000786401003F +:10580000945E0100B02301000000000005000000CC +:10581000CFEE20EAE0EDE0EBE0EC0000000100005C +:105820007C4F010000000000010000001058010042 +:105830007460010001000000806401004460010008 +:10584000010000008C4F01003059010001000000F0 +:10585000E839010088580100C82301000000000059 +:1058600005000000000100009C4F01000000000046 +:1058700000010000FC3901000000000002000000EF +:105880007818010000000000AC4F01001D820000EC +:105890000300000000010000BC4F010000000000F8 +:1058A00000010000103A01000000000002000000AA +:1058B0007818010000000000CC4F01001D8200009C +:1058C0000300000002030000E80B010000000000DC +:1058D0000200000078150100000000000200000036 +:1058E000A81501000000000002000000D81501000A +:1058F00000000000243A0100000000000401000044 +:1059000002030000D818010000000000020000009F +:105910000819010000000000020000003819010011 +:1059200000000000020000006819010000000000F3 +:10593000383A010025820000040100000001000047 +:105940004C3A010000000000020000005814010061 +:1059500000000000020000008814010000000000A8 +:1059600002000000B814010000000000603A0100CD +:10597000000000000401000000010000743A010072 +:105980000000000002000000E81401000000000018 +:1059900002000000181501000000000002000000D5 +:1059A0004815010000000000883A010000000000D6 +:1059B0000401000000010000DC4F010000000000B5 +:1059C0000100000088640100985A010001000000F5 +:1059D000EC4F0100305C0100010000009C3A010026 +:1059E000105B010001000000B03A010014600100EA +:1059F00001000000FC4F0100705B0100020000008C +:105A0000D80C010000000000641E0100000000002E +:105A10000700000002030000B80B010000000000B6 +:105A200002000000780C01000000000002000000ED +:105A3000A80C01000000000002000000480F010057 +:105A40000000000002000000780F010000000000CC +:105A500002000000D80F010000000000020000005A +:105A6000A80F010000000000020000000810010063 +:105A700000000000020000003810010000000000DB +:105A8000010000001C4F0100E05A0100010000006D +:105A90002C4F0100E85B0100581A01002D82000024 +:105AA0000B0000000203000098100100000000003D +:105AB0000200000088110100000000000200000048 +:105AC000B81101000000000002000000F810010001 +:105AD000000000000200000058110100000000005A +:105AE000E0230100498200000500000000010000E1 +:105AF000C43A01000000000002000000E8170100A5 +:105B0000000000000100000020390100405B01009E +:105B10000C5001005D820000030000000001000045 +:105B20001C500100000000000200000048180100A5 +:105B3000000000001C5B0100285B01000000000069 +:105B4000345B01005D8200000300000000010000E2 +:105B50002C5001000000000000010000D83A0100B4 +:105B60000000000002000000181801000000000002 +:105B70003C500100658200000300000000010000AD +:105B80004C500100000000000200000088170100D6 +:105B9000000000007C5B0100885B01000000000049 +:105BA000945B0100000000000200000002030000FE +:105BB000681001000000000002000000E811010070 +:105BC00000000000020000001812010000000000A8 +:105BD00002000000C81001000000000002000000E8 +:105BE0002811010000000000F82301004982000094 +:105BF00005000000000100005C50010000000000F2 +:105C0000010000002C650100845C0100020000001E +:105C1000080D010000000000010000006C500100B0 +:105C2000B45C01000100000090640100145D0100FB +:105C30001024010000000000050000000001000029 +:105C40007C5001000000000002000000B80E0100BE +:105C50000000000002000000981601000000000093 +:105C600002000000C8160100000000000200000051 +:105C7000F81601000000000002000000E80E01001C +:105C800000000000741F010000000000060000007A +:105C900000010000EC3A01000000000002000000DA +:105CA000580E01000000000002000000880E0100F4 +:105CB000000000008C500100000000000300000004 +:105CC00000010000003B0100000000000200000095 +:105CD000380D01000000000002000000980D0100D6 +:105CE0000000000002000000280E0100000000007B +:105CF00002000000C80D01000000000002000000CA +:105D0000981901000000000002000000A81801001E +:105D100000000000841E01000000000007000000D9 +:105D200000010000B4540040000000000001000029 +:105D3000CC5400400000000000010000E45400408A +:105D40000000000000010000FC54004000000000C2 +:105D5000143B01002D0C00000401000000000000B5 +:105D60009C5001000000000000000000283B0100E2 +:105D70000000000000000000A76501000000000016 +:105D80003C3B010000000000040100000000000096 +:105D9000503B01000000000000000000AC5001007A +:105DA0000000000000000000BC50010000000000E6 +:105DB00000000000CC50010000000000643B010026 +:105DC000000000000401000000000000DC500100A1 +:105DD0000000000000000000EC5001000000000086 +:105DE00000000000A865010000000000783B0100F1 +:105DF000000000000401000000000000FC50010051 +:105E000000000000000000000C5101000000000034 +:105E100000000000A9650100000000008C3B0100AB +:105E2000000000000401000000010000A03B010090 +:105E300000000000010000001C510100A85F0100EB +:105E4000010000002C510100E45F0100010000008E +:105E5000B43B0100B8580100C83B0100000000003D +:105E600004000000000100003C510100000000009F +:105E70000100000098640100D05E010001000000F4 +:105E8000A06401000C5F010001000000DC3B010088 +:105E90003C5F0100F03B01000183000004000000B2 +:105EA000000100004C510100000000000000000053 +:105EB000043C01000000000000000000183C01004C +:105EC00000000000000000002C3C01000000000069 +:105ED000403C010029830000040100000001000093 +:105EE0005C5101000000000000000000543C010073 +:105EF0000000000000000000683C010000000000FD +:105F0000000000002C3C0100000000007C3C01006F +:105F1000298300000401000000010000903C010002 +:105F20000000000000000000A43C01000000000090 +:105F300000000000B83C010000000000CC3C010063 +:105F4000298300000401000000010000AA6501008F +:105F500000000000000000006C5101000000000083 +:105F600000000000E03C0100000000007C51010046 +:105F7000000000000301000002030000A81201005D +:105F80000000000002000000D81201000000000024 +:105F900002000000081301000000000002000000E1 +:105FA0006813010000000000F43C01003B83000086 +:105FB000040100000203000098130100000000002B +:105FC00002000000C81301000000000000000000F3 +:105FD0001455004000000000000000002C55004057 +:105FE00000000000083D01001185000004010000D0 +:105FF000000100001C3D0100000000000200000044 +:106000002814010000000000F05F0100FC5F0100A7 +:106010000000000008600100000000000200000015 +:1060200000010000303D0100000000000100000000 +:10603000443D01006C59010001000000583D010081 +:10604000A85901008C51010000000000030000006D +:10605000000100006C3D0100000000000100000094 +:10606000443D0100F458010001000000583D0100CA +:10607000B06001009C51010000000000030000001E +:1060800002030000180C01000000000002000000E4 +:106090000816010000000000020000003816010090 +:1060A000000000000200000068160100000000006F +:1060B000803D010000000000040100005B72656388 +:1060C00065697665725D3D005B61705F646E735DEE +:1060D0003D0000005B61705F69705D3D0000000085 +:1060E0005B61705F757365725D3D00005B61705F41 +:1060F00061706E5D3D00000041542B4350494E3F9E +:106100000D0A000041545E534953433D300D0A00CF +:1061100041545E5349534F3D300D0A007C202537D2 +:1061200064207C20000000007C2025313664202083 +:10613000000000007C202531326420207C200000FB +:1061400002000630000000000200063300000000DC +:1061500002000635000000000200064100000000B9 +:10616000CAC0CD2E25642000CED8C8C1CAC0000048 +:10617000CDC0C6CCC8D2C50025302E336600000085 +:10618000EEF8E8E1EAE00000EEE1ECE0EDE000002E +:10619000EEEFF2E8EAE80000E4E0F2F7E8EAE00017 +:1061A000ECEEE4E5ECE00000D4CF2031000000008C +:1061B000D4CF203200000000EDE52042434400002F +:1061C000F1ECE5EDFB000000E220D4CF0000000080 +:1061D000F120D4CF00000000EFE8F2E0EDE8FF008E +:1061E000EBE5EDF2FB000000E4E0F2E0000000006F +:1061F000F7E5EAE000000000EFEEEBE5E900000063 +:10620000F120DDCACBC70000DDCACBC7000000000B +:10621000D0F3F72E00000000C0E2F2EE0000000014 +:10622000C1F3F4E5F00000000000000009000000E8 +:106230000000000001000000E2FBEAEB2E0000007D +:10624000E2EAEB2E00000000000000000200000067 +:10625000D1EEEBFFF0E8E9000000000001000000D3 +:10626000CAEDEEEFEAE00000D1D2C0D0D2000000CB +:10627000CFD3D1CA000000000000000001000000E0 +:10628000E2FBEAEB2E000000E2EAEB2E0000000049 +:106290000000000001000000CCEEE4E5EC0000008E +:1062A0000000000001000000D1F2E0F2F3F1000074 +:1062B000000000009F05000054EEF2EFF02E0000F9 +:1062C0000000000001000000010000000F27000096 +:1062D00000000000010000000000000001000000BC +:1062E00000000000FFFFFFFF00000000E7030000C8 +:1062F000000000006300000001000000E703000050 +:1063000001000000E703000000000000040000009E +:10631000EFF22DE2F1000000F1E12DE2F1000000CA +:10632000EFF22DF1E1000000EFF22DEFED000000A3 +:10633000000000000100000000000000FFFFFFFF60 +:10634000010000000F270000010000000F270000DF +:1063500001000000E703000001000000E703000067 +:1063600000000000180000000000000018000000FD +:10637000CAEEEDE5F62CF700000000001800000062 +:106380000000000018000000CAEEEDE5F62CF70052 +:1063900000000000010000005A2DEEF2F7E5F200C7 +:1063A000EFE5F7E0F2FC0000582DEEF2F7E5F20021 +:1063B00000000000FFFFFFFF00000000A900000038 +:1063C00000000000FFFFFFFFC7E0EFF3F1EAE80085 +:1063D000C2F02EF0E0E12E000000000002000000FC +:1063E0000000000001000000D7E5EA3A00000000CC +:1063F000F1F3ECECE0000000000000000000000001 +:10640000000000000F27000000000000FFE0F5057D +:10641000CFC0D0CECB62000000000000170000000B +:10642000CAEEEB2DE2EE0000000000000F27000096 +:106430002564207275622E007261626F74610000C3 +:106440002575207275622E00EAE0ED2E25640000AD +:10645000256420F0F3E12E00F0E0E1EEF2E0000030 +:10646000257520F0F3E12E00EFF3F1F2EE000000CD +:10647000C6F3F0EDE0EBFB00CEF2F7E5F2FB000037 +:10648000CEE1F9E0FF000000CAE0EDE0EBFB000028 +:10649000CCEEE4E5EC000000582DEEF2F7E5F2005A +:1064A0005A2DEEF2F7E5F20041540D0A000000000B +:1064B0004F4B0D0A000000004552524F520D0A008A +:1064C00020207C202000000031300000CEEA0000B7 +:1064D000EDE5F200D4CF0000313100003132000090 +:1064E0003133000031340000313500003136000016 +:1064F00031370000313800003139000032300000FF +:1065000032310000323200003233000032340000F9 +:10651000D4D00000EDE5F200E4E00000EDE5F2008B +:10652000EDE5F200E4E00000EDE5F200D4D000007B +:10653000785634120EF0B0E101000A0000000100AC +:106540001000A00001000C00140002000500000073 +:106550001F0001000100050000001400640001009C +:106560000400010004001800040001000400010000 +:106570000100010080000100110000000000800007 +:106580000100010020004800E80301001D01010096 +:106590001000000008000A0024004002080040002B +:1065A000B40B00000000000000000000D0640100F7 +:1065B000BC3F0100CC3F01003C2C0100502C0100ED +:1065C000642C0100782C01008C2C0100A02C01000F +:1065D000B42C0100C82C0100DC2C0100DC3F0100C0 +:1065E000EC3F0100F02C0100FC3F01000C400100D9 +:1065F0001C400100E02001002C400100042D01009E +:106600003C4001004C4001005C400100182D01009D +:1066100080610100806101002C2D0100402D0100EE +:10662000542D0100682D0100305301007C2D010024 +:10663000902D01006C4001007C400100F820010019 +:1066400010210100A42D0100B82D0100CC2D010066 +:106650003C5301008C4001009C40010028210100B6 +:10666000E02D0100F42D0100082E01001C2E010078 +:1066700048530100302E0100442E0100582E010025 +:106680006C2E010040210100802E0100AC40010071 +:1066900054530100942E0100A82E0100BC2E0100CD +:1066A000D02E0100BC400100E42E0100F82E0100B4 +:1066B0000C2F0100CC400100202F0100342F0100DD +:1066C000482F01005C2F0100702F0100842F010072 +:1066D000982F0100DC400100AC2F0100C02F010009 +:1066E000D42F0100E82F0100FC2F01001030010021 +:1066F000EC400100FC400100582101002430010061 +:10670000383001004C30010060300100743001006D +:106710000C4101001C4101002C4101003C410100E1 +:10672000883001004C4101005C4101009C300100B7 +:106730006C410100B0300100C4300100D8300100CC +:10674000EC30010070210100003101001431010022 +:10675000283101003C310100503101007C41010031 +:1067600064310100783101008C310100A031010059 +:10677000B4310100C83101008C410100DC3101005D +:10678000F0310100043201009C410100AC410100E4 +:10679000BC410100183201002C320100CC41010043 +:1067A000DC41010040320100EC410100FC410100EC +:1067B000543201000C4201001C4201002C42010035 +:1067C0003C420100683201007C320100903201003D +:1067D000A4320100B8320100CC320100E0320100E5 +:1067E000F43201004C42010088210100083301000D +:1067F0005C4201001C3301006C4201003033010097 +:10680000A02101007C4201004433010060530100DB +:106810008C420100583301006C33010080330100C9 +:106820009C4201006C530100AC420100BC420100DB +:1068300094330100CC420100DC420100EC42010033 +:10684000FC4201000C430100A8330100BC330100ED +:10685000D0330100D0640100E43301001C43010087 +:10686000785301002C4301003C430100F833010040 +:106870004C4301000C34010084530100203401001A +:10688000905301009C530100A85301005C43010098 +:10689000B453010088610100343401004834010020 +:1068A000483401006C430100A853010090610100CD +:1068B000C053010098610100A0610100CC530100A8 +:1068C0005C340100A8610100B06101007C4301005B +:1068D000703401008C4301009C430100D853010037 +:1068E000AC430100B8610100E4530100F053010022 +:1068F0008434010098340100FC5301000854010065 +:1069000014540100C0610100C0610100C8610100B0 +:10691000A2650100BC430100CC430100AC3401007E +:10692000C0340100D4340100A2650100A265010059 +:1069300020540100DC43010020540100E834010030 +:10694000FC3401002C54010038540100EC430100D8 +:10695000A2650100FC43010010350100243501004F +:10696000383501004C3501006035010074350100F7 +:10697000883501009C350100B0350100C4350100A7 +:10698000D8350100B821010044540100EC35010064 +:106990005054010000360100143601002836010071 +:1069A000A26501000C4401003C360100D021010029 +:1069B000E8210100002201005C5401005036010072 +:1069C00064360100783601008C3601001C44010059 +:1069D0002C44010068540100745401003C4401003F +:1069E0004C440100A0360100B4360100A26501004C +:1069F0005C4401005C440100D0610100C836010024 +:106A0000C8360100D8610100E0610100E0610100C9 +:106A10006C4401006C440100DC360100D4640100C8 +:106A2000805401008C5401008C540100A2650100C7 +:106A3000D86101007C44010098540100A265010066 +:106A4000A26501008C4401009C440100E861010042 +:106A5000A45401001822010030220100B0540100AA +:106A6000B0540100B0540100B0540100BC54010006 +:106A7000C8540100D4540100F0360100482201003E +:106A800004370100183701002C370100AC44010025 +:106A900040370100F0610100BC440100543701009F +:106AA00068370100F86101007C37010060220100B5 +:106AB00000620100A853010078220100CC440100CB +:106AC000A2650100DC44010090370100FC53010085 +:106AD00090220100A822010008620100A4370100F1 +:106AE000B8370100CC370100EC440100FC44010040 +:106AF000E0540100E03701000C450100EC540100B6 +:106B0000A41B0100081B0100041D0100C81B01009B +:106B1000241D0100441D0100641D0100041F01002B +:106B2000841D0100C0220100F43701000838010073 +:106B3000D82201001C4501002C450100201F010046 +:106B4000A41D0100F0220100C41D0100083801004D +:106B50003C4501000823010020230100301B0100F7 +:106B60003C1F01001C3801004C4501005C45010040 +:106B70006C4501007C4501008C4501009C450100ED +:106B8000AC450100BC450100CC450100DC450100DD +:106B9000EC450100FC4501000C4601001C460100CB +:106BA0002C4601003C4601004C4601005C460100B9 +:106BB0006C4601007C4601008C4601009C460100A9 +:106BC000AC460100BC460100CC460100DC46010099 +:106BD000EC460100FC4601000C4701001C47010087 +:106BE0002C4701003C4701004C4701005C47010075 +:106BF0006C4701007C4701008C4701009C47010065 +:106C0000AC470100BC470100CC470100DC47010054 +:106C1000EC470100FC4701000C4801001C48010042 +:106C20002C4801003C4801004C4801005C48010030 +:106C30006C4801007C4801008C4801009C48010020 +:106C4000AC480100BC480100CC480100DC48010010 +:106C5000EC480100FC4801000C4901001C490100FE +:106C60002C4901003C4901004C4901005C490100EC +:106C70006C4901007C4901008C4901009C490100DC +:106C8000AC490100BC490100CC490100DC490100CC +:106C9000EC490100FC4901000C4A01001C4A0100BA +:106CA0002C4A01003C4A01004C4A01005C4A0100A8 +:106CB0006C4A01007C4A01008C4A01009C4A010098 +:106CC000AC4A0100BC4A0100CC4A0100DC4A010088 +:106CD000EC4A0100FC4A01000C4B01001C4B010076 +:106CE0002C4B01003C4B01004C4B01005C4B010064 +:106CF0006C4B01007C4B01008C4B01009C4B010054 +:106D0000AC4B0100BC4B0100CC4B0100DC4B010043 +:106D1000EC4B0100FC4B01000C4C01001C4C010031 +:106D20002C4C01003C4C01004C4C01005C4C01001F +:106D30006C4C01007C4C01008C4C01009C4C01000F +:106D4000AC4C0100BC4C0100CC4C0100DC4C0100FF +:106D5000EC4C0100FC4C01000C4D01001C4D0100ED +:106D60002C4D01003C4D01004C4D01005C4D0100DB +:106D70006C4D01007C4D01008C4D01009C4D0100CB +:106D8000AC4D0100BC4D0100CC4D0100DC4D0100BB +:106D9000EC4D0100FC4D01000C4E0100E41D010012 +:106DA00000000000FC25010010260100242601003F +:106DB000382601004C2601006026010074260100DF +:106DC000882601009C260100B0260100C42601008F +:106DD000D8260100EC26010000270100142701003D +:106DE000282701003C2701005027010064270100EB +:106DF000782701008C270100A0270100B42701009B +:106E0000C8270100DC270100F02701000428010049 +:106E1000182801002C2801004028010054280100F6 +:106E2000682801007C28010090280100A4280100A6 +:106E3000B8280100CC280100E0280100F428010056 +:106E400008290100000000001C2901003029010070 +:106E500044290100582901006C2901008029010002 +:106E600094290100A8290100BC290100D0290100B2 +:106E7000E4290100F82901000C2A0100202A010060 +:106E8000342A0100482A01005C2A0100702A01000E +:106E9000842A0100982A0100AC2A0100C02A0100BE +:106EA000D42A0100E82A0100FC2A0100102B01006D +:106EB000242B0100382B01004C2B0100602B01001A +:106EC000742B0100882B01009C2B0100B02B0100CA +:106ED000C42B0100D82B0100EC2B0100002C010079 +:106EE000142C0100282C010000000000A6A10000C5 +:106EF00062C4000092D00000CAE4000032F3000037 +:106F000082F4000096FA0000360A0100E21A01003D +:106F1000C8640100D8640100DC640100E064010081 +:106F2000E4640100E8640100EC640100F064010025 +:106F3000F4640100F8640100FC64010000650100D4 +:106F400004650100086501000C650100A6A10000B0 +:106F500062C4000092D00000CAE4000032F30000D6 +:106F600082F4000096FA0000360A0100E21A0100DD +:106F7000C86401001C650100106301001863010072 +:106F8000206301002863010000000000DE200100F2 +:106F90005062010028550100CC6401001853010023 +:106FA0002453010020650100246501000000000059 +:106FB00010620100186201002062010038620100C5 +:106FC000406201006862010070620100806201009D +:106FD0008862010080620100886201008062010015 +:106FE0008862010080620100886201008062010005 +:106FF0008862010014650100186501002865010020 +:10700000A06301000C560100F0630100FFFFFFFFC9 +:10701000FFFFFFFF140000001C4E010018000000DD +:04702000010000006B +:04000005000108B03E +:00000001FF diff --git a/.svn/pristine/32/32be97f9ce9bacdbb5b912cc79d345d86b30cf70.svn-base b/.svn/pristine/32/32be97f9ce9bacdbb5b912cc79d345d86b30cf70.svn-base new file mode 100644 index 0000000..63bee96 --- /dev/null +++ b/.svn/pristine/32/32be97f9ce9bacdbb5b912cc79d345d86b30cf70.svn-base @@ -0,0 +1,74 @@ + + + + + + + + + 300Find-in-FilesBreakpoints201222 + + + + + + 2091624461300Debug-LogBreakpointsFind-in-Files + + + + + + + 372272727 + + + + + + 200100Disassembly_I05002000 + + + TRangeValueULONG-Max3TVariant32-Val32U4 + {W}Watch-0:state4{W}Watch-0:ulIndex3 + + + + + + 200139313100100 + 200100100100100ExpressionLocationTypeValue233150100237FiscFullStatusFiscShortStatus300Debug-LogBreakpoints35050601200110$PROJ_DIR$\TermIOInput.txt1030010300Debug-LogFind-in-Files200Locals100100100100200100100100100LocationTypeValueVariable150100181168 + + + + + + + + + TabID-16311-17664 + Workspace + Workspace + + + solariumsolarium/DRIVERSsolarium/DRIVERS/modemsolarium/PROJECTsolarium/PROJECT/appsolarium/PROJECT/datasolarium/PROJECT/menusolarium/PROJECT/service + + + + 0TabID-23366-6968Debug LogDebug-LogTabID-1787-14946BreakpointsBreakpointsTabID-31768-15979Find in FilesFind-in-Files0TabID-4750-16799LocalsLocals1001001001000TabID-25216-28894DisassemblyDisassembly0TabID-6501-5953Quick WatchQuickWatch0 + + + + + + TextEditor$WS_DIR$\OS\app\app.c0059059000100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1-2-2643467-2-2300278156250283673244271658163-2-2242677-2-22002001041672040823536462489800000-22402002001041672040823536462051020000-2439375368195313375510353646208163-2-22651922-2-219242671002083272449156250272449 + + + + diff --git a/.svn/pristine/35/350b1d7039f14543a5d348513a31ac5bfa2ba4ff.svn-base b/.svn/pristine/35/350b1d7039f14543a5d348513a31ac5bfa2ba4ff.svn-base new file mode 100644 index 0000000..caa006c --- /dev/null +++ b/.svn/pristine/35/350b1d7039f14543a5d348513a31ac5bfa2ba4ff.svn-base @@ -0,0 +1,37 @@ +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + + +// +#define KEY_EMPTY 0 +// +#define KEY_F1 1 +#define KEY_F2 2 +#define KEY_F3 3 +#define KEY_LEFT 4 +#define KEY_UP 5 +#define KEY_RIGHT 6 +#define KEY_STOP 7 +#define KEY_DOWN 8 +#define KEY_START 9 +// +#define KEY_USER_START 10 + +// +#define KEY_DEFERRED_CH1 11 +#define KEY_DEFERRED_CH2 12 +#define KEY_DEFERRED_CH3 13 +#define KEY_DEFERRED_CH4 14 +#define KEY_DEFERRED_CH5 15 +#define KEY_DEFERRED_CH6 16 +#define KEY_DEFERRED_CH7 17 +#define KEY_DEFERRED_CH8 18 +#define KEY_DEFERRED_CH9 19 +#define KEY_DEFERRED_CH10 20 + +#define KEY_COUNT 21 + +extern void InitKbrd(); +extern int GetKbrdEvent(int* event); + +#endif //#ifndef _KEYBOARD_H_ diff --git a/.svn/pristine/35/354359d11fe9bab6f021b6eedb23767250ad93e8.svn-base b/.svn/pristine/35/354359d11fe9bab6f021b6eedb23767250ad93e8.svn-base new file mode 100644 index 0000000..f5e6d5a --- /dev/null +++ b/.svn/pristine/35/354359d11fe9bab6f021b6eedb23767250ad93e8.svn-base @@ -0,0 +1,170 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include "cpu.h" +#include "app_serv.h" +#include "coin.h" +#include "data.h" +#include "datadesc.h" +#include "modem.h" + + +OS_STK CoinTaskStk[COIN_TASK_STK_SIZE]; + +void InitImpInput(void); + +CPU_INT32U CoinImpCounter; + +void CoinTask(void *p_arg) +{ + + while(1) + { + CPU_INT32U enable_coin; + OSTimeDly(100); + GetData(&EnableCoinDesc, &enable_coin, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable_coin) + { + if (GetCoinCount()) + { + PostUserEvent(EVENT_COIN_INSERTED); + } + } + else + { + CoinDisable(); + GetResetCoinCount(); + } + } + +} + +void CoinDisable(void) +{ + CPU_INT32U enable; + GetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable) FIO0SET_bit.P0_24 = 1; +} + +void CoinEnable(void) +{ + CPU_INT32U enable; + GetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable) FIO0CLR_bit.P0_24 = 1; +} + +// +CPU_INT32U GetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +CPU_INT32U GetResetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + CoinImpCounter = 0; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +void InitCoin(void) +{ + CoinImpCounter = 0; + InitImpInput(); + + OSTaskCreate(CoinTask, (void *)0, (OS_STK *)&CoinTaskStk[COIN_TASK_STK_SIZE-1], COIN_TASK_PRIO); +} + + +void InputCapture_ISR(void) +{ + CPU_INT08U ir = T3IR; + static CPU_INT32U period = 0; + T3IR = 0xFF; + + if (ir & 0x10) + {// CR0 interrupt + + if (FIO0PIN_bit.P0_23) + {// + CPU_INT32U cr=T3CR0; + if (((cr-period) > COIN_IMP_MIN_LEN) + && ((cr-period) < COIN_IMP_MAX_LEN)) + CoinImpCounter++; + } + else + {// + period = T3CR0; + } + } +} + + +extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk); + +/* +P0.23 MK_P9 IMPULSE OUTPUT ( ) +P0.24 MK_P8 INHIBIT () +*/ +// +// CAP3.0 +void InitImpInput (void) +{ + #define INPUT_CAPTURE_FREQ 100000 // + + CPU_INT32U pclk_freq; + CPU_INT32U rld_cnts; + + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + PINSEL1_bit.P0_24 = 0x0; + PINMODE1_bit.P0_24 = 0; + FIO0DIR_bit.P0_24 = 1; + FIO0MASK_bit.P0_24 = 0; + FIO0SET_bit.P0_24 = 1; // + + PCONP_bit.PCTIM3 = 1; + PCLKSEL1_bit.PCLK_TIMER3 = 2; + + PINSEL1_bit.P0_23 = 0x3; + PINMODE1_bit.P0_23 = 0; + FIO0DIR_bit.P0_23 = 0; + FIO0MASK_bit.P0_23 = 0; + + pclk_freq = BSP_CPU_PclkFreq(23); + rld_cnts = pclk_freq / INPUT_CAPTURE_FREQ; + + T3CTCR_bit.CTM = 0; + T3CTCR_bit.CIS = 0; // select CAP3.0 input + T3PR = rld_cnts-1; + T3MCR = 0; + T3CCR = 0x07; + T3EMR = 0; + T3TCR = 0x03; + T3TCR = 0x01; + + VICINTSELECT &= ~(1 << VIC_TIMER3); + VICVECTADDR27 = (CPU_INT32U)InputCapture_ISR; + VICVECTPRIORITY27 = 10; + VICINTENABLE = (1 << VIC_TIMER3); + + T3IR = 0xFF; + + OS_EXIT_CRITICAL(); +} + diff --git a/.svn/pristine/36/3689fb4654c8aed207f60be1bdde303c686c0b8f.svn-base b/.svn/pristine/36/3689fb4654c8aed207f60be1bdde303c686c0b8f.svn-base new file mode 100644 index 0000000..7a2dda2 --- /dev/null +++ b/.svn/pristine/36/3689fb4654c8aed207f60be1bdde303c686c0b8f.svn-base @@ -0,0 +1,15 @@ +#ifndef _UART0_H_ +#define _UART0_H_ + +extern void Uart0_Send(unsigned char *buf, int len); +extern int Uart0_Receive(unsigned char *buf, int len, int timeout); +extern void Uart0_Init(CPU_INT32U baud_rate); +extern void Uart0_WrByte(CPU_INT08U tx_byte); +extern void Uart0_Flush(void); +extern int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout); +extern int Uart0_Ready(); +extern int Uart0_Gotc(void); +extern int Uart0_Getc(void); +extern int Uart0_Putc(unsigned char ch); + +#endif //#ifndef _UART0_H_ diff --git a/.svn/pristine/36/36d8a1b42619ee3e46ea3426fdb10ec6ff9aebc2.svn-base b/.svn/pristine/36/36d8a1b42619ee3e46ea3426fdb10ec6ff9aebc2.svn-base new file mode 100644 index 0000000..c968758 --- /dev/null +++ b/.svn/pristine/36/36d8a1b42619ee3e46ea3426fdb10ec6ff9aebc2.svn-base @@ -0,0 +1,462 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* STANDARD MEMORY OPERATIONS +* +* Filename : lib_mem.c +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define LIB_MEM_MODULE +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Clr() +* +* Description : Clear data buffer (see Note #2). +* +* Argument(s) : pmem Pointer to memory buffer to clear. +* +* size Number of data buffer octets to clear. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null clears allowed (i.e. 0-octet size). +* +* See also 'Mem_Set() Note #1'. +* +* (2) Clear data by setting each data octet to 0. +********************************************************************************************************* +*/ + +void Mem_Clr (void *pmem, + CPU_SIZE_T size) +{ + Mem_Set((void *)pmem, + (CPU_INT08U)0, /* See Note #2. */ + (CPU_SIZE_T)size); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Set() +* +* Description : Fill data buffer with specified data octet. +* +* Argument(s) : pmem Pointer to memory buffer to fill with specified data octet. +* +* data_val Data fill octet value. +* +* size Number of data buffer octets to fill. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null sets allowed (i.e. 0-octet size). +* +* (2) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +********************************************************************************************************* +*/ + +void Mem_Set (void *pmem, + CPU_INT08U data_val, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN data_align; + CPU_ALIGN *pmem_align; + CPU_INT08U *pmem_08; + CPU_INT08U mem_align_modulo; + CPU_INT08U i; + + + if (size < 1) { /* See Note #1. */ + return; + } + if (pmem == (void *)0) { + return; + } + + + data_align = 0; + for (i = 0; i < sizeof(CPU_ALIGN); i++) { /* Fill each data_align octet with data val. */ + data_align <<= DEF_OCTET_NBR_BITS; + data_align |= (CPU_ALIGN)data_val; + } + + size_rem = (CPU_SIZE_T)size; + mem_align_modulo = (CPU_INT08U)((CPU_ADDR)pmem % sizeof(CPU_ALIGN)); /* See Note #3. */ + + pmem_08 = (CPU_INT08U *)pmem; + if (mem_align_modulo != 0) { /* If leading octets avail, ... */ + i = mem_align_modulo; + while ((size_rem > 0) && /* ... start mem buf fill with leading octets ... */ + (i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */ + *pmem_08++ = data_val; + size_rem -= sizeof(CPU_INT08U); + i++; + } + } + + pmem_align = (CPU_ALIGN *)pmem_08; /* See Note #2a. */ + while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem buf aligned on CPU_ALIGN word boundaries, */ + *pmem_align++ = data_align; /* ... fill mem buf with CPU_ALIGN-sized data. */ + size_rem -= sizeof(CPU_ALIGN); + } + + pmem_08 = (CPU_INT08U *)pmem_align; + while (size_rem > 0) { /* Finish mem buf fill with trailing octets. */ + *pmem_08++ = data_val; + size_rem -= sizeof(CPU_INT08U); + } +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Copy() +* +* Description : Copy data octets from one buffer to another buffer. +* +* Argument(s) : pdest Pointer to destination memory buffer. +* +* psrc Pointer to source memory buffer. +* +* size Number of data buffer octets to copy. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null copies allowed (i.e. 0-octet size). +* +* (2) Memory buffers NOT checked for overlapping. +* +* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if ((!defined(uC_CFG_OPTIMIZE_ASM_EN)) || \ + ((defined(uC_CFG_OPTIMIZE_ASM_EN)) && \ + (uC_CFG_OPTIMIZE_ASM_EN != DEF_ENABLED))) +void Mem_Copy (void *pdest, + void *psrc, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN *pmem_align_dest; + CPU_ALIGN *pmem_align_src; + CPU_INT08U *pmem_08_dest; + CPU_INT08U *pmem_08_src; + CPU_INT08U i; + CPU_INT08U mem_align_modulo_dest; + CPU_INT08U mem_align_modulo_src; + CPU_BOOLEAN mem_aligned; + + + if (size < 1) { /* See Note #1. */ + return; + } + if (pdest == (void *)0) { + return; + } + if (psrc == (void *)0) { + return; + } + + + size_rem = (CPU_SIZE_T )size; + + pmem_08_dest = (CPU_INT08U *)pdest; + pmem_08_src = (CPU_INT08U *)psrc; + /* See Note #4. */ + mem_align_modulo_dest = (CPU_INT08U )((CPU_ADDR)pmem_08_dest % sizeof(CPU_ALIGN)); + mem_align_modulo_src = (CPU_INT08U )((CPU_ADDR)pmem_08_src % sizeof(CPU_ALIGN)); + + mem_aligned = (mem_align_modulo_dest == mem_align_modulo_src) ? DEF_YES : DEF_NO; + + if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */ + /* ... optimize copy for mem buf alignment. */ + if (mem_align_modulo_dest != 0) { /* If leading octets avail, ... */ + i = mem_align_modulo_dest; + while ((size_rem > 0) && /* ... start mem buf copy with leading octets ... */ + (i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */ + *pmem_08_dest++ = *pmem_08_src++; + size_rem -= sizeof(CPU_INT08U); + i++; + } + } + + pmem_align_dest = (CPU_ALIGN *)pmem_08_dest; /* See Note #3a. */ + pmem_align_src = (CPU_ALIGN *)pmem_08_src; + while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem bufs aligned on CPU_ALIGN word boundaries, */ + *pmem_align_dest++ = *pmem_align_src++; /* ... copy psrc to pdest with CPU_ALIGN-sized words. */ + size_rem -= sizeof(CPU_ALIGN); + } + + pmem_08_dest = (CPU_INT08U *)pmem_align_dest; + pmem_08_src = (CPU_INT08U *)pmem_align_src; + } + + while (size_rem > 0) { /* For unaligned mem bufs or trailing octets, ... */ + *pmem_08_dest++ = *pmem_08_src++; /* ... copy psrc to pdest by octets. */ + size_rem -= sizeof(CPU_INT08U); + } +} +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Cmp() +* +* Description : Verify that ALL data octets in two memory buffers are identical in sequence. +* +* Argument(s) : p1_mem Pointer to first memory buffer. +* +* p2_mem Pointer to second memory buffer. +* +* size Number of data buffer octets to compare. +* +* Return(s) : DEF_YES, if 'size' number of data octets are identical in both memory buffers. +* +* DEF_NO, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Null compares allowed (i.e. 0-octet size); 'DEF_YES' returned to indicate identical +* null compare. +* +* (2) Many memory buffer comparisons vary ONLY in the least significant octets -- e.g. +* network address buffers. Consequently, memory buffer comparison is more efficient +* if the comparison starts from the end of the memory buffers which will abort sooner +* on dissimilar memory buffers that vary only in the least significant octets. +* +* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +******************************************************************************************************** +*/ +/*$PAGE*/ +CPU_BOOLEAN Mem_Cmp (void *p1_mem, + void *p2_mem, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN *p1_mem_align; + CPU_ALIGN *p2_mem_align; + CPU_INT08U *p1_mem_08; + CPU_INT08U *p2_mem_08; + CPU_INT08U i; + CPU_INT08U mem_align_modulo_1; + CPU_INT08U mem_align_modulo_2; + CPU_BOOLEAN mem_aligned; + CPU_BOOLEAN mem_cmp; + + + if (size < 1) { /* See Note #1. */ + return (DEF_YES); + } + if (p1_mem == (void *)0) { + return (DEF_NO); + } + if (p2_mem == (void *)0) { + return (DEF_NO); + } + + + mem_cmp = DEF_YES; + size_rem = size; + /* Start @ end of mem bufs (see Note #2). */ + p1_mem_08 = (CPU_INT08U *)p1_mem + size; + p2_mem_08 = (CPU_INT08U *)p2_mem + size; + /* See Note #4. */ + mem_align_modulo_1 = (CPU_INT08U )((CPU_ADDR)p1_mem_08 % sizeof(CPU_ALIGN)); + mem_align_modulo_2 = (CPU_INT08U )((CPU_ADDR)p2_mem_08 % sizeof(CPU_ALIGN)); + + mem_aligned = (mem_align_modulo_1 == mem_align_modulo_2) ? DEF_YES : DEF_NO; + + if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */ + /* ... optimize cmp for mem buf alignment. */ + if (mem_align_modulo_1 != 0) { /* If trailing octets avail, ... */ + i = mem_align_modulo_1; + while ((mem_cmp == DEF_YES) && /* ... cmp mem bufs while identical & ... */ + (size_rem > 0) && /* ... start mem buf cmp with trailing octets ... */ + (i > 0)) { /* ... until next CPU_ALIGN word boundary. */ + p1_mem_08--; + p2_mem_08--; + if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_INT08U); + i--; + } + } + + if (mem_cmp == DEF_YES) { /* If cmp still identical, cmp aligned mem bufs. */ + p1_mem_align = (CPU_ALIGN *)p1_mem_08; /* See Note #3a. */ + p2_mem_align = (CPU_ALIGN *)p2_mem_08; + + while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical & ... */ + (size_rem >= sizeof(CPU_ALIGN))) { /* ... mem bufs aligned on CPU_ALIGN word boundaries. */ + p1_mem_align--; + p2_mem_align--; + if (*p1_mem_align != *p2_mem_align) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_ALIGN); + } + + p1_mem_08 = (CPU_INT08U *)p1_mem_align; + p2_mem_08 = (CPU_INT08U *)p2_mem_align; + } + } + + while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical ... */ + (size_rem > 0)) { /* ... for unaligned mem bufs or trailing octets. */ + p1_mem_08--; + p2_mem_08--; + if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_INT08U); + } + + return (mem_cmp); +} + diff --git a/.svn/pristine/37/37e0d0cf2382fa41e5a93791c4fd331e8c0f3699.svn-base b/.svn/pristine/37/37e0d0cf2382fa41e5a93791c4fd331e8c0f3699.svn-base new file mode 100644 index 0000000..bb8ff9b --- /dev/null +++ b/.svn/pristine/37/37e0d0cf2382fa41e5a93791c4fd331e8c0f3699.svn-base @@ -0,0 +1,186 @@ +#ifndef _DATADESC_H_ +#define _DATADESC_H_ + +#include "data.h" +#include "control.h" + +#define INCAS_SEND_FLAG 0x87654321 + +#define MAX_PRICE 9999 + +#define DEFAULT_PASSWORD 1111 +#define MASTER_PASSWORD 11300045//1234567890L + +// +typedef struct{ + // + CPU_INT32U Enable[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutBefore[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutAfter[CHANNELS_NUM]; + // , . + CPU_INT32U MaxWorkTime[CHANNELS_NUM]; + // , . + CPU_INT32U MinWorkTime[CHANNELS_NUM]; + // , + CPU_INT32U WeekEnd[CHANNELS_NUM]; + #define WEEKEND_NO 0 + #define WEEKEND_FRIDAY_SUNDAY 1 + #define WEEKEND_SATURDAY_SUNDAY 2 + #define WEEKEND_FRIDAY_SATURDAY 3 + #define WEEKEND_FRIDAY_MONDAY 4 + // + CPU_INT32U Name[CHANNELS_NUM]; + + // + #define PRICE_PERIODS_NUM 4 + CPU_INT32U T_Start_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_Start_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + // + CPU_INT32U Price_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U Price_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + + + +}TChannelConfig; + + + +// +typedef struct{ + CPU_INT32U EnableValidator; + CPU_INT32U EnableCoinAcceptor; + CPU_INT32U EnableModem; + CPU_INT32U EnableFiscal; + CPU_INT32U EnableFiscalDayClear; + CPU_INT32U ServiceName; + + CPU_INT32U CoinPerPulse; // + CPU_INT32U BillFormat; + + CPU_INT32U DisableFiscalErrors; // + + CPU_INT32U EnableEmailErrorSend; + CPU_INT32U EnableEmailStatSend; + CPU_INT32U EnableEmailJournalSend; + CPU_INT32U ClearJournalAfterSend; + CPU_INT32U StatSendHourMin; + + CPU_INT32U DeviceId; +}TDeviceConfig; + + +extern CPU_INT32U PeriodIndex; +extern CPU_INT32U ChannelIndex; +extern TDataDescStruct const DeviceIDDesc; + +extern TDataDescStruct const LastEmailSendTime; + +extern TDataDescStruct const ChannelIndexDesc; +extern TDataDescStruct const EnableChannelDesc; +extern TDataDescStruct const TimeOutBeforeDesc; +extern TDataDescStruct const TimeOutAfterDesc; +extern TDataDescStruct const MaxWorkTimeDesc; +extern TDataDescStruct const MinWorkTimeDesc; +extern TDataDescStruct const WeekEndDesc; + +extern TDataDescStruct const PeriodWeekendIndexDesc; +extern TDataDescStruct const PeriodWeekdaysIndexDesc; +extern TDataDescStruct const ServiceNameDesc; +extern TDataDescStruct const PassDesc; +extern TDataDescStruct const PassCRCDesc; +extern TDataDescStruct const PassTempDesc; +extern CPU_INT32U TempPass; +extern TDataDescStruct const PassTempDesc1; +extern TDataDescStruct const PassTempDesc2; + +extern TDataDescStruct const PriceWeekendDesc; +extern TDataDescStruct const PriceWeekdaysDesc; +extern TDataDescStruct const PriceTimeWeekendDesc; +extern TDataDescStruct const PriceTimeWeekdaysDesc; +extern TDataDescStruct const T_Start_WeekdaysDesc; +extern TDataDescStruct const T_End_WeekdaysDesc; +extern TDataDescStruct const T_Start_WeekendDesc; +extern TDataDescStruct const T_End_WeekendDesc; + +extern TDataDescStruct const EnableFiscalDesc; +extern TDataDescStruct const EnableCoinDesc; +extern TDataDescStruct const EnableModemDesc; +extern TDataDescStruct const EnableValidatorDesc; +extern TDataDescStruct const CoinPerPulseDesc; +extern TDataDescStruct const EnableFiscalDayClearDesc; + +extern TDataDescStruct const InitByDefaultDesc; +extern TDataDescStruct const PrintZReportDesc; +extern TDataDescStruct const PrintXReportDesc; + +extern TDataDescStruct const ErrorJournalIndexDesc; +extern TDataDescStruct const EventJournalIndexDesc; +extern TDataDescStruct const JournalEventTimeDesc; + +extern TDataDescStruct const JournalErrorNumberDesc0; +extern TDataDescStruct const JournalErrorNumberDesc1; +extern TDataDescStruct const JournalErrorTimeDesc; +extern TDataDescStruct const ClearJournalCmdDesc; + + +extern TDataDescStruct const SystemTimeDesc; +extern TDataDescStruct const SystemTimeEditDesc; + +extern const TDataDescArrayStruct AllDataArray[]; + +extern CPU_INT32U ErrorJournalIndex; +extern CPU_INT32U EventJournalIndex; + +extern TDataDescStruct const CounterRunDesc; +extern TDataDescStruct const CounterMoneyDesc; +extern TDataDescStruct const CounterTimeDesc; +extern TDataDescStruct const CounterChannelRunDesc; +extern TDataDescStruct const CounterChannelMoneyDesc; +extern TDataDescStruct const CounterChannelTimeDesc; +extern TDataDescStruct const ChannelStIndexDesc; +extern TDataDescStruct const ClearStatCmdDesc; +extern TDataDescStruct const BillFormatDesc; +extern TDataDescStruct const NameChannelDesc; + +extern TDataDescStruct const AcceptedMoneyDesc; +extern TDataDescStruct const AcceptedMoneyCRC16Desc; + +extern TDataDescStruct const DisableFiscalErrorsDesc; + +extern TDataDescStruct const EnableEmailErrorSendDesc; +extern TDataDescStruct const EnableEmailJournalSendDesc; +extern TDataDescStruct const ClearJournalAfterSendDesc; +extern TDataDescStruct const StatSendPeriodDesc; +extern TDataDescStruct const JournalErrorNumberDescEng; +extern TDataDescStruct const SendTestEmailDesc; +extern TDataDescStruct const ModemStatusDesc; + +extern TDataDescStruct const BillnomIndexDesc; +extern TDataDescStruct const BillnomDesc; +extern TDataDescStruct const BillnomCountersDesc; +extern TDataDescStruct const BillCounterDesc; + +extern TDataDescStruct const CounterLongRunDesc; +extern TDataDescStruct const CounterLongMoneyDesc; +extern TDataDescStruct const CounterLongTimeDesc; + +extern TDataDescStruct const MasterPassTempDesc; + +extern TDataDescStruct const CounterChannelRunLongDesc; +extern TDataDescStruct const CounterChannelMoneyLongDesc; +extern TDataDescStruct const CounterChannelTimeLongDesc; +extern TDataDescStruct const ChannelStLongIndexDesc; + +extern TDataDescStruct const StatSendHourMinDesc; +extern TDataDescStruct const IncasSendFlagDesc; +extern TDataDescStruct const IncasMoneyDesc; +extern TDataDescStruct const IncasTimeDesc; + + +#endif //#ifndef _DATADESC_H_ diff --git a/.svn/pristine/38/389d894960aaca49802c9be390d450cfc6990a28.svn-base b/.svn/pristine/38/389d894960aaca49802c9be390d450cfc6990a28.svn-base new file mode 100644 index 0000000..7d46d75 --- /dev/null +++ b/.svn/pristine/38/389d894960aaca49802c9be390d450cfc6990a28.svn-base @@ -0,0 +1,1799 @@ +#include +#include "app_serv.h" +#include "menu.h" +#include "menudesc.h" +#include "data.h" +#include "datadesc.h" +#include "control.h" +#include "journal.h" +#include "time.h" +#include "mode.h" +#include "version.h" + +char FlagForPrintReport=0; + +/*********************************** + - +***********************************/ +const CPU_INT08U str_StartMenu_0[] = "-------------------"; +const CPU_INT08U str_StartMenu_1[] = " "; +const CPU_INT08U str_StartMenu_2[] = " !"; +const CPU_INT08U str_StartMenu_3[] = "-------------------"; + +const TMenuLine line_StartMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_0, // + NULL // +}; + +const TMenuLine line_StartMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_1, // + NULL // +}; + +const TMenuLine line_StartMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_2, // + NULL // +}; + +const TMenuLine line_StartMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_StartMenuArray[] = {&line_StartMenu_0, &line_StartMenu_1, &line_StartMenu_2, &line_StartMenu_3, NULL}; +const TMenuPanel StartMenuPanel[] = {arr_StartMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_IncasMenu_0[] = "-------------------"; +const CPU_INT08U str_IncasMenu_1[] = " "; +const CPU_INT08U str_IncasMenu_2[] = " "; +CPU_INT08U str_IncasMenu_3[32]; + +const TMenuLine line_IncasMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_0, // + NULL // +}; + +const TMenuLine line_IncasMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_1, // + NULL // +}; + +const TMenuLine line_IncasMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_2, // + NULL // +}; + +const TMenuLine line_IncasMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_IncasMenuArray[] = {&line_IncasMenu_0, &line_IncasMenu_1, &line_IncasMenu_2, &line_IncasMenu_3, NULL}; +const TMenuPanel IncasMenuPanel[] = {arr_IncasMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalEmptyMenu_0[] = ""; +const CPU_INT08U str_JournalEmptyMenu_1[] = " "; +const CPU_INT08U str_JournalEmptyMenu_2[] = " "; +const CPU_INT08U str_JournalEmptyMenu_3[] = ""; + +const TMenuLine line_JournalEmptyMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_0, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_1, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_2, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_JournalEmptyMenuArray[] = {&line_JournalEmptyMenu_0, &line_JournalEmptyMenu_1, &line_JournalEmptyMenu_2, &line_JournalEmptyMenu_3, NULL}; +const TMenuPanel JournalEmptyMenuPanel[] = {arr_JournalEmptyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_ServiceMenu_0[] = " . "DEVICE_FW_VERSION; +const CPU_INT08U str_ServiceMenu_1[] = ""; +const CPU_INT08U str_ServiceMenu_2[] = ""; +const CPU_INT08U str_ServiceMenu_3[] = ""; +const CPU_INT08U str_ServiceMenu_4[] = ""; + +const TMenuLine line_ServiceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ServiceMenu_0, // + NULL // +}; + +const TMenuLine line_ServiceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_1, // + (void*)&SettingsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_2, // + (void*)&StatisticsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_3, // + (void*)&SelectJournalMenuPanel // +}; + +const TMenuLine line_ServiceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_4, // + (void*)&ReportMenuPanel // +}; + +const TMenuLineArray arr_ServiceMenuArray[] = {&line_ServiceMenu_0, &line_ServiceMenu_1, &line_ServiceMenu_2, &line_ServiceMenu_3, &line_ServiceMenu_4, NULL}; +const TMenuPanel ServiceMenuPanel[] = {arr_ServiceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_StatisticsMenu_0[] = " "; +const CPU_INT08U str_StatisticsMenu_1[] = " "; +const CPU_INT08U str_StatisticsMenu_2[] = ""; +const CPU_INT08U str_StatisticsMenu_3[] = " "; +const CPU_INT08U str_StatisticsMenu_4[] = " "; + + +const TMenuLine line_StatisticsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_StatisticsMenu_0, // + NULL // +}; + +const TMenuLine line_StatisticsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_1, // + (void*)ChanStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_2, // + (void*)CommStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_3, // + (void*)BillCountersPanel // +}; + +const TMenuLine line_StatisticsMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_4, // + (void*)ClearStatMenu // +}; + +const TMenuLineArray arr_StatisticsMenuArray[] = {&line_StatisticsMenu_0, &line_StatisticsMenu_1, &line_StatisticsMenu_2, &line_StatisticsMenu_3, &line_StatisticsMenu_4, NULL}; +const TMenuPanel StatisticsMenuPanel[] = {arr_StatisticsMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearStatMenu_0[] = " "; +const char str_ClearStatMenu_1[] = " "; + +void OnEnterPanelClearStat(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_0, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_1, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearStatMenuArray[] = {&line_ClearStatMenu_0, &line_ClearStatMenu_1, &line_ClearStatMenu_2, NULL}; +const TMenuPanel ClearStatMenu[] = {arr_ClearStatMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearJournalMenu_0[] = " "; +const char str_ClearJournalMenu_1[] = " "; + +void OnEnterPanelClearJournal(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_0, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_1, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearJournalMenuArray[] = {&line_ClearJournalMenu_0, &line_ClearJournalMenu_1, &line_ClearJournalMenu_2, NULL}; +const TMenuPanel ClearJournalMenuPanel[] = {arr_ClearJournalMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersArray[] = {&line_ChannelCountersMenu_0, &line_ChannelCountersMenu_1, &line_ChannelCountersMenu_2, &line_ChannelCountersMenu_3, NULL}; +const TMenuPanel ChannelCountersPanel[] = {arr_ChannelCountersArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_BillCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&BillnomIndexDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomCountersDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillCounterDesc, // + NULL // +}; + +extern CPU_INT32U BillnomViewIndex; + +void OnEnterBillCountersMenu() +{ + BillnomViewIndex = 0; +} + +const TMenuLineArray arr_BillCountersArray[] = {&line_BillCountersMenu_0, &line_BillCountersMenu_1, &line_BillCountersMenu_2, &line_BillCountersMenu_3, NULL}; +const TMenuPanel BillCountersPanel[] = {arr_BillCountersArray, OnEnterBillCountersMenu, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersMenu_0[] = " "; + +const TMenuLine line_CommonCountersMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersArray[] = {&line_CommonCountersMenu_0, &line_CommonCountersMenu_1, &line_CommonCountersMenu_2, &line_CommonCountersMenu_3, NULL}; +const TMenuPanel CommonCountersPanel[] = {arr_CommonCountersArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersLongMenu_0[] = " "; + +const TMenuLine line_CommonCountersLongMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersLongMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersLongArray[] = {&line_CommonCountersLongMenu_0, &line_CommonCountersLongMenu_1, &line_CommonCountersLongMenu_2, &line_CommonCountersLongMenu_3, NULL}; +const TMenuPanel CommonCountersLongPanel[] = {arr_CommonCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_SettingsMenu_0[] = " "; +const CPU_INT08U str_SettingsMenu_1[] = ""; +const CPU_INT08U str_SettingsMenu_2[] = ""; +const CPU_INT08U str_SettingsMenu_3[] = " "; +const CPU_INT08U str_SettingsMenu_4[] = " "; +const CPU_INT08U str_SettingsMenu_5[] = " "; + +const TMenuLine line_SettingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SettingsMenu_0, // + NULL // +}; + +const TMenuLine line_SettingsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_1, // + (void*)&ChannelMenuPanel // +}; + +const TMenuLine line_SettingsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_2, // + (void*)&DeviceMenuPanel // +}; + +const TMenuLine line_SettingsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_3, // + (void*)&SetPassMenuPanel // +}; + +const TMenuLine line_SettingsMenu_5 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_4, // + (void*)&TimeSetupMenuPanel // +}; + +const TMenuLine line_SettingsMenu_6 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_5, // + (void*)&ResetSettingsMenuPanel // +}; + +const TMenuLineArray arr_SettingsMenuArray[] = {&line_SettingsMenu_0, &line_SettingsMenu_1, &line_SettingsMenu_2, &line_SettingsMenu_5, &line_SettingsMenu_3, &line_SettingsMenu_6, NULL}; +const TMenuPanel SettingsMenuPanel[] = {arr_SettingsMenuArray, NULL, 6, MENU_PANEL_STANDARD}; + + + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_9 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&NameChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutBeforeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutAfterDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MinWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MaxWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&WeekEndDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_7 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekdaysMenuPanel // +}; + +const TMenuLine line_ChannelMenu_8 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekendMenuPanel // +}; + +const TMenuLineArray arr_ChannelMenuArray[] = {&line_ChannelMenu_0, + &line_ChannelMenu_1, + &line_ChannelMenu_9, + &line_ChannelMenu_2, + &line_ChannelMenu_3, + &line_ChannelMenu_4, + &line_ChannelMenu_5, + &line_ChannelMenu_6, + &line_ChannelMenu_7, + &line_ChannelMenu_8, + NULL}; +char flag_enter_periods=0; + +void OnEnterChannelSettingsMenu(void) +{ + if (!flag_enter_periods) + { + ChannelIndex = 0; + } + else + { + flag_enter_periods = 0; + } +} + +const TMenuPanel ChannelMenuPanel[] = {arr_ChannelMenuArray, OnEnterChannelSettingsMenu, 10, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +void OnEnterPanelPrice(void) +{ + PeriodIndex = ChannelIndex*PRICE_PERIODS_NUM; + flag_enter_periods = 1; +} + +const TMenuLine line_PriceMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekdaysIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekdaysDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArray[] = {&line_PriceMenu_0, &line_PriceMenu_1, &line_PriceMenu_2, &line_PriceMenu_3, &line_PriceMenu_4, NULL}; +const TMenuPanel PriceWeekdaysMenuPanel[] = {arr_PriceMenuArray, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_SetPassMenu_0[] = " "; + +void OnEnterPanelSetPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_SetPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc, // + NULL // +}; + +const TMenuLine line_SetPassMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " -", // + (void*)MasterPassMenuPanel // +}; + +const TMenuLineArray arr_SetPassMenuArray[] = {&line_SetPassMenu_0, &line_SetPassMenu_1, &line_SetPassMenu_2, NULL}; +const TMenuPanel SetPassMenuPanel[] = {arr_SetPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + - +***********************************/ +const char str_MasterPassMenu_0[] = " -"; + +void OnEnterPanelMasterPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_MasterPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_MasterPassMenu_0, // + NULL // +}; + +const TMenuLine line_MasterPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MasterPassTempDesc, // + NULL // +}; + +const TMenuLineArray arr_MasterPassMenuArray[] = {&line_MasterPassMenu_0, &line_MasterPassMenu_1, NULL}; +const TMenuPanel MasterPassMenuPanel[] = {arr_MasterPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_ResetSetingsMenu_0[] = " "; +const char str_ResetSetingsMenu_1[] = " "; + +void OnEnterPanelResetSetings(void) +{ + TempPass = 0; +} + +const TMenuLine line_ResetSetingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_0, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_1, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc1, // + NULL // +}; + +const TMenuLineArray arr_ResetSettingsMenuArray[] = {&line_ResetSetingsMenu_0, &line_ResetSetingsMenu_1, &line_ResetSetingsMenu_2, NULL}; +const TMenuPanel ResetSettingsMenuPanel[] = {arr_ResetSettingsMenuArray, OnEnterPanelResetSetings, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_SetNewPassMenu_0[] = " "; + +const TMenuLine line_SetNewPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetNewPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetNewPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassDesc, // + NULL // +}; + +const TMenuLineArray arr_SetNewPassMenuArray[] = {&line_SetNewPassMenu_0, &line_SetNewPassMenu_1, NULL}; +const TMenuPanel SetNewPassMenuPanel[] = {arr_SetNewPassMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_PriceMenuWend_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekendIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekendDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArrayWend[] = {&line_PriceMenuWend_0, &line_PriceMenuWend_1, &line_PriceMenuWend_2, &line_PriceMenuWend_3, &line_PriceMenuWend_4, NULL}; +const TMenuPanel PriceWeekendMenuPanel[] = {arr_PriceMenuArrayWend, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_DeviceMenu_0[] = " "; +const CPU_INT08U str_DeviceMenu_1[] = ""; +const CPU_INT08U str_DeviceMenu_2[] = ""; +const CPU_INT08U str_DeviceMenu_3[] = ""; + +const TMenuLine line_DeviceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_DeviceMenu_0, // + NULL // +}; + +const TMenuLine line_DeviceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_1, // + (void*)&FrMenuPanel // +}; + +const TMenuLine line_DeviceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableValidatorDesc, // + NULL // +}; + +const TMenuLine line_DeviceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_2, // + (void*)&CoinSetupPanel // +}; + +const TMenuLine line_DeviceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_3, // + (void*)&ModemSetupPanel // +}; + +const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, &line_DeviceMenu_1, &line_DeviceMenu_2, &line_DeviceMenu_3, &line_DeviceMenu_4, NULL}; +const TMenuPanel DeviceMenuPanel[] = {arr_DeviceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrMenu_0[] = " "; + +const TMenuLine line_FrMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrMenu_0, // + NULL // +}; + +const TMenuLine line_FrMenu_1 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&EnableFiscalDesc, + NULL +}; + +const TMenuLine line_FrMenu_2 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&EnableFiscalDayClearDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_3 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&BillFormatDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_4 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&ServiceNameDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_5 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&DisableFiscalErrorsDesc, + NULL +}; + +const TMenuLineArray arr_FrMenuArray[] = {&line_FrMenu_0, &line_FrMenu_1, &line_FrMenu_2, &line_FrMenu_3, &line_FrMenu_4, &line_FrMenu_5, NULL}; +const TMenuPanel FrMenuPanel[] = {arr_FrMenuArray, NULL, 6, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CoinMenu_0[] = " ."; + +const TMenuLine line_CoinMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CoinMenu_0, // + NULL // +}; + +const TMenuLine line_CoinMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableCoinDesc, // + NULL // +}; + +const TMenuLine line_CoinMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CoinPerPulseDesc, // + NULL // +}; + +const TMenuLineArray arr_CoinMenuArray[] = {&line_CoinMenu_0, &line_CoinMenu_1, &line_CoinMenu_2, NULL}; +const TMenuPanel CoinSetupPanel[] = {arr_CoinMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ModemMenu_0[] = " "; + +const TMenuLine line_ModemMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ModemMenu_0, // + NULL // +}; + +const TMenuLine line_ModemMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableModemDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&ModemStatusDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&StatSendHourMinDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableEmailJournalSendDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&DeviceIDDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SendTestEmailDesc, // + NULL // +}; + + +const TMenuLineArray arr_ModemMenuArray[] = {&line_ModemMenu_0, &line_ModemMenu_1, &line_ModemMenu_2, &line_ModemMenu_3, &line_ModemMenu_4, &line_ModemMenu_5, &line_ModemMenu_6, NULL}; +const TMenuPanel ModemSetupPanel[] = {arr_ModemMenuArray, NULL, 7, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ + +char str_UserMenu_0[22] = ""; +char str_UserMenu_1[22] = ""; +char str_UserMenu_2[22] = ""; +char str_UserMenu_3[22] = ""; + +char str_buf[22]; + + +void PrintUserMenuStr(char* str, CPU_INT08U n) +{ + char *strptr; + char *instr; + // + + switch (n) + { + case 0: + strptr = str_UserMenu_0; + break; + case 1: + strptr = str_UserMenu_1; + break; + case 2: + strptr = str_UserMenu_2; + break; + case 3: + strptr = str_UserMenu_3; + break; + default: + return; + } + + // , + instr = str; + while (*instr==0x20) instr++; + + memset(strptr, 0x20, 20); + + int len = strlen(instr); + if ((len >= 20) || ((10-len/2-1) < 0)) {strcpy(strptr, instr); return;} + + strcpy(&strptr[10-len/2-1], instr); +} + +const TMenuLine line_FirstMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_0, // + NULL // +}; + +const TMenuLine line_FirstMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_1, // + NULL // +}; + +const TMenuLine line_FirstMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_2, // + NULL // +}; + +const TMenuLine line_FirstMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_3, // + NULL // +}; + + +const TMenuLineArray FirstMenuArray[] = {&line_FirstMenu_0, &line_FirstMenu_1, &line_FirstMenu_2, &line_FirstMenu_3, NULL}; +const TMenuPanel FirstMenuPanel[] = {FirstMenuArray, InitUserMenu, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_ErrPass_0[] = " "; +const CPU_INT08U str_ErrPass_1[] = " "; +const CPU_INT08U str_ErrPass_2[] = ""; + +const TMenuLine line_ErrPassMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_0, // + NULL // +}; + +const TMenuLine line_ErrPassMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_1, // + NULL // +}; +const TMenuLine line_ErrPassMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_2, // + NULL // +}; + +const TMenuLineArray ErrPassMenuArray[] = {&line_ErrPassMenu_2, &line_ErrPassMenu_0, &line_ErrPassMenu_1, &line_ErrPassMenu_2, NULL}; +const TMenuPanel ErrorPassPanel[] = {ErrPassMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_SettingsIsResetPass_0[] = " "; +const CPU_INT08U str_SettingsIsResetPass_1[] = " "; +const CPU_INT08U str_SettingsIsResetPass_2[] = " "; +const CPU_INT08U str_SettingsIsResetPass_3[] = " "; + +const TMenuLine line__SettingsIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_0, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_1, // + NULL // +}; +const TMenuLine line__SettingsIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_2, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_3, // + NULL // +}; + +const TMenuLineArray SettingsIsResetMenuArray[] = {&line__SettingsIsResetMenu_0, &line__SettingsIsResetMenu_1, &line__SettingsIsResetMenu_2, &line__SettingsIsResetMenu_3, NULL}; +const TMenuPanel SettingsIsReset[] = {SettingsIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_StatIsResetPass_0[] = " "; +const CPU_INT08U str_StatIsResetPass_1[] = " "; +const CPU_INT08U str_StatIsResetPass_2[] = ""; + +const TMenuLine line__StatIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_0, // + NULL // +}; + +const TMenuLine line__StatIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_1, // + NULL // +}; +const TMenuLine line__StatIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_2, // + NULL // +}; + +const TMenuLineArray StatIsResetMenuArray[] = {&line__StatIsResetMenu_2, &line__StatIsResetMenu_0, &line__StatIsResetMenu_1, &line__StatIsResetMenu_2, NULL}; +const TMenuPanel StatIsReset[] = {StatIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalIsResetPass_0[] = " "; +const CPU_INT08U str_JournalIsResetPass_1[] = " "; +const CPU_INT08U str_JournalIsResetPass_2[] = ""; + +const TMenuLine line__JournalIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_0, // + NULL // +}; + +const TMenuLine line__JournalIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_1, // + NULL // +}; +const TMenuLine line__JournalIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_2, // + NULL // +}; + +const TMenuLineArray JournalIsResetMenuArray[] = {&line__JournalIsResetMenu_2, &line__JournalIsResetMenu_0, &line__JournalIsResetMenu_1, &line__JournalIsResetMenu_2, NULL}; +const TMenuPanel JournalIsReset[] = {JournalIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_GetMoney_0[] = " "; + +const TMenuLine line_GetMoneyMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_1 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE, // . + (void*)&AcceptedMoneyDesc, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + + +const TMenuLineArray GetMoneyMenuArray[] = {&line_GetMoneyMenu_0, &line_GetMoneyMenu_1, &line_GetMoneyMenu_2, &line_GetMoneyMenu_3, NULL}; +const TMenuPanel GetMoneyMenuPanel[] = {GetMoneyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_SelectJournalMenu_0[] = " "; +const CPU_INT08U str_SelectJournalMenu_1[] = " "; +const CPU_INT08U str_SelectJournalMenu_2[] = " "; +const CPU_INT08U str_SelectJournalMenu_3[] = " "; + +const TMenuLine line_SelectJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SelectJournalMenu_0, // + NULL // +}; + +const TMenuLine line_SelectJournalMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_1, // + (void*)&ErrorJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_2, // + (void*)&EventJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_3, // + (void*)&ClearJournalMenuPanel // +}; + +const TMenuLineArray arr_SelectJournalMenuArray[] = {&line_SelectJournalMenu_0, &line_SelectJournalMenu_1, &line_SelectJournalMenu_2, &line_SelectJournalMenu_3, NULL}; +const TMenuPanel SelectJournalMenuPanel[] = {arr_SelectJournalMenuArray, NULL, 4, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ReportMenu_0[] = " "; +const CPU_INT08U str_ReportMenu_1[] = "X-"; +const CPU_INT08U str_ReportMenu_2[] = "Z-"; +const CPU_INT08U str_ReportMenu_3[] = "Z- "; + +const TMenuLine line_ReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ReportMenu_0, // + NULL // +}; + +const TMenuLine line_ReportMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_1, // + (void*)&xReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_2, // + (void*)&zReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_3, // + (void*)&bufReportMenuPanel // +}; + + +void OnEnterReportsPanel(void) +{ + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (!enable) + { + GoToPreviousMenu(); + GoToMenu(FrIsOffMenuPanel); + } + FlagForPrintReport = 0; +} + +const TMenuLineArray arr_ReportMenuArray[] = {&line_ReportMenu_0, &line_ReportMenu_1, &line_ReportMenu_2, &line_ReportMenu_3, NULL}; +const TMenuPanel ReportMenuPanel[] = {arr_ReportMenuArray, OnEnterReportsPanel, 4, MENU_PANEL_STANDARD}; + +/*********************************** + X- +***********************************/ +const CPU_INT08U str_xReportMenu_0[] = " X-"; +const CPU_INT08U str_xReportMenu_1[] = " "; +const CPU_INT08U str_xReportMenu_2[] = " ?"; +const CPU_INT08U str_xReportMenu_3[] = "-START STOP-"; + +const TMenuLine line_xReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_xReportMenu_0, // + NULL // +}; + +const TMenuLine line_xReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_1, // + NULL // +}; + +const TMenuLine line_xReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_2, // + NULL // +}; + +const TMenuLine line_xReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +void OnEnterZXReportPanel(void) +{ + OSTimeDly(20); + FlagForPrintReport = 1; +} + +const TMenuLineArray arr_xReportMenuArray[] = {&line_xReportMenu_0, &line_xReportMenu_1, &line_xReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel xReportMenuPanel[] = {arr_xReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_zReportMenu_0[] = " Z-"; +const CPU_INT08U str_zReportMenu_1[] = " "; +const CPU_INT08U str_zReportMenu_2[] = " ?"; + +const TMenuLine line_zReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_zReportMenu_0, // + NULL // +}; + +const TMenuLine line_zReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_1, // + NULL // +}; + +const TMenuLine line_zReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_2, // + NULL // +}; + +const TMenuLine line_zReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_zReportMenuArray[] = {&line_zReportMenu_0, &line_zReportMenu_1, &line_zReportMenu_2, &line_zReportMenu_3, NULL}; +const TMenuPanel zReportMenuPanel[] = {arr_zReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_bufReportMenu_0[] = " Z- "; +const CPU_INT08U str_bufReportMenu_1[] = " "; +const CPU_INT08U str_bufReportMenu_2[] = " ?"; + +const TMenuLine line_bufReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_bufReportMenu_0, // + NULL // +}; + +const TMenuLine line_bufReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_1, // + NULL // +}; + +const TMenuLine line_bufReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_2, // + NULL // +}; + +const TMenuLine line_bufReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_bufReportMenuArray[] = {&line_bufReportMenu_0, &line_bufReportMenu_1, &line_bufReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel bufReportMenuPanel[] = {arr_bufReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrIsOff_0[] = ""; +const CPU_INT08U str_FrIsOff_1[] = " "; +const CPU_INT08U str_FrIsOff_2[] = " "; + +const TMenuLine line_FrIsOff_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrIsOff_0, // + NULL // +}; + +const TMenuLine line_FrIsOff_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_1, // + NULL // +}; + +const TMenuLine line_FrIsOff_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_2, // + NULL // +}; + +const TMenuLineArray arr_FrIsOffMenuArray[] = {&line_FrIsOff_0, &line_FrIsOff_1, &line_FrIsOff_2, NULL}; +const TMenuPanel FrIsOffMenuPanel[] = {arr_FrIsOffMenuArray, NULL, 3, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_ErrorJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ErrorJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc0, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc1, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorTimeDesc, // + NULL // +}; + +void OnEnterErrorJournal(void) +{ + TErrorRecord record; + ErrorJournalIndex = 0; + CPU_INT32U last = 0; + CPU_INT32U i; + + for (i=0; i= last) + { + last = record.time; + ErrorJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} +} + +const TMenuLineArray arr_ErrorJournalMenuArray[] = {&line_ErrorJournalMenu_0, &line_ErrorJournalMenu_1, &line_ErrorJournalMenu_2, &line_ErrorJournalMenu_3, NULL}; +const TMenuPanel ErrorJournalMenuPanel[] = {arr_ErrorJournalMenuArray, OnEnterErrorJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +char str_EventNumber[24]; +char str_EventData[24]; + +const TMenuLine line_EventJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&EventJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalEventTimeDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventNumber, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventData, // + NULL // +}; + + +void PrintEventJournalRecord(TEventRecord *record) +{ + if (record->event) + { // + GetEventStr(str_EventNumber, record->event); + if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN)) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, "%d .", record->data); + } + else if (record->event == JOURNAL_EVENT_START_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + PrintSecToHourMinSec(str_EventData, record->data); + } + else if (record->event == JOURNAL_EVENT_END_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_DEVICE_ON) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BILL) + { + sprintf(str_EventData, " %d", record->channel+1); + } + else if (record->event == JOURNAL_EVENT_PRINT_Z) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_X) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BUF) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_CHANGE_MODE) + { + if (record->data == MODE_WORK) sprintf(str_EventData, ""); + else sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_INCASSATION) + { + sprintf(str_EventData, "%u .", record->data); + } + else if (record->event == JOURNAL_EVENT_PASS_FAIL) + { + sprintf(str_EventData, "%u", record->data); + } + else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL)) + { + sprintf(str_EventData, ""); + } + + } + else + { // + sprintf(str_EventNumber, ""); + sprintf(str_EventData, ""); + } +} + +void OnEnterEventJournal(void) +{ + TEventRecord record; + EventJournalIndex = 0; + CPU_INT32U last = 0; + + for (CPU_INT32U i=0; i= last) + { + last = record.time; + EventJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +const TMenuLineArray arr_EventJournalMenuArray[] = {&line_EventJournalMenu_0, &line_EventJournalMenu_1, &line_EventJournalMenu_2, &line_EventJournalMenu_3 ,NULL}; +const TMenuPanel EventJournalMenuPanel[] = {arr_EventJournalMenuArray, OnEnterEventJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_TimeSetupMenu_0[] = " "; + +const TMenuLine line_TimeSetupMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_TimeSetupMenu_0, // + NULL // +}; + +const TMenuLine line_TimeSetupMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SystemTimeEditDesc, // + NULL // +}; + +const TMenuLineArray arr_TimeSetupMenuArray[] = {&line_TimeSetupMenu_0, &line_TimeSetupMenu_1, NULL}; +const TMenuPanel TimeSetupMenuPanel[] = {arr_TimeSetupMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonStatMenu_0[] = " "; +const CPU_INT08U str_CommonStatMenu_1[] = " "; +const CPU_INT08U str_CommonStatMenu_2[] = " "; + +const TMenuLine line_StatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CommonStatMenu_0, // + NULL // +}; + +const TMenuLine line_StatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)CommonCountersPanel // +}; + +const TMenuLine line_StatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)CommonCountersLongPanel // +}; + +const TMenuLineArray arr_StatMenuArray[] = {&line_StatMenu_0, &line_StatMenu_1, &line_StatMenu_2, NULL}; +const TMenuPanel CommStatMenuPanel[] = {arr_StatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_ChanStatMenu_0[] = " - "; + +const TMenuLine line_ChanStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ChanStatMenu_0, // + NULL // +}; + +const TMenuLine line_ChanStatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)ChannelCountersPanel // +}; + +const TMenuLine line_ChanStatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)ChannelCountersLongPanel // +}; + +const TMenuLineArray arr_ChanStatMenuArray[] = {&line_ChanStatMenu_0, &line_ChanStatMenu_1, &line_ChanStatMenu_2, NULL}; +const TMenuPanel ChanStatMenuPanel[] = {arr_ChanStatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersLongMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStLongIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeLongDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersLongArray[] = {&line_ChannelCountersLongMenu_0, &line_ChannelCountersLongMenu_1, &line_ChannelCountersLongMenu_2, &line_ChannelCountersLongMenu_3, NULL}; +const TMenuPanel ChannelCountersLongPanel[] = {arr_ChannelCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; diff --git a/.svn/pristine/3e/3eec29b2be22d31ad62ac290e2e98cce5fe5e77a.svn-base b/.svn/pristine/3e/3eec29b2be22d31ad62ac290e2e98cce5fe5e77a.svn-base new file mode 100644 index 0000000..dce3f39 --- /dev/null +++ b/.svn/pristine/3e/3eec29b2be22d31ad62ac290e2e98cce5fe5e77a.svn-base @@ -0,0 +1,161 @@ +#include +#include "spi.h" +#include "fram.h" + +void Write_ON(unsigned short address) +{ + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_ON); + spi_unselectChip(FM25_SPI); +} + +void Write_OFF(unsigned short address) +{ + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_OFF); + spi_unselectChip(FM25_SPI); +} + +void Write_Status_Register(unsigned char byte, unsigned short address) +{ + spi_getSem(); + + Write_ON(address); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_STATUS); + SpiExchange(FM25_SPI, byte); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); +} + +void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array) +{ + unsigned short i; + + spi_getSem(); + + Write_ON(uAddress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE); + SpiExchange(FM25_SPI, (char)(uAddress >> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)adress); + SpiExchange(FM25_SPI, byte); + spi_unselectChip(FM25_SPI); + + Write_OFF(adress); + + spi_freeSem(); +} + +unsigned char Read_Status_Register(unsigned short adress) +{ + unsigned char temp = 0; + + spi_getSem(); + + Write_OFF(adress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_READ_STATUS); + temp = SpiExchange(FM25_SPI, 0x00); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); + + return temp; +} + +void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array) +{ + unsigned short i; + + spi_getSem(); + + Write_OFF(uAddress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_READ); + SpiExchange(FM25_SPI, (char)(uAddress >> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)adress); + temp = SpiExchange(FM25_SPI, 0xFF); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); + + return temp; +} + +void WriteFullControl(void) +{ + +} + diff --git a/.svn/pristine/41/415518ca463526c028407e3b454f9ce2bc4d3565.svn-base b/.svn/pristine/41/415518ca463526c028407e3b454f9ce2bc4d3565.svn-base new file mode 100644 index 0000000..9ac9550 --- /dev/null +++ b/.svn/pristine/41/415518ca463526c028407e3b454f9ce2bc4d3565.svn-base @@ -0,0 +1,279 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* ASCII STRING MANAGEMENT +* +* Filename : lib_str.h +* Version : V1.24 +* Programmer(s) : ITJ +* JDH +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_STR_MODULE_PRESENT +#define LIB_STR_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +* +* (3) NO compiler-supplied standard library functions SHOULD be used. +* +* #### The reference to standard library header files SHOULD be removed once all custom +* library functions are implemented WITHOUT reference to ANY standard library function(s). +* +* See also 'STANDARD LIBRARY MACRO'S Note #1'. +********************************************************************************************************* +*/ + +#include +#include +#include + + /* See Note #3. */ +#include +#include +#include +#include +#include + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef LIB_STR_MODULE +#define LIB_STR_EXT +#else +#define LIB_STR_EXT extern +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEFAULT CONFIGURATION +********************************************************************************************************* +*/ + +#ifndef LIB_STR_CFG_FP_EN +#define LIB_STR_CFG_FP_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define LIB_STR_NULL ((CPU_CHAR *)0) +#define LIB_STR_CMP_IDENTICAL 0 + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* STANDARD LIBRARY MACRO'S +* +* Note(s) : (1) NO compiler-supplied standard library functions SHOULD be used. +* +* #### The reference to standard memory functions SHOULD be removed once all custom library +* functions are implemented WITHOUT reference to ANY standard library function(s). +* +* See also 'INCLUDE FILES Note #3'. +********************************************************************************************************* +*/ + + /* See Note #1. */ +#define Str_IsAlpha(a) isalpha(a) +#define Str_IsDigit(a) isdigit(a) +#define Str_IsSpace(a) isspace(a) +#define Str_IsPrint(a) isprint(a) +#define Str_IsUpper(a) isupper(a) +#define Str_IsLower(a) islower(a) +#define Str_ToUpper(a) toupper(a) +#define Str_ToLower(a) tolower(a) + +#define Str_ToLong(a, b, c) strtol((char *)a, (char **)b, c) +#define Str_FmtPrint snprintf +#define Str_FmtScan sscanf + + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SIZE_T Str_Len (CPU_CHAR *pstr); + + + +CPU_CHAR *Str_Copy (CPU_CHAR *pdest, + CPU_CHAR *psrc); + +CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest, + CPU_CHAR *psrc, + CPU_SIZE_T len_max); + + +CPU_CHAR *Str_Cat (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat); + +CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat, + CPU_SIZE_T len_max); + + + +CPU_INT16S Str_Cmp (CPU_CHAR *p1_str, + CPU_CHAR *p2_str); + +CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str, + CPU_CHAR *p2_str, + CPU_SIZE_T len_max); + + +CPU_CHAR *Str_Char (CPU_CHAR *pstr, + CPU_CHAR srch_char); + +CPU_CHAR *Str_Char_N (CPU_CHAR *pstr, + CPU_SIZE_T len_max, + CPU_CHAR srch_char); + +CPU_CHAR *Str_Char_Last(CPU_CHAR *pstr, + CPU_CHAR srch_char); + + +CPU_CHAR *Str_Str (CPU_CHAR *pstr, + CPU_CHAR *srch_str); + + + +#if (LIB_STR_CFG_FP_EN == DEF_ENABLED) +CPU_CHAR *Str_FmtNbr_32(CPU_FP32 nbr, + CPU_INT08U nbr_dig, + CPU_INT08U nbr_dp, + CPU_BOOLEAN lead_zeros, + CPU_BOOLEAN nul, + CPU_CHAR *pstr_fmt); +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef LIB_STR_CFG_FP_EN +#error "LIB_STR_CFG_FP_EN not #define'd in 'app_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((LIB_STR_CFG_FP_EN != DEF_DISABLED) && \ + (LIB_STR_CFG_FP_EN != DEF_ENABLED )) +#error "LIB_STR_CFG_FP_EN illegally #define'd in 'app_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib str module include. */ + diff --git a/.svn/pristine/42/422692cf538764c56f4c0cccc558ea67aa10c855.svn-base b/.svn/pristine/42/422692cf538764c56f4c0cccc558ea67aa10c855.svn-base new file mode 100644 index 0000000..041e01e --- /dev/null +++ b/.svn/pristine/42/422692cf538764c56f4c0cccc558ea67aa10c855.svn-base @@ -0,0 +1,11 @@ +#ifndef _UART1_H_ +#define _UART1_H_ + +extern void Uart1_Purge(void); +extern void Uart1_Send(unsigned char *buf, int len); +extern int Uart1_Receive(unsigned char *buf, int len, int timeout); +extern void Uart1_WrByte(CPU_INT08U tx_byte); +extern int Uart1_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout); +extern void Uart1_Init(CPU_INT32U baud_rate); + +#endif //#ifndef _UART0_H_ diff --git a/.svn/pristine/48/4835c4fea373bb259539f233f42aebd4d1d435cf.svn-base b/.svn/pristine/48/4835c4fea373bb259539f233f42aebd4d1d435cf.svn-base new file mode 100644 index 0000000..25e23a2 --- /dev/null +++ b/.svn/pristine/48/4835c4fea373bb259539f233f42aebd4d1d435cf.svn-base @@ -0,0 +1,179 @@ +#ifndef _JOURNAL_H_ +#define _JOURNAL_H_ + +#include "control.h" +#include "fiscal.h" + +#define ERROR_RECORDS_NUM 256 // +#define EVENT_RECORDS_NUM 256 // + +// +typedef struct{ + CPU_INT32U time; + + // , 256 + CPU_INT32U error; + // + #define ERROR_EMPTY 0 + // + #define ERROR_VALIDATOR_CONN 1 + // + #define ERROR_VALIDATOR_FAILURE 2 + + // + // + #define ERROR_VALIDATOR_INSERTION 3 + // . + #define ERROR_VALIDATOR_MAGNETIC 4 + // + #define ERROR_VALIDATOR_CONVEYING 5 + // + #define ERROR_VALIDATOR_IDENT 6 + // + #define ERROR_VALIDATOR_VRFY 7 + // . + #define ERROR_VALIDATOR_OPT 8 + // + #define ERROR_VALIDATOR_INHIBIT 9 + // + #define ERROR_VALIDATOR_CAP 10 + // + #define ERROR_VALIDATOR_LNG 11 + // + #define ERROR_STACKER_FULL 12 + // + #define ERROR_STACKER_REMOVED 13 + // + #define ERROR_BV_JAMMED 14 + // + #define ERROR_ST_JAMMED 15 + // + #define ERROR_CHEATED 16 + // + #define ERROR_FLR_STACKER 17 + // . + #define ERROR_TR_SPEED 18 + // . + #define ERROR_FLR_TRANSPORT 19 + // + #define ERROR_FLR_ALIGNIN 20 + // + #define ERROR_FLR_INIT_CAS 21 + // + #define ERROR_FLR_OPT 22 + // . + #define ERROR_FLR_MAG 23 + // + #define ERROR_FLR_CAP 24 + + // + #define ERROR_MODEM_CONN 25 + + // + #define ERROR_FR_CONN 26 + + // + #define ERROR_FR 27 + + #define ERRORS_NUM (ERROR_FR+FR_ERROR_NUMBER) + + +}TErrorRecord; + +// +typedef struct{ + // + CPU_INT32U time; + + // : - , - , . + CPU_INT32U data; + + // + CPU_INT08U event; + #define JOURNAL_EVENT_NO_EVENT 0 // + #define JOURNAL_EVENT_MONEY_NOTE 1 // + #define JOURNAL_EVENT_MONEY_COIN 2 // (- ) + #define JOURNAL_EVENT_START_SESSION 3 // + #define JOURNAL_EVENT_END_SESSION 4 // + #define JOURNAL_EVENT_DEVICE_ON 6 // + #define JOURNAL_EVENT_PRINT_BILL 7 // + #define JOURNAL_EVENT_PRINT_Z 8 // z- + #define JOURNAL_EVENT_PRINT_X 9 // x- + #define JOURNAL_EVENT_PRINT_BUF 10 // x- + #define JOURNAL_EVENT_CHANGE_MODE 11 // + #define JOURNAL_EVENT_INCASSATION 12 // + #define JOURNAL_EVENT_PASS_FAIL 13 // + #define JOURNAL_EVENT_EMAIL_OK 14 // email + #define JOURNAL_EVENT_EMAIL_FAIL 15 // email + + #define JOURNAL_EVENTS_NUM 16 // + + // + CPU_INT08U channel; + +}TEventRecord; + + +// +typedef struct{ + // + CPU_INT32U CounterChannelRun[CHANNELS_NUM]; + // , . + CPU_INT32U CounterChannelTime[CHANNELS_NUM]; + // + CPU_INT32U CounterChannelMoney[CHANNELS_NUM]; + + // + CPU_INT32U CounterRun; + // , . + CPU_INT32U CounterTime; + // + CPU_INT32U CounterMoney; + + // + CPU_INT32U CounterBillNominals[24]; + // ( ) + CPU_INT32U BillsCount; +}TCounters; + + +// +// +typedef struct{ + // + CPU_INT32U CounterChannelRunLong[CHANNELS_NUM]; + // , . + CPU_INT32U CounterChannelTimeLong[CHANNELS_NUM]; + // + CPU_INT32U CounterChannelMoneyLong[CHANNELS_NUM]; + CPU_INT32U CounterRunLong; + CPU_INT32U CounterTimeLong; + CPU_INT32U CounterMoneyLong; + CPU_INT16U crc; +}TCountersLong; + + +extern CPU_INT32U GetShortMoney(); +extern void IncBillnomCounter(CPU_INT32U index); +extern void CheckLongCounters(void); +extern void SaveErrorRecord(CPU_INT32U error); +extern void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT32U data); +extern void SetErrorFlag(CPU_INT08U error); +extern void ClrErrorFlag(CPU_INT08U error); +extern int TstErrorFlag(CPU_INT08U error); +extern int TstCriticalErrors(void); +extern void ClearErrorJournal(void); +extern void ClearEventJournal(void); +extern void GetEventStr(char* str, char event); +extern int GetEventRecord(TEventRecord* record, CPU_INT32U index); +extern int GetErrorRecord(TErrorRecord* record, CPU_INT32U index); +extern void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money); +extern void ClearCounters(void); +extern void ErrorServer(void); +extern int TstCriticalValidatorErrors(void); +extern void ClrValidatorErrors(void); +extern void PrintEventJournalRecordEng(char* str, TEventRecord *record); +extern void GetEventStrEng(char* str, char event); +extern void ClearBillnomCounter(void); + +#endif //#ifndef _JOURNAL_H_ diff --git a/.svn/pristine/4d/4d13467a3603da0dee16dec1a34f9dfe3e564a84.svn-base b/.svn/pristine/4d/4d13467a3603da0dee16dec1a34f9dfe3e564a84.svn-base new file mode 100644 index 0000000..a6ba9bd --- /dev/null +++ b/.svn/pristine/4d/4d13467a3603da0dee16dec1a34f9dfe3e564a84.svn-base @@ -0,0 +1,328 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/CPU in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/CPU. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* IAR C Compiler +* +* Filename : cpu.h +* Version : V1.17 +* Programmer(s) : ITJ +* JJL +* JDH +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_MODULE_PRESENT +#define CPU_CFG_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_def.h +* +* (b) \\\\cpu*.* +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory & the +* specific CPU-compiler directory as additional include path directories. +********************************************************************************************************* +*/ + +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *pobj +* +* FnctName(pobj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef unsigned char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *); /* See Note #2b. */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size. */ + +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size. */ +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order. */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_DATA CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler allows in-line +* assembly AND will correctly modify the local stack pointer when interrupt status is +* pushed/popped onto the stack. +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (a) Save interrupt status into a local variable +* (b) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (c) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to +* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure +* 'CPU_SR' data type with the appropriate-sized CPU data type large enough to completely +* store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3). */ + + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +#define CPU_CRITICAL_ENTER() { cpu_sr = CPU_SR_Save(); } +#define CPU_CRITICAL_EXIT() { CPU_SR_Restore(cpu_sr); } + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of CPU cfg module inclusion. */ + diff --git a/.svn/pristine/4d/4d53cd22c76ed36a098618123bf8d6d9877a6a51.svn-base b/.svn/pristine/4d/4d53cd22c76ed36a098618123bf8d6d9877a6a51.svn-base new file mode 100644 index 0000000..c496b4d --- /dev/null +++ b/.svn/pristine/4d/4d53cd22c76ed36a098618123bf8d6d9877a6a51.svn-base @@ -0,0 +1,1239 @@ + + + + 2 + + Flash + + ARM + + 1 + + General + 3 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 28 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + DRIVERS + + ccnet + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.h + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.h + + + $PROJ_DIR$\DRIVERS\ccnet\VMCConst.h + + + + fiscal + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.h + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.h + + + + fram + + $PROJ_DIR$\DRIVERS\fram\fram.c + + + $PROJ_DIR$\DRIVERS\fram\fram.h + + + $PROJ_DIR$\DRIVERS\fram\spi.c + + + $PROJ_DIR$\DRIVERS\fram\spi.h + + + + keyboard + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.h + + + + lcd + + $PROJ_DIR$\DRIVERS\lcd\lcd.c + + + $PROJ_DIR$\DRIVERS\lcd\lcd.h + + + + modem + + $PROJ_DIR$\DRIVERS\modem\modem.c + + + $PROJ_DIR$\DRIVERS\modem\modem.h + + + $PROJ_DIR$\DRIVERS\modem\uart2.c + + + $PROJ_DIR$\DRIVERS\modem\uart2.h + + + + + OS + + app + + $PROJ_DIR$\OS\app\app.c + + + $PROJ_DIR$\OS\app\app_cfg.h + + + $PROJ_DIR$\OS\app\includes.h + + + $PROJ_DIR$\OS\app\os_cfg.h + + + + bsp + + $PROJ_DIR$\OS\bsp\bsp.c + + + $PROJ_DIR$\OS\bsp\bsp.h + + + $PROJ_DIR$\OS\bsp\cstartup.s + + + $PROJ_DIR$\OS\bsp\iolpc2368.h + + + $PROJ_DIR$\OS\bsp\LPC2368_Flash.icf + + + $PROJ_DIR$\OS\bsp\LPC2368_Flash.mac + + + + uc + + cpu + + $PROJ_DIR$\OS\uc\cpu\cpu.h + + + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + + + $PROJ_DIR$\OS\uc\cpu\cpu_def.h + + + + lib + + $PROJ_DIR$\OS\uc\lib\lib_def.h + + + $PROJ_DIR$\OS\uc\lib\lib_mem.c + + + $PROJ_DIR$\OS\uc\lib\lib_mem.h + + + $PROJ_DIR$\OS\uc\lib\lib_str.c + + + $PROJ_DIR$\OS\uc\lib\lib_str.h + + + + os_ii + + port + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu.h + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + + + + source + + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + + + $PROJ_DIR$\OS\uc\os_ii\source\ucos_ii.h + + + + + + + PROJECT + + app + + $PROJ_DIR$\PROJECT\app\app_serv.c + + + $PROJ_DIR$\PROJECT\app\app_serv.h + + + $PROJ_DIR$\PROJECT\app\control.c + + + $PROJ_DIR$\PROJECT\app\control.h + + + $PROJ_DIR$\PROJECT\app\journal.c + + + $PROJ_DIR$\PROJECT\app\journal.h + + + $PROJ_DIR$\PROJECT\app\modem_task.c + + + $PROJ_DIR$\PROJECT\app\modem_task.h + + + + data + + $PROJ_DIR$\PROJECT\data\data.c + + + $PROJ_DIR$\PROJECT\data\data.h + + + $PROJ_DIR$\PROJECT\data\datadesc.c + + + $PROJ_DIR$\PROJECT\data\datadesc.h + + + $PROJ_DIR$\PROJECT\data\fram_map.h + + + + menu + + $PROJ_DIR$\PROJECT\menu\menu.c + + + $PROJ_DIR$\PROJECT\menu\menu.h + + + $PROJ_DIR$\PROJECT\menu\menudesc.c + + + $PROJ_DIR$\PROJECT\menu\menudesc.h + + + + service + + $PROJ_DIR$\PROJECT\service\coin.c + + + $PROJ_DIR$\PROJECT\service\coin.h + + + $PROJ_DIR$\PROJECT\service\fr.c + + + $PROJ_DIR$\PROJECT\service\fr.h + + + $PROJ_DIR$\PROJECT\service\mode.c + + + $PROJ_DIR$\PROJECT\service\mode.h + + + $PROJ_DIR$\PROJECT\service\time.c + + + $PROJ_DIR$\PROJECT\service\time.h + + + $PROJ_DIR$\PROJECT\service\validator.c + + + $PROJ_DIR$\PROJECT\service\validator.h + + + + tools + + $PROJ_DIR$\PROJECT\tools\crc16.c + + + $PROJ_DIR$\PROJECT\tools\crc16.h + + + + $PROJ_DIR$\PROJECT\version.h + + + + + diff --git a/.svn/pristine/4d/4d7f94f10a834238832f14e0db4d77eb1416efbe.svn-base b/.svn/pristine/4d/4d7f94f10a834238832f14e0db4d77eb1416efbe.svn-base new file mode 100644 index 0000000..b775e75 --- /dev/null +++ b/.svn/pristine/4d/4d7f94f10a834238832f14e0db4d77eb1416efbe.svn-base @@ -0,0 +1,615 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* STANDARD MEMORY OPERATIONS +* +* Filename : lib_mem.h +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_MEM_MODULE_PRESENT +#define LIB_MEM_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +* +* (3) NO compiler-supplied standard library functions SHOULD be used. +********************************************************************************************************* +*/ + +#include +#include +#include + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef LIB_MEM_MODULE +#define LIB_MEM_EXT +#else +#define LIB_MEM_EXT extern +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MEMORY DATA VALUE MACRO'S +* +* Note(s) : (1) (a) Some variables & variable buffers to pass & receive data values MUST start on appropriate +* CPU word-aligned addresses. This is required because most word-aligned processors are more +* efficient & may even REQUIRE that multi-octet words start on CPU word-aligned addresses. +* +* (1) For 16-bit word-aligned processors, this means that +* +* all 16- & 32-bit words MUST start on addresses that are multiples of 2 octets +* +* (2) For 32-bit word-aligned processors, this means that +* +* all 16-bit words MUST start on addresses that are multiples of 2 octets +* all 32-bit words MUST start on addresses that are multiples of 4 octets +* +* (b) However, some data values macro's appropriately access data values from any CPU addresses, +* word-aligned or not. Thus for processors that require data word alignment, data words can +* be accessed to/from any CPU address, word-aligned or not, without generating data-word- +* alignment exceptions/faults. +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_GET_xxx() +* +* Description : Decode data values from any CPU memory address. +* +* Argument(s) : addr Lowest CPU memory address of data value to decode (see Notes #2 & #3a). +* +* Return(s) : Decoded data value from CPU memory address (see Notes #1 & #3b). +* +* Caller(s) : various. +* +* Note(s) : (1) Decode data values based on the values' data-word order in CPU memory : +* +* MEM_VAL_GET_xxx_BIG() Decode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_GET_xxx_LITTLE() Decode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_GET_xxx() Decode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) (a) MEM_VAL_GET_xxx() macro's decode data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be decoded from any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +* +* (b) However, any variable to receive the returned data value MUST start on an appropriate CPU +* word-aligned address. +* +* See also 'MEMORY DATA VALUE MACRO'S Note #1'. +* +* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_COPY_GET_xxx() Note #4'. +* +* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ + +#define MEM_VAL_GET_INT08U_BIG(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + +#define MEM_VAL_GET_INT16U_BIG(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (0 * DEF_OCTET_NBR_BITS))) + +#define MEM_VAL_GET_INT32U_BIG(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (3 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (2 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (0 * DEF_OCTET_NBR_BITS))) + + + +#define MEM_VAL_GET_INT08U_LITTLE(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + +#define MEM_VAL_GET_INT16U_LITTLE(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS))) + +#define MEM_VAL_GET_INT32U_LITTLE(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (2 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (3 * DEF_OCTET_NBR_BITS))) + + + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + +#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_BIG(addr) +#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_BIG(addr) +#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_BIG(addr) + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + +#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_LITTLE(addr) +#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_LITTLE(addr) +#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_LITTLE(addr) + +#else /* See Note #5. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_SET_xxx() +* +* Description : Encode data values to any CPU memory address. +* +* Argument(s) : addr Lowest CPU memory address to encode data value (see Notes #2 & #3a). +* +* val Data value to encode (see Notes #1 & #3b). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Encode data values into CPU memory based on the values' data-word order : +* +* MEM_VAL_SET_xxx_BIG() Encode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_SET_xxx_LITTLE() Encode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_SET_xxx() Encode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) (a) MEM_VAL_SET_xxx() macro's encode data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be encoded to any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +* +* (b) However, 'val' data value to encode MUST start on an appropriate CPU word-aligned address. +* +* See also 'MEMORY DATA VALUE MACRO'S Note #1'. +* +* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_COPY_SET_xxx() Note #4'. +* +* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ + +#define MEM_VAL_SET_INT08U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT16U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT32U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); } + + + +#define MEM_VAL_SET_INT08U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT16U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT32U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); } + + + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + +#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_BIG(addr, val) +#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_BIG(addr, val) +#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_BIG(addr, val) + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + +#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_LITTLE(addr, val) +#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_LITTLE(addr, val) +#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_LITTLE(addr, val) + +#else /* See Note #5. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_GET_xxx() +* +* Description : Copy & decode data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy/decode source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy/decode +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Copy/decode data values based on the values' data-word order : +* +* MEM_VAL_COPY_GET_xxx_BIG() Decode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_COPY_GET_xxx_LITTLE() Decode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_COPY_GET_xxx() Decode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_GET_xxx() macro's copy/decode data values without regard to CPU word-aligned +* addresses. Thus for processors that require data word alignment, data words can be copied/ +* decoded to/from any CPU address, word-aligned or not, without generating data-word-alignment +* exceptions/faults. +* +* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_GET_xxx() Note #4'. +* +* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets are +* inverse operations. +* +* See also 'MEM_VAL_COPY_SET_xxx() Note #5'. +* +* (6) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ +/*$PAGE*/ + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + + +#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + + +#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + + + +#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) + + + + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + + +#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + + + +#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + + +#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) + + + + +#else /* See Note #6. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_SET_xxx() +* +* Description : Copy & encode data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy/encode source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy/encode +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Copy/encode data values based on the values' data-word order : +* +* MEM_VAL_COPY_SET_xxx_BIG() Encode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_COPY_SET_xxx_LITTLE() Encode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_COPY_SET_xxx() Encode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_SET_xxx() macro's copy/encode data values without regard to CPU word-aligned +* addresses. Thus for processors that require data word alignment, data words can be copied/ +* encoded to/from any CPU address, word-aligned or not, without generating data-word-alignment +* exceptions/faults. +* +* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_SET_xxx() Note #4'. +* +* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets +* are inverse operations. +* +* See also 'MEM_VAL_COPY_GET_xxx() Note #5'. +********************************************************************************************************* +*/ + + /* See Note #5. */ +#define MEM_VAL_COPY_SET_INT08U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) + +#define MEM_VAL_COPY_SET_INT08U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) + + +#define MEM_VAL_COPY_SET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_xxx() +* +* Description : Copy data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) MEM_VAL_COPY_xxx() macro's copy data values based on CPU's native data-word order. +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_xxx() macro's copy data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be copied to/from any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +********************************************************************************************************* +*/ + +#define MEM_VAL_COPY_08(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_16(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_32(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void Mem_Clr (void *pmem, + CPU_SIZE_T size); + +void Mem_Set (void *pmem, + CPU_INT08U data_val, + CPU_SIZE_T size); + +void Mem_Copy(void *pdest, + void *psrc, + CPU_SIZE_T size); + +CPU_BOOLEAN Mem_Cmp (void *p1_mem, + void *p2_mem, + CPU_SIZE_T size); + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib mem module include. */ + diff --git a/.svn/pristine/51/51d60af534b455bdac2379c7c856bd152e928fed.svn-base b/.svn/pristine/51/51d60af534b455bdac2379c7c856bd152e928fed.svn-base new file mode 100644 index 0000000..62a46e6 --- /dev/null +++ b/.svn/pristine/51/51d60af534b455bdac2379c7c856bd152e928fed.svn-base @@ -0,0 +1,1320 @@ + + + + 2 + 2335931049 + + Flash + + $PROJ_DIR$\DRIVERS\ccnet\uart1.h + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + $PROJ_DIR$\DRIVERS\ccnet\VMCConst.h + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.h + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + $PROJ_DIR$\OS\uc\lib\lib_mem.c + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + $PROJ_DIR$\OS\uc\lib\lib_str.h + $PROJ_DIR$\OS\uc\lib\lib_str.c + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + $PROJ_DIR$\OS\uc\lib\lib_mem.h + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu.h + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + $PROJ_DIR$\OS\uc\os_ii\source\ucos_ii.h + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + $PROJ_DIR$\PROJECT\app\app_serv.c + $PROJ_DIR$\PROJECT\app\app_serv.h + $PROJ_DIR$\PROJECT\data\fram_map.h + $PROJ_DIR$\PROJECT\app\modem_task.c + $PROJ_DIR$\PROJECT\app\modem_task.h + $PROJ_DIR$\PROJECT\app\journal.c + $PROJ_DIR$\PROJECT\menu\menu.c + $PROJ_DIR$\PROJECT\menu\menudesc.h + $PROJ_DIR$\PROJECT\data\datadesc.c + $PROJ_DIR$\PROJECT\data\datadesc.h + $PROJ_DIR$\PROJECT\service\coin.c + $PROJ_DIR$\PROJECT\data\data.h + $PROJ_DIR$\PROJECT\app\journal.h + $PROJ_DIR$\Flash\Obj\uart1.o + $PROJ_DIR$\PROJECT\data\data.c + $PROJ_DIR$\PROJECT\menu\menudesc.c + $PROJ_DIR$\PROJECT\service\fr.c + $PROJ_DIR$\PROJECT\app\control.h + $PROJ_DIR$\PROJECT\menu\menu.h + $PROJ_DIR$\PROJECT\app\control.c + $PROJ_DIR$\Flash\Obj\cstartup.o + $PROJ_DIR$\Flash\Obj\data.o + $PROJ_DIR$\Flash\Obj\CCRSProtocol.pbi + $PROJ_DIR$\Flash\Obj\datadesc.pbi + $PROJ_DIR$\Flash\Obj\uart0.o + $PROJ_DIR$\Flash\Obj\time.pbi + $PROJ_DIR$\Flash\Obj\os_sem.o + $PROJ_DIR$\Flash\Obj\os_mem.o + $TOOLKIT_DIR$\inc\xencoding_limits.h + $PROJ_DIR$\Flash\Obj\os_time.pbi + $PROJ_DIR$\Flash\Obj\os_mutex.o + $PROJ_DIR$\Flash\Obj\os_mbox.pbi + $TOOLKIT_DIR$\inc\c\xlocale_c.h + $PROJ_DIR$\Flash\Obj\modem_task.pbi + $PROJ_DIR$\Flash\Obj\os_cpu_c.o + $TOOLKIT_DIR$\inc\DLib_Config_Normal.h + $TOOLKIT_DIR$\inc\c\wchar.h + $PROJ_DIR$\PROJECT\version.h + $PROJ_DIR$\PROJECT\tools\crc16.c + $PROJ_DIR$\PROJECT\service\time.h + $PROJ_DIR$\PROJECT\service\mode.h + $TOOLKIT_DIR$\inc\intrinsics.h + $PROJ_DIR$\PROJECT\service\fr.h + $PROJ_DIR$\PROJECT\service\time.c + $PROJ_DIR$\Flash\Obj\os_mbox.o + $TOOLKIT_DIR$\inc\c\io_macros.h + $TOOLKIT_DIR$\inc\c\xtgmath.h + $TOOLKIT_DIR$\inc\c\math.h + $TOOLKIT_DIR$\inc\xtls.h + $PROJ_DIR$\PROJECT\tools\crc16.h + $TOOLKIT_DIR$\inc\limits.h + $PROJ_DIR$\PROJECT\service\mode.c + $PROJ_DIR$\PROJECT\service\validator.c + $PROJ_DIR$\PROJECT\service\validator.h + $PROJ_DIR$\Flash\Obj\app_serv.pbi + $PROJ_DIR$\Flash\Obj\validator.pbi + $TOOLKIT_DIR$\inc\c\stdio.h + $PROJ_DIR$\Flash\Obj\os_core.o + $PROJ_DIR$\Flash\Obj\lib_mem.o + $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $TOOLKIT_DIR$\lib\rt4t_al.a + $TOOLKIT_DIR$\inc\c\yvals.h + $PROJ_DIR$\Flash\Obj\os_tmr.o + $TOOLKIT_DIR$\inc\c\ystdio.h + $PROJ_DIR$\Flash\Obj\mode.o + $TOOLKIT_DIR$\inc\xlocale.h + $TOOLKIT_DIR$\inc\stdarg.h + $PROJ_DIR$\Flash\Obj\coin.o + $TOOLKIT_DIR$\inc\xlocale_c.h + $PROJ_DIR$\Flash\Obj\crc16.o + $PROJ_DIR$\Flash\Obj\solarium.pbd + $PROJ_DIR$\Flash\Obj\bsp.pbi + $PROJ_DIR$\Flash\Obj\app.o + $PROJ_DIR$\Flash\Obj\lib_str.pbi + $PROJ_DIR$\Flash\Obj\os_core.pbi + $PROJ_DIR$\Flash\Obj\os_flag.o + $TOOLKIT_DIR$\inc\ycheck.h + $PROJ_DIR$\Flash\Obj\modem_task.o + $PROJ_DIR$\Flash\Obj\menu.pbi + $PROJ_DIR$\Flash\Exe\solarium.out + $TOOLKIT_DIR$\inc\DLib_Product_string.h + $PROJ_DIR$\Flash\Obj\os_dbg.o + $PROJ_DIR$\Flash\Obj\data.pbi + $PROJ_DIR$\Flash\Obj\uart2.pbi + $TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h + $TOOLKIT_DIR$\lib\shs_l.a + $PROJ_DIR$\Flash\Obj\os_sem.pbi + $TOOLKIT_DIR$\lib\dl4t_tln.a + $PROJ_DIR$\Flash\Obj\uart.pbi + $TOOLKIT_DIR$\inc\ctype.h + $PROJ_DIR$\Flash\Obj\uart.o + $PROJ_DIR$\Flash\Obj\os_mem.pbi + $PROJ_DIR$\Flash\Obj\crc16.pbi + $TOOLKIT_DIR$\inc\xmtx.h + $TOOLKIT_DIR$\inc\xlocaleuse.h + $PROJ_DIR$\Flash\Obj\modem.pbi + $TOOLKIT_DIR$\inc\io_macros.h + $TOOLKIT_DIR$\inc\c\errno.h + $PROJ_DIR$\Flash\Obj\lib_mem.pbi + $TOOLKIT_DIR$\inc\string.h + $TOOLKIT_DIR$\inc\c\xlocale.h + $PROJ_DIR$\Flash\Obj\journal.pbi + $TOOLKIT_DIR$\inc\c\ctype.h + $PROJ_DIR$\Flash\Obj\os_flag.pbi + $TOOLKIT_DIR$\inc\c\xmtx.h + $PROJ_DIR$\Flash\Obj\validator.o + $TOOLKIT_DIR$\lib\m4t_tl.a + $TOOLKIT_DIR$\inc\c\limits.h + $TOOLKIT_DIR$\inc\c\stddef.h + $PROJ_DIR$\DRIVERS\lcd.h + $PROJ_DIR$\Flash\Obj\fram.o + $PROJ_DIR$\Flash\Obj\os_time.o + $PROJ_DIR$\DRIVERS\modem\uart.c + $PROJ_DIR$\DRIVERS\ccnet\Command.h + $PROJ_DIR$\Flash\Obj\keyboard.o + $PROJ_DIR$\Flash\Obj\menu.o + $TOOLKIT_DIR$\inc\c\ycheck.h + $TOOLKIT_DIR$\inc\c\DLib_Threads.h + $PROJ_DIR$\Flash\Obj\app.pbi + $PROJ_DIR$\Flash\Obj\lcd.o + $TOOLKIT_DIR$\inc\errno.h + $TOOLKIT_DIR$\inc\c\xencoding_limits.h + $PROJ_DIR$\Flash\Obj\cpu_a.o + $PROJ_DIR$\Flash\Obj\datadesc.o + $PROJ_DIR$\Flash\Obj\os_mutex.pbi + $TOOLKIT_DIR$\inc\DLib_Defaults.h + $PROJ_DIR$\Flash\Obj\os_q.o + $PROJ_DIR$\Flash\Obj\uart2.o + $PROJ_DIR$\Flash\Obj\control.o + $TOOLKIT_DIR$\inc\DLib_Threads.h + $PROJ_DIR$\Flash\Obj\app_serv.o + $PROJ_DIR$\Flash\Obj\os_cpu_c.pbi + $TOOLKIT_DIR$\inc\c\xlocaleuse.h + $PROJ_DIR$\Flash\Obj\fr.o + $PROJ_DIR$\Flash\Obj\control.pbi + $TOOLKIT_DIR$\inc\ysizet.h + $PROJ_DIR$\Flash\Obj\Command.pbi + $PROJ_DIR$\Flash\Obj\spi.o + $PROJ_DIR$\DRIVERS\ccnet\Command.c + $TOOLKIT_DIR$\inc\c\string.h + $TOOLKIT_DIR$\inc\c\DLib_Product_string.h + $PROJ_DIR$\Flash\Obj\menudesc.o + $PROJ_DIR$\Flash\Obj\spi.pbi + $TOOLKIT_DIR$\inc\yvals.h + $PROJ_DIR$\DRIVERS\modem\uart.h + $PROJ_DIR$\Flash\Obj\os_dcc.o + $TOOLKIT_DIR$\inc\stdio.h + $TOOLKIT_DIR$\inc\c\DLib_Product.h + $PROJ_DIR$\Flash\Obj\journal.o + $PROJ_DIR$\Flash\Obj\lcd.pbi + $TOOLKIT_DIR$\inc\wchar.h + $PROJ_DIR$\Flash\Exe\solarium.hex + $TOOLKIT_DIR$\inc\c\ymath.h + $PROJ_DIR$\Flash\Obj\fiscal.pbi + $PROJ_DIR$\Flash\Obj\fr.pbi + $PROJ_DIR$\Flash\Obj\lib_str.o + $TOOLKIT_DIR$\inc\DLib_Product.h + $PROJ_DIR$\Flash\Obj\os_cpu_a.o + $PROJ_DIR$\Flash\Obj\os_q.pbi + $PROJ_DIR$\Flash\Obj\fiscal.o + $TOOLKIT_DIR$\inc\stdlib.h + $TOOLKIT_DIR$\inc\c\stdarg.h + $TOOLKIT_DIR$\inc\c\intrinsics.h + $PROJ_DIR$\Flash\Obj\fram.pbi + $PROJ_DIR$\Flash\Obj\uart1.pbi + $TOOLKIT_DIR$\inc\c\xtls.h + $PROJ_DIR$\Flash\Obj\os_dbg.pbi + $PROJ_DIR$\Flash\Obj\coin.pbi + $PROJ_DIR$\Flash\Obj\mode.pbi + $PROJ_DIR$\Flash\Obj\time.o + $PROJ_DIR$\Flash\Obj\uart0.pbi + $PROJ_DIR$\Flash\Obj\CCRSProtocol.o + $PROJ_DIR$\Flash\Obj\menudesc.pbi + $TOOLKIT_DIR$\inc\c\stdlib.h + $PROJ_DIR$\DRIVERS\lcd.c + $PROJ_DIR$\Flash\Obj\keyboard.pbi + $PROJ_DIR$\Flash\Obj\os_dcc.pbi + $PROJ_DIR$\Flash\Obj\os_task.o + $TOOLKIT_DIR$\inc\c\ysizet.h + $PROJ_DIR$\Flash\Obj\os_tmr.pbi + $PROJ_DIR$\Flash\Obj\modem.o + $PROJ_DIR$\Flash\Obj\bsp.o + $PROJ_DIR$\Flash\Obj\os_task.pbi + $PROJ_DIR$\OS\app\app.c + $PROJ_DIR$\OS\bsp\bsp.c + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + $PROJ_DIR$\DRIVERS\fiscal\fiscal.h + $PROJ_DIR$\DRIVERS\lcd\lcd.c + $PROJ_DIR$\DRIVERS\modem\uart2.h + $PROJ_DIR$\OS\app\app_cfg.h + $PROJ_DIR$\OS\bsp\bsp.h + $PROJ_DIR$\DRIVERS\keyboard\keyboard.h + $PROJ_DIR$\DRIVERS\lcd\lcd.h + $PROJ_DIR$\DRIVERS\modem\modem.c + $PROJ_DIR$\DRIVERS\fram\spi.h + $PROJ_DIR$\DRIVERS\fiscal\uart0.h + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + $PROJ_DIR$\DRIVERS\fram\fram.c + $PROJ_DIR$\DRIVERS\fram\spi.c + $PROJ_DIR$\DRIVERS\modem\modem.h + $PROJ_DIR$\DRIVERS\fram\fram.h + $PROJ_DIR$\DRIVERS\modem\uart2.c + $PROJ_DIR$\OS\uc\cpu\cpu_def.h + $PROJ_DIR$\OS\bsp\LPC2368_Flash.mac + $PROJ_DIR$\OS\uc\lib\lib_def.h + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + $PROJ_DIR$\OS\uc\cpu\cpu.h + $PROJ_DIR$\OS\bsp\iolpc2368.h + $PROJ_DIR$\OS\bsp\cstartup.s + $PROJ_DIR$\OS\app\includes.h + $PROJ_DIR$\OS\app\os_cfg.h + $PROJ_DIR$\PROJECT\service\coin.h + $PROJ_DIR$\OS\bsp\LPC2368_Flash.icf + + + [ROOT_NODE] + + + ILINK + 105 + + + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + + + BICOMP + 190 + + + ICCARM + 39 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 0 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 0 + + + + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + + + BICOMP + 179 + + + ICCARM + 185 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 221 212 68 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 221 212 68 + + + + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + + + BICOMP + 48 + + + ICCARM + 197 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 4 2 79 0 73 178 72 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 4 2 79 0 73 178 72 + + + + + $PROJ_DIR$\OS\uc\lib\lib_mem.c + + + BICOMP + 124 + + + ICCARM + 84 + + + + + BICOMP + 12 232 228 230 215 + + + ICCARM + 12 232 228 230 215 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + + + BICOMP + 100 + + + ICCARM + 83 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + + + AARM + 183 + + + + + $PROJ_DIR$\OS\uc\lib\lib_str.c + + + BICOMP + 99 + + + ICCARM + 181 + + + + + BICOMP + 9 232 228 230 215 199 142 87 85 173 147 143 204 128 126 191 130 158 58 62 123 133 82 89 + + + ICCARM + 9 232 228 230 215 199 142 87 85 110 173 147 143 204 128 126 191 130 158 58 62 123 133 82 89 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + + + BICOMP + 129 + + + ICCARM + 101 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + + + BICOMP + 57 + + + ICCARM + 70 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + + + BICOMP + 157 + + + ICCARM + 60 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + + + BICOMP + 117 + + + ICCARM + 53 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + + + BICOMP + 184 + + + ICCARM + 152 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + + + BICOMP + 112 + + + ICCARM + 52 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + + + BICOMP + 192 + + + ICCARM + 107 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + + + BICOMP + 208 + + + ICCARM + 203 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + + + BICOMP + 202 + + + ICCARM + 171 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + + + BICOMP + 55 + + + ICCARM + 137 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + + + BICOMP + 205 + + + ICCARM + 88 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + + + BICOMP + 150 + + + ICCARM + 56 + + + + + BICOMP + 24 215 236 20 + + + ICCARM + 24 215 236 20 + + + + + $PROJ_DIR$\PROJECT\app\app_serv.c + + + BICOMP + 80 + + + ICCARM + 156 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 225 79 237 65 212 44 37 66 33 38 43 35 4 68 75 30 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 225 79 237 65 212 44 37 66 33 38 43 35 4 68 75 30 + + + + + $PROJ_DIR$\PROJECT\app\modem_task.c + + + BICOMP + 59 + + + ICCARM + 103 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 38 43 212 225 30 27 37 35 65 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 38 43 212 225 30 27 37 35 65 + + + + + $PROJ_DIR$\PROJECT\app\journal.c + + + BICOMP + 127 + + + ICCARM + 174 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 134 38 43 212 226 28 35 37 65 68 75 66 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 134 38 43 212 226 28 35 37 65 68 75 66 + + + + + $PROJ_DIR$\PROJECT\menu\menu.c + + + BICOMP + 104 + + + ICCARM + 141 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 44 33 38 43 212 37 217 218 66 27 65 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 44 33 38 43 212 37 217 218 66 27 65 + + + + + $PROJ_DIR$\PROJECT\data\datadesc.c + + + BICOMP + 49 + + + ICCARM + 149 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 37 35 43 44 33 38 212 28 134 65 75 30 27 225 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 37 35 43 44 33 38 212 28 134 65 75 30 27 225 + + + + + $PROJ_DIR$\PROJECT\service\coin.c + + + BICOMP + 193 + + + ICCARM + 93 + + + + + BICOMP + 233 71 24 215 236 20 232 228 27 237 37 35 43 225 + + + ICCARM + 233 71 24 215 236 20 232 228 27 237 37 35 43 225 + + + + + $PROJ_DIR$\PROJECT\data\data.c + + + BICOMP + 108 + + + ICCARM + 47 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 37 35 43 226 65 134 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 37 35 43 226 65 134 + + + + + $PROJ_DIR$\PROJECT\menu\menudesc.c + + + BICOMP + 198 + + + ICCARM + 167 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 44 33 38 43 212 37 35 65 66 63 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 44 33 38 43 212 37 35 65 66 63 + + + + + $PROJ_DIR$\PROJECT\service\fr.c + + + BICOMP + 180 + + + ICCARM + 159 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 212 68 221 37 35 43 38 65 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 212 68 221 37 35 43 38 65 + + + + + $PROJ_DIR$\PROJECT\app\control.c + + + BICOMP + 160 + + + ICCARM + 154 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 43 37 35 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 43 37 35 + + + + + $PROJ_DIR$\PROJECT\tools\crc16.c + + + BICOMP + 118 + + + ICCARM + 95 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 75 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 75 + + + + + $PROJ_DIR$\PROJECT\service\time.c + + + BICOMP + 51 + + + ICCARM + 195 + + + + + BICOMP + 233 71 24 215 236 20 232 228 27 65 199 142 87 85 173 147 143 204 82 89 165 166 + + + ICCARM + 233 71 24 215 236 20 232 228 27 65 199 142 87 85 110 173 147 143 204 82 89 165 166 + + + + + $PROJ_DIR$\PROJECT\service\mode.c + + + BICOMP + 194 + + + ICCARM + 90 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 66 27 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 66 27 + + + + + $PROJ_DIR$\PROJECT\service\validator.c + + + BICOMP + 81 + + + ICCARM + 131 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 79 4 0 27 38 43 212 37 35 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 79 4 0 27 38 43 212 37 35 + + + + + $PROJ_DIR$\Flash\Obj\solarium.pbd + + + BILINK + 48 144 80 97 193 160 118 108 49 179 180 189 127 201 175 124 99 104 198 194 121 59 100 157 192 202 129 57 117 150 184 112 208 55 205 168 51 196 190 109 81 + + + + + $PROJ_DIR$\Flash\Exe\solarium.out + + + OBJCOPY + 177 + + + + + ILINK + 238 197 98 156 207 93 154 148 95 46 47 149 185 159 136 174 140 145 84 181 141 167 90 206 103 83 183 60 107 171 101 70 53 56 152 52 203 137 88 163 195 50 39 153 131 111 86 132 113 + + + + + $PROJ_DIR$\DRIVERS\modem\uart.c + + + BICOMP + 114 + + + ICCARM + 116 + + + + + BICOMP + 235 172 102 169 151 182 54 155 161 125 106 115 91 74 119 186 120 94 176 92 233 122 24 215 236 20 232 228 230 12 9 146 76 216 170 + + + ICCARM + 235 172 102 169 151 61 182 54 155 161 125 106 115 91 74 119 186 120 94 176 92 233 122 24 215 236 20 232 228 230 12 9 146 76 216 170 + + + + + $PROJ_DIR$\DRIVERS\ccnet\Command.c + + + BICOMP + 162 + + + + + BICOMP + 139 172 102 169 151 182 54 155 161 + + + ICCARM + 139 172 102 169 151 61 182 54 155 161 + + + + + $PROJ_DIR$\DRIVERS\lcd.c + + + BICOMP + 175 + + + ICCARM + 145 + + + + + BICOMP + 235 172 102 169 151 182 54 155 161 125 106 115 91 74 119 186 120 94 176 92 233 122 24 215 236 20 232 228 230 12 9 146 76 216 67 135 + + + ICCARM + 235 172 102 169 151 61 182 54 155 161 125 106 115 91 74 119 186 120 94 176 92 233 122 24 215 236 20 232 228 230 12 9 146 76 216 67 135 + + + + + $PROJ_DIR$\OS\app\app.c + + + BICOMP + 144 + + + ICCARM + 98 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 218 220 217 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 27 218 220 217 + + + + + $PROJ_DIR$\OS\bsp\bsp.c + + + BICOMP + 97 + + + ICCARM + 207 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 + + + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + + + BICOMP + 196 + + + ICCARM + 50 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 221 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 221 + + + + + $PROJ_DIR$\DRIVERS\lcd\lcd.c + + + BICOMP + 175 + + + ICCARM + 145 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 188 218 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 188 218 + + + + + $PROJ_DIR$\DRIVERS\modem\modem.c + + + BICOMP + 121 + + + ICCARM + 206 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 225 30 27 37 35 43 214 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 225 30 27 37 35 43 214 + + + + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + + + BICOMP + 201 + + + ICCARM + 140 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 217 27 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 217 27 + + + + + $PROJ_DIR$\DRIVERS\fram\fram.c + + + BICOMP + 189 + + + ICCARM + 136 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 220 226 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 220 226 + + + + + $PROJ_DIR$\DRIVERS\fram\spi.c + + + BICOMP + 168 + + + ICCARM + 163 + + + + + BICOMP + 233 71 24 215 236 20 199 142 87 85 173 147 143 204 232 228 220 + + + ICCARM + 233 71 24 215 236 20 199 142 87 85 110 173 147 143 204 232 228 220 + + + + + $PROJ_DIR$\DRIVERS\modem\uart2.c + + + BICOMP + 109 + + + ICCARM + 153 + + + + + BICOMP + 235 82 142 87 85 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 214 + + + ICCARM + 235 82 142 87 85 110 173 147 143 204 89 165 166 128 126 191 130 199 158 58 62 187 233 71 24 215 236 20 232 228 230 12 9 123 133 216 214 + + + + + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + + + AARM + 148 + + + + + $PROJ_DIR$\OS\bsp\cstartup.s + + + AARM + 46 + + + + + + + diff --git a/.svn/pristine/54/5499a160d26773cb5379183240262b1ffdc6ab53.svn-base b/.svn/pristine/54/5499a160d26773cb5379183240262b1ffdc6ab53.svn-base new file mode 100644 index 0000000..c62c23b --- /dev/null +++ b/.svn/pristine/54/5499a160d26773cb5379183240262b1ffdc6ab53.svn-base @@ -0,0 +1,5 @@ +#ifndef _VMCCONSTS_H_ +#define _VMCCONSTS_H_ + + +#endif // _VMCCONSTS_H_ diff --git a/.svn/pristine/55/55cd02b7c57a99aa8cc27a2a378e57c29807ce55.svn-base b/.svn/pristine/55/55cd02b7c57a99aa8cc27a2a378e57c29807ce55.svn-base new file mode 100644 index 0000000..2db1e44 --- /dev/null +++ b/.svn/pristine/55/55cd02b7c57a99aa8cc27a2a378e57c29807ce55.svn-base @@ -0,0 +1,270 @@ +#include +#include "uart0.h" + +#define UART0_RX_BUFSIZE 128 +#define UART0_TX_BUFSIZE 64 + +unsigned char UART0TXBuffer[UART0_TX_BUFSIZE]; +unsigned short UART0TXhead = 0; +unsigned short UART0TXtail = 0; +unsigned short UART0TXcount = 0; +unsigned char UART0RXBuffer[UART0_RX_BUFSIZE]; +unsigned short UART0RXhead = 0; +unsigned short UART0RXtail = 0; +unsigned short UART0RXcount = 0; + + +void Uart0_Flush(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + UART0TXcount = UART0TXhead = UART0TXtail = 0; + UART0RXcount = UART0RXhead = UART0RXtail = 0; + U0IER_bit.THREIE = 0; + U0FCR = 0x06; + OS_EXIT_CRITICAL(); +} + + +int Uart0_Getc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = -1; + + if (UART0RXcount > 0) + { + UART0RXcount--; + res = UART0RXBuffer[UART0RXhead++]; + UART0RXhead %= UART0_RX_BUFSIZE; + } + OS_EXIT_CRITICAL(); + + return res; +} + +int Uart0_Gotc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART0RXcount > 0) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + + +int Uart0_Ready() +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART0TXcount < UART0_TX_BUFSIZE) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart0_Putc(unsigned char ch) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + + if (UART0TXcount < UART0_TX_BUFSIZE) + { + if (UART0TXcount == 0) + { + if (U0LSR_bit.THRE) + { + U0THR = ch; + } + else + { + UART0TXcount++; + UART0TXBuffer[UART0TXtail++] = ch; + UART0TXtail %= UART0_TX_BUFSIZE; + U0IER = 3; + } + } + else + { + UART0TXcount++; + UART0TXBuffer[UART0TXtail++] = ch; + UART0TXtail %= UART0_TX_BUFSIZE; + U0IER = 3; + } + } + else + { + res = -1; + } + OS_EXIT_CRITICAL(); + return res; +} + + +void Uart0_Isr(void) +{ + CPU_INT08U IIRValue; + CPU_INT08U u1lsr; + volatile CPU_INT08U Dummy; + + IIRValue = U0IIR; + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + + if (IIRValue == 2) /* Receive Data Available */ + { + /* Receive Data Available */ + if (U0LSR_bit.DR) + { + if (UART0RXcount < UART0_RX_BUFSIZE) + { + UART0RXBuffer[UART0RXtail++] = U0RBR; + UART0RXtail %= UART0_RX_BUFSIZE; + UART0RXcount++; + } + else + { + Dummy = U0RBR; + } + } + } + else if (IIRValue == 1) /* THRE, transmit holding register empty */ + { + /* THRE interrupt */ + if (UART0TXcount > 0) + { + U0THR = UART0TXBuffer[UART0TXhead++]; + UART0TXhead %= UART0_TX_BUFSIZE; + UART0TXcount--; + } + else + { + U0IER = 1; + } + } + else + { + Dummy = U0RBR; + u1lsr = U0LSR; + u1lsr = u1lsr; + } + +} + +void Uart0_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(3); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */ + + U0IER = 0; + + U0FCR = 0x06; // enable and reset fifo + + U0ACR = 0; + + //U1FCR = 0x01; // enable and reset fifo + + U0LCR = 0x80; /* Enable acces to Divisor latches */ + + U0DLL = divlo; /* Load divisor */ + U0DLM = divhi; + U0FDR = 0x10; + + U0LCR = 0; + + U0LCR_bit.WLS = 0x03; // 8 bit + U0LCR_bit.SBS = 0; // 1 stop bit + + U0IER = 1; + + PINSEL0_bit.P0_2 = 0x1; + PINSEL0_bit.P0_3 = 0x1; + + PINMODE0_bit.P0_2 = 0; + PINMODE0_bit.P0_3 = 0; + + FIO0DIR_bit.P0_2 = 1; + FIO0DIR_bit.P0_3 = 0; + + FIO0MASK_bit.P0_2 = 1; + FIO0MASK_bit.P0_3 = 1; + + VICINTSELECT &= ~(1 << VIC_UART0); + VICVECTADDR6 = (CPU_INT32U)Uart0_Isr; + VICINTENABLE = (1 << VIC_UART0); + + Uart0_Flush(); + + OS_EXIT_CRITICAL(); +} + + +void Uart0_WrByte(CPU_INT08U tx_byte) +{ + while (Uart0_Putc(tx_byte) != 0) OSTimeDly(1); +} + + +void Uart0_Send(unsigned char *buf, int len) +{ + while (len--) Uart0_WrByte(*buf++); +} + + +int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout) +{ + CPU_INT32U ctr = 0; + int res = -1; + + while (res < 0) { + res = Uart0_Getc(); + if (res >= 0) break; + OSTimeDly(1); + if (ctr++ > timeout) return 0; + } + + *byte = res; + return 1; +} + + +int Uart0_Receive(unsigned char *buf, int len, int timeout) +{ + while (len--) + { + if (!Uart0_RdByteWithTimeOut(buf++, timeout)) return 0; + } + return 1; +} + diff --git a/.svn/pristine/56/5687b4ebe3351cf386222111c3cb4dd510abbac1.svn-base b/.svn/pristine/56/5687b4ebe3351cf386222111c3cb4dd510abbac1.svn-base new file mode 100644 index 0000000..60f82be --- /dev/null +++ b/.svn/pristine/56/5687b4ebe3351cf386222111c3cb4dd510abbac1.svn-base @@ -0,0 +1,372 @@ +#include +#include "validator.h" +#include "CCRSProtocol.h" +#include "uart1.h" +#include "app_serv.h" +#include "journal.h" +#include "data.h" +#include "datadesc.h" + + +OS_STK ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE]; +OS_EVENT *VLock = NULL; + +void CC_BusReset(void); +int ValidatorConnect(void); + +// +unsigned char VConnStat = VCONN_STATUS_NOCONN; + +TBillRecord VBillTable[24]; +/// - GUI +CPU_INT32U BillNominals[24]; + +TBillStatus VBillStatus; +/// +CPU_INT32U VBillCount = 0; +/// +CPU_INT32U VLastBillIndex = V_BILLS_NUMBER; + +void ValidatorTask(void *p_arg) +{ + char incas = 0; + // 1. , RESET + // 2. BUS RESET - min 100 ms + // 3. POLL 100-200 , 200 + + VBillCount = 0; + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + + while(1) + { + TPollResults polldata; + OSTimeDly(CC_POLL_TIME_OUT); + + CPU_INT32U enable; + GetData(&EnableValidatorDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + + // + if (VConnStat == VCONN_STATUS_NOCONN) + { // + if (!enable) + { // + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + continue; + } + // + if (ValidatorConnect() != 0) {SetErrorFlag(ERROR_VALIDATOR_CONN); continue;} + // + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + VConnStat = VCONN_STATUS_CONN; + } + else + { // + if (!enable) + { // + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + continue; + } + } + + // + if (CC_CmdPoll(ADDR_FL, &polldata)) + {// poll + + if ((incas) && (polldata.Z1 != ST_BOX)) + { + incas = 0; + PostUserEvent(EVENT_INCASSATION_FINISH); + } + + switch (polldata.Z1){ + // States CCNET states and events + case ST_POWER_UP: + case ST_POWER_BILL_ESCROW: + case ST_POWER_BILL_STACKER: + case ST_INITIALIZE: + case ST_IDLING: + case ST_ACCEPTING: + case ST_PACKING: + case ST_RETURNING: + case ST_DISABLED: + case ST_HOLDING: + case ST_BUSY: + ClrValidatorErrors(); + break; + case ST_REJECTING: + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + switch (polldata.Z2){ + case RJ_INSERTION: //!< Rejection because of insertion problem + case RJ_REMAINING: //!< Rejection because of other bill remaining in the device + SetErrorFlag(ERROR_VALIDATOR_INSERTION); + break; + case RJ_MAGNETIC: //!< Rejection because of invalid magnetic pattern + SetErrorFlag(ERROR_VALIDATOR_MAGNETIC); + break; + case RJ_CONVEYING: //!< Rejection because of conveying + SetErrorFlag(ERROR_VALIDATOR_CONVEYING); + break; + case RJ_IDENT: //!< Rejection because of identification failure + SetErrorFlag(ERROR_VALIDATOR_IDENT); + break; + case RJ_VRFY: //!< Rejection because of verification failure + SetErrorFlag(ERROR_VALIDATOR_VRFY); + break; + case RJ_OPT: //!< Rejection because of optical pattern mismatch + SetErrorFlag(ERROR_VALIDATOR_OPT); + break; + case RJ_INHIBIT: //!< Rejection because the denomination is inhibited + SetErrorFlag(ERROR_VALIDATOR_INHIBIT); + break; + case RJ_CAP: //!< Rejection because of capacity sensor pattern mismatch + SetErrorFlag(ERROR_VALIDATOR_CAP); + break; + case RJ_LNG: //!< Rejection because of invalid bill length + SetErrorFlag(ERROR_VALIDATOR_LNG); + break; + default: + break; + } + break; + case ST_ST_FULL: //!< DROP CASSETTE IS FULL state + SetErrorFlag(ERROR_STACKER_FULL); + break; + case ST_BOX: //!< DROP CASSETTE REMOVED state + //SetErrorFlag(ERROR_STACKER_REMOVED); + if (incas == 0) + { + PostUserEvent(EVENT_INCASSATION); + ClrValidatorErrors(); + incas = 1; + } + break; + case ST_BV_JAMMED: //!< JAM IN VALIDATOR state + SetErrorFlag(ERROR_BV_JAMMED); + break; + case ST_ST_JAMMED: //!< JAM IN STACKER state + SetErrorFlag(ERROR_ST_JAMMED); + break; + case ST_CHEATED: //!< CHEATED event + SetErrorFlag(ERROR_CHEATED); + break; + case ST_FAILURE: + switch (polldata.Z2){ + case FLR_STACKER: //!< Stacking mechanism failure + SetErrorFlag(ERROR_FLR_STACKER); + break; + case FLR_TR_SPEED: //!< Invalid speed of transport mechanism + SetErrorFlag(ERROR_TR_SPEED); + break; + case FLR_TRANSPORT: //!< Transport mechanism failure + SetErrorFlag(ERROR_FLR_TRANSPORT); + break; + case FLR_ALIGNING: //!< Aligning mechanism failure + SetErrorFlag(ERROR_FLR_ALIGNIN); + break; + case FLR_INIT_CAS: //!< Initial cassette status failure + SetErrorFlag(ERROR_FLR_INIT_CAS); + break; + case FLR_OPT: //!< Optical channel failure + SetErrorFlag(ERROR_FLR_OPT); + break; + case FLR_MAG: //!< Inductive channel failure + SetErrorFlag(ERROR_FLR_MAG); + break; + case FLR_CAP: //!< Capacity sensor failure + SetErrorFlag(ERROR_FLR_CAP); + break; + } + // , + SetErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_NOCONN; + break; + // Failure codes + case FLR_STACKER: + case FLR_TR_SPEED: + case FLR_TRANSPORT: + case FLR_ALIGNING: + case FLR_INIT_CAS: + case FLR_OPT: + case FLR_MAG: + case FLR_CAP: + SetErrorFlag(ERROR_VALIDATOR_FAILURE); + break; + // Credit events + case ST_PACKED: + // + // + if (!CC_CmdBillType(0x000000, 0x000000, ADDR_FL)){SetErrorFlag(ERROR_VALIDATOR_CONN);} + // + if (polldata.Z2 < V_BILLS_NUMBER) + { + VBillCount += VBillTable[polldata.Z2].Denomination; + // + VLastBillIndex = polldata.Z2; + } + else + { + VBillCount = 0; + // + VLastBillIndex = V_BILLS_NUMBER; + } + PostUserEvent(EVENT_BILL_STACKED); + ClrValidatorErrors(); + break; + case ESCROW: + if (polldata.Z2 < V_BILLS_NUMBER) + { + VBillCount += VBillTable[polldata.Z2].Denomination; + // + VLastBillIndex = polldata.Z2; + } + else + { + VBillCount = 0; + // + VLastBillIndex = V_BILLS_NUMBER; + } + PostUserEvent(EVENT_BILL_ESCROW); + ClrValidatorErrors(); + break; + case RETURNED: + ClrValidatorErrors(); + break; + default: + ClrValidatorErrors(); + break; + }// switch (polldata.Z1) + ClrErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_CONN; + } + else + { // + SetErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_NOCONN; + } + + } + +} + + +int ValidatorConnect(void) +{ + int i; + OSTimeDly(200); + + for (i = 0; i < 24; i++) + { + BillNominals[i] = 0; + } + + CC_BusReset(); + + // + if (!CC_CmdReset(ADDR_FL)) return -1; + + // + if (!CC_CmdGetBillTable(ADDR_FL, VBillTable)) return -2; + + for (i = 0; i < 24; i++) + { + BillNominals[i] = (CPU_INT32U)VBillTable[i].Denomination; + } + + // + if (!CC_CmdBillType(0x00000000, 0x00000000, ADDR_FL)) return -3; + + VConnStat = VCONN_STATUS_CONN; + + return 0; +} + + +int IsValidatorConnected(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int retval; + if (VConnStat == VCONN_STATUS_CONN) retval=1; + else retval=0; + OS_EXIT_CRITICAL(); + return retval; +} + + +// +void StartUpValidator(void) +{ + Uart1_Init(CC_VALIDATOR_SPEED); + + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + // BUS RESET init + PINSEL4_bit.P2_4 = 0; + PINMODE4_bit.P2_4 = 0; + FIO2DIR_bit.P2_4 = 1; + FIO2MASK_bit.P2_4 = 0; + FIO2CLR_bit.P2_4 = 1; + + OS_EXIT_CRITICAL(); + + if (!VLock) + { + VLock = OSSemCreate(1); + OSTaskCreate(ValidatorTask, (void *)0, (OS_STK *)&ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE-1], VALIDATOR_TASK_PRIO); + } +} + + +void CC_BusReset(void) +{ + VPend(); + FIO2CLR_bit.P2_4 = 1; + OSTimeDly(CC_BUS_RESET_TIME_OUT); + FIO2SET_bit.P2_4 = 1; + VPost(); +} + +// +void VPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(VLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// +void VPost(void) +{ + OSSemPost(VLock); +} + +// +CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U count = VBillCount; + VBillCount = 0; + *bill_index = VLastBillIndex; + OS_EXIT_CRITICAL(); + return count; +} + diff --git a/.svn/pristine/5e/5eab627664a90b2ef14758e7b9cf2a31e20d02ac.svn-base b/.svn/pristine/5e/5eab627664a90b2ef14758e7b9cf2a31e20d02ac.svn-base new file mode 100644 index 0000000..a66cf6b --- /dev/null +++ b/.svn/pristine/5e/5eab627664a90b2ef14758e7b9cf2a31e20d02ac.svn-base @@ -0,0 +1,229 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_CPU.H +* Version : V1.82 +* By : Jean J. Labrosse +* Jean-Denis Hatier +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#ifndef OS_CPU_H +#define OS_CPU_H + + +#ifdef OS_CPU_GLOBALS +#define OS_CPU_EXT +#else +#define OS_CPU_EXT extern +#endif + +#ifndef OS_CPU_FPU_EN +#define OS_CPU_FPU_EN 0 /* HW floating point support disabled by default */ +#endif + +/* +********************************************************************************************************* +* INTERRUPT DISABLE TIME MEASUREMENT +********************************************************************************************************* +*/ + +#define OS_CPU_INT_DIS_MEAS_EN 0 + + +/* +********************************************************************************************************* +* EXCEPTION DEFINES +********************************************************************************************************* +*/ + + /* ARM exception IDs */ +#define OS_CPU_ARM_EXCEPT_RESET 0x00 +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01 +#define OS_CPU_ARM_EXCEPT_SWI 0x02 +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03 +#define OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04 +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05 +#define OS_CPU_ARM_EXCEPT_IRQ 0x06 +#define OS_CPU_ARM_EXCEPT_FIQ 0x07 +#define OS_CPU_ARM_EXCEPT_NBR 0x08 + + /* ARM exception vectors addresses */ +#define OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x00) + + /* ARM exception handlers addresses */ +#define OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x20) + + /* ARM "Jump To Self" assembled instruction */ +#define OS_CPU_ARM_INSTR_JUMP_TO_SELF 0xEAFFFFFE + /* ARM "Jump To Exception Handler" assembled instruction*/ +#define OS_CPU_ARM_INSTR_JUMP_TO_HANDLER 0xE59FF018 + + +/* +********************************************************************************************************* +* DATA TYPES +* (Compiler Specific) +********************************************************************************************************* +*/ + +typedef unsigned char BOOLEAN; +typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ +typedef signed char INT8S; /* Signed 8 bit quantity */ +typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ +typedef signed short INT16S; /* Signed 16 bit quantity */ +typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ +typedef signed int INT32S; /* Signed 32 bit quantity */ +typedef float FP32; /* Single precision floating point */ +typedef double FP64; /* Double precision floating point */ + +typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */ +typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ + +/* +********************************************************************************************************* +* ARM +* +* Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts +* will be enabled even if they were disabled before entering the critical section. +* NOT IMPLEMENTED +* +* Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if +* interrupts were disabled before entering the critical section, they will be disabled when +* leaving the critical section. +* NOT IMPLEMENTED +* +* Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you +* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then +* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to +* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' +* into the CPU's status register. +********************************************************************************************************* +*/ + +#define OS_CRITICAL_METHOD 3 + + +#if OS_CRITICAL_METHOD == 3 + +#if OS_CPU_INT_DIS_MEAS_EN > 0 + +#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save(); \ + OS_CPU_IntDisMeasStart();} +#define OS_EXIT_CRITICAL() {OS_CPU_IntDisMeasStop(); \ + OS_CPU_SR_Restore(cpu_sr);} + +#else + +#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();} +#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);} + +#endif + +#endif + +/* +********************************************************************************************************* +* ARM Miscellaneous +********************************************************************************************************* +*/ + +#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */ + +#define OS_TASK_SW() OSCtxSw() + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + /* Variables used to measure interrupt disable time */ +#if OS_CPU_INT_DIS_MEAS_EN > 0 +OS_CPU_EXT INT16U OS_CPU_IntDisMeasNestingCtr; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsEnter; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsExit; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsMax; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsDelta; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsOvrhd; +#endif + +/* +********************************************************************************************************* +* PROTOTYPES +********************************************************************************************************* +*/ + +#if OS_CRITICAL_METHOD == 3 +__arm OS_CPU_SR OS_CPU_SR_Save(void); /* See OS_CPU_A.ASM */ +__arm void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); +#endif + +__arm void OS_CPU_SR_INT_Dis(void); +__arm void OS_CPU_SR_INT_En(void); +__arm void OS_CPU_SR_FIQ_Dis(void); +__arm void OS_CPU_SR_FIQ_En(void); +__arm void OS_CPU_SR_IRQ_Dis(void); +__arm void OS_CPU_SR_IRQ_En(void); + +#if OS_CPU_FPU_EN > 0 + void OS_CPU_FP_Init(void); /* See OS_CPU_C.C */ +__arm void OS_CPU_FP_Restore(void *pblk); +__arm void OS_CPU_FP_Save(void *pblk); +#endif + +__arm void OSCtxSw(void); +__arm void OSIntCtxSw(void); +__arm void OSStartHighRdy(void); + + void OS_CPU_InitExceptVect(void); + +__arm void OS_CPU_ARM_ExceptResetHndlr(void); +__arm void OS_CPU_ARM_ExceptUndefInstrHndlr(void); +__arm void OS_CPU_ARM_ExceptSwiHndlr(void); +__arm void OS_CPU_ARM_ExceptPrefetchAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptDataAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptAddrAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptIrqHndlr(void); +__arm void OS_CPU_ARM_ExceptFiqHndlr(void); + + void OS_CPU_ExceptHndlr(INT32U except_type); + +#if OS_CPU_INT_DIS_MEAS_EN > 0 + void OS_CPU_IntDisMeasInit(void); + void OS_CPU_IntDisMeasStart(void); + void OS_CPU_IntDisMeasStop(void); + INT16U OS_CPU_IntDisMeasTmrRd(void); +#endif + +#if OS_CPU_ARM_DCC_EN > 0 + void OSDCC_Handler(void); +#endif + +#endif diff --git a/.svn/pristine/5f/5fb79265af79d0210118506b98770e65c99237e9.svn-base b/.svn/pristine/5f/5fb79265af79d0210118506b98770e65c99237e9.svn-base new file mode 100644 index 0000000..24a309d --- /dev/null +++ b/.svn/pristine/5f/5fb79265af79d0210118506b98770e65c99237e9.svn-base @@ -0,0 +1,268 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* TIME MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_TIME.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +/* +********************************************************************************************************* +* DELAY TASK 'n' TICKS (n from 0 to 65535) +* +* Description: This function is called to delay execution of the currently running task until the +* specified number of system ticks expires. This, of course, directly equates to delaying +* the current task for some time to expire. No delay will result If the specified delay is +* 0. If the specified delay is greater than 0 then, a context switch will result. +* +* Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'. +* Note that by specifying 0, the task will not be delayed. +* +* Returns : none +********************************************************************************************************* +*/ + +void OSTimeDly (INT16U ticks) +{ + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + return; + } + if (ticks > 0) { /* 0 means no delay! */ + OS_ENTER_CRITICAL(); + y = OSTCBCur->OSTCBY; /* Delay current task */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; + } + OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next task to run! */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELAY TASK FOR SPECIFIED TIME +* +* Description: This function is called to delay execution of the currently running task until some time +* expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and +* MILLISECONDS instead of ticks. +* +* Arguments : hours specifies the number of hours that the task will be delayed (max. is 255) +* minutes specifies the number of minutes (max. 59) +* seconds specifies the number of seconds (max. 59) +* milli specifies the number of milliseconds (max. 999) +* +* Returns : OS_ERR_NONE +* OS_ERR_TIME_INVALID_MINUTES +* OS_ERR_TIME_INVALID_SECONDS +* OS_ERR_TIME_INVALID_MS +* OS_ERR_TIME_ZERO_DLY +* OS_ERR_TIME_DLY_ISR +* +* Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do +* a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be +* set to 0. The actual delay is rounded to the nearest tick. +********************************************************************************************************* +*/ + +#if OS_TIME_DLY_HMSM_EN > 0 +INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U ms) +{ + INT32U ticks; + INT16U loops; + + + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + return (OS_ERR_TIME_DLY_ISR); + } +#if OS_ARG_CHK_EN > 0 + if (hours == 0) { + if (minutes == 0) { + if (seconds == 0) { + if (ms == 0) { + return (OS_ERR_TIME_ZERO_DLY); + } + } + } + } + if (minutes > 59) { + return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */ + } + if (seconds > 59) { + return (OS_ERR_TIME_INVALID_SECONDS); + } + if (ms > 999) { + return (OS_ERR_TIME_INVALID_MS); + } +#endif + /* Compute the total number of clock ticks required.. */ + /* .. (rounded to the nearest tick) */ + ticks = ((INT32U)hours * 3600L + (INT32U)minutes * 60L + (INT32U)seconds) * OS_TICKS_PER_SEC + + OS_TICKS_PER_SEC * ((INT32U)ms + 500L / OS_TICKS_PER_SEC) / 1000L; + loops = (INT16U)(ticks >> 16); /* Compute the integral number of 65536 tick delays */ + ticks = ticks & 0xFFFFL; /* Obtain the fractional number of ticks */ + OSTimeDly((INT16U)ticks); + while (loops > 0) { + OSTimeDly((INT16U)32768u); + OSTimeDly((INT16U)32768u); + loops--; + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* RESUME A DELAYED TASK +* +* Description: This function is used resume a task that has been delayed through a call to either +* OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a +* task that is waiting for an event with timeout. This would make the task look +* like a timeout occurred. +* +* Also, you cannot resume a task that has called OSTimeDlyHMSM() with a combined time that +* exceeds 65535 clock ticks. In other words, if the clock tick runs at 100 Hz then, you will +* not be able to resume a delayed task that called OSTimeDlyHMSM(0, 10, 55, 350) or higher: +* +* (10 Minutes * 60 + 55 Seconds + 0.35) * 100 ticks/second. +* +* Arguments : prio specifies the priority of the task to resume +* +* Returns : OS_ERR_NONE Task has been resumed +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire +* OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex. +********************************************************************************************************* +*/ + +#if OS_TIME_DLY_RESUME_EN > 0 +INT8U OSTimeDlyResume (INT8U prio) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (prio >= OS_LOWEST_PRIO) { + return (OS_ERR_PRIO_INVALID); + } + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */ + if (ptcb == (OS_TCB *)0) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ + } + if (ptcb == OS_TCB_RESERVED) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ + } + if (ptcb->OSTCBDly == 0) { /* See if task is delayed */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */ + } + + ptcb->OSTCBDly = 0; /* Clear the time delay */ + if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { + ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */ + ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ + } else { + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + } + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OS_EXIT_CRITICAL(); + OS_Sched(); /* See if this is new highest priority */ + } else { + OS_EXIT_CRITICAL(); /* Task may be suspended */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET CURRENT SYSTEM TIME +* +* Description: This function is used by your application to obtain the current value of the 32-bit +* counter which keeps track of the number of clock ticks. +* +* Arguments : none +* +* Returns : The current value of OSTime +********************************************************************************************************* +*/ + +#if OS_TIME_GET_SET_EN > 0 +INT32U OSTimeGet (void) +{ + INT32U ticks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + ticks = OSTime; + OS_EXIT_CRITICAL(); + return (ticks); +} +#endif + +/* +********************************************************************************************************* +* SET SYSTEM CLOCK +* +* Description: This function sets the 32-bit counter which keeps track of the number of clock ticks. +* +* Arguments : ticks specifies the new value that OSTime needs to take. +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TIME_GET_SET_EN > 0 +void OSTimeSet (INT32U ticks) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + OSTime = ticks; + OS_EXIT_CRITICAL(); +} +#endif diff --git a/.svn/pristine/61/61df778e439040bc2e7c7390c57595ce9f80350c.svn-base b/.svn/pristine/61/61df778e439040bc2e7c7390c57595ce9f80350c.svn-base new file mode 100644 index 0000000..53ac529 --- /dev/null +++ b/.svn/pristine/61/61df778e439040bc2e7c7390c57595ce9f80350c.svn-base @@ -0,0 +1,30 @@ +#ifndef _FR_H_ +#define _FR_H_ + +// +#define WAIT_PRINT_TIMEOUT 10000 + +// +#define DEFAULT_PASS 1 + +extern CPU_INT08U FiscalConnState; + +extern int FReportGet(void); +extern void InitFiscal(void); +extern int IsFiscalConnected(void); +extern void FPend(void); +extern void FPost(void); +extern int PrintFiscalBill(CPU_INT32U money, CPU_INT32U time); +extern int PrintFiscalBillRepeated(CPU_INT32U money, CPU_INT32U time); +extern void SetFiscalErrorByCode(CPU_INT08U err); +extern void ClearFiscalErrors(void); +extern int TstCriticalFiscalError(void); +extern int GetFirstCriticalFiscalError(CPU_INT08U *err); +extern void ClrFiscalErrorByCode(CPU_INT08U err); +extern void FReportPend(void); +extern void FReportPost(void); +extern CPU_INT16U FReportTest(void); +extern int CheckFiscalStatus(); +extern int ConnectFiscalFast(void); + +#endif //#ifndef _FR_H_ diff --git a/.svn/pristine/62/628409cd914026c0cf635cc18ad73e615b8d93d2.svn-base b/.svn/pristine/62/628409cd914026c0cf635cc18ad73e615b8d93d2.svn-base new file mode 100644 index 0000000..ce75e5c --- /dev/null +++ b/.svn/pristine/62/628409cd914026c0cf635cc18ad73e615b8d93d2.svn-base @@ -0,0 +1,7 @@ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define DEVICE_FW_VERSION "03.25" + + +#endif // #ifndef _VERSION_H_ \ No newline at end of file diff --git a/.svn/pristine/63/63437cfb8210b598b7533626af5f844900a3a406.svn-base b/.svn/pristine/63/63437cfb8210b598b7533626af5f844900a3a406.svn-base new file mode 100644 index 0000000..6c086c1 --- /dev/null +++ b/.svn/pristine/63/63437cfb8210b598b7533626af5f844900a3a406.svn-base @@ -0,0 +1,322 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include "cpu.h" +#include "app_serv.h" +#include "time.h" +#include +#include +#include + + +void RTC_Isr (void) +{ + CPU_INT32U ilr; + + ilr = ILR & 0x7; + if (ilr & 0x1) PostUserEvent(EVENT_SEC); + + ILR = ilr; +} + + +void RTC_ReadTime(TRTC_Data *rtc) +{ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + rtc->sec = SEC; + rtc->min = MIN; + rtc->hour = HOUR; + rtc->day = DOW; + rtc->date = DOM; + rtc->mon = MONTH; + rtc->year = YEAR-2000; + OS_EXIT_CRITICAL(); +} + +void RTC_SetTime(TRTC_Data *rtc) +{ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + SEC = rtc->sec; + MIN = rtc->min; + HOUR = rtc->hour; + DOW = rtc->day; + DOM = rtc->date; + MONTH = rtc->mon; + YEAR = rtc->year+2000; + OS_EXIT_CRITICAL(); +} + + +extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk); + +void InitRTC(void) +{ +#if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; +#endif + + PCONP_bit.PCRTC = 1; + PCLKSEL0_bit.PCLK_RTC = 0; + + OS_ENTER_CRITICAL(); + + CCR = 0x0011; + PREINT = (BSP_CPU_PclkFreq(9) / 32768) - 1; + PREFRAC = BSP_CPU_PclkFreq(9) - ((PREINT + 1) * 32768); + + // If year is corrupt, set reasonable date. + if ((YEAR < 2010) || (HOUR > 23) || (YEAR > 2100)) { + CCR = 0x0000; + YEAR = 2010; + MONTH = 8; + DOM = 8; + HOUR = 7; + MIN = 0; + CCR = 0x0011; + } + + VICVECTADDR13 = (CPU_INT32U)RTC_Isr; + VICINTSELECT &= ~(1 << VIC_RTC); + VICVECTPRIORITY13 = 7; + VICINTENABLE = (1 << VIC_RTC); + + CISS = 0; + AMR = 0xff; + CIIR = 0x1; // sec interrupt + + OS_EXIT_CRITICAL(); +} + + +const char str_sunday[] = "b"; +const char str_monday[] = "b"; +const char str_tuesday[] = ""; +const char str_wednesday[] = ""; +const char str_thirsday[] = ""; +const char str_friday[] = ""; +const char str_saturday[] = ""; +const char* weekday[]={str_sunday, str_monday, str_tuesday, str_wednesday, str_thirsday, str_friday, str_saturday}; + +void GetDayText(char* str, char day) +{ + strcpy(str, weekday[day]); +} + +const char str_jan[] = ""; +const char str_feb[] = ""; +const char str_mar[] = ""; +const char str_apr[] = ""; +const char str_may[] = ""; +const char str_jun[] = ""; +const char str_jul[] = ""; +const char str_aug[] = ""; +const char str_sep[] = ""; +const char str_okt[] = ""; +const char str_nov[] = ""; +const char str_dec[] = ""; +const char* month[]={str_jan, str_feb, str_mar, str_apr, str_may, str_jun, str_jul, str_aug, str_sep, str_okt, str_nov, str_dec}; + + +// 1 1970 +#define JESUS_TO_70 2007437056 +// 1 1970 +#define JESUS_TO_70MIN 1035616320 + +// +CPU_INT16U const mon_add[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334}; +// +CPU_INT08U const mon_len[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; + +void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc) +{ + sprintf(str, "%02d:%02d:%02d %02d/%02d/%02d", rtc->hour, rtc->min, rtc->sec, rtc->date, rtc->mon, rtc->year); +} + +void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc) +{ + int hour, min, sec, date, mon, year; + sscanf(str, "%02d:%02d:%02d %02d/%02d/%02d", &hour, &min, &sec, &date, &mon, &year); + rtc->year = year; + rtc->mon = mon; + rtc->date = date; + rtc->hour = hour; + rtc->min = min; + rtc->sec = sec; +} + +// / +int RTCCheckTime(TRTC_Data *rtc) +{ + if (rtc->hour > 23) return -1; + if (rtc->min > 59) return -2; + if (rtc->sec > 59) return -3; + if ((rtc->mon > 12) || (rtc->mon < 1)) return -5; + if (rtc->year > 99) return -6; + + if ((rtc->year%4 == 0) && (rtc->mon == 2)) + { // + if ((rtc->date == 0) || (rtc->date > 29)) return -4; + } + else + { + if ((rtc->date == 0) || (rtc->date > mon_len[rtc->mon])) return -4; + } + return 0; +} + +void PrintRTCDateTimeString(char *str, TRTC_Data *rtc) +{ + sprintf(str, "20%02d/%02d/%02d %02d:%02d:%02d", rtc->year, rtc->mon, rtc->date, rtc->hour, rtc->min, rtc->sec); +} + +void PrintRTCTimeString(char *str, TRTC_Data *rtc) +{ + sprintf(str, "%02d:%02d:%02d", rtc->hour, rtc->min, rtc->sec); +} + +void PrintTimeString(char *str, CPU_INT32U time) +{ + TRTC_Data rtc_data; + Sec2Date(&rtc_data, time); + PrintRTCDateTimeStringRus(str, &rtc_data); +} + +void PrintSecToMinSec(char *str, int seconds) +{ + int min_ = seconds/60; + int sec_ = seconds%60; + sprintf(str, "%02d:%02d", min_, sec_); +} + +void PrintSecToHourMinSec(char *str, int seconds) +{ + int min_ = (seconds/60)%60; + int sec_ = seconds%60; + int hour_ = seconds/3600; + sprintf(str, "%02d:%02d:%02d", hour_, min_, sec_); +} + +void PrintSecToBigHourMinSec(char *str, int seconds) +{ + int min_ = (seconds/60)%60; + int sec_ = seconds%60; + int hour_ = seconds/3600; + sprintf(str, "%d:%02d:%02d", hour_, min_, sec_); +} + +CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType) +{ // + CPU_INT16U year = (CPU_INT16U)pData->year + ((pData->year >= 70) ? 1900 : 2000); + + // + CPU_INT32U ulIndex = (CPU_INT32U)(((year - 1) * 12) + pData->mon - 1); + + // . + if ( ucType != MONTH_TYPE ) + { // + ulIndex = ((year - 1) * 365L) + ((year - 1)/4) + mon_add[pData->mon] + pData->date; + + // . + if ( (!(year % 4)) && (pData->mon > 2) ) {ulIndex++;} + + // + if ( ucType != DAY_TYPE ) + { // c + ulIndex = ulIndex * 24L + pData->hour; + + if ( ucType != HOUR_TYPE ) + { // . + ulIndex = ulIndex * 60L + pData->min; + + if ( ucType != MIN_TYPE ) + { // . + ulIndex = ulIndex * 60L + pData->sec; + }//if( ) + }//if( ) + }//if( ) + }//if( ) + + return ulIndex; +} + +//------------------------------------------------------------------------ +// 1 1970 , pData +//------------------------------------------------------------------------ +CPU_INT32U GetSec( TRTC_Data *pData) +{ + CPU_INT32U ulIndex = Date2Sec(pData, MIN_TYPE);// . + ulIndex -= JESUS_TO_70MIN; // 1 1970 . + ulIndex *= 60L; // + ulIndex += pData->sec; // . + + return ulIndex; +} + +// e +CPU_INT32U GetTimeSec(void) +{ + TRTC_Data rtc; + RTC_ReadTime(&rtc); + return GetSec(&rtc); +} + + +// +void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec) +{ + pDest->year = 0; + pDest->mon = 0; + pDest->date = 0; + pDest->hour = ulSec/3600L; // + + ulSec %= 3600L; + pDest->min = ulSec/60L; // + + ulSec %= 60L; + pDest->sec = ulSec; // +} + + +// 1 1970 TRTC_Data. +void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec) +{ + CPU_INT32U dl = 0; + + dl = (ulSec)/86400L; + // + pDest->day = (dl+4)%7; + + if ( ulSec >= 946684800L ) + { // 1 2000 + ulSec -= 946684800L; + pDest->year = 0; + }//if( ) + else + { // 1970 1999 + pDest->year = 70; + }//else ( ) + + for ( dl = 365L; + ulSec >= (dl = 86400L * (365L + visocosn(pDest->year))); + ulSec -= dl, pDest->year++ ){;} + + for ( pDest->mon = 1; + ulSec >= ( dl = 86400L * + (mon_len[pDest->mon] + ((pDest->mon == 2) ? + visocosn(pDest->year) : 0))); ulSec -= dl, pDest->mon++){;} + + pDest->date = ulSec / (86400L) + 1; + ulSec %= 86400L; + pDest->hour = ulSec / 3600L; + ulSec %= 3600L; + pDest->min = ulSec / 60L; + ulSec %= 60L; + pDest->sec = ulSec; +} + + diff --git a/.svn/pristine/67/671d6f8eb0c01aaa11f2155ca9a3ddfb49824262.svn-base b/.svn/pristine/67/671d6f8eb0c01aaa11f2155ca9a3ddfb49824262.svn-base new file mode 100644 index 0000000..c5b201f --- /dev/null +++ b/.svn/pristine/67/671d6f8eb0c01aaa11f2155ca9a3ddfb49824262.svn-base @@ -0,0 +1,720 @@ +#include +#include "journal.h" +#include "modem.h" +#include "modem_task.h" +#include "data.h" +#include "datadesc.h" +#include "time.h" + +OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE]; +OS_EVENT *ModemQuery = NULL; +void *ModemTbl[MODEM_QUERY_LEN]; + +static int index; +static CPU_INT32U enable_journals; + +#define STAT_STR_NUM 17 + +static void GetChannelStatStr(char* str, int ch) +{ + CPU_INT32U val; + + GetData(&CounterChannelMoneyDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val); + + GetData(&CounterChannelRunDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %7d | ", val); + + GetData(&CounterChannelTimeDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); +} + +static void GetChannelStatStrLong(char* str, int ch) +{ + CPU_INT32U val; + + GetData(&CounterChannelMoneyLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val); + + GetData(&CounterChannelRunLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %7d | ", val); + + GetData(&CounterChannelTimeLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); +} + +extern CPU_INT32U BillNominals[24]; + +static int GetEmailStr(char *str) +{ + if (index < STAT_STR_NUM) + { + str[0] = 0; + if (index == 0) + { + // + TRTC_Data rtc; + RTC_ReadTime(&rtc); + sprintf(str, "Systemnoe vremya: "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc); + sprintf(&str[strlen(str)], "\r\n\r\n-------------------------------------------------------------\r\nStatistika obshaya. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n"); + } + else if (index == 1) + { + CPU_INT32U val; + // + sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n"); + + GetData(&CounterMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %16d ", val); + + GetData(&CounterRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %12d | ", val); + + GetData(&CounterTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); + } + else if (index == 2) + { + sprintf(&str[strlen(str)], "\r\n-------------------------------------------------------------\r\nStatistika obshaya. Dlinnye schetchiki\r\n-------------------------------------------------------------\r\n"); + } + else if (index == 3) + { + CPU_INT32U val; + // + sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n"); + + GetData(&CounterLongMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %16d ", val); + + GetData(&CounterLongRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %12d | ", val); + + GetData(&CounterLongTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); + + } + else if (index == 4) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n"); + } + else if (index == 5) + { + int i; + for (i = 0; i < 3; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 6) + { + int i; + for (i = 3; i < 6; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 7) + { + int i; + for (i = 6; i < 10; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 8) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Dlinnye schetchiki.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n"); + } + else if (index == 9) + { + int i; + for (i = 0; i < 3; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 10) + { + int i; + for (i = 3; i < 6; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 11) + { + int i; + for (i = 6; i < 10; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 12) + { + CPU_INT32U val; + // + sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n"); + GetData(&BillCounterDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + if (!val) + { + // + sprintf(&str[strlen(str)], "Kupuropriemnik pust.\r\n\r\n"); + index++; + index++; + } + else + { + sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n"); + } + } + else if (index == 13) + { + int i; + str[0] = 0; + for (i = 0; i < 6; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + val = strlen(str); + } + } + else if (index == 14) + { + int i; + str[0] = 0; + for (i = 6; i < 12; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 15) + { + int i; + str[0] = 0; + for (i = 12; i < 18; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 16) + { + int i; + str[0] = 0; + for (i = 18; i < 24; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + index++; + return 0; + } + else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM) + { + TEventRecord record; + + if (enable_journals == 0) return -1; + + GetEventRecord(&record, index-STAT_STR_NUM); + + + str[0] = 0; + if ((index-STAT_STR_NUM) == 0) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal sobytiy\r\n-------------------------------------------------------------\r\n"); + } + if (record.time == 0x00000000) + { + index++; + return 0; + } + PrintEventJournalRecordEng(&str[strlen(str)], &record); + index++; + return 0; + } + else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM+ERROR_RECORDS_NUM) + { + CPU_INT32U time = 0; + TRTC_Data rtc_data; + + str[0] = 0; + if ((index-(STAT_STR_NUM+EVENT_RECORDS_NUM)) == 0) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal oshibok\r\n-------------------------------------------------------------\r\n"); + } + + GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + if (time == 0x00000000) + { + index++; + return 0; + } + + sprintf(&str[strlen(str)], "| "); + GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + Sec2Date(&rtc_data, time); + PrintRTCDateTimeString(&str[strlen(str)], &rtc_data); + + sprintf(&str[strlen(str)], " | "); + GetDataStr(&JournalErrorNumberDescEng, (CPU_INT08U*)&str[strlen(str)], index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "\r\n"); + index++; + return 0; + } + + return -1; +} + +/// e-mail +int SendStatistics(void) +{ + CPU_INT32U dev_id; + char theme[48]; + index = 0; + // + GetData(&EnableEmailJournalSendDesc, &enable_journals, 0, DATA_FLAG_SYSTEM_INDEX); + // id + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Report from solarium device id %d.", dev_id); + return ModemSendEmail(theme, GetEmailStr); +} + +// +static int GetModemTask(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(ModemQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + +int GetTestText(char *str) +{ + if (index == 0) + { + index++; + sprintf(str, "Test message from solarium."); + return 0; + } + + return -1; +} +// +int SendTest(void) +{ + CPU_INT32U dev_id; + char theme[48]; + + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Test message. Device id %d.", dev_id); + + index = 0; + return ModemSendEmail(theme, GetTestText); +} + + +static CPU_INT32U incas_money; +static CPU_INT32U incas_time; + + +int GetIncasText(char *str) +{ + if (index == 0) + { + // + TRTC_Data rtc; + Sec2Date(&rtc, incas_time); + sprintf(str, "Vremya incassacii: "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc); + sprintf(&str[strlen(str)], "\r\n\r\nSumma %d rub.\r\n", incas_money); + } + else if (index == 1) + { + CPU_INT32U val; + // + val = incas_common_bill_counter; + if (!val) + { + // + sprintf(&str[strlen(str)], "Kupuropriemnik byl pust.\r\n\r\n"); + index=100; + } + else + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n"); + } + } + else if (index == 2) + { + int i; + str[0] = 0; + for (i = 0; i < 6; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + val = strlen(str); + } + } + else if (index == 3) + { + int i; + str[0] = 0; + for (i = 6; i < 12; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 4) + { + int i; + str[0] = 0; + for (i = 12; i < 18; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 5) + { + int i; + str[0] = 0; + for (i = 18; i < 24; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else + { + return -1; + } + + index++; + return 0; +} + +// +int SendIncas(void) +{ + CPU_INT32U dev_id; + char theme[48]; + + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Incassation. Device id %d.", dev_id); + + index = 0; + return ModemSendEmail(theme, GetIncasText); +} + + + +// +const int send_period_list[7] = {0, 1, 2, 4, 8, 12, 24}; +// +CPU_INT32U modem_status = 0; + +// , +int SamePeriod(CPU_INT32U time1, CPU_INT32U time2, CPU_INT08U period) +{ + TRTC_Data rtc1, rtc2; + CPU_INT08U hour1, hour2; + + Sec2Date(&rtc1, time1); + Sec2Date(&rtc2, time2); + + if ((rtc1.year != rtc2.year) || (rtc1.mon != rtc2.mon) || (rtc1.date != rtc2.date)) + { + // - + return 0; + } + + // time1 - + // + hour1 = rtc1.hour - (rtc1.hour % period); + // + hour2 = rtc2.hour - (rtc2.hour % period); + + if (hour1 != hour2) + { + return 0; + } + + return 1; +} + +#define MODEM_REPEAT_NUM 3 + +static CPU_INT32U last_stat_send_time; + +// +void ModemTask(void *p_arg) +{ + int task; + int send_res, send_ctr, repeat_ctr; + + while (1) + { + CPU_INT32U en = 0; + + OSTimeDly(100); + + if (!IsModemValid()) + { + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + if (en) + { + if (!IsModemConn()) + { + modem_status = 2; + } + else if (!IsModemConf()) + { + modem_status = 1; + } + + // + if (InitModem() != 0) + { + SetErrorFlag(ERROR_MODEM_CONN); + } + else + { + ClrErrorFlag(ERROR_MODEM_CONN); + } + } + else + { + modem_status = 0; + } + continue; + } + + modem_status = 0; + + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + if (!en) + { + ResetModemValid(); + continue; + } + + if (GetModemTask(&task)) + { + // + switch (task) + { + case MODEM_TASK_SEND_INCAS: + { + CPU_INT32U temp; + GetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + if (temp != INCAS_SEND_FLAG) + { + break; + } + GetData(&IncasMoneyDesc, &incas_money, 0, DATA_FLAG_SYSTEM_INDEX); + GetData(&IncasTimeDesc, &incas_time, 0, DATA_FLAG_SYSTEM_INDEX); + repeat_ctr = 0; + while (repeat_ctr < MODEM_REPEAT_NUM) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendIncas(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= MODEM_REPEAT_NUM) + { + // + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + // , , + PostModemTask(MODEM_TASK_SEND_INCAS); + } + else + { + temp = 0; + SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&IncasMoneyDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + } + } + break; + + case MODEM_TASK_SEND_STATISTICS: + repeat_ctr = 0; + while (repeat_ctr < MODEM_REPEAT_NUM) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendStatistics(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= MODEM_REPEAT_NUM) + { + // + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + // , , + // - , .. + //PostModemTask(MODEM_TASK_SEND_STATISTICS); + } + else + { + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + ClearCounters(); + SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + } + break; + + case MODEM_TASK_SEND_TEST_MSG: + repeat_ctr = 0; + while (repeat_ctr < 3) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendTest(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= 3) + { + // , + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + } + else + { + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + } + break; + + case MODEM_TASK_RECONNECT: + // + InitModem(); + break; + } + } + else + { + CPU_INT32U send_time, send_hour, send_minute; + CPU_INT32U last_send_time, sec; + TRTC_Data rtc_1, rtc_2; + + OSTimeDly(MODEM_TASK_DELAY); + // + GetData(&SystemTimeDesc, &sec, 0, DATA_FLAG_SYSTEM_INDEX); + + GetData(&StatSendHourMinDesc, &send_time, 0, DATA_FLAG_SYSTEM_INDEX); + send_hour = send_time / 60; + send_minute = send_time % 60; + + // + GetData(&LastEmailSendTime, &last_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + + Sec2Date(&rtc_1, sec); + Sec2Date(&rtc_2, last_send_time); + + // , + // 9.10 + if ((rtc_1.hour >= send_hour) && (rtc_1.min >= send_minute) && ((rtc_2.date != rtc_1.date) || (rtc_2.year != rtc_1.year) || (rtc_2.mon != rtc_1.mon))) + { + PostModemTask(MODEM_TASK_SEND_STATISTICS); + last_stat_send_time = sec; + //SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + // , + } + } + } +} + +// +void PostModemTask(int new_task) +{ + OSQPost(ModemQuery, (void *)new_task); +} diff --git a/.svn/pristine/6d/6d1c24d9e86a4c69729ee53d7085bfa1fd9f1201.svn-base b/.svn/pristine/6d/6d1c24d9e86a4c69729ee53d7085bfa1fd9f1201.svn-base new file mode 100644 index 0000000..c599dfb --- /dev/null +++ b/.svn/pristine/6d/6d1c24d9e86a4c69729ee53d7085bfa1fd9f1201.svn-base @@ -0,0 +1,141 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* uC/OS-II Configuration File for V2.8x +* +* File : OS_CFG.H +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_CFG_H +#define OS_CFG_H + + /* ---------------------- MISCELLANEOUS ----------------------- */ +#define OS_APP_HOOKS_EN 0 /* Application-defined hooks are called from the uC/OS-II hooks */ +#define OS_ARG_CHK_EN 0 /* Enable (1) or Disable (0) argument checking */ +#define OS_CPU_HOOKS_EN 1 /* uC/OS-II hooks are found in the processor port files */ + +#define OS_DEBUG_EN 1 /* Enable(1) debug variables */ + +#define OS_EVENT_NAME_SIZE 0 /* Determine the size of the name of a Sem, Mutex, Mbox or Q */ + +#define OS_LOWEST_PRIO 31 /* Defines the lowest priority that can be assigned ... */ + /* ... MUST NEVER be higher than 254! */ + +#define OS_MAX_EVENTS 10 /* Max. number of event control blocks in your application */ +#define OS_MAX_FLAGS 5 /* Max. number of Event Flag Groups in your application */ +#define OS_MAX_MEM_PART 5 /* Max. number of memory partitions */ +#define OS_MAX_QS 4 /* Max. number of queue control blocks in your application */ +#define OS_MAX_TASKS 16 /* Max. number of tasks in your application, MUST be >= 2 */ + +#define OS_SCHED_LOCK_EN 1 /* Include code for OSSchedLock() and OSSchedUnlock() */ + +#define OS_TICK_STEP_EN 1 /* Enable tick stepping feature for uC/OS-View */ +#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */ + + + /* --------------------- TASK STACK SIZE ---------------------- */ +#define OS_TASK_TMR_STK_SIZE 128 /* Timer task stack size (# of OS_STK wide entries) */ +#define OS_TASK_STAT_STK_SIZE 128 /* Statistics task stack size (# of OS_STK wide entries) */ +#define OS_TASK_IDLE_STK_SIZE 128 /* Idle task stack size (# of OS_STK wide entries) */ + + + /* --------------------- TASK MANAGEMENT ---------------------- */ +#define OS_TASK_CHANGE_PRIO_EN 1 /* Include code for OSTaskChangePrio() */ +#define OS_TASK_CREATE_EN 1 /* Include code for OSTaskCreate() */ +#define OS_TASK_CREATE_EXT_EN 1 /* Include code for OSTaskCreateExt() */ +#define OS_TASK_DEL_EN 1 /* Include code for OSTaskDel() */ +#define OS_TASK_NAME_SIZE 0 /* Determine the size of a task name */ +#define OS_TASK_PROFILE_EN 1 /* Include variables in OS_TCB for profiling */ +#define OS_TASK_QUERY_EN 1 /* Include code for OSTaskQuery() */ +#define OS_TASK_STAT_EN 0 /* Enable (1) or Disable(0) the statistics task */ +#define OS_TASK_STAT_STK_CHK_EN 1 /* Check task stacks from statistic task */ +#define OS_TASK_SUSPEND_EN 1 /* Include code for OSTaskSuspend() and OSTaskResume() */ +#define OS_TASK_SW_HOOK_EN 1 /* Include code for OSTaskSwHook() */ + + + /* ----------------------- EVENT FLAGS ------------------------ */ +#define OS_FLAG_EN 1 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ +#define OS_FLAG_ACCEPT_EN 1 /* Include code for OSFlagAccept() */ +#define OS_FLAG_DEL_EN 1 /* Include code for OSFlagDel() */ +#define OS_FLAG_NAME_SIZE 0 /* Determine the size of the name of an event flag group */ +#define OS_FLAGS_NBITS 16 /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ +#define OS_FLAG_QUERY_EN 1 /* Include code for OSFlagQuery() */ +#define OS_FLAG_WAIT_CLR_EN 1 /* Include code for Wait on Clear EVENT FLAGS */ + + + /* -------------------- MESSAGE MAILBOXES --------------------- */ +#define OS_MBOX_EN 1 /* Enable (1) or Disable (0) code generation for MAILBOXES */ +#define OS_MBOX_ACCEPT_EN 1 /* Include code for OSMboxAccept() */ +#define OS_MBOX_DEL_EN 1 /* Include code for OSMboxDel() */ +#define OS_MBOX_PEND_ABORT_EN 1 /* Include code for OSMboxPendAbort() */ +#define OS_MBOX_POST_EN 1 /* Include code for OSMboxPost() */ +#define OS_MBOX_POST_OPT_EN 1 /* Include code for OSMboxPostOpt() */ +#define OS_MBOX_QUERY_EN 1 /* Include code for OSMboxQuery() */ + + + /* --------------------- MEMORY MANAGEMENT -------------------- */ +#define OS_MEM_EN 1 /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ +#define OS_MEM_NAME_SIZE 0 /* Determine the size of a memory partition name */ +#define OS_MEM_QUERY_EN 1 /* Include code for OSMemQuery() */ + + + /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */ +#define OS_MUTEX_EN 1 /* Enable (1) or Disable (0) code generation for MUTEX */ +#define OS_MUTEX_ACCEPT_EN 1 /* Include code for OSMutexAccept() */ +#define OS_MUTEX_DEL_EN 1 /* Include code for OSMutexDel() */ +#define OS_MUTEX_QUERY_EN 1 /* Include code for OSMutexQuery() */ + + + /* ---------------------- MESSAGE QUEUES ---------------------- */ +#define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */ +#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */ +#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */ +#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */ +#define OS_Q_PEND_ABORT_EN 1 /* Include code for OSQPendAbort() */ +#define OS_Q_POST_EN 1 /* Include code for OSQPost() */ +#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */ +#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */ +#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */ + + + /* ------------------------ SEMAPHORES ------------------------ */ +#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */ +#define OS_SEM_ACCEPT_EN 1 /* Include code for OSSemAccept() */ +#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */ +#define OS_SEM_PEND_ABORT_EN 1 /* Include code for OSSemPendAbort() */ +#define OS_SEM_QUERY_EN 1 /* Include code for OSSemQuery() */ +#define OS_SEM_SET_EN 1 /* Include code for OSSemSet() */ + + + /* --------------------- TIME MANAGEMENT ---------------------- */ +#define OS_TIME_DLY_HMSM_EN 1 /* Include code for OSTimeDlyHMSM() */ +#define OS_TIME_DLY_RESUME_EN 1 /* Include code for OSTimeDlyResume() */ +#define OS_TIME_GET_SET_EN 1 /* Include code for OSTimeGet() and OSTimeSet() */ +#define OS_TIME_TICK_HOOK_EN 1 /* Include code for OSTimeTickHook() */ + + + /* --------------------- TIMER MANAGEMENT --------------------- */ +#define OS_TMR_EN 1 /* Enable (1) or Disable (0) code generation for TIMERS */ +#define OS_TMR_CFG_MAX 16 /* Maximum number of timers */ +#define OS_TMR_CFG_NAME_SIZE 0 /* Determine the size of a timer name */ +#define OS_TMR_CFG_WHEEL_SIZE 8 /* Size of timer wheel (#Spokes) */ +#define OS_TMR_CFG_TICKS_PER_SEC 10 /* Rate at which timer management task runs (Hz) */ + + +#endif diff --git a/.svn/pristine/71/7160dac02848c671305abb87fdf70346ff457c13.svn-base b/.svn/pristine/71/7160dac02848c671305abb87fdf70346ff457c13.svn-base new file mode 100644 index 0000000..51c02c6 --- /dev/null +++ b/.svn/pristine/71/7160dac02848c671305abb87fdf70346ff457c13.svn-base @@ -0,0 +1,616 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CUSTOM LIBRARY MODULE +* +* Filename : lib_def.h +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_DEF_MODULE_PRESENT +#define LIB_DEF_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CUSTOM LIBRARY MODULE VERSION NUMBER +* +* Note(s) : (1) (a) The custom library module software version is denoted as follows : +* +* Vx.yy +* +* where +* V denotes 'Version' label +* x denotes major software version revision number +* yy denotes minor software version revision number +* +* (b) The software version label #define is formatted as follows : +* +* ver = x.yy * 100 +* +* where +* ver denotes software version number scaled as an integer value +* x.yy denotes software version number +********************************************************************************************************* +*/ + +#define LIB_VERSION 124u /* See Note #1. */ + + +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +********************************************************************************************************* +*/ + +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* STANDARD DEFINES +********************************************************************************************************* +*/ + + +#define DEF_DISABLED 0 +#define DEF_ENABLED 1 + +#define DEF_FALSE 0 +#define DEF_TRUE 1 + +#define DEF_NO 0 +#define DEF_YES 1 + +#define DEF_OFF 0 +#define DEF_ON 1 + +#define DEF_CLR 0 +#define DEF_SET 1 + +#define DEF_ACTIVE 0 +#define DEF_INACTIVE 1 + +#define DEF_FAIL 0 +#define DEF_OK 1 + + + /* -------------------- BIT DEFINES ------------------- */ +#define DEF_BIT_NONE 0x00 + +#define DEF_BIT_00 0x01 +#define DEF_BIT_01 0x02 +#define DEF_BIT_02 0x04 +#define DEF_BIT_03 0x08 +#define DEF_BIT_04 0x10 +#define DEF_BIT_05 0x20 +#define DEF_BIT_06 0x40 +#define DEF_BIT_07 0x80 + +#define DEF_BIT_08 0x0100 +#define DEF_BIT_09 0x0200 +#define DEF_BIT_10 0x0400 +#define DEF_BIT_11 0x0800 +#define DEF_BIT_12 0x1000 +#define DEF_BIT_13 0x2000 +#define DEF_BIT_14 0x4000 +#define DEF_BIT_15 0x8000 + +#define DEF_BIT_16 0x00010000 +#define DEF_BIT_17 0x00020000 +#define DEF_BIT_18 0x00040000 +#define DEF_BIT_19 0x00080000 +#define DEF_BIT_20 0x00100000 +#define DEF_BIT_21 0x00200000 +#define DEF_BIT_22 0x00400000 +#define DEF_BIT_23 0x00800000 + +#define DEF_BIT_24 0x01000000 +#define DEF_BIT_25 0x02000000 +#define DEF_BIT_26 0x04000000 +#define DEF_BIT_27 0x08000000 +#define DEF_BIT_28 0x10000000 +#define DEF_BIT_29 0x20000000 +#define DEF_BIT_30 0x40000000 +#define DEF_BIT_31 0x80000000 + + /* ------------------- OCTET DEFINES ------------------ */ +#define DEF_OCTET_NBR_BITS 8 +#define DEF_OCTET_MASK 0xFF + +#define DEF_NIBBLE_NBR_BITS 4 +#define DEF_NIBBLE_MASK 0x0F + + +/*$PAGE*/ + /* ------------------ INTEGER DEFINES ----------------- */ +#define DEF_INT_08_NBR_BITS 8 +#define DEF_INT_08_MASK 0xFF + +#define DEF_INT_08U_MIN_VAL 0u +#define DEF_INT_08U_MAX_VAL 255u + +#define DEF_INT_08S_MIN_VAL -128 +#define DEF_INT_08S_MAX_VAL 127 + +#define DEF_INT_08S_MIN_VAL_ONES_CPL -127 +#define DEF_INT_08S_MAX_VAL_ONES_CPL 127 + + +#define DEF_INT_16_NBR_BITS 16 +#define DEF_INT_16_MASK 0xFFFF + +#define DEF_INT_16U_MIN_VAL 0u +#define DEF_INT_16U_MAX_VAL 65535u + +#define DEF_INT_16S_MIN_VAL -32768 +#define DEF_INT_16S_MAX_VAL 32767 + +#define DEF_INT_16S_MIN_VAL_ONES_CPL -32767 +#define DEF_INT_16S_MAX_VAL_ONES_CPL 32767 + + +#define DEF_INT_32_NBR_BITS 32 +#define DEF_INT_32_MASK 0xFFFFFFFF + +#define DEF_INT_32U_MIN_VAL 0u +#define DEF_INT_32U_MAX_VAL 4294967295u + +#define DEF_INT_32S_MIN_VAL -2147483648 +#define DEF_INT_32S_MAX_VAL 2147483647 + +#define DEF_INT_32S_MIN_VAL_ONES_CPL -2147483647 +#define DEF_INT_32S_MAX_VAL_ONES_CPL 2147483647 + + +#define DEF_INT_64_NBR_BITS 64 +#define DEF_INT_64_MASK 0xFFFFFFFFFFFFFFFF + +#define DEF_INT_64U_MIN_VAL 0u +#define DEF_INT_64U_MAX_VAL 18446744073709551615u + +#define DEF_INT_64S_MIN_VAL -9223372036854775808 +#define DEF_INT_64S_MAX_VAL 9223372036854775807 + +#define DEF_INT_64S_MIN_VAL_ONES_CPL -9223372036854775807 +#define DEF_INT_64S_MAX_VAL_ONES_CPL 9223372036854775807 + + +/*$PAGE*/ + /* ---------------- CPU INTEGER DEFINES --------------- */ +#define DEF_INT_CPU_NBR_BITS (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) + + +#if (DEF_INT_CPU_NBR_BITS == DEF_INT_08_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_08_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_08U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_08U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_08S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_08S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_08S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_08S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_16_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_16_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_16U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_16U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_16S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_16S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_16S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_16S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_32_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_32_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_32U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_32U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_32S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_32S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_32S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_32S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_64_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_64_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_64U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_64U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_64S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_64S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_64S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_64S_MAX_VAL_ONES_CPL + + +#else + +#error "CPU_CFG_DATA_SIZE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ + /* ------------------- TIME DEFINES ------------------- */ +#define DEF_TIME_NBR_HR_PER_DAY 24uL + +#define DEF_TIME_NBR_MIN_PER_HR 60uL +#define DEF_TIME_NBR_MIN_PER_DAY (DEF_TIME_NBR_MIN_PER_HR * DEF_TIME_NBR_HR_PER_DAY) + +#define DEF_TIME_NBR_SEC_PER_MIN 60uL +#define DEF_TIME_NBR_SEC_PER_HR (DEF_TIME_NBR_SEC_PER_MIN * DEF_TIME_NBR_MIN_PER_HR) +#define DEF_TIME_NBR_SEC_PER_DAY (DEF_TIME_NBR_SEC_PER_HR * DEF_TIME_NBR_HR_PER_DAY) + +#define DEF_TIME_NBR_mS_PER_SEC 1000uL +#define DEF_TIME_NBR_uS_PER_SEC 1000000uL +#define DEF_TIME_NBR_nS_PER_SEC 1000000000uL + + +/*$PAGE*/ +/* +********************************************************************************************************* +* BIT MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_BIT() +* +* Description : Create bit mask with single, specified bit set. +* +* Argument(s) : bit Bit number of bit to set. +* +* Return(s) : Bit mask with single, specified bit set. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT(bit) (1u << (bit)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_MASK() +* +* Description : Shift a bit mask. +* +* Argument(s) : bit_mask Bit mask to shift. +* +* bit_shift Number of bit positions to left-shift bit mask. +* +* Return(s) : Shifted bit mask. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_MASK(bit_mask, bit_shift) ((bit_mask) << (bit_shift)) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD() +* +* Description : Create & shift a contiguous bit field. +* +* Argument(s) : bit_field Number of contiguous bits to set in the bit field. +* +* bit_shift Number of bit positions to left-shift bit field. +* +* Return(s) : Shifted bit field. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler environment +* (e.g. negative or greater-than-CPU-data-size values) MAY generate compiler warnings +* &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD(bit_field, bit_shift) ((((bit_field) >= DEF_INT_CPU_NBR_BITS) ? (DEF_INT_CPU_U_MAX_VAL) \ + : (DEF_BIT(bit_field) - 1)) \ + << (bit_shift)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_SET() +* +* Description : Set specified bit(s) in a value. +* +* Argument(s) : val Value to modify by setting specified bit(s). +* +* mask Mask of bits to set. +* +* Return(s) : Modified value with specified bit(s) set. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_SET(val, mask) { (val) |= (mask); } + + +/* +********************************************************************************************************* +* DEF_BIT_CLR() +* +* Description : Clear specified bit(s) in a value. +* +* Argument(s) : val Value to modify by clearing specified bit(s). +* +* mask Mask of bits to clear. +* +* Return(s) : Modified value with specified bit(s) clear. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_CLR(val, mask) { (val) &= ~(mask); } + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_IS_SET() +* +* Description : Determine if specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set. +* +* Return(s) : DEF_YES, if ALL specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET(val, mask) ((((val) & (mask)) == (mask)) ? (DEF_YES) : (DEF_NO )) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR() +* +* Description : Determine if specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear. +* +* Return(s) : DEF_YES, if ALL specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR(val, mask) (((val) & (mask)) ? (DEF_NO ) : (DEF_YES)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_IS_SET_ANY() +* +* Description : Determine if any specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set. +* +* Return(s) : DEF_YES, if ANY specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET_ANY(val, mask) (((val) & (mask)) ? (DEF_YES) : (DEF_NO )) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR_ANY() +* +* Description : Determine if any specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear. +* +* Return(s) : DEF_YES, if ANY specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR_ANY(val, mask) ((((val) & (mask)) != (mask)) ? (DEF_YES) : (DEF_NO )) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MATH MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_MIN() +* +* Description : Determine the minimum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Minimum of the two values. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MIN(a, b) (((a) < (b)) ? (a) : (b)) + + +/* +********************************************************************************************************* +* DEF_MAX() +* +* Description : Determine the maximum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Maximum of the two values. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_ABS() +* +* Description : Determine the absolute value of a value. +* +* Argument(s) : a Value to calculate absolute value. +* +* Return(s) : Absolute value of the value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_ABS(a) (((a) < 0) ? (-(a)) : (a)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib def module include. */ + diff --git a/.svn/pristine/75/7522885d43c6c1fa2ee18af53264a130881aef8d.svn-base b/.svn/pristine/75/7522885d43c6c1fa2ee18af53264a130881aef8d.svn-base new file mode 100644 index 0000000..7da138c --- /dev/null +++ b/.svn/pristine/75/7522885d43c6c1fa2ee18af53264a130881aef8d.svn-base @@ -0,0 +1,1632 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* CORE FUNCTIONS +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_CORE.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#define OS_GLOBALS +#include +#endif + +/* +********************************************************************************************************* +* PRIORITY RESOLUTION TABLE +* +* Note: Index into table is bit pattern to resolve highest priority +* Indexed value corresponds to highest priority bit position (i.e. 0..7) +********************************************************************************************************* +*/ + +INT8U const OSUnMapTbl[256] = { + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */ + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */ + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */ + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */ +}; + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_InitEventList(void); + +static void OS_InitMisc(void); + +static void OS_InitRdyList(void); + +static void OS_InitTaskIdle(void); + +#if OS_TASK_STAT_EN > 0 +static void OS_InitTaskStat(void); +#endif + +static void OS_InitTCBList(void); + +static void OS_SchedNew(void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function is used to obtain the name assigned to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, the actual +* type is irrelevant. +* +* pname is a pointer to an ASCII string that will receive the name of the semaphore, +* mutex, mailbox or queue. The string must be able to hold at least +* OS_EVENT_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* +* Returns : The length of the string or 0 if the 'pevent' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +INT8U OSEventNameGet (OS_EVENT *pevent, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + len = OS_StrCopy(pname, pevent->OSEventName); /* Copy name from OS_EVENT */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function assigns a name to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, it doesn't +* matter the actual type. +* +* pname is a pointer to an ASCII string that will be used as the name of the semaphore, +* mutex, mailbox or queue. The string must be able to hold at least +* OS_EVENT_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +void OSEventNameSet (OS_EVENT *pevent, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return; + } + OS_ENTER_CRITICAL(); + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_EVENT_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pevent->OSEventName, pname); /* Yes, copy name to the event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* +* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to +* creating any uC/OS-II object and, prior to calling OSStart(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSInit (void) +{ + OSInitHookBegin(); /* Call port specific initialization code */ + + OS_InitMisc(); /* Initialize miscellaneous variables */ + + OS_InitRdyList(); /* Initialize the Ready List */ + + OS_InitTCBList(); /* Initialize the free list of OS_TCBs */ + + OS_InitEventList(); /* Initialize the free list of OS_EVENTs */ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + OS_FlagInit(); /* Initialize the event flag structures */ +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + OS_MemInit(); /* Initialize the memory manager */ +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + OS_QInit(); /* Initialize the message queue structures */ +#endif + + OS_InitTaskIdle(); /* Create the Idle Task */ +#if OS_TASK_STAT_EN > 0 + OS_InitTaskStat(); /* Create the Statistic Task */ +#endif + +#if OS_TMR_EN > 0 + OSTmr_Init(); /* Initialize the Timer Manager */ +#endif + + OSInitHookEnd(); /* Call port specific init. code */ + +#if OS_DEBUG_EN > 0 + OSDebugInit(); +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ENTER ISR +* +* Description: This function is used to notify uC/OS-II that you are about to service an interrupt +* service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus +* only perform rescheduling at the last nested ISR. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function should be called ith interrupts already disabled +* 2) Your ISR can directly increment OSIntNesting without calling this function because +* OSIntNesting has been declared 'global'. +* 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly. +* 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 5) You are allowed to nest interrupts up to 255 levels deep. +* 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because +* OSIntEnter() is always called with interrupts disabled. +********************************************************************************************************* +*/ + +void OSIntEnter (void) +{ + if (OSRunning == OS_TRUE) { + if (OSIntNesting < 255u) { + OSIntNesting++; /* Increment ISR nesting level */ + } + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* EXIT ISR +* +* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When +* the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether +* a new, high-priority task, is ready to run. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OSIntExit (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */ + OSIntNesting--; + } + if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */ + if (OSLockNesting == 0) { /* ... and not locked. */ + OS_SchedNew(); + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; +#if OS_TASK_PROFILE_EN > 0 + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Keep track of the number of ctx switches */ + OSIntCtxSw(); /* Perform interrupt level ctx switch */ + } + } + } + OS_EXIT_CRITICAL(); + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* PREVENT SCHEDULING +* +* Description: This function is used to prevent rescheduling to take place. This allows your application +* to prevent context switches until you are ready to permit context switching. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedLock (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0) { /* Can't call from an ISR */ + if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */ + OSLockNesting++; /* Increment lock nesting level */ + } + } + OS_EXIT_CRITICAL(); + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ENABLE SCHEDULING +* +* Description: This function is used to re-allow rescheduling. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedUnlock (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSLockNesting > 0) { /* Do not decrement if already 0 */ + OSLockNesting--; /* Decrement lock nesting level */ + if (OSLockNesting == 0) { /* See if scheduler is enabled and ... */ + if (OSIntNesting == 0) { /* ... not in an ISR */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* See if a HPT is ready */ + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* START MULTITASKING +* +* Description: This function is used to start the multitasking process which lets uC/OS-II manages the +* task that you have created. Before you can call OSStart(), you MUST have called OSInit() +* and you MUST have created at least one task. +* +* Arguments : none +* +* Returns : none +* +* Note : OSStartHighRdy() MUST: +* a) Call OSTaskSwHook() then, +* b) Set OSRunning to OS_TRUE. +* c) Load the context of the task pointed to by OSTCBHighRdy. +* d_ Execute the task. +********************************************************************************************************* +*/ + +void OSStart (void) +{ + if (OSRunning == OS_FALSE) { + OS_SchedNew(); /* Find highest priority's task priority number */ + OSPrioCur = OSPrioHighRdy; + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ + OSTCBCur = OSTCBHighRdy; + OSStartHighRdy(); /* Execute target specific code to start task */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS INITIALIZATION +* +* Description: This function is called by your application to establish CPU usage by first determining +* how high a 32-bit counter would count to in 1 second if no other tasks were to execute +* during that time. CPU usage is then determined by a low priority task which keeps track +* of this 32-bit counter every second but this time, with other tasks running. CPU usage is +* determined by: +* +* OSIdleCtr +* CPU Usage (%) = 100 * (1 - ------------) +* OSIdleCtrMax +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +void OSStatInit (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OSTimeDly(2); /* Synchronize with clock tick */ + OS_ENTER_CRITICAL(); + OSIdleCtr = 0L; /* Clear idle counter */ + OS_EXIT_CRITICAL(); + OSTimeDly(OS_TICKS_PER_SEC / 10); /* Determine MAX. idle counter value for 1/10 second */ + OS_ENTER_CRITICAL(); + OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1/10 second */ + OSStatRdy = OS_TRUE; + OS_EXIT_CRITICAL(); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* PROCESS SYSTEM TICK +* +* Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known +* as a 'clock tick'). This function should be called by the ticker ISR but, can also be +* called by a high priority task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSTimeTick (void) +{ + OS_TCB *ptcb; +#if OS_TICK_STEP_EN > 0 + BOOLEAN step; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_TIME_TICK_HOOK_EN > 0 + OSTimeTickHook(); /* Call user definable hook */ +#endif +#if OS_TIME_GET_SET_EN > 0 + OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */ + OSTime++; + OS_EXIT_CRITICAL(); +#endif + if (OSRunning == OS_TRUE) { +#if OS_TICK_STEP_EN > 0 + switch (OSTickStepState) { /* Determine whether we need to process a tick */ + case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */ + step = OS_TRUE; + break; + + case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */ + step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */ + break; + + case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */ + step = OS_TRUE; /* ... step command from uC/OS-View */ + OSTickStepState = OS_TICK_STEP_WAIT; + break; + + default: /* Invalid case, correct situation */ + step = OS_TRUE; + OSTickStepState = OS_TICK_STEP_DIS; + break; + } + if (step == OS_FALSE) { /* Return if waiting for step command */ + return; + } +#endif + ptcb = OSTCBList; /* Point at first TCB in TCB list */ + while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */ + OS_ENTER_CRITICAL(); + if (ptcb->OSTCBDly != 0) { /* No, Delayed or waiting for event with TO */ + if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */ + /* Check for timeout */ + if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_PEND_ANY; /* Yes, Clear status flag */ + ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ + } else { + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + } + + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } + } + } + ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */ + OS_EXIT_CRITICAL(); + } + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET VERSION +* +* Description: This function is used to return the version number of uC/OS-II. The returned value +* corresponds to uC/OS-II's version number multiplied by 100. In other words, version 2.00 +* would be returned as 200. +* +* Arguments : none +* +* Returns : the version number of uC/OS-II multiplied by 100. +********************************************************************************************************* +*/ + +INT16U OSVersion (void) +{ + return (OS_VERSION); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DUMMY FUNCTION +* +* Description: This function doesn't do anything. It is called by OSTaskDel(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0 +void OS_Dummy (void) +{ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY TO RUN BASED ON EVENT OCCURING +* +* Description: This function is called by other uC/OS-II services and is used to ready a task that was +* waiting for an event to occur. +* +* Arguments : pevent is a pointer to the event control block corresponding to the event. +* +* pmsg is a pointer to a message. This pointer is used by message oriented services +* such as MAILBOXEs and QUEUEs. The pointer is not used when called by other +* service functions. +* +* msk is a mask that is used to clear the status byte of the TCB. For example, +* OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc. +* +* pend_stat is used to indicate the readied task's pending status: +* +* OS_STAT_PEND_OK Task ready due to a post (or delete), not a timeout or +* an abort. +* OS_STAT_PEND_ABORT Task ready due to an abort. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *pmsg, INT8U msk, INT8U pend_stat) +{ + OS_TCB *ptcb; + INT8U x; + INT8U y; + INT8U prio; +#if OS_LOWEST_PRIO <= 63 + INT8U bitx; + INT8U bity; +#else + INT16U bitx; + INT16U bity; + INT16U *ptbl; +#endif + + +#if OS_LOWEST_PRIO <= 63 + y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message */ + bity = (INT8U)(1 << y); + x = OSUnMapTbl[pevent->OSEventTbl[y]]; + bitx = (INT8U)(1 << x); + prio = (INT8U)((y << 3) + x); /* Find priority of task getting the msg */ +#else + if ((pevent->OSEventGrp & 0xFF) != 0) { /* Find HPT waiting for message */ + y = OSUnMapTbl[pevent->OSEventGrp & 0xFF]; + } else { + y = OSUnMapTbl[(pevent->OSEventGrp >> 8) & 0xFF] + 8; + } + bity = (INT16U)(1 << y); + ptbl = &pevent->OSEventTbl[y]; + if ((*ptbl & 0xFF) != 0) { + x = OSUnMapTbl[*ptbl & 0xFF]; + } else { + x = OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8; + } + bitx = (INT16U)(1 << x); + prio = (INT8U)((y << 4) + x); /* Find priority of task getting the msg */ +#endif + + pevent->OSEventTbl[y] &= ~bitx; /* Remove this task from the waiting list */ + if (pevent->OSEventTbl[y] == 0) { + pevent->OSEventGrp &= ~bity; /* Clr group bit if this was only task pending */ + } + ptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB */ + ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from readying task */ + ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Unlink ECB from this task */ +#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) + ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task */ +#else + pmsg = pmsg; /* Prevent compiler warning if not used */ +#endif + ptcb->OSTCBStatPend = pend_stat; /* Set pend status of post or abort */ + ptcb->OSTCBStat &= ~msk; /* Clear bit associated with event type */ + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is ready (could be susp'd) */ + OSRdyGrp |= bity; /* Put task in the ready to run list */ + OSRdyTbl[y] |= bitx; + } + return (prio); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK WAIT FOR EVENT TO OCCUR +* +* Description: This function is called by other uC/OS-II services to suspend a task because an event has +* not occurred. +* +* Arguments : pevent is a pointer to the event control block for which the task will be waiting for. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventTaskWait (OS_EVENT *pevent) +{ + INT8U y; + + + OSTCBCur->OSTCBEventPtr = pevent; /* Store pointer to event control block in TCB */ + y = OSTCBCur->OSTCBY; /* Task no longer ready */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; /* Clear event grp bit if this was only task pending */ + } + pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list */ + pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY TO RUN BASED ON EVENT TIMEOUT OR ABORT +* +* Description: This function is called by other uC/OS-II services to make a task ready to run because a +* timeout or abort occurred. +* +* Arguments : pevent is a pointer to the event control block which is readying a task. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventTOAbort (OS_EVENT *pevent) +{ + INT8U y; + + + y = OSTCBCur->OSTCBY; + pevent->OSEventTbl[y] &= ~OSTCBCur->OSTCBBitX; /* Remove task from wait list */ + if (pevent->OSEventTbl[y] == 0x00) { + pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; + } + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ + OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set status to ready */ + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST +* +* Description: This function is called by other uC/OS-II services to initialize the event wait list. +* +* Arguments : pevent is a pointer to the event control block allocated to the event. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventWaitListInit (OS_EVENT *pevent) +{ +#if OS_LOWEST_PRIO <= 63 + INT8U *ptbl; +#else + INT16U *ptbl; +#endif + INT8U i; + + + pevent->OSEventGrp = 0; /* No task waiting on event */ + ptbl = &pevent->OSEventTbl[0]; + + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *ptbl++ = 0; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF EVENT CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of event control blocks. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitEventList (void) +{ +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +#if (OS_MAX_EVENTS > 1) + INT16U i; + OS_EVENT *pevent1; + OS_EVENT *pevent2; + + + OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table */ + pevent1 = &OSEventTbl[0]; + pevent2 = &OSEventTbl[1]; + for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */ + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = pevent2; +#if OS_EVENT_NAME_SIZE > 1 + pevent1->OSEventName[0] = '?'; /* Unknown name */ + pevent1->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent1++; + pevent2++; + } + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_SIZE > 1 + pevent1->OSEventName[0] = '?'; + pevent1->OSEventName[1] = OS_ASCII_NUL; +#endif + OSEventFreeList = &OSEventTbl[0]; +#else + OSEventFreeList = &OSEventTbl[0]; /* Only have ONE event control block */ + OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED; + OSEventFreeList->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_SIZE > 1 + OSEventFreeList->OSEventName[0] = '?'; /* Unknown name */ + OSEventFreeList->OSEventName[1] = OS_ASCII_NUL; +#endif +#endif +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE MISCELLANEOUS VARIABLES +* +* Description: This function is called by OSInit() to initialize miscellaneous variables. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitMisc (void) +{ +#if OS_TIME_GET_SET_EN > 0 + OSTime = 0L; /* Clear the 32-bit system clock */ +#endif + + OSIntNesting = 0; /* Clear the interrupt nesting counter */ + OSLockNesting = 0; /* Clear the scheduling lock counter */ + + OSTaskCtr = 0; /* Clear the number of tasks */ + + OSRunning = OS_FALSE; /* Indicate that multitasking not started */ + + OSCtxSwCtr = 0; /* Clear the context switch counter */ + OSIdleCtr = 0L; /* Clear the 32-bit idle counter */ + +#if OS_TASK_STAT_EN > 0 + OSIdleCtrRun = 0L; + OSIdleCtrMax = 0L; + OSStatRdy = OS_FALSE; /* Statistic task is not ready */ +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE READY LIST +* +* Description: This function is called by OSInit() to initialize the Ready List. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitRdyList (void) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *prdytbl; +#else + INT16U *prdytbl; +#endif + + + OSRdyGrp = 0; /* Clear the ready list */ + prdytbl = &OSRdyTbl[0]; + for (i = 0; i < OS_RDY_TBL_SIZE; i++) { + *prdytbl++ = 0; + } + + OSPrioCur = 0; + OSPrioHighRdy = 0; + + OSTCBHighRdy = (OS_TCB *)0; + OSTCBCur = (OS_TCB *)0; +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE IDLE TASK +* +* Description: This function creates the Idle Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTaskIdle (void) +{ +#if OS_TASK_NAME_SIZE > 7 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[0], /* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], + OS_TASK_IDLE_PRIO); + #else + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[0], + OS_TASK_IDLE_PRIO); + #endif +#endif + +#if OS_TASK_NAME_SIZE > 14 + OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err); +#else +#if OS_TASK_NAME_SIZE > 7 + OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err); +#endif +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE STATISTIC TASK +* +* Description: This function creates the Statistic Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +static void OS_InitTaskStat (void) +{ +#if OS_TASK_NAME_SIZE > 7 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #else + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #else + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #endif +#endif + +#if OS_TASK_NAME_SIZE > 14 + OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err); +#else +#if OS_TASK_NAME_SIZE > 7 + OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err); +#endif +#endif +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TASK CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TCBs. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTCBList (void) +{ + INT8U i; + OS_TCB *ptcb1; + OS_TCB *ptcb2; + + + OS_MemClr((INT8U *)&OSTCBTbl[0], sizeof(OSTCBTbl)); /* Clear all the TCBs */ + OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl)); /* Clear the priority table */ + ptcb1 = &OSTCBTbl[0]; + ptcb2 = &OSTCBTbl[1]; + for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { /* Init. list of free TCBs */ + ptcb1->OSTCBNext = ptcb2; +#if OS_TASK_NAME_SIZE > 1 + ptcb1->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + ptcb1++; + ptcb2++; + } + ptcb1->OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */ +#if OS_TASK_NAME_SIZE > 1 + ptcb1->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + OSTCBList = (OS_TCB *)0; /* TCB lists initializations */ + OSTCBFreeList = &OSTCBTbl[0]; +} +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR A SECTION OF MEMORY +* +* Description: This function is called by other uC/OS-II services to clear a contiguous block of RAM. +* +* Arguments : pdest is the start of the RAM to clear (i.e. write 0x00 to) +* +* size is the number of bytes to clear. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Note that we can only clear up to 64K bytes of RAM. This is not an issue because none +* of the uses of this function gets close to this limit. +* 3) The clear is done one byte at a time since this will work on any processor irrespective +* of the alignment of the destination. +********************************************************************************************************* +*/ + +void OS_MemClr (INT8U *pdest, INT16U size) +{ + while (size > 0) { + *pdest++ = (INT8U)0; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* COPY A BLOCK OF MEMORY +* +* Description: This function is called by other uC/OS-II services to copy a block of memory from one +* location to another. +* +* Arguments : pdest is a pointer to the 'destination' memory block +* +* psrc is a pointer to the 'source' memory block +* +* size is the number of bytes to copy. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. There is +* no provision to handle overlapping memory copy. However, that's not a problem since this +* is not a situation that will happen. +* 2) Note that we can only copy up to 64K bytes of RAM +* 3) The copy is done one byte at a time since this will work on any processor irrespective +* of the alignment of the source and destination. +********************************************************************************************************* +*/ + +void OS_MemCopy (INT8U *pdest, INT8U *psrc, INT16U size) +{ + while (size > 0) { + *pdest++ = *psrc++; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* SCHEDULER +* +* Description: This function is called by other uC/OS-II services to determine whether a new, high +* priority task has been made ready to run. This function is invoked by TASK level code +* and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling). +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OS_Sched (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0) { /* Schedule only if all ISRs done and ... */ + if (OSLockNesting == 0) { /* ... scheduler is not locked */ + OS_SchedNew(); + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; +#if OS_TASK_PROFILE_EN > 0 + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Increment context switch counter */ + OS_TASK_SW(); /* Perform a context switch */ + } + } + } + OS_EXIT_CRITICAL(); +} + + +/* +********************************************************************************************************* +* FIND HIGHEST PRIORITY TASK READY TO RUN +* +* Description: This function is called by other uC/OS-II services to determine the highest priority task +* that is ready to run. The global variable 'OSPrioHighRdy' is changed accordingly. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Interrupts are assumed to be disabled when this function is called. +********************************************************************************************************* +*/ + +static void OS_SchedNew (void) +{ +#if OS_LOWEST_PRIO <= 63 /* See if we support up to 64 tasks */ + INT8U y; + + + y = OSUnMapTbl[OSRdyGrp]; + OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); +#else /* We support up to 256 tasks */ + INT8U y; + INT16U *ptbl; + + + if ((OSRdyGrp & 0xFF) != 0) { + y = OSUnMapTbl[OSRdyGrp & 0xFF]; + } else { + y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8; + } + ptbl = &OSRdyTbl[y]; + if ((*ptbl & 0xFF) != 0) { + OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]); + } else { + OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8); + } +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* COPY AN ASCII STRING +* +* Description: This function is called by other uC/OS-II services to copy an ASCII string from a 'source' +* string to a 'destination' string. +* +* Arguments : pdest is a pointer to the string that will be receiving the copy. Note that there MUST +* be sufficient space in the destination storage area to receive this string. +* +* psrc is a pointer to the source string. The source string MUST NOT be greater than +* 254 characters. +* +* Returns : The size of the string (excluding the NUL terminating character) +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) || (OS_TMR_CFG_NAME_SIZE > 1) +INT8U OS_StrCopy (INT8U *pdest, INT8U *psrc) +{ + INT8U len; + + + len = 0; + while (*psrc != OS_ASCII_NUL) { + *pdest++ = *psrc++; + len++; + } + *pdest = OS_ASCII_NUL; + return (len); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* DETERMINE THE LENGTH OF AN ASCII STRING +* +* Description: This function is called by other uC/OS-II services to determine the size of an ASCII string +* (excluding the NUL character). +* +* Arguments : psrc is a pointer to the string for which we need to know the size. +* +* Returns : The size of the string (excluding the NUL terminating character) +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) The string to check must be less than 255 characters long. +********************************************************************************************************* +*/ + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) || (OS_TMR_CFG_NAME_SIZE > 1) +INT8U OS_StrLen (INT8U *psrc) +{ + INT8U len; + + + len = 0; + while (*psrc != OS_ASCII_NUL) { + psrc++; + len++; + } + return (len); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* IDLE TASK +* +* Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks +* executes because they are ALL waiting for event(s) to occur. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be +* enabled for at least a few instructions. On some processors (ex. Philips XA), enabling +* and then disabling interrupts didn't allow the processor enough time to have interrupts +* enabled before they were disabled again. uC/OS-II would thus never recognize +* interrupts. +* 2) This hook has been added to allow you to do such things as STOP the CPU to conserve +* power. +********************************************************************************************************* +*/ + +void OS_TaskIdle (void *p_arg) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + (void)p_arg; /* Prevent compiler warning for not using 'parg' */ + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtr++; + OS_EXIT_CRITICAL(); + OSTaskIdleHook(); /* Call user definable HOOK */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS TASK +* +* Description: This task is internal to uC/OS-II and is used to compute some statistics about the +* multitasking environment. Specifically, OS_TaskStat() computes the CPU usage. +* CPU usage is determined by: +* +* OSIdleCtr +* OSCPUUsage = 100 * (1 - ------------) (units are in %) +* OSIdleCtrMax +* +* Arguments : parg this pointer is not used at this time. +* +* Returns : none +* +* Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the +* next higher priority, OS_TASK_IDLE_PRIO-1. +* 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0. +* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the +* maximum value for the idle counter. +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +void OS_TaskStat (void *p_arg) +{ + INT32U run; + INT32U max; + INT8S usage; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + p_arg = p_arg; /* Prevent compiler warning for not using 'parg' */ + while (OSStatRdy == OS_FALSE) { + OSTimeDly(2 * OS_TICKS_PER_SEC / 10); /* Wait until statistic task is ready */ + } + max = OSIdleCtrMax / 100L; + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */ + run = OSIdleCtr; + OSIdleCtr = 0L; /* Reset the idle counter for the next second */ + OS_EXIT_CRITICAL(); + if (max > 0L) { + usage = (INT8S)(100L - run / max); + if (usage >= 0) { /* Make sure we don't have a negative percentage */ + OSCPUUsage = usage; + } else { + OSCPUUsage = 0; + } + } else { + OSCPUUsage = 0; + max = OSIdleCtrMax / 100L; + } + OSTaskStatHook(); /* Invoke user definable hook */ +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) + OS_TaskStatStkChk(); /* Check the stacks for each task */ +#endif + OSTimeDly(OS_TICKS_PER_SEC / 10); /* Accumulate OSIdleCtr for the next 1/10 second */ + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK ALL TASK STACKS +* +* Description: This function is called by OS_TaskStat() to check the stacks of each active task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) +void OS_TaskStatStkChk (void) +{ + OS_TCB *ptcb; + OS_STK_DATA stk_data; + INT8U err; + INT8U prio; + + + for (prio = 0; prio <= OS_TASK_IDLE_PRIO; prio++) { + err = OSTaskStkChk(prio, &stk_data); + if (err == OS_ERR_NONE) { + ptcb = OSTCBPrioTbl[prio]; + if (ptcb != (OS_TCB *)0) { /* Make sure task 'ptcb' is ... */ + if (ptcb != OS_TCB_RESERVED) { /* ... still valid. */ +#if OS_TASK_PROFILE_EN > 0 + #if OS_STK_GROWTH == 1 + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom + ptcb->OSTCBStkSize; + #else + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom - ptcb->OSTCBStkSize; + #endif + ptcb->OSTCBStkUsed = stk_data.OSUsed; /* Store the number of bytes used */ +#endif + } + } + } + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE TCB +* +* Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when +* a task is created (see OSTaskCreate() and OSTaskCreateExt()). +* +* Arguments : prio is the priority of the task being created +* +* ptos is a pointer to the task's top-of-stack assuming that the CPU registers +* have been placed on the stack. Note that the top-of-stack corresponds to a +* 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory +* location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU +* specific. +* +* pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by +* 'OSTaskCreate()'. +* +* id is the task's ID (0..65535) +* +* stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us +* then, 'stk_size' contains the number of bytes for the stack. If the stack +* units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack +* units are established by the #define constant OS_STK which is CPU +* specific. 'stk_size' is 0 if called by 'OSTaskCreate()'. +* +* pext is a pointer to a user supplied memory area that is used to extend the task +* control block. This allows you to store the contents of floating-point +* registers, MMU registers or anything else you could find useful during a +* context switch. You can even assign a name to each task and store this name +* in this TCB extension. A NULL pointer is passed if called by OSTaskCreate(). +* +* opt options as passed to 'OSTaskCreateExt()' or, +* 0 if called from 'OSTaskCreate()'. +* +* Returns : OS_ERR_NONE if the call was successful +* OS_ERR_TASK_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot +* be created. +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */ + if (ptcb != (OS_TCB *)0) { + OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */ + OS_EXIT_CRITICAL(); + ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */ + ptcb->OSTCBPrio = prio; /* Load task priority into TCB */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ + ptcb->OSTCBDly = 0; /* Task is not delayed */ + +#if OS_TASK_CREATE_EXT_EN > 0 + ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */ + ptcb->OSTCBStkSize = stk_size; /* Store stack size */ + ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */ + ptcb->OSTCBOpt = opt; /* Store task options */ + ptcb->OSTCBId = id; /* Store task ID */ +#else + pext = pext; /* Prevent compiler warning if not used */ + stk_size = stk_size; + pbos = pbos; + opt = opt; + id = id; +#endif + +#if OS_TASK_DEL_EN > 0 + ptcb->OSTCBDelReq = OS_ERR_NONE; +#endif + +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)(prio >> 3); /* Pre-compute X, Y, BitX and BitY */ + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBX = (INT8U)(prio & 0x07); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((prio >> 4) & 0xFF);/* Pre-compute X, Y, BitX and BitY */ + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBX = (INT8U)(prio & 0x0F); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + +#if OS_EVENT_EN + ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0) + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; /* Task is not pending on an event flag */ +#endif + +#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) + ptcb->OSTCBMsg = (void *)0; /* No message received */ +#endif + +#if OS_TASK_PROFILE_EN > 0 + ptcb->OSTCBCtxSwCtr = 0L; /* Initialize profiling variables */ + ptcb->OSTCBCyclesStart = 0L; + ptcb->OSTCBCyclesTot = 0L; + ptcb->OSTCBStkBase = (OS_STK *)0; + ptcb->OSTCBStkUsed = 0L; +#endif + +#if OS_TASK_NAME_SIZE > 1 + ptcb->OSTCBTaskName[0] = '?'; /* Unknown name at task creation */ + ptcb->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + + OSTCBInitHook(ptcb); + + OSTaskCreateHook(ptcb); /* Call user defined hook */ + + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = ptcb; + ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */ + ptcb->OSTCBPrev = (OS_TCB *)0; + if (OSTCBList != (OS_TCB *)0) { + OSTCBList->OSTCBPrev = ptcb; + } + OSTCBList = ptcb; + OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OSTaskCtr++; /* Increment the #tasks counter */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NO_MORE_TCB); +} diff --git a/.svn/pristine/76/764880feb06711602e0a204cffd8a595ed186056.svn-base b/.svn/pristine/76/764880feb06711602e0a204cffd8a595ed186056.svn-base new file mode 100644 index 0000000..069fadc --- /dev/null +++ b/.svn/pristine/76/764880feb06711602e0a204cffd8a595ed186056.svn-base @@ -0,0 +1,77 @@ + + + + + + solarium/Flash + + + + + + + + + 262272727 + + + + + + 62962754 + + + + + + 2091624461 + 201222 + + + + + + + TabID-4922-2358 + Workspace + Workspace + + + solariumsolarium/DRIVERSsolarium/DRIVERS/ccnetsolarium/DRIVERS/framsolarium/DRIVERS/keyboardsolarium/PROJECTsolarium/PROJECT/appsolarium/PROJECT/datasolarium/PROJECT/menu + + + + 0 + + + TabID-31733-19868 + Find in Files + Find-in-Files + + + + TabID-17681-20541 + Build + Build + + + TabID-13605-29828Debug LogDebug-LogTabID-31897-1342BreakpointsBreakpoints + + 1 + + + + + + TextEditor$WS_DIR$\PROJECT\version.h00777700100000010000001 + + + + + + + iaridepm.enu1-2-2711357-2-222401167880187174730533-2-22171920-2-2192221910020862243851167880 + + + + diff --git a/.svn/pristine/79/796635eb3b4390988467031c0b94eefa83975877.svn-base b/.svn/pristine/79/796635eb3b4390988467031c0b94eefa83975877.svn-base new file mode 100644 index 0000000..68e2fd0 --- /dev/null +++ b/.svn/pristine/79/796635eb3b4390988467031c0b94eefa83975877.svn-base @@ -0,0 +1,711 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_MUTEX.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + + +#if OS_MUTEX_EN > 0 +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + +#define OS_MUTEX_KEEP_LOWER_8 (INT16U)0x00FFu +#define OS_MUTEX_KEEP_UPPER_8 (INT16U)0xFF00u + +#define OS_MUTEX_AVAILABLE (INT16U)0x00FFu + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + +static void OSMutex_RdyAtPrio(OS_TCB *ptcb, INT8U prio); + +/*$PAGE*/ +/* +********************************************************************************************************* +* ACCEPT MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function checks the mutual exclusion semaphore to see if a resource is available. +* Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is +* not available or the event did not occur. +* +* Arguments : pevent is a pointer to the event control block +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_EVENT_TYPE if 'pevent' is not a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR if you called this function from an ISR +* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +* +* Returns : == OS_TRUE if the resource is available, the mutual exclusion semaphore is acquired +* == OS_FALSE a) if the resource is not available +* b) you didn't pass a pointer to a mutual exclusion semaphore +* c) you called this function from an ISR +* +* Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are +* intended to be used by tasks only. +********************************************************************************************************* +*/ + +#if OS_MUTEX_ACCEPT_EN > 0 +BOOLEAN OSMutexAccept (OS_EVENT *pevent, INT8U *perr) +{ + INT8U pip; /* Priority Inheritance Priority (PIP) */ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (OS_FALSE); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (OS_FALSE); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* Make sure it's not called from an ISR */ + *perr = OS_ERR_PEND_ISR; + return (OS_FALSE); + } + OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */ + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */ + if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */ + pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */ + pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */ + if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + *perr = OS_ERR_PIP_LOWER; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } + return (OS_TRUE); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (OS_FALSE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function creates a mutual exclusion semaphore. +* +* Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In +* other words, when the semaphore is acquired and a higher priority task +* attempts to obtain the semaphore then the priority of the task owning the +* semaphore is raised to this priority. It is assumed that you will specify +* a priority that is LOWER in value than ANY of the tasks competing for the +* mutex. +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR +* OS_ERR_PRIO_EXIST if a task at the priority inheritance priority +* already exist. +* OS_ERR_PEVENT_NULL No more event control blocks available. +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the +* maximum allowed (i.e. > OS_LOWEST_PRIO) +* +* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created mutex. +* == (void *)0 if an error is detected. +* +* Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number +* of the task owning the mutex or 0xFF if no task owns the mutex. +* +* 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number +* to use to reduce priority inversion. +********************************************************************************************************* +*/ + +OS_EVENT *OSMutexCreate (INT8U prio, INT8U *perr) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_EVENT *)0); + } + if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */ + *perr = OS_ERR_PRIO_INVALID; + return ((OS_EVENT *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */ + return ((OS_EVENT *)0); + } + OS_ENTER_CRITICAL(); + if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */ + OS_EXIT_CRITICAL(); /* Task already exist at priority ... */ + *perr = OS_ERR_PRIO_EXIST; /* ... inheritance priority */ + return ((OS_EVENT *)0); + } + OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */ + pevent = OSEventFreeList; /* Get next free event control block */ + if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */ + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */ + return (pevent); + } + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */ + OS_EXIT_CRITICAL(); + pevent->OSEventType = OS_EVENT_TYPE_MUTEX; + pevent->OSEventCnt = (INT16U)((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is avail. */ + pevent->OSEventPtr = (void *)0; /* No task owning the mutex */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); + *perr = OS_ERR_NONE; + return (pevent); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MUTEX +* +* Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it. +* +* Arguments : pevent is a pointer to the event control block associated with the desired mutex. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the mutex was deleted +* OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the mutex was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the mutex MUST check the return code of OSMutexPend(). +* +* 2) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the mutex. +* +* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the +* resource(s) will no longer be guarded by the mutex. +* +* 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there +* is one) is ready-to-run and is thus NOT pending on another kernel object or +* has delayed itself. In other words, if a task owns the mutex being deleted, +* that task will be made ready-to-run at its original priority. +********************************************************************************************************* +*/ + +#if OS_MUTEX_DEL_EN +OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; + INT8U pip; /* Priority inheritance priority */ + INT8U prio; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mutex */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pip = (INT8U)(pevent->OSEventCnt >> 8); + OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* ALWAYS DELETE THE MUTEX ---------------- */ + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP of mutex */ + prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original prio */ + ptcb = (OS_TCB *)pevent->OSEventPtr; + if (ptcb != (OS_TCB *)0) { /* See if any task owns the mutex */ + if (ptcb->OSTCBPrio == pip) { /* See if original prio was changed */ + OSMutex_RdyAtPrio(ptcb, prio); /* Yes, Restore the task's original prio */ + } + } + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mutex */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pip = (INT8U)(pevent->OSEventCnt >> 8); + OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function waits for a mutual exclusion semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mutex. +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for the resource up to the amount of time specified by this argument. +* If you specify 0, however, your task will wait forever at the specified +* mutex or, until the resource becomes available. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* OS_ERR_NONE The call was successful and your task owns the mutex +* OS_ERR_TIMEOUT The mutex was not available within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the mutex was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : none +* +* Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex. +* +* 2) You MUST NOT change the priority of the task that owns the mutex +********************************************************************************************************* +*/ +void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + INT8U pip; /* Priority Inheritance Priority (PIP) */ + INT8U mprio; /* Mutex owner priority */ + BOOLEAN rdy; /* Flag indicating task was ready */ + OS_TCB *ptcb; + OS_EVENT *pevent2; + INT8U y; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return; + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return; + } + OS_ENTER_CRITICAL(); + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */ + /* Is Mutex available? */ + if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */ + pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */ + pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */ + if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + *perr = OS_ERR_PIP_LOWER; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } + return; + } + mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* No, Get priority of mutex owner */ + ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */ + if (ptcb->OSTCBPrio > pip) { /* Need to promote prio of owner?*/ + if (mprio > OSTCBCur->OSTCBPrio) { + y = ptcb->OSTCBY; + if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0) { /* See if mutex owner is ready */ + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Yes, Remove owner from Rdy ...*/ + if (OSRdyTbl[y] == 0) { /* ... list at current prio */ + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + rdy = OS_TRUE; + } else { + pevent2 = ptcb->OSTCBEventPtr; + if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */ + if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { + pevent2->OSEventGrp &= ~ptcb->OSTCBBitY; + } + } + rdy = OS_FALSE; /* No */ + } + ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */ +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3); + ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07); + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((ptcb->OSTCBPrio >> 4) & 0xFF); + ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x0F); + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + if (rdy == OS_TRUE) { /* If task was ready at owner's priority ...*/ + OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } else { + pevent2 = ptcb->OSTCBEventPtr; + if (pevent2 != (OS_EVENT *)0) { /* Add to event wait list */ + pevent2->OSEventGrp |= ptcb->OSTCBBitY; + pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } + } + OSTCBPrioTbl[pip] = ptcb; + } + } + OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend current task */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed out during the pend */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get mutex within TO */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted getting mutex */ + break; + } + return; + } + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +/*$PAGE*/ +/* +********************************************************************************************************* +* POST TO A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function signals a mutual exclusion semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mutex. +* +* Returns : OS_ERR_NONE The call was successful and the mutex was signaled. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes) +* OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX. +* OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +********************************************************************************************************* +*/ + +INT8U OSMutexPost (OS_EVENT *pevent) +{ + INT8U pip; /* Priority inheritance priority */ + INT8U prio; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */ + } +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get priority inheritance priority of mutex */ + prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */ + if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NOT_MUTEX_OWNER); + } + if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */ + OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */ + } + OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */ + if (pevent->OSEventGrp != 0) { /* Any task waiting for the mutex? */ + /* Yes, Make HPT waiting for mutex ready */ + prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */ + pevent->OSEventCnt |= prio; + pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */ + if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_PIP_LOWER); + } else { + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + } + pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */ + pevent->OSEventPtr = (void *)0; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function obtains information about a mutex +* +* Arguments : pevent is a pointer to the event control block associated with the desired mutex +* +* p_mutex_data is a pointer to a structure that will contain information about the mutex +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_QUERY_ISR If you called this function from an ISR +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex. +********************************************************************************************************* +*/ + +#if OS_MUTEX_QUERY_EN > 0 +INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */ + } +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8); + p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); + if (p_mutex_data->OSOwnerPrio == 0xFF) { + p_mutex_data->OSValue = OS_TRUE; + } else { + p_mutex_data->OSValue = OS_FALSE; + } + p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_mutex_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_MUTEX_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY +* +* Description: This function makes a task ready at the specified priority +* +* Arguments : ptcb is a pointer to OS_TCB of the task to make ready +* +* prio is the desired priority +* +* Returns : none +********************************************************************************************************* +*/ + +static void OSMutex_RdyAtPrio (OS_TCB *ptcb, INT8U prio) +{ + INT8U y; + + + y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */ + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + ptcb->OSTCBPrio = prio; +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)((prio >> (INT8U)3) & (INT8U)0x07); + ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x07); + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((prio >> (INT8U)4) & (INT8U)0x0F); + ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x0F); + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OSTCBPrioTbl[prio] = ptcb; +} + + +#endif /* OS_MUTEX_EN */ diff --git a/.svn/pristine/7a/7ac514db93f1416966fb123053dd67eac6acb7d5.svn-base b/.svn/pristine/7a/7ac514db93f1416966fb123053dd67eac6acb7d5.svn-base new file mode 100644 index 0000000..0086ea6 --- /dev/null +++ b/.svn/pristine/7a/7ac514db93f1416966fb123053dd67eac6acb7d5.svn-base @@ -0,0 +1,38 @@ +#include "cpu.h" +#include "datadesc.h" +#include "journal.h" + + +typedef struct{ + + CPU_INT32U SerialNum; + + TChannelConfig ChannelConfig; + + TDeviceConfig DeviceConfig; + + // + TCounters Counters; + + // CRC16 + TCountersLong CountersLong; + + CPU_INT32U FRAM_AcceptedMoney; + CPU_INT32U crc_AcceptedMoney; + + // + TErrorRecord ErrorRecords[ERROR_RECORDS_NUM]; + // + TEventRecord EventRecords[EVENT_RECORDS_NUM]; + + CPU_INT32U Pass; + CPU_INT32U crc_Pass; + + CPU_INT32U LastEmailTime; + + CPU_INT32U IncasEmailFlag; + CPU_INT32U IncasMoney; + CPU_INT32U IncasTime; + +}TFramMap; + diff --git a/.svn/pristine/7b/7b0e8b7015cad3f8f755534e03a7302161e929d0.svn-base b/.svn/pristine/7b/7b0e8b7015cad3f8f755534e03a7302161e929d0.svn-base new file mode 100644 index 0000000..f92913a --- /dev/null +++ b/.svn/pristine/7b/7b0e8b7015cad3f8f755534e03a7302161e929d0.svn-base @@ -0,0 +1,28 @@ +#ifndef _MODEM_TASK_H_ +#define _MODEM_TASK_H_ + +#include "app_serv.h" + +// +#define MODEM_QUERY_LEN 8 +// +#define MODEM_TASK_DELAY 10000 + +enum{ + MODEM_TASK_NONE = 0, + MODEM_TASK_SEND_STATISTICS, + MODEM_TASK_SEND_TEST_MSG, + MODEM_TASK_RECONNECT, + MODEM_TASK_SEND_INCAS, + +}; + +extern OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE]; +extern OS_EVENT *ModemQuery; +extern void *ModemTbl[MODEM_QUERY_LEN]; + + +extern void ModemTask(void *p_arg); +extern void PostModemTask(int new_task); + +#endif //#ifndef _MODEM_TASK_H_ diff --git a/.svn/pristine/7c/7ce900fc30ec4334a07778a66890842b4f2901f0.svn-base b/.svn/pristine/7c/7ce900fc30ec4334a07778a66890842b4f2901f0.svn-base new file mode 100644 index 0000000..0a7d790 --- /dev/null +++ b/.svn/pristine/7c/7ce900fc30ec4334a07778a66890842b4f2901f0.svn-base @@ -0,0 +1,18 @@ +#ifndef _COIN_H_ +#define _COIN_H_ + + + +#define COIN_IMP_MIN_LEN 2200 // /100 +#define COIN_IMP_MAX_LEN 9000 // /100 + + +extern void InitCoin(void); +extern CPU_INT32U GetCoinCount(void); +extern CPU_INT32U GetResetCoinCount(void); +extern void CoinDisable(void); +extern void CoinEnable(void); + +#endif //#ifndef _COIN_H_ + + diff --git a/.svn/pristine/7d/7d0688ac7c08e9f6c9c94651c41f8141cd49c6c9.svn-base b/.svn/pristine/7d/7d0688ac7c08e9f6c9c94651c41f8141cd49c6c9.svn-base new file mode 100644 index 0000000..e4dcb08 --- /dev/null +++ b/.svn/pristine/7d/7d0688ac7c08e9f6c9c94651c41f8141cd49c6c9.svn-base @@ -0,0 +1,78 @@ +#include +#include "app_serv.h" +#include "lcd.h" +#include "spi.h" +#include "keyboard.h" + +static OS_STK AppTaskStartStk[APP_TASK_START_STK_SIZE]; +static void AppTaskStart(void *p_arg); + + +/* +********************************************************************************************************* +* main() +* +* Description : This is the standard entry point for C code. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void main (void) +{ + BSP_IntDisAll(); /* Disable all interrupts until we are ready to accept them */ + + OSInit(); /* Initialize "uC/OS-II, The Real-Time Kernel" */ + + OSTaskCreate(AppTaskStart, (void *)0, (OS_STK *)&AppTaskStartStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO); + + OSStart(); /* Start multitasking (i.e. give control to uC/OS-II) */ +} + +/* +********************************************************************************************************* +* AppTaskStart() +* +* Description : The startup task. The uC/OS-II ticker should only be initialize once multitasking starts. +* +* Argument(s) : p_arg Argument passed to 'AppTaskStart()' by 'OSTaskCreate()'. +* +* Return(s) : none. +* +* Note(s) : (1) The first line of code is used to prevent a compiler warning because 'p_arg' is not +* used. The compiler should not generate any code for this statement. +* +* (2) Interrupts are enabled once the task starts because the I-bit of the CCR register was +* set to 0 by 'OSTaskCreate()'. +********************************************************************************************************* +*/ + +unsigned char arr[256]; + +static void AppTaskStart (void *p_arg) +{ + (void)p_arg; + + BSP_Init(); /* Initialize BSP functions */ + +#if OS_TASK_STAT_EN > 0 + OSStatInit(); /* Determine CPU capacity */ +#endif + + OSTimeDly(1000); + // + InitLcd(); + InitKbrd(); + SpiInit(); + + // + UserStartupFunc(); + + while (1) { /* Task body, always written as an infinite loop. */ + OSTimeDly(1000); + //PostUserEvent(EVENT_SEC); + } +} + diff --git a/.svn/pristine/7e/7ea2debb32f5cf8bb087808d270a7143a1a91f3c.svn-base b/.svn/pristine/7e/7ea2debb32f5cf8bb087808d270a7143a1a91f3c.svn-base new file mode 100644 index 0000000..6b8d8f6 --- /dev/null +++ b/.svn/pristine/7e/7ea2debb32f5cf8bb087808d270a7143a1a91f3c.svn-base @@ -0,0 +1,982 @@ +#include +#include "app_serv.h" +#include "fiscal.h" +#include "fr.h" +#include "uart0.h" +#include "data.h" +#include "datadesc.h" +#include "journal.h" +#include "time.h" + +TFiscDevType FiscDevInfo; +static TFiscFullStatus FiscFullStatus; +CPU_INT08U FiscalConnState = FISCAL_NOCONN; + + +OS_EVENT *FLock = NULL; +//OS_EVENT *FReportLock = NULL; +//OS_STK FiscalTaskStk[FISCAL_TASK_STK_SIZE]; + + +// +int CheckFiscalStatus() +{ + CPU_INT08U err; + int poll; + CPU_INT32U time1, time2; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (!enable) return 0; + + time1 = time2 = OSTimeGet(); + + while (labs(time2 - time1) < WAIT_PRINT_TIMEOUT) + { + OSTimeDly(100); + time2 = OSTimeGet(); + // + poll = FiscPollExt(); + if (poll == FISC_UNDEF) + { + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + return -1; + } + else if (poll == FISC_BUSY) + { + continue; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + if (err) SetFiscalErrorByCode(err); + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + } + return -2; + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + + CPU_INT16U flags; + memcpy(&flags, &FiscFullStatus.Flags, sizeof(CPU_INT16U)); + + // : + // (0 , 1 ) + if (!(flags & (1L<<5))) + { + // + SetFiscalErrorByCode(FR_ERROR_CODE_a1); + return -3; + } + else + { + ClrFiscalErrorByCode(FR_ERROR_CODE_a1); + } + + ClrFiscalErrorByCode(FR_ERROR_CODE_6b); + // + switch (FiscFullStatus.SubMode) + { + case 1: + // 1. + // , , + // . + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + return -4; + case 2: + // 2. + // , . 3. + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + return -5; + case 3: + // 3. . + // , . + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + // + FiscPrintContinue(DEFAULT_PASS, &err); + return -6; + case 4: // + case 5: // + continue; + default: + break; + } + + // + switch (FiscFullStatus.Mode) + { + case 0: + // 0. . + // + // OK + ClearFiscalErrors(); + goto check_exit; + case 1: + // 1. . + // OK + ClearFiscalErrors(); + goto check_exit; + case 2: + // 2. , 24 . + // OK + ClearFiscalErrors(); + goto check_exit; + case 3: + // 3. , 24 . + { + CPU_INT32U autoclose; + GetData(&EnableFiscalDayClearDesc, &autoclose, 0, DATA_FLAG_SYSTEM_INDEX); + + if (autoclose==2) + { + // + FiscPrintDayReportToBuf(30, &err); + // , + if (err == FR_ERROR_CODE_4b) + { + SetFiscalErrorByCode(err); + SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec()); + FiscPrintDayReportsFromBuf(30, &err); + if (err) + { + SetFiscalErrorByCode(err); + return -8; + } + } + else if (err) + { + SetFiscalErrorByCode(err); + return -9; + } + } + else if (autoclose==1) + { + // Z- + FiscPrintDayReportClear(30, &err); + SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec()); + if (err) + { + SetFiscalErrorByCode(err); + return -10; + } + } + else if (autoclose==0) + { + // - + SetFiscalErrorByCode(FR_ERROR_CODE_4e); + return -11; + } + } + goto check_exit; + case 4: + // 4. . + ClearFiscalErrors(); + goto check_exit; + case 5: + // 5. . + SetFiscalErrorByCode(FR_ERROR_CODE_4f); + goto check_exit; + case 6: + // 6. . + SetFiscalErrorByCode(FR_ERROR_CODE_c0); + goto check_exit; + case 8: + // 8. : + // 8.0. . + // 8.1. . + // 8.2. . + // 8.3. . + // 8.4. . + { + CPU_INT64U cash = 0; + CPU_INT08U tax[4] = {0,0,0,0}; + FiscCloseBill(DEFAULT_PASS, &cash, &tax[0], " !!!", &err); + if (err) + { + SetFiscalErrorByCode(err); + return -11; + } + } + goto check_exit; + case 12: + // Z- + continue; + default: + goto check_exit; + } + } + +check_exit: + + if (labs(time2 - time1) < WAIT_PRINT_TIMEOUT) + { + // OK + return 0; + } + + return -1; +} + +#define FISCAL_BAUDS_COUNT 7 +static const CPU_INT32U fiscal_bauds[FISCAL_BAUDS_COUNT] = {2400, 4800, 9600, 19200, 38400, 57600, 115200}; + +// +int ConnectFiscal(void) +{ + int i, poll; + CPU_INT08U err; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + FPend(); + if (enable) + { + int j; + // + for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--) + { + Uart0_Init(fiscal_bauds[j]); + i = 10; + do + { + OSTimeDly(100); + poll = FiscPollExt(); + if ((poll == FISC_READY) || (poll == FISC_BUSY)) break; + } while (--i); + // + if (i) + { + break; + } + } + + if (j < 0) + { + SetErrorFlag(ERROR_FR_CONN); + FiscalConnState = FISCAL_NOCONN; + FPost(); + return -1; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + // + if (err) SetFiscalErrorByCode(err); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + FPost(); + return -2; + } + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + FiscalConnState = FISCAL_NOCONN; + ClearFiscalErrors(); + ClrErrorFlag(ERROR_FR_CONN); + FPost(); + return -3; + } + + FPost(); + return 0; +} + +// +int ConnectFiscalFast(void) +{ + int i, poll; + CPU_INT08U err; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + FPend(); + if (enable) + { + int j; + // + for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--) + { + Uart0_Init(fiscal_bauds[j]); + i = 2; + do + { + poll = FiscPollExt(); + if ((poll == FISC_READY) || (poll == FISC_BUSY)) break; + } while (--i); + // + if (i) + { + break; + } + } + + if (j < 0) + { + SetErrorFlag(ERROR_FR_CONN); + FiscalConnState = FISCAL_NOCONN; + FPost(); + return -1; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + // + if (err) SetFiscalErrorByCode(err); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + FPost(); + return -2; + } + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + FiscalConnState = FISCAL_NOCONN; + ClearFiscalErrors(); + ClrErrorFlag(ERROR_FR_CONN); + FPost(); + return -3; + } + + FPost(); + return 0; +} + +// +void InitFiscal(void) +{ + if (!FLock) + { + FLock = OSSemCreate(1); + //FReportLock = OSSemCreate(1); + //OSTaskCreate(FiscalTask, (void *)0, (OS_STK *)&FiscalTaskStk[FISCAL_TASK_STK_SIZE-1], FISCAL_TASK_PRIO); + } + + if (ConnectFiscal()) return; + + CheckFiscalStatus(); +} + +int IsFiscalConnected(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int retval; + if (FiscalConnState == FISCAL_CONN) retval=1; + else retval=0; + OS_EXIT_CRITICAL(); + return retval; +} + +// +void FPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(FLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// +void FPost(void) +{ + OSTimeDly(200); + OSSemPost(FLock); +} +/* +// +void FReportPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(FReportLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// 2 +int FReportGet(void) +{ + CPU_INT08U err; + OSSemPend(FReportLock, 1, &err); + if (!err) return 1; + return 0; +} + +// +void FReportPost(void) +{ + if (!FReportTest()) OSSemPost(FReportLock); +} + +// +// 0 - +// >0 - +CPU_INT16U FReportTest(void) +{ + return OSSemCheck(FReportLock); +} + +*/ +// +void ClearFiscalErrors(void) +{ + for (unsigned char i=ERROR_FR; i0)) + { + OSTimeDly(5000); + res = PrintFiscalBill(money, time); + i--; + } + return res; +} +*/ + +int TstFiscalErrorByCode(unsigned char code) +{ + for (unsigned char i=0; i +#include "app_serv.h" +#include "modem.h" +#include "validator.h" +#include "coin.h" +#include "time.h" +#include "fiscal.h" +#include "menu.h" +#include "data.h" +#include "mode.h" +#include "menudesc.h" +#include "datadesc.h" +#include "control.h" +#include "validator.h" +#include "CCRSProtocol.h" +#include "menu.h" +#include "journal.h" +#include "fr.h" +#include "CRC16.h" +#include "modem_task.h" + +// , F1 +//#define _DEBUG_MONEY + +CPU_INT32U SystemTime; +CPU_INT08U EnabledChannelsNum; +CPU_INT08U RecentChannel; +CPU_INT08U UserMenuState; + #define USER_STATE_FIRST_PAGE 0 + #define USER_STATE_ACCEPT_MONEY 1 + #define USER_STATE_SHOW_THANKS 2 +CPU_INT08U ThanksCtr; + +CPU_INT08U ChannelsState[CHANNELS_NUM]; + #define CHANNEL_STATE_EMPTY 0 + #define CHANNEL_STATE_PAUSE_BEFORE 1 + #define CHANNEL_STATE_WORK 2 + #define CHANNEL_STATE_PAUSE_AFTER 3 +CPU_INT32U ChannelsCounters[CHANNELS_NUM]; +CPU_INT32U ChannelsPayedTime[CHANNELS_NUM]; + +extern CPU_INT32U BillNominals[24]; +CPU_INT32U incas_bill_nom_counter[24]; +CPU_INT32U incas_common_bill_counter; + +CPU_INT08U max_msg = 0; + +#define USER_QUERY_LEN 64 + +OS_STK UserTaskStk[USER_TASK_STK_SIZE]; +OS_EVENT *UserQuery = NULL; +void *UserTbl[USER_QUERY_LEN]; + +int GetUserEvent(int* event); +void UserPrintMoneyMenu(void); +void IncRecentChannel(void); +void DecRecentChannel(void); +void WorkServer(void); +void UserPrintThanksMenu(void); +void UserPrintFirstMenu(CPU_INT08U recentchannel); +void UserPrintErrorMenu(void); +CPU_INT32U GetChannelsTimeForFree(CPU_INT08U ch); +void LoadAcceptedMoney(void); +void SetAcceptedMoney(CPU_INT32U money); +void ClearAcceptedMoney(void); +CPU_INT32U GetAcceptedMoney(void); +void InitPass(void); + +static char incassation; +static char was_critical_error; +/*! + +*/ +void UserAppTask(void *p_arg) +{ + int event; + CPU_INT32U temp; + static CPU_INT08U fr_conn_ctr = 0; + + { + CPU_INT32U m=0; + GetData(&AcceptedMoneyDesc, &m, 0, DATA_FLAG_SYSTEM_INDEX); + if (m) + { + EnabledChannelsNum = 0; + for (CPU_INT08U i=0; i maxtime*60) + { + CoinDisable(); + } + else + { + CoinEnable(); + } + was_critical_error = 0; + } + } + else if (UserMenuState == USER_STATE_SHOW_THANKS) + { // "" + LED_off(); + CoinDisable(); + if (ThanksCtr) {UserPrintThanksMenu(); ThanksCtr--;} + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + else if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + LED_off(); + CoinDisable(); + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + break; + case EVENT_INCASSATION: + { + CPU_INT32U incas_sum = 0, temp; + for (CPU_INT32U i = 0; i < 24; i++) + { + CPU_INT32U val = 0; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + incas_sum += val*BillNominals[i]; + } + incassation = 1; + sprintf((char*)str_IncasMenu_3, " %u .", incas_sum); + // + GoToMenu(IncasMenuPanel); + // + SaveEventRecord(0, JOURNAL_EVENT_INCASSATION, incas_sum); + GetData(&BillCounterDesc, &incas_common_bill_counter, 0, DATA_FLAG_SYSTEM_INDEX); + for (CPU_INT32U i = 0; i < 24; i++) + { + GetData(&BillnomCountersDesc, &incas_bill_nom_counter[i], i, DATA_FLAG_DIRECT_INDEX); + } + + SetData(&IncasMoneyDesc, &incas_sum, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = GetTimeSec(); + SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = INCAS_SEND_FLAG; + SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + PostModemTask(MODEM_TASK_SEND_INCAS); + // + ClearBillnomCounter(); + } + break; + case EVENT_INCASSATION_FINISH: + incassation = 0; + GoToPreviousMenu(); + break; + case EVENT_MODE_CHANGE: + ReInitMenu(); + SaveEventRecord(0, JOURNAL_EVENT_CHANGE_MODE, GetMode()); + break; + case EVENT_COIN_INSERTED: + { + CPU_INT32U cpp = 1; + CPU_INT32U money, accmoney; + GetData(&CoinPerPulseDesc, &cpp, 0, DATA_FLAG_SYSTEM_INDEX); + money = cpp*GetResetCoinCount(); + accmoney = GetAcceptedMoney(); + accmoney += money; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_COIN, money); + + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if ((pricetime*accmoney*60)/price > maxtime*60) + { + CoinDisable(); + } + } + break; + case EVENT_BILL_ESCROW: + // + { + CPU_INT32U billnom_index; + CPU_INT32U billnom = GetResetBillCount(&billnom_index); + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff, accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + accmoney = GetAcceptedMoney(); + if ((pricetime*(accmoney+billnom)*60)/price > maxtime*60) + { + max_msg = 3; + if (IsValidatorConnected()) if (!CC_CmdReturn(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + else + { + max_msg = 0; + if (IsValidatorConnected()) if (!CC_CmdPack(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + } + break; + case EVENT_BILL_STACKED: + // + { + CPU_INT32U billnom_index; + CPU_INT32U note,accmoney; + note = GetResetBillCount(&billnom_index); + accmoney = GetAcceptedMoney(); + accmoney += note; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_NOTE, note); + IncBillnomCounter(billnom_index); + } + break; + + case EVENT_KEY_F1: + #ifdef _DEBUG_MONEY + { + CPU_INT32U accmoney; + accmoney = GetAcceptedMoney(); + accmoney += 10; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + } + #endif + break; + case EVENT_KEY_F2: + break; + case EVENT_KEY_F3: + break; + + case EVENT_KEY_LEFT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + DecRecentChannel(); + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + break; + case EVENT_KEY_RIGHT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + IncRecentChannel(); + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + break; + case EVENT_KEY_DOWN: + break; + case EVENT_KEY_UP: + break; + + case EVENT_KEY_STOP: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + break; + case EVENT_KEY_START: + case EVENT_KEY_USER_START: + if (incassation) break; + if (GetMode() != MODE_WORK) + { + if (!FlagForPrintReport) break; + if (GetCurrentMenu() == xReportMenuPanel) + { // X- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportNoClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_X, GetTimeSec()); + GoToPreviousMenu(); + } + } + else if (GetCurrentMenu() == zReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec()); + GoToPreviousMenu(); + ClrFiscalErrorByCode(FR_ERROR_CODE_4e); + } + } + else if (GetCurrentMenu() == bufReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportsFromBuf(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec()); + GoToPreviousMenu(); + } + } + break; + } + + if (TstCriticalErrors()) + { + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + + // -------------------------- + // + // -------------------------- + + if (EnabledChannelsNum == 0) break; + + if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + if (IsChannelOn(RecentChannel)) break; + FPend(); + if ((CheckFiscalStatus() < 0) && (TstCriticalErrors())) + { + FPost(); + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + FPost(); + UserMenuState = USER_STATE_ACCEPT_MONEY; + UserPrintMoneyMenu(); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + CoinEnable(); + max_msg = 0; + break; + } + + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { // + CPU_INT32U price=1, pricetime=0, mintime=0,accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + accmoney = GetAcceptedMoney(); + ChannelsPayedTime[RecentChannel] = (pricetime*accmoney*60)/price; + GetData(&MinWorkTimeDesc, &mintime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (ChannelsPayedTime[RecentChannel] >= mintime*60) + { // , + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + // + if (IsFiscalConnected()) + { + if (PrintFiscalBill(accmoney, ChannelsPayedTime[RecentChannel]) == 0) + { + SaveEventRecord(RecentChannel, JOURNAL_EVENT_PRINT_BILL, GetTimeSec()); + } + else + { + // + + } + } + IncCounter(RecentChannel, ChannelsPayedTime[RecentChannel], accmoney); + SetAcceptedMoney(0); + // + GetData(&TimeOutBeforeDesc, &ChannelsCounters[RecentChannel], RecentChannel, DATA_FLAG_DIRECT_INDEX); + ChannelsState[RecentChannel] = CHANNEL_STATE_PAUSE_BEFORE; + // "" + if (IsFiscalConnected()) + { + UserPrintThanksMenu(); + RefreshMenu(); + UserMenuState = USER_STATE_SHOW_THANKS; + } + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + } + + ThanksCtr = 5; + } + else + { // + + + + } + break; + } + + + break; + + } + } + else + { + OSTimeDly(1); + } + } +} + +/*! + +*/ +void UserStartupFunc(void) +{ + // + InitMode(); + + // + CheckAllData(); + + // + CheckLongCounters(); + + // + LoadAcceptedMoney(); + + // + InitPass(); + + // + InitChannels(); + + // + PINSEL3_bit.P1_21 = 0x0; + PINMODE3_bit.P1_21 = 0; + FIO1DIR_bit.P1_21= 1; + FIO1MASK_bit.P1_21 = 0; + LED_off(); + + // + InitMenu(); + + OSTimeDly(1000); + + // + StartUpValidator(); + + OSTimeDly(10000); + InitFiscal(); + + // + InitRTC(); + + // + SaveEventRecord(0, JOURNAL_EVENT_DEVICE_ON, GetTimeSec()); + + CPU_INT32U enable; + GetData(&EnableModemDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable) + { + enable = 0; + SetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + } + + // - + if (InitModem() != 0) + { + SetErrorFlag(ERROR_MODEM_CONN); + } + else + { + ClrErrorFlag(ERROR_MODEM_CONN); + } + + // + InitCoin(); + + // + if (UserQuery == NULL) + { + UserQuery = OSQCreate(&UserTbl[0], USER_QUERY_LEN); + OSTaskCreate(UserAppTask, (void *)0, (OS_STK *)&UserTaskStk[USER_TASK_STK_SIZE-1], USER_TASK_PRIO); + } + + SystemTime = GetTimeSec(); + + // , + if (GetMode() == MODE_WORK) {SetMenu(WORK_MENU);} + else SetMenu(SERVICE_MENU); +} + +int GetUserEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(UserQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + + +void PostUserEvent(int event) +{ + OSQPost(UserQuery, (void *)event); +} + + +void InitUserMenu(void) +{ + for (RecentChannel=0; RecentChannel 1) sprintf(buf, ".%d ", RecentChannel+1); + else sprintf(buf, ""); + if (time >= mintime*60) + { + LED_on(); + if (time >= maxtime*60) sprintf(&buf[strlen(buf)], "."); + else sprintf(&buf[strlen(buf)], "."); + } + else + { + LED_off(); + sprintf(&buf[strlen(buf)], "."); + } + } + PrintUserMenuStr(buf, 3); +} + +// +void UserPrintErrorMenu(void) +{ + char buf[32]; + + if (TstErrorFlag(ERROR_VALIDATOR_CONN) || TstCriticalValidatorErrors()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + if (TstErrorFlag(ERROR_VALIDATOR_CONN)) + { + sprintf(buf, " "); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + } + else if (TstErrorFlag(ERROR_FR_CONN)) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + PrintUserMenuStr(buf, 3); + } + else if (TstCriticalFiscalError()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + CPU_INT08U errcode = 0; + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + GetFirstCriticalFiscalError(&errcode); + GetDataItem(&JournalErrorNumberDesc0, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 2); + GetDataItem(&JournalErrorNumberDesc1, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 3); + } + /* + else if (!FReportTest()) + { + sprintf(buf, "b "); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + */ +} + +// +int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time) +{ + TRTC_Data rtc; + + if (EnabledChannelsNum == 0) return -1; + + RTC_ReadTime(&rtc); + + // , + CPU_INT32U wend = 0; + CPU_INT08U iswend = 0; // + GetData(&WeekEndDesc, &wend, RecentChannel, DATA_FLAG_DIRECT_INDEX); + + switch (wend) + { + case WEEKEND_FRIDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day > 4)) iswend = 1; + break; + case WEEKEND_SATURDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_SATURDAY: + if ((rtc.day == 5) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_MONDAY: + if ((rtc.day > 4) || (rtc.day < 2)) iswend = 1; + break; + default: + iswend = 0; + break; + } + + // + CPU_INT08U i; + for (i=0; i= start) && (rtc.hour < end)){break;} + } + + if (i >= PRICE_PERIODS_NUM) return -2; + + // + if (iswend) + { + GetData(&PriceTimeWeekendDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekendDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + else + { + GetData(&PriceTimeWeekdaysDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekdaysDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + + return 0; +} + + +void IncRecentChannel(void) +{ + CPU_INT08U i; + + for (i=RecentChannel+1; i=0; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {break;} + } + + if (i>=0) {RecentChannel = i; return;} + + for (i=CHANNELS_NUM-1; i>RecentChannel; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {RecentChannel = i; return;} + } + +} + + +void WorkServer(void) +{ + for (CPU_INT08U i=0; i +#include "modem.h" +#include "modem_task.h" +#include "app_serv.h" +#include "data.h" +#include "datadesc.h" +#include "uart2.h" + +static char additional_buf[256]; + +#define ModemUart_Ready Uart2_Ready +#define ModemComPortFlush Uart2_Flush +#define ModemUart_Getc Uart2_Getc +#define ModemUart_Gotc Uart2_Gotc +#define ModemUart_Putc Uart2_Putc +#define ModemUart_Init Uart2_Init + + +static OS_EVENT *ModemLock = NULL; +static char modem_buf[512]; +static int modem_connected; + +// +static void GetModem(void) +{ + CPU_INT08U err; + while (1) + { + OSSemPend(ModemLock, 1, &err); + if (!err) break; + OSTimeDly(1); + } +} + +// +static void FreeModem(void) +{ + OSSemPost(ModemLock); +} + +// +static void ModemWriteStr(char const *str) +{ + while (*str != 0) + { + while (!ModemUart_Ready()) OSTimeDly(1); + ModemUart_Putc(*str++); + } +} + +// +static int ModemReadStr(char *str, unsigned long timeout) +{ + int byte_ctr = 0; + while (byte_ctr < 256) + { + CPU_INT08U byte; + unsigned long to = timeout; + + while (!ModemUart_Gotc()) + { + if (to == 0) + { + *str = 0x00; + return 0; + } + OSTimeDly(1); + to--; + } + + int ch = ModemUart_Getc(); + if (ch < 0) + { + *str = 0x00; + return 0; + } + + byte = (char)ch; + *str++ = byte; + byte_ctr++; + if (byte == 0x0a) break; + } + + *str = 0x00; + return 1; +} + +static int ModemReadByte(CPU_INT08U *byte, unsigned long timeout) +{ + unsigned long ctr = 0; + + while (!ModemUart_Gotc()) + { + OSTimeDly(1); + ctr++; + if (ctr > timeout) return 0; + } + + *byte = (CPU_INT08U)ModemUart_Getc(); + return 1; +} + +// +static int ModemReadStrAndComp(char *str, char const *format, unsigned long timeout) +{ + int result; + + if (ModemReadStr(str, timeout)) + { + result = strcmp ((char *)str, (char const *)format); + } + else + { + return -1; + } + + return result; +} + +// / +int InitModem(void) +{ + int result; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT32U val; + + OS_ENTER_CRITICAL(); + email_options.valid = 0; + modem_connected = 0; + OS_EXIT_CRITICAL(); + + GetData(&EnableModemDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + if (val) + { + PINSEL1_bit.P0_24 = 0x0; + PINMODE1_bit.P0_24 = 0; + FIO0DIR_bit.P0_24 = 1; + FIO0MASK_bit.P0_24 = 0; + FIO0CLR_bit.P0_24 = 1; + OSTimeDly(1000); + FIO0SET_bit.P0_24 = 1; + + OSTimeDly(60000); + + ModemUart_Init(115200); + + if (!ModemLock) ModemLock = OSSemCreate(1); + + GetModem(); + + // + sprintf(modem_buf, "AT\r\n"); + result = ModemSendOKCommand(modem_buf, 1000); + if (result != 0) + { + FreeModem(); + goto EXIT_INIT; + } + + // , + sprintf(modem_buf, "AT+CPIN?\r\n"); + result = ModemSendOKCommand(modem_buf, 1000); + if (result != 0) + { + FreeModem(); + goto EXIT_INIT; + } + + FreeModem(); + + OS_ENTER_CRITICAL(); + modem_connected = 1; + OS_EXIT_CRITICAL(); + + OSTimeDly(1000); + + result = InitModemEmailParams(); + } + else + { + result = 0; + } +EXIT_INIT: + // + if (ModemQuery == NULL) + { + ModemQuery = OSQCreate(&ModemTbl[0], MODEM_QUERY_LEN); + OSTaskCreate(ModemTask, (void *)0, (OS_STK *)&ModemTaskStk[MODEM_TASK_STK_SIZE-1], MODEM_TASK_PRIO); + } + return result; +} + + + +// - - +int ModemSendSMSMessage(char const* number, char const* text) +{ + char i; + + GetModem(); + + if (ModemWriteSMS(text, (unsigned char*)&i)) {FreeModem(); return -1;} + ModemComPortFlush(); + OSTimeDly(200); + if (ModemSendSMS(number, i)) {FreeModem(); return -1;} + ModemComPortFlush(); + OSTimeDly(200); + if (ModemDeleteSMS(i)) {FreeModem(); return -1;} + OSTimeDly(200); + ModemComPortFlush(); + + FreeModem(); + return 0; +} + + +// +int ModemReadSMS(char *text, int index) +{ + unsigned char count; + char *ptr; + + GetModem(); + ModemComPortFlush(); + sprintf((char*)modem_buf, "AT+CMGR=%d\r\n", index); + ModemWriteStr(modem_buf); + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + + // + count = 0; + while (count < 160) + { + modem_buf[0] = 0; + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + if (strcmp(modem_buf, "OK\r\n") == 0) + { + break; + } + else if (strlen(modem_buf) != 0) + { + // + ptr = (char*)modem_buf; + if (strlen((char const*)modem_buf) < 1) {FreeModem(); return -1;} + while (*ptr) {*text++ = *ptr++; count++;} + } + else + { + break; + } + } + + FreeModem(); + return 0; +} + + +// index +int ModemSendSMS(char const* number, unsigned char index) +{ + GetModem(); + + sprintf((char*)modem_buf, "AT+CMSS=%d,%s\r\n", index, number); + ModemWriteStr(modem_buf); + if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;} + if (!ModemReadStr(modem_buf, 10000)) {FreeModem(); return -1;} + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMSS:")) {FreeModem(); return -1;} + if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;} + if (ModemReadStrAndComp(modem_buf, "OK\r\n", 10000)) {FreeModem(); return -1;} + + FreeModem(); + return 0; +} + + +// index +int ModemDeleteSMS(unsigned char index) +{ + int result; + GetModem(); + sprintf((char*)modem_buf, "AT+CMGD=%d\r\n",index); + result = ModemSendOKCommand(modem_buf, 1000); + FreeModem(); + return result; +} + +// , index , +int ModemWriteSMS(char const* text, unsigned char *index) +{ + CPU_INT08U byte; + unsigned long word; + int result; + + GetModem(); + + // + ModemWriteStr("AT+CMGW\r\n"); + if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;} + + if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;} + if (byte != '>') {FreeModem(); return -1;} + + if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;} + if (byte != ' ') {FreeModem(); return -1;} + + // + ModemWriteStr(text); + // + ModemUart_Putc(0x1a); + // + if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;} + // , + if (!ModemReadStr(modem_buf, 5000)) {FreeModem(); return -1;} + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMGW:")) {FreeModem(); return -1;} + { + int len = strlen((char const*)&modem_buf[7]); + if (len == 3) word = modem_buf[7]-0x30; + else if (len == 4) {word = (modem_buf[7]-0x30)*10 + (modem_buf[8]-0x30);} + } + + *index = (unsigned char)word; + + result = ModemReadStrAndComp(modem_buf, "\r\n", 1000) + ModemReadStrAndComp(modem_buf, "OK\r\n", 1000); + FreeModem(); + // + return result; +} + +// , "OK" +// 0 +int ModemSendOKCommand(char *str, unsigned long timeout) +{ + int i; + + ModemComPortFlush(); + + ModemWriteStr(str); + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "OK\r\n") == 0) + { + return 0; + } + else if (strcmp(str, "ERROR\r\n") == 0) + { + return -2; + } + + continue; + } + else + { + return -1; + } + } + + return -3; +} + +int ModemSendOKData(char *str, int len, unsigned long timeout) +{ + int i; + + ModemComPortFlush(); + + for (i = 0; i < len; i++) + { + while (!ModemUart_Ready()) OSTimeDly(1); + ModemUart_Putc(str[i]); + } + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "OK\r\n") == 0) + { + return 0; + } + else if (strcmp(str, "ERROR\r\n") == 0) + { + return -2; + } + + continue; + } + else + { + return -1; + } + } + + return -3; +} + + +// , , "\r\n" +// 0 +int ModemSendCommand(char *str, unsigned long timeout) +{ + CPU_INT08U i; + + ModemComPortFlush(); + + ModemWriteStr(str); + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "\r\n") == 0) + { + continue; + } + else + { + return 0; + } + } + else + { + return -1; + } + } + + return -3; +} + + +// , num , +int ModemRxNewSMS(unsigned long *num) +{ + int len; + + GetModem(); + + if (!ModemReadStr(modem_buf, 10)) {FreeModem(); return 0;} + + if (!strcmp((char const*)modem_buf, "\r\n")) + { + // + if (!ModemReadStr(modem_buf, 100)) {FreeModem(); return 0;} + } + + if (strlen((char const*)modem_buf) < 13) {FreeModem(); return 0;} + + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMTI:")) {FreeModem(); return 0;} + + len = strlen((char*)&modem_buf[12]); + if (len == 3) *num = modem_buf[12]-0x30; + else if (len == 4) {*num = (modem_buf[12]-0x30)*10 + (modem_buf[13]-0x30);} + + OSTimeDly(200); + FreeModem(); + return 1; +} + +typedef struct +{ + char const *name; // + char *dest; // +} CfgElem; + +static const CfgElem email_cfg_list[EMAIL_CFG_ELEM_COUNT] = +{ + {"[receiver]=", email_options.receiver}, + {"[ap_dns]=", email_options.ap_dns}, + {"[ap_password]=", email_options.ap_password}, + {"[ap_ip]=", email_options.ap_ip}, + {"[ap_user]=", email_options.ap_user}, + {"[ap_apn]=", email_options.ap_apn}, + {"[smtp_user]=", email_options.smtp_user}, + {"[smtp_password]=", email_options.smtp_password}, + {"[smtp_mail]=", email_options.smtp_mail}, + {"[smtp_server]=", email_options.smtp_server}, + {"[smtp_port]=", email_options.smtp_port} +}; + + +// +int InitModemEmailParams(void) +{ + CPU_INT08U i, j; + char *text; + CPU_INT32U status = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + text = additional_buf; + + OS_ENTER_CRITICAL(); + email_options.valid = 0; + OS_EXIT_CRITICAL(); + + for (i = 1; i < 24; i++) + { + if (ModemReadSMS(text, i)) + { + // + continue; + } + + for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++) + { + int str_len = strlen(email_cfg_list[j].name); + char flag = 0; + while (str_len--) + { + if (email_cfg_list[j].name[str_len] != text[str_len]) + { + flag = 1; + break; + } + } + if (!flag) + { + strcpy(email_cfg_list[j].dest, &text[strlen(email_cfg_list[j].name)]); + for (str_len = 0; str_len < 64; str_len++) + { + if (email_cfg_list[j].dest[str_len] == 0) break; + if (email_cfg_list[j].dest[str_len] == '\r') {email_cfg_list[j].dest[str_len] = 0; break;} + if (email_cfg_list[j].dest[str_len] == '\n') {email_cfg_list[j].dest[str_len] = 0; break;} + } + + // + status |= 1L << j; + break; + } + } + + OSTimeDly(200); + } + + i = 1; + for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++) + { + if ((status & (1 << j)) == 0) + { + i = 0; + break; + } + } + + OS_ENTER_CRITICAL(); + email_options.valid = i; + OS_EXIT_CRITICAL(); + + return 0; +} + +void ResetModemValid(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + email_options.valid = 0; + modem_connected = 0; + OS_EXIT_CRITICAL(); +} + + +// , ( ) +CPU_INT08U IsModemValid(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (email_options.valid && modem_connected) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + +CPU_INT08U IsModemConn(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (modem_connected) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + +CPU_INT08U IsModemConf(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (email_options.valid) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + + +// .. , , +int ModemConfigGprs() +{ + int repeat = 0; + if (!email_options.valid) return -1; + + GetModem(); + +REP_1: + sprintf(modem_buf, "AT^SICS=0,conType,GPRS0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + sprintf(modem_buf, "AT^SISC=0\r\n"); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + OSTimeDly(500); + if (repeat++ == 0) goto REP_1; + FreeModem(); + return -5; + } + + sprintf(modem_buf, "AT^SICS=0,inactTO,\"20\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -6; + } + + sprintf(modem_buf, "AT^SICS=0,dns1,\"%s\"\r\n", email_options.ap_dns); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -7; + } + + sprintf(modem_buf, "AT^SICS=0,passwd,\"%s\"\r\n", email_options.ap_password); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -8; + } + + sprintf(modem_buf, "AT^SICS=0,apn,\"%s\"\r\n", email_options.ap_apn); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -9; + } + + sprintf(modem_buf, "AT^SICS=0,user,\"%s\"\r\n", email_options.ap_user); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -10; + } + + FreeModem(); + return 0; +} + +int ModemConfigSmtp() +{ + int repeat = 0; + if (!email_options.valid) return -1; + + GetModem(); +REP_2: + // Select service type SMTP. + sprintf(modem_buf, "AT^SISS=0,srvType,\"Smtp\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + sprintf(modem_buf, "AT^SISC=0\r\n"); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + OSTimeDly(10000); + if (repeat++ == 0) goto REP_2; + FreeModem(); + return -25; + } + + // Choose ASCII alphabet. + sprintf(modem_buf, "AT^SISS=0,alphabet,\"1\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -26; + } + + // Select connection profile 0. + sprintf(modem_buf, "AT^SISS=0,conId,\"0\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -27; + } + + // Specify SMTP server address. + sprintf(modem_buf, "AT^SISS=0,address,\"%s\"\r\n", email_options.smtp_server); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -28; + } + + // Specify sender's user name required for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,user,\"%s\"\r\n", email_options.smtp_user); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -29; + } + + // Specify password used by the sender for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,passwd,\"%s\"\r\n", email_options.smtp_password); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -30; + } + + // Sender name and password can be used for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,smAuth,\"1\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -31; + } + + // Port for SMTP connection. + sprintf(modem_buf, "AT^SISS=0,tcpPort,\"%s\"\r\n", email_options.smtp_port); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -32; + } + + FreeModem(); + return 0; +} + +// : , +// callback , +int ModemSendEmail(char *subj, TextCallbackFunc text_callback) +{ + char *text; + int result = -1; + + if (!email_options.valid) return -50; + + result = ModemConfigGprs(); + if (result) + { + return result; + } + + result = ModemConfigSmtp(); + if (result) + { + return result; + } + + GetModem(); + + // Sender's email address. + sprintf(modem_buf, "AT^SISS=0,smFrom,\"%s\"\r\n", email_options.smtp_mail); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -51; + } + + // Recipient's email address. + sprintf(modem_buf, "AT^SISS=0,smRcpt,\"%s\"\r\n", email_options.receiver); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -52; + } + + // Enter text for subject field. + sprintf(modem_buf, "AT^SISS=0,smSubj,\"%s\"\r\n", subj); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -53; + } + + sprintf(modem_buf, "AT^SISC=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + FreeModem(); + return -54; + } + + OSTimeDly(5000); + // Open the service, i.e. start to send the email. + sprintf(modem_buf, "AT^SISO=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + FreeModem(); + return -55; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + FreeModem(); + return -56; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + FreeModem(); + return -57; + } + + if (strcmp(modem_buf, "^SISW: 0, 1\r\n") != 0) + { + return -58; + } + + text = additional_buf; + + OSTimeDly(1000); + + // + while (text_callback(text) == 0) + { + int lenght = strlen(text); + int wr_len, reg, eof; + int wr_ctr = 0; + + while (wr_ctr < lenght) + { + sprintf(modem_buf, "AT^SISW=0,%d\r\n", lenght-wr_ctr); + if (ModemSendCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + result = -59; + goto EMAIL_EXIT_FAIL; + } + + sscanf(modem_buf, "^SISW: %d, %d, %d", ®, &wr_len, &eof); + + if ((reg != 0) || (eof != 0) || (wr_len > lenght-wr_ctr) || (wr_len == 0)) + { + result = -60; + goto EMAIL_EXIT_FAIL; + } + + if (ModemSendOKData(text, wr_len, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -61; + goto EMAIL_EXIT_FAIL; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + result = -62; + goto EMAIL_EXIT_FAIL; + } + + wr_ctr += wr_len; + OSTimeDly(50); + } + } + + // Set the to mark the end of the email body. + // The is accepted by the service. + sprintf(modem_buf, "AT^SISW=0,0,1\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -63; + goto EMAIL_EXIT_FAIL; + } + + // The "^SISW" URC confirms that all data is sent suc-cessfully. + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // odoa + { + result = -64; + goto EMAIL_EXIT_FAIL; + } + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // ^sisw + { + result = -65; + goto EMAIL_EXIT_FAIL; + } + if (strcmp(modem_buf, "^SISW: 0, 2\r\n") != 0) + { + result = -66; + goto EMAIL_EXIT_FAIL; + } + + // Close the service. + sprintf(modem_buf, "AT^SISC=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -67; + goto EMAIL_EXIT_FAIL; + } + + FreeModem(); + return 0; + +EMAIL_EXIT_FAIL: + sprintf(modem_buf, "AT^SISC=0\r\n"); + OSTimeDly(10000); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + FreeModem(); + return result; +} + diff --git a/.svn/pristine/90/9099a53862d301a6b22bca1a8083a07295b4dbed.svn-base b/.svn/pristine/90/9099a53862d301a6b22bca1a8083a07295b4dbed.svn-base new file mode 100644 index 0000000..8302ae0 --- /dev/null +++ b/.svn/pristine/90/9099a53862d301a6b22bca1a8083a07295b4dbed.svn-base @@ -0,0 +1,1814 @@ +#include +#include "app_serv.h" +#include "menu.h" +#include "menudesc.h" +#include "data.h" +#include "datadesc.h" +#include "control.h" +#include "journal.h" +#include "time.h" +#include "mode.h" +#include "version.h" + +char FlagForPrintReport=0; + +/*********************************** + - +***********************************/ +const CPU_INT08U str_StartMenu_0[] = "-------------------"; +const CPU_INT08U str_StartMenu_1[] = " "; +const CPU_INT08U str_StartMenu_2[] = " !"; +const CPU_INT08U str_StartMenu_3[] = "-------------------"; + +const TMenuLine line_StartMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_0, // + NULL // +}; + +const TMenuLine line_StartMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_1, // + NULL // +}; + +const TMenuLine line_StartMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_2, // + NULL // +}; + +const TMenuLine line_StartMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_StartMenuArray[] = {&line_StartMenu_0, &line_StartMenu_1, &line_StartMenu_2, &line_StartMenu_3, NULL}; +const TMenuPanel StartMenuPanel[] = {arr_StartMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_IncasMenu_0[] = "-------------------"; +const CPU_INT08U str_IncasMenu_1[] = " "; +const CPU_INT08U str_IncasMenu_2[] = " "; +CPU_INT08U str_IncasMenu_3[32]; + +const TMenuLine line_IncasMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_0, // + NULL // +}; + +const TMenuLine line_IncasMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_1, // + NULL // +}; + +const TMenuLine line_IncasMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_2, // + NULL // +}; + +const TMenuLine line_IncasMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_IncasMenuArray[] = {&line_IncasMenu_0, &line_IncasMenu_1, &line_IncasMenu_2, &line_IncasMenu_3, NULL}; +const TMenuPanel IncasMenuPanel[] = {arr_IncasMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalEmptyMenu_0[] = ""; +const CPU_INT08U str_JournalEmptyMenu_1[] = " "; +const CPU_INT08U str_JournalEmptyMenu_2[] = " "; +const CPU_INT08U str_JournalEmptyMenu_3[] = ""; + +const TMenuLine line_JournalEmptyMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_0, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_1, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_2, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_JournalEmptyMenuArray[] = {&line_JournalEmptyMenu_0, &line_JournalEmptyMenu_1, &line_JournalEmptyMenu_2, &line_JournalEmptyMenu_3, NULL}; +const TMenuPanel JournalEmptyMenuPanel[] = {arr_JournalEmptyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_ServiceMenu_0[] = " . "DEVICE_FW_VERSION; +const CPU_INT08U str_ServiceMenu_1[] = ""; +const CPU_INT08U str_ServiceMenu_2[] = ""; +const CPU_INT08U str_ServiceMenu_3[] = ""; +const CPU_INT08U str_ServiceMenu_4[] = ""; + +const TMenuLine line_ServiceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ServiceMenu_0, // + NULL // +}; + +const TMenuLine line_ServiceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_1, // + (void*)&SettingsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_2, // + (void*)&StatisticsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_3, // + (void*)&SelectJournalMenuPanel // +}; + +const TMenuLine line_ServiceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_4, // + (void*)&ReportMenuPanel // +}; + +const TMenuLineArray arr_ServiceMenuArray[] = {&line_ServiceMenu_0, &line_ServiceMenu_1, &line_ServiceMenu_2, &line_ServiceMenu_3, &line_ServiceMenu_4, NULL}; +const TMenuPanel ServiceMenuPanel[] = {arr_ServiceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_StatisticsMenu_0[] = " "; +const CPU_INT08U str_StatisticsMenu_1[] = " "; +const CPU_INT08U str_StatisticsMenu_2[] = ""; +const CPU_INT08U str_StatisticsMenu_3[] = " "; +const CPU_INT08U str_StatisticsMenu_4[] = " "; + + +const TMenuLine line_StatisticsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_StatisticsMenu_0, // + NULL // +}; + +const TMenuLine line_StatisticsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_1, // + (void*)ChanStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_2, // + (void*)CommStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_3, // + (void*)BillCountersPanel // +}; + +const TMenuLine line_StatisticsMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_4, // + (void*)ClearStatMenu // +}; + +const TMenuLineArray arr_StatisticsMenuArray[] = {&line_StatisticsMenu_0, &line_StatisticsMenu_1, &line_StatisticsMenu_2, &line_StatisticsMenu_3, &line_StatisticsMenu_4, NULL}; +const TMenuPanel StatisticsMenuPanel[] = {arr_StatisticsMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearStatMenu_0[] = " "; +const char str_ClearStatMenu_1[] = " "; + +void OnEnterPanelClearStat(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_0, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_1, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearStatMenuArray[] = {&line_ClearStatMenu_0, &line_ClearStatMenu_1, &line_ClearStatMenu_2, NULL}; +const TMenuPanel ClearStatMenu[] = {arr_ClearStatMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearJournalMenu_0[] = " "; +const char str_ClearJournalMenu_1[] = " "; + +void OnEnterPanelClearJournal(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_0, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_1, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearJournalMenuArray[] = {&line_ClearJournalMenu_0, &line_ClearJournalMenu_1, &line_ClearJournalMenu_2, NULL}; +const TMenuPanel ClearJournalMenuPanel[] = {arr_ClearJournalMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersArray[] = {&line_ChannelCountersMenu_0, &line_ChannelCountersMenu_1, &line_ChannelCountersMenu_2, &line_ChannelCountersMenu_3, NULL}; +const TMenuPanel ChannelCountersPanel[] = {arr_ChannelCountersArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_BillCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&BillnomIndexDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomCountersDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillCounterDesc, // + NULL // +}; + +extern CPU_INT32U BillnomViewIndex; + +void OnEnterBillCountersMenu() +{ + BillnomViewIndex = 0; +} + +const TMenuLineArray arr_BillCountersArray[] = {&line_BillCountersMenu_0, &line_BillCountersMenu_1, &line_BillCountersMenu_2, &line_BillCountersMenu_3, NULL}; +const TMenuPanel BillCountersPanel[] = {arr_BillCountersArray, OnEnterBillCountersMenu, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersMenu_0[] = " "; + +const TMenuLine line_CommonCountersMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersArray[] = {&line_CommonCountersMenu_0, &line_CommonCountersMenu_1, &line_CommonCountersMenu_2, &line_CommonCountersMenu_3, NULL}; +const TMenuPanel CommonCountersPanel[] = {arr_CommonCountersArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersLongMenu_0[] = " "; + +const TMenuLine line_CommonCountersLongMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersLongMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersLongArray[] = {&line_CommonCountersLongMenu_0, &line_CommonCountersLongMenu_1, &line_CommonCountersLongMenu_2, &line_CommonCountersLongMenu_3, NULL}; +const TMenuPanel CommonCountersLongPanel[] = {arr_CommonCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_SettingsMenu_0[] = " "; +const CPU_INT08U str_SettingsMenu_1[] = ""; +const CPU_INT08U str_SettingsMenu_2[] = ""; +const CPU_INT08U str_SettingsMenu_3[] = " "; +const CPU_INT08U str_SettingsMenu_4[] = " "; +const CPU_INT08U str_SettingsMenu_5[] = " "; + +const TMenuLine line_SettingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SettingsMenu_0, // + NULL // +}; + +const TMenuLine line_SettingsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_1, // + (void*)&ChannelMenuPanel // +}; + +const TMenuLine line_SettingsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_2, // + (void*)&DeviceMenuPanel // +}; + +const TMenuLine line_SettingsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_3, // + (void*)&SetPassMenuPanel // +}; + +const TMenuLine line_SettingsMenu_5 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_4, // + (void*)&TimeSetupMenuPanel // +}; + +const TMenuLine line_SettingsMenu_6 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_5, // + (void*)&ResetSettingsMenuPanel // +}; + +const TMenuLine line_SettingsMenu_7 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&StartButtonNameDesc, // + NULL // +}; + +const TMenuLineArray arr_SettingsMenuArray[] = {&line_SettingsMenu_0, &line_SettingsMenu_1, &line_SettingsMenu_2, &line_SettingsMenu_5, &line_SettingsMenu_3, &line_SettingsMenu_6, &line_SettingsMenu_7, NULL}; +const TMenuPanel SettingsMenuPanel[] = {arr_SettingsMenuArray, NULL, 7, MENU_PANEL_STANDARD}; + + + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&NameChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutBeforeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutAfterDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MinWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MaxWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_7 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&WeekEndDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_8 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&DeferredStartDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_9 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekdaysMenuPanel // +}; + +const TMenuLine line_ChannelMenu_10 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekendMenuPanel // +}; + +const TMenuLineArray arr_ChannelMenuArray[] = {&line_ChannelMenu_0, + &line_ChannelMenu_1, + &line_ChannelMenu_2, + &line_ChannelMenu_3, + &line_ChannelMenu_4, + &line_ChannelMenu_5, + &line_ChannelMenu_6, + &line_ChannelMenu_7, + &line_ChannelMenu_8, + &line_ChannelMenu_9, + &line_ChannelMenu_10, + NULL}; +char flag_enter_periods=0; + +void OnEnterChannelSettingsMenu(void) +{ + if (!flag_enter_periods) + { + ChannelIndex = 0; + } + else + { + flag_enter_periods = 0; + } +} + +const TMenuPanel ChannelMenuPanel[] = {arr_ChannelMenuArray, OnEnterChannelSettingsMenu, 11, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +void OnEnterPanelPrice(void) +{ + PeriodIndex = ChannelIndex*PRICE_PERIODS_NUM; + flag_enter_periods = 1; +} + +const TMenuLine line_PriceMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekdaysIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekdaysDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArray[] = {&line_PriceMenu_0, &line_PriceMenu_1, &line_PriceMenu_2, &line_PriceMenu_3, &line_PriceMenu_4, NULL}; +const TMenuPanel PriceWeekdaysMenuPanel[] = {arr_PriceMenuArray, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_SetPassMenu_0[] = " "; + +void OnEnterPanelSetPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_SetPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc, // + NULL // +}; + +const TMenuLine line_SetPassMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " -", // + (void*)MasterPassMenuPanel // +}; + +const TMenuLineArray arr_SetPassMenuArray[] = {&line_SetPassMenu_0, &line_SetPassMenu_1, &line_SetPassMenu_2, NULL}; +const TMenuPanel SetPassMenuPanel[] = {arr_SetPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + - +***********************************/ +const char str_MasterPassMenu_0[] = " -"; + +void OnEnterPanelMasterPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_MasterPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_MasterPassMenu_0, // + NULL // +}; + +const TMenuLine line_MasterPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MasterPassTempDesc, // + NULL // +}; + +const TMenuLineArray arr_MasterPassMenuArray[] = {&line_MasterPassMenu_0, &line_MasterPassMenu_1, NULL}; +const TMenuPanel MasterPassMenuPanel[] = {arr_MasterPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_ResetSetingsMenu_0[] = " "; +const char str_ResetSetingsMenu_1[] = " "; + +void OnEnterPanelResetSetings(void) +{ + TempPass = 0; +} + +const TMenuLine line_ResetSetingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_0, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_1, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc1, // + NULL // +}; + +const TMenuLineArray arr_ResetSettingsMenuArray[] = {&line_ResetSetingsMenu_0, &line_ResetSetingsMenu_1, &line_ResetSetingsMenu_2, NULL}; +const TMenuPanel ResetSettingsMenuPanel[] = {arr_ResetSettingsMenuArray, OnEnterPanelResetSetings, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_SetNewPassMenu_0[] = " "; + +const TMenuLine line_SetNewPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetNewPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetNewPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassDesc, // + NULL // +}; + +const TMenuLineArray arr_SetNewPassMenuArray[] = {&line_SetNewPassMenu_0, &line_SetNewPassMenu_1, NULL}; +const TMenuPanel SetNewPassMenuPanel[] = {arr_SetNewPassMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_PriceMenuWend_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekendIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekendDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArrayWend[] = {&line_PriceMenuWend_0, &line_PriceMenuWend_1, &line_PriceMenuWend_2, &line_PriceMenuWend_3, &line_PriceMenuWend_4, NULL}; +const TMenuPanel PriceWeekendMenuPanel[] = {arr_PriceMenuArrayWend, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_DeviceMenu_0[] = " "; +const CPU_INT08U str_DeviceMenu_1[] = ""; +const CPU_INT08U str_DeviceMenu_2[] = ""; +const CPU_INT08U str_DeviceMenu_3[] = ""; + +const TMenuLine line_DeviceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_DeviceMenu_0, // + NULL // +}; + +const TMenuLine line_DeviceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_1, // + (void*)&FrMenuPanel // +}; + +const TMenuLine line_DeviceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableValidatorDesc, // + NULL // +}; + +const TMenuLine line_DeviceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_2, // + (void*)&CoinSetupPanel // +}; + +const TMenuLine line_DeviceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_3, // + (void*)&ModemSetupPanel // +}; + +const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, &line_DeviceMenu_1, &line_DeviceMenu_2, &line_DeviceMenu_3, &line_DeviceMenu_4, NULL}; +const TMenuPanel DeviceMenuPanel[] = {arr_DeviceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrMenu_0[] = " "; + +const TMenuLine line_FrMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrMenu_0, // + NULL // +}; + +const TMenuLine line_FrMenu_1 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&EnableFiscalDesc, + NULL +}; + +const TMenuLine line_FrMenu_2 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&EnableFiscalDayClearDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_3 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&BillFormatDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_4 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&ServiceNameDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_5 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&DisableFiscalErrorsDesc, + NULL +}; + +const TMenuLineArray arr_FrMenuArray[] = {&line_FrMenu_0, &line_FrMenu_1, &line_FrMenu_2, &line_FrMenu_3, &line_FrMenu_4, &line_FrMenu_5, NULL}; +const TMenuPanel FrMenuPanel[] = {arr_FrMenuArray, NULL, 6, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CoinMenu_0[] = " ."; + +const TMenuLine line_CoinMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CoinMenu_0, // + NULL // +}; + +const TMenuLine line_CoinMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableCoinDesc, // + NULL // +}; + +const TMenuLine line_CoinMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CoinPerPulseDesc, // + NULL // +}; + +const TMenuLineArray arr_CoinMenuArray[] = {&line_CoinMenu_0, &line_CoinMenu_1, &line_CoinMenu_2, NULL}; +const TMenuPanel CoinSetupPanel[] = {arr_CoinMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ModemMenu_0[] = " "; + +const TMenuLine line_ModemMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ModemMenu_0, // + NULL // +}; + +const TMenuLine line_ModemMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableModemDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&ModemStatusDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&StatSendHourMinDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableEmailJournalSendDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&DeviceIDDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SendTestEmailDesc, // + NULL // +}; + + +const TMenuLineArray arr_ModemMenuArray[] = {&line_ModemMenu_0, &line_ModemMenu_1, &line_ModemMenu_2, &line_ModemMenu_3, &line_ModemMenu_4, &line_ModemMenu_5, &line_ModemMenu_6, NULL}; +const TMenuPanel ModemSetupPanel[] = {arr_ModemMenuArray, NULL, 7, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ + +char str_UserMenu_0[22] = ""; +char str_UserMenu_1[22] = ""; +char str_UserMenu_2[22] = ""; +char str_UserMenu_3[22] = ""; + +char str_buf[22]; + + +void PrintUserMenuStr(char* str, CPU_INT08U n) +{ + char *strptr; + char *instr; + // + + switch (n) + { + case 0: + strptr = str_UserMenu_0; + break; + case 1: + strptr = str_UserMenu_1; + break; + case 2: + strptr = str_UserMenu_2; + break; + case 3: + strptr = str_UserMenu_3; + break; + default: + return; + } + + // , + instr = str; + while (*instr==0x20) instr++; + + memset(strptr, 0x20, 20); + + int len = strlen(instr); + if ((len >= 20) || ((10-len/2-1) < 0)) {strcpy(strptr, instr); return;} + + strcpy(&strptr[10-len/2-1], instr); +} + +const TMenuLine line_FirstMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_0, // + NULL // +}; + +const TMenuLine line_FirstMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_1, // + NULL // +}; + +const TMenuLine line_FirstMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_2, // + NULL // +}; + +const TMenuLine line_FirstMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_3, // + NULL // +}; + + +const TMenuLineArray FirstMenuArray[] = {&line_FirstMenu_0, &line_FirstMenu_1, &line_FirstMenu_2, &line_FirstMenu_3, NULL}; +const TMenuPanel FirstMenuPanel[] = {FirstMenuArray, InitUserMenu, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_ErrPass_0[] = " "; +const CPU_INT08U str_ErrPass_1[] = " "; +const CPU_INT08U str_ErrPass_2[] = ""; + +const TMenuLine line_ErrPassMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_0, // + NULL // +}; + +const TMenuLine line_ErrPassMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_1, // + NULL // +}; +const TMenuLine line_ErrPassMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_2, // + NULL // +}; + +const TMenuLineArray ErrPassMenuArray[] = {&line_ErrPassMenu_2, &line_ErrPassMenu_0, &line_ErrPassMenu_1, &line_ErrPassMenu_2, NULL}; +const TMenuPanel ErrorPassPanel[] = {ErrPassMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_SettingsIsResetPass_0[] = " "; +const CPU_INT08U str_SettingsIsResetPass_1[] = " "; +const CPU_INT08U str_SettingsIsResetPass_2[] = " "; +const CPU_INT08U str_SettingsIsResetPass_3[] = " "; + +const TMenuLine line__SettingsIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_0, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_1, // + NULL // +}; +const TMenuLine line__SettingsIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_2, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_3, // + NULL // +}; + +const TMenuLineArray SettingsIsResetMenuArray[] = {&line__SettingsIsResetMenu_0, &line__SettingsIsResetMenu_1, &line__SettingsIsResetMenu_2, &line__SettingsIsResetMenu_3, NULL}; +const TMenuPanel SettingsIsReset[] = {SettingsIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_StatIsResetPass_0[] = " "; +const CPU_INT08U str_StatIsResetPass_1[] = " "; +const CPU_INT08U str_StatIsResetPass_2[] = ""; + +const TMenuLine line__StatIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_0, // + NULL // +}; + +const TMenuLine line__StatIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_1, // + NULL // +}; +const TMenuLine line__StatIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_2, // + NULL // +}; + +const TMenuLineArray StatIsResetMenuArray[] = {&line__StatIsResetMenu_2, &line__StatIsResetMenu_0, &line__StatIsResetMenu_1, &line__StatIsResetMenu_2, NULL}; +const TMenuPanel StatIsReset[] = {StatIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalIsResetPass_0[] = " "; +const CPU_INT08U str_JournalIsResetPass_1[] = " "; +const CPU_INT08U str_JournalIsResetPass_2[] = ""; + +const TMenuLine line__JournalIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_0, // + NULL // +}; + +const TMenuLine line__JournalIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_1, // + NULL // +}; +const TMenuLine line__JournalIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_2, // + NULL // +}; + +const TMenuLineArray JournalIsResetMenuArray[] = {&line__JournalIsResetMenu_2, &line__JournalIsResetMenu_0, &line__JournalIsResetMenu_1, &line__JournalIsResetMenu_2, NULL}; +const TMenuPanel JournalIsReset[] = {JournalIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_GetMoney_0[] = " "; + +const TMenuLine line_GetMoneyMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_1 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE, // . + (void*)&AcceptedMoneyDesc, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + + +const TMenuLineArray GetMoneyMenuArray[] = {&line_GetMoneyMenu_0, &line_GetMoneyMenu_1, &line_GetMoneyMenu_2, &line_GetMoneyMenu_3, NULL}; +const TMenuPanel GetMoneyMenuPanel[] = {GetMoneyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_SelectJournalMenu_0[] = " "; +const CPU_INT08U str_SelectJournalMenu_1[] = " "; +const CPU_INT08U str_SelectJournalMenu_2[] = " "; +const CPU_INT08U str_SelectJournalMenu_3[] = " "; + +const TMenuLine line_SelectJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SelectJournalMenu_0, // + NULL // +}; + +const TMenuLine line_SelectJournalMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_1, // + (void*)&ErrorJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_2, // + (void*)&EventJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_3, // + (void*)&ClearJournalMenuPanel // +}; + +const TMenuLineArray arr_SelectJournalMenuArray[] = {&line_SelectJournalMenu_0, &line_SelectJournalMenu_1, &line_SelectJournalMenu_2, &line_SelectJournalMenu_3, NULL}; +const TMenuPanel SelectJournalMenuPanel[] = {arr_SelectJournalMenuArray, NULL, 4, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ReportMenu_0[] = " "; +const CPU_INT08U str_ReportMenu_1[] = "X-"; +const CPU_INT08U str_ReportMenu_2[] = "Z-"; +const CPU_INT08U str_ReportMenu_3[] = "Z- "; + +const TMenuLine line_ReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ReportMenu_0, // + NULL // +}; + +const TMenuLine line_ReportMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_1, // + (void*)&xReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_2, // + (void*)&zReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_3, // + (void*)&bufReportMenuPanel // +}; + + +void OnEnterReportsPanel(void) +{ + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (!enable) + { + GoToPreviousMenu(); + GoToMenu(FrIsOffMenuPanel); + } + FlagForPrintReport = 0; +} + +const TMenuLineArray arr_ReportMenuArray[] = {&line_ReportMenu_0, &line_ReportMenu_1, &line_ReportMenu_2, &line_ReportMenu_3, NULL}; +const TMenuPanel ReportMenuPanel[] = {arr_ReportMenuArray, OnEnterReportsPanel, 4, MENU_PANEL_STANDARD}; + +/*********************************** + X- +***********************************/ +const CPU_INT08U str_xReportMenu_0[] = " X-"; +const CPU_INT08U str_xReportMenu_1[] = " "; +const CPU_INT08U str_xReportMenu_2[] = " ?"; +const CPU_INT08U str_xReportMenu_3[] = "-START STOP-"; + +const TMenuLine line_xReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_xReportMenu_0, // + NULL // +}; + +const TMenuLine line_xReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_1, // + NULL // +}; + +const TMenuLine line_xReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_2, // + NULL // +}; + +const TMenuLine line_xReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +void OnEnterZXReportPanel(void) +{ + OSTimeDly(20); + FlagForPrintReport = 1; +} + +const TMenuLineArray arr_xReportMenuArray[] = {&line_xReportMenu_0, &line_xReportMenu_1, &line_xReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel xReportMenuPanel[] = {arr_xReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_zReportMenu_0[] = " Z-"; +const CPU_INT08U str_zReportMenu_1[] = " "; +const CPU_INT08U str_zReportMenu_2[] = " ?"; + +const TMenuLine line_zReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_zReportMenu_0, // + NULL // +}; + +const TMenuLine line_zReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_1, // + NULL // +}; + +const TMenuLine line_zReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_2, // + NULL // +}; + +const TMenuLine line_zReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_zReportMenuArray[] = {&line_zReportMenu_0, &line_zReportMenu_1, &line_zReportMenu_2, &line_zReportMenu_3, NULL}; +const TMenuPanel zReportMenuPanel[] = {arr_zReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_bufReportMenu_0[] = " Z- "; +const CPU_INT08U str_bufReportMenu_1[] = " "; +const CPU_INT08U str_bufReportMenu_2[] = " ?"; + +const TMenuLine line_bufReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_bufReportMenu_0, // + NULL // +}; + +const TMenuLine line_bufReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_1, // + NULL // +}; + +const TMenuLine line_bufReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_2, // + NULL // +}; + +const TMenuLine line_bufReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_bufReportMenuArray[] = {&line_bufReportMenu_0, &line_bufReportMenu_1, &line_bufReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel bufReportMenuPanel[] = {arr_bufReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrIsOff_0[] = ""; +const CPU_INT08U str_FrIsOff_1[] = " "; +const CPU_INT08U str_FrIsOff_2[] = " "; + +const TMenuLine line_FrIsOff_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrIsOff_0, // + NULL // +}; + +const TMenuLine line_FrIsOff_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_1, // + NULL // +}; + +const TMenuLine line_FrIsOff_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_2, // + NULL // +}; + +const TMenuLineArray arr_FrIsOffMenuArray[] = {&line_FrIsOff_0, &line_FrIsOff_1, &line_FrIsOff_2, NULL}; +const TMenuPanel FrIsOffMenuPanel[] = {arr_FrIsOffMenuArray, NULL, 3, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_ErrorJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ErrorJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc0, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc1, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorTimeDesc, // + NULL // +}; + +void OnEnterErrorJournal(void) +{ + TErrorRecord record; + ErrorJournalIndex = 0; + CPU_INT32U last = 0; + CPU_INT32U i; + + for (i=0; i= last) + { + last = record.time; + ErrorJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} +} + +const TMenuLineArray arr_ErrorJournalMenuArray[] = {&line_ErrorJournalMenu_0, &line_ErrorJournalMenu_1, &line_ErrorJournalMenu_2, &line_ErrorJournalMenu_3, NULL}; +const TMenuPanel ErrorJournalMenuPanel[] = {arr_ErrorJournalMenuArray, OnEnterErrorJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +char str_EventNumber[24]; +char str_EventData[24]; + +const TMenuLine line_EventJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&EventJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalEventTimeDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventNumber, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventData, // + NULL // +}; + + +void PrintEventJournalRecord(TEventRecord *record) +{ + if (record->event) + { // + GetEventStr(str_EventNumber, record->event); + if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN)) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, "%d .", record->data); + } + else if (record->event == JOURNAL_EVENT_START_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + PrintSecToHourMinSec(str_EventData, record->data); + } + else if (record->event == JOURNAL_EVENT_END_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_DEVICE_ON) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BILL) + { + sprintf(str_EventData, " %d", record->channel+1); + } + else if (record->event == JOURNAL_EVENT_PRINT_Z) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_X) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BUF) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_CHANGE_MODE) + { + if (record->data == MODE_WORK) sprintf(str_EventData, ""); + else sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_INCASSATION) + { + sprintf(str_EventData, "%u .", record->data); + } + else if (record->event == JOURNAL_EVENT_PASS_FAIL) + { + sprintf(str_EventData, "%u", record->data); + } + else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL)) + { + sprintf(str_EventData, ""); + } + + } + else + { // + sprintf(str_EventNumber, ""); + sprintf(str_EventData, ""); + } +} + +void OnEnterEventJournal(void) +{ + TEventRecord record; + EventJournalIndex = 0; + CPU_INT32U last = 0; + + for (CPU_INT32U i=0; i= last) + { + last = record.time; + EventJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +const TMenuLineArray arr_EventJournalMenuArray[] = {&line_EventJournalMenu_0, &line_EventJournalMenu_1, &line_EventJournalMenu_2, &line_EventJournalMenu_3 ,NULL}; +const TMenuPanel EventJournalMenuPanel[] = {arr_EventJournalMenuArray, OnEnterEventJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_TimeSetupMenu_0[] = " "; + +const TMenuLine line_TimeSetupMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_TimeSetupMenu_0, // + NULL // +}; + +const TMenuLine line_TimeSetupMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SystemTimeEditDesc, // + NULL // +}; + +const TMenuLineArray arr_TimeSetupMenuArray[] = {&line_TimeSetupMenu_0, &line_TimeSetupMenu_1, NULL}; +const TMenuPanel TimeSetupMenuPanel[] = {arr_TimeSetupMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonStatMenu_0[] = " "; +const CPU_INT08U str_CommonStatMenu_1[] = " "; +const CPU_INT08U str_CommonStatMenu_2[] = " "; + +const TMenuLine line_StatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CommonStatMenu_0, // + NULL // +}; + +const TMenuLine line_StatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)CommonCountersPanel // +}; + +const TMenuLine line_StatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)CommonCountersLongPanel // +}; + +const TMenuLineArray arr_StatMenuArray[] = {&line_StatMenu_0, &line_StatMenu_1, &line_StatMenu_2, NULL}; +const TMenuPanel CommStatMenuPanel[] = {arr_StatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_ChanStatMenu_0[] = " - "; + +const TMenuLine line_ChanStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ChanStatMenu_0, // + NULL // +}; + +const TMenuLine line_ChanStatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)ChannelCountersPanel // +}; + +const TMenuLine line_ChanStatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)ChannelCountersLongPanel // +}; + +const TMenuLineArray arr_ChanStatMenuArray[] = {&line_ChanStatMenu_0, &line_ChanStatMenu_1, &line_ChanStatMenu_2, NULL}; +const TMenuPanel ChanStatMenuPanel[] = {arr_ChanStatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersLongMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStLongIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeLongDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersLongArray[] = {&line_ChannelCountersLongMenu_0, &line_ChannelCountersLongMenu_1, &line_ChannelCountersLongMenu_2, &line_ChannelCountersLongMenu_3, NULL}; +const TMenuPanel ChannelCountersLongPanel[] = {arr_ChannelCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; diff --git a/.svn/pristine/95/95c51dd96386a0726157a5d113fe824650c50814.svn-base b/.svn/pristine/95/95c51dd96386a0726157a5d113fe824650c50814.svn-base new file mode 100644 index 0000000..4a590a3 --- /dev/null +++ b/.svn/pristine/95/95c51dd96386a0726157a5d113fe824650c50814.svn-base @@ -0,0 +1,99 @@ +#ifndef __BSP_H__ +#define __BSP_H__ + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef BSP_GLOBALS +#define BSP_EXT +#else +#define BSP_EXT extern +#endif + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define MAIN_OSC_FRQ 12000000L +#define IRC_OSC_FRQ 4000000L +#define RTC_OSC_FRQ 32768L + +/* +********************************************************************************************************* +* PCLK PERIPHERAL IDS +* (see 'BSP_CPU_PclkFreq()') +********************************************************************************************************* +*/ + +#define PCLK_WDT 0 +#define PCLK_TIMER0 1 +#define PCLK_TIMER1 2 +#define PCLK_UART0 3 +#define PCLK_UART1 4 +#define PCLK_PWM0 5 +#define PCLK_PWM1 6 +#define PCLK_I2C0 7 +#define PCLK_SPI 8 +#define PCLK_RTC 9 +#define PCLK_SSP1 10 +#define PCLK_DAC 11 +#define PCLK_ADC 12 +#define PCLK_CAN1 13 +#define PCLK_CAN2 14 +#define PCLK_ACF 15 +#define PCLK_BAT_RAM 16 +#define PCLK_GPIO 17 +#define PCLK_PCB 18 +#define PCLK_I2C1 19 +#define PCLK_SSP0 21 +#define PCLK_TIMER2 22 +#define PCLK_TIMER3 23 +#define PCLK_UART2 24 +#define PCLK_UART3 25 +#define PCLK_I2C2 26 +#define PCLK_MCI 27 +#define PCLK_SYSCON 29 + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void BSP_Init (void); +void BSP_IntDisAll (void); +CPU_INT32U BSP_CPU_ClkFreq (void); +CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U id); + + +/* +********************************************************************************************************* +* TICK SERVICES +********************************************************************************************************* +*/ + +void Tmr_TickISR_Handler(void); + + + + +#endif diff --git a/.svn/pristine/97/9797818d0e66aad88377898fa1b4c6724f62a30e.svn-base b/.svn/pristine/97/9797818d0e66aad88377898fa1b4c6724f62a30e.svn-base new file mode 100644 index 0000000..ddc0e23 --- /dev/null +++ b/.svn/pristine/97/9797818d0e66aad88377898fa1b4c6724f62a30e.svn-base @@ -0,0 +1,71 @@ +#ifndef _APP_SERV_H_ +#define _APP_SERV_H_ + +#include "app_cfg.h" + +extern CPU_INT32U incas_bill_nom_counter[24]; +extern CPU_INT32U incas_common_bill_counter; + +#define KBRD_TASK_STK_SIZE 256 +#define USER_TASK_STK_SIZE 384 +#define MENU_TASK_STK_SIZE 512 +#define COIN_TASK_STK_SIZE 384 +#define VALIDATOR_TASK_STK_SIZE 384 +#define FISCAL_TASK_STK_SIZE 384 +#define MODEM_TASK_STK_SIZE 768 + + +#define VALIDATOR_TASK_PRIO USER_HIGHEST_PRIO +#define USER_TASK_PRIO (USER_HIGHEST_PRIO+1) +#define COIN_TASK_PRIO (USER_HIGHEST_PRIO+2) +#define KBRD_TASK_PRIO (USER_HIGHEST_PRIO+3) +#define FISCAL_TASK_PRIO (USER_HIGHEST_PRIO+4) +#define MENU_TASK_PRIO (USER_HIGHEST_PRIO+5) +#define MODEM_TASK_PRIO USER_LOWEST_PRIO + +enum{ + EVENT_SEC = 1, + EVENT_STARTUP, + + EVENT_COIN_INSERTED, + EVENT_BILL_ESCROW, + EVENT_BILL_STACKED, + + EVENT_MODE_CHANGE, + + EVENT_KEY_EMPTY, + EVENT_KEY_F1, + EVENT_KEY_F2, + EVENT_KEY_F3, + EVENT_KEY_LEFT, + EVENT_KEY_UP, + EVENT_KEY_RIGHT, + EVENT_KEY_STOP, + EVENT_KEY_DOWN, + EVENT_KEY_START, + EVENT_KEY_USER_START, + EVENT_KEY_DEFERRED_CH1, + EVENT_KEY_DEFERRED_CH2, + EVENT_KEY_DEFERRED_CH3, + EVENT_KEY_DEFERRED_CH4, + EVENT_KEY_DEFERRED_CH5, + EVENT_KEY_DEFERRED_CH6, + EVENT_KEY_DEFERRED_CH7, + EVENT_KEY_DEFERRED_CH8, + EVENT_KEY_DEFERRED_CH9, + EVENT_KEY_DEFERRED_CH10, + + EVENT_INCASSATION, + EVENT_INCASSATION_FINISH +}; + +#define LED_on() {FIO1SET_bit.P1_21= 1;} +#define LED_off() {FIO1CLR_bit.P1_21= 1;} + +extern void UserStartupFunc(void); +extern void PostUserEvent(int event); + +extern void InitUserMenu(void); +extern int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time); + +#endif //#ifndef _APP_SERV_H_ diff --git a/.svn/pristine/98/98c384363ac3993e8f8ac947fe5fac773a99adc6.svn-base b/.svn/pristine/98/98c384363ac3993e8f8ac947fe5fac773a99adc6.svn-base new file mode 100644 index 0000000..c3eceec --- /dev/null +++ b/.svn/pristine/98/98c384363ac3993e8f8ac947fe5fac773a99adc6.svn-base @@ -0,0 +1,15 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM + + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armproc.dll" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armjlink.dll" %1 --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armbat.dll" --flash_loader "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\config\flashloader\NXP\FlashNXPLPC512k2.board" --backend -B "--endian=little" "--cpu=ARM7TDMI-S" "--fpu=None" "-p" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\CONFIG\debugger\NXP\iolpc2368.ddf" "--drv_verify_download" "--semihosting" "--device=LPC2368" "--drv_communication=USB0" "--jlink_speed=adaptive" "--jlink_reset_strategy=0,9" + + diff --git a/.svn/pristine/9d/9dafea76c830b0bd105faa1f39e727b4ec7a1f88.svn-base b/.svn/pristine/9d/9dafea76c830b0bd105faa1f39e727b4ec7a1f88.svn-base new file mode 100644 index 0000000..efc59f8 --- /dev/null +++ b/.svn/pristine/9d/9dafea76c830b0bd105faa1f39e727b4ec7a1f88.svn-base @@ -0,0 +1,1116 @@ +/* +************************************************************************************************************************ +* uC/OS-III +* The Real-Time Kernel +* +* (c) Copyright 2005-2007, Micrium, Weston, FL +* All Rights Reserved +* +* TIMER MANAGEMENT +* +* File : OS_TMR.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +************************************************************************************************************************ +*/ + +#include + +/* +************************************************************************************************************************ +* NOTES +* +* 1) Your application MUST define the following #define constants: +* +* OS_TASK_TMR_PRIO The priority of the Timer management task +* OS_TASK_TMR_STK_SIZE The size of the Timer management task's stack +* +* 2) You must call OSTmrSignal() to notify the Timer management task that it's time to update the timers. +************************************************************************************************************************ +*/ + +/* +************************************************************************************************************************ +* CONSTANTS +************************************************************************************************************************ +*/ + +#define OS_TMR_LINK_DLY 0 +#define OS_TMR_LINK_PERIODIC 1 + +/* +************************************************************************************************************************ +* LOCAL PROTOTYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static OS_TMR *OSTmr_Alloc (void); +static void OSTmr_Free (OS_TMR *ptmr); +static void OSTmr_InitTask (void); +static void OSTmr_Link (OS_TMR *ptmr, INT8U type); +static void OSTmr_Unlink (OS_TMR *ptmr); +static void OSTmr_Lock (void); +static void OSTmr_Unlock (void); +static void OSTmr_Task (void *p_arg); +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* CREATE A TIMER +* +* Description: This function is called by your application code to create a timer. +* +* Arguments : dly Initial delay. +* If the timer is configured for ONE-SHOT mode, this is the timeout used +* If the timer is configured for PERIODIC mode, this is the first timeout to wait for +* before the timer starts entering periodic mode +* +* period The 'period' being repeated for the timer. +* If you specified 'OS_TMR_OPT_PERIODIC' as an option, when the timer expires, it will +* automatically restart with the same period. +* +* opt Specifies either: +* OS_TMR_OPT_ONE_SHOT The timer counts down only once +* OS_TMR_OPT_PERIODIC The timer counts down and then reloads itself +* +* callback Is a pointer to a callback function that will be called when the timer expires. The +* callback function must be declared as follows: +* +* void MyCallback (OS_TMR *ptmr, void *p_arg); +* +* callback_arg Is an argument (a pointer) that is passed to the callback function when it is called. +* +* pname Is a pointer to an ASCII string that is used to name the timer. Names are useful for +* debugging. The length of the ASCII string for the name can be as big as: +* +* OS_TMR_CFG_NAME_SIZE and should be found in OS_CFG.H +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID_DLY you specified an invalid delay +* OS_ERR_TMR_INVALID_PERIOD you specified an invalid period +* OS_ERR_TMR_INVALID_OPT you specified an invalid option +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_NON_AVAIL if there are no free timers from the timer pool +* OS_ERR_TMR_NAME_TOO_LONG if the timer name is too long to fit +* +* Returns : A pointer to an OS_TMR data structure. +* This is the 'handle' that your application will use to reference the timer created. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr) +{ + OS_TMR *ptmr; +#if OS_TMR_CFG_NAME_SIZE > 0 + INT8U len; +#endif + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return ((OS_TMR *)0); + } + switch (opt) { + case OS_TMR_OPT_PERIODIC: + if (period == 0) { + *perr = OS_ERR_TMR_INVALID_PERIOD; + return ((OS_TMR *)0); + } + break; + + case OS_TMR_OPT_ONE_SHOT: + if (dly == 0) { + *perr = OS_ERR_TMR_INVALID_DLY; + return ((OS_TMR *)0); + } + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + return ((OS_TMR *)0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return ((OS_TMR *)0); + } + OSTmr_Lock(); + ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */ + if (ptmr == (OS_TMR *)0) { + OSTmr_Unlock(); + *perr = OS_ERR_TMR_NON_AVAIL; + return ((OS_TMR *)0); + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; /* Indicate that timer is not running yet */ + ptmr->OSTmrDly = dly; + ptmr->OSTmrPeriod = period; + ptmr->OSTmrOpt = opt; + ptmr->OSTmrCallback = callback; + ptmr->OSTmrCallbackArg = callback_arg; +#if OS_TMR_CFG_NAME_SIZE > 0 + if (pname !=(INT8U *)0) { + len = OS_StrLen(pname); /* Copy timer name */ + if (len < OS_TMR_CFG_NAME_SIZE) { + (void)OS_StrCopy(ptmr->OSTmrName, pname); + } else { +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr->OSTmrName[0] = '#'; /* Invalid size specified */ + ptmr->OSTmrName[1] = OS_ASCII_NUL; +#endif + *perr = OS_ERR_TMR_NAME_TOO_LONG; + OSTmr_Unlock(); + return (ptmr); + } + } +#endif + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (ptmr); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* DELETE A TIMER +* +* Description: This function is called by your application code to delete a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop and delete. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE If the call was successful +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr) +{ +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */ + case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Already deleted */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET THE NAME OF A TIMER +* +* Description: This function is called to obtain the name of a timer. +* +* Arguments : ptmr Is a pointer to the timer to obtain the name for +* +* pdest Is a pointer to where the name of the timer will be placed. It is the caller's responsibility +* to ensure that he has sufficient storage in the destination, i.e. at least OS_TMR_CFG_NAME_SIZE +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE The call was successful +* OS_ERR_TMR_INVALID_DEST 'pdest' is a NULL pointer +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_NAME_GET_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The length of the string or 0 if the timer does not exist. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 && OS_TMR_CFG_NAME_SIZE > 0 +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U *pdest, + INT8U *perr) +{ + INT8U len; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (pdest == (INT8U *)0) { + *perr = OS_ERR_TMR_INVALID_DEST; + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + len = OS_StrCopy(pdest, ptmr->OSTmrName); + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (len); + + case OS_TMR_STATE_UNUSED: /* Timer is not allocated */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET HOW MUCH TIME IS LEFT BEFORE A TIMER EXPIRES +* +* Description: This function is called to get the number of ticks before a timer times out. +* +* Arguments : ptmr Is a pointer to the timer to obtain the remaining time from. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The time remaining for the timer to expire. The time represents 'timer' increments. In other words, if +* OSTmr_Task() is signaled every 1/10 of a second then the returned value represents the number of 1/10 of +* a second remaining before the timer expires. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT32U remain; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + remain = ptmr->OSTmrMatch - OSTmrTime; /* Determine how much time is left to timeout */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (remain); + + case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */ + switch (ptmr->OSTmrOpt) { + case OS_TMR_OPT_PERIODIC: + if (ptmr->OSTmrDly == 0) { + remain = ptmr->OSTmrPeriod; + } else { + remain = ptmr->OSTmrDly; + } + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + break; + + case OS_TMR_OPT_ONE_SHOT: + default: + remain = ptmr->OSTmrDly; + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + break; + } + return (remain); + + case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (0); + + case OS_TMR_STATE_UNUSED: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* FIND OUT WHAT STATE A TIMER IS IN +* +* Description: This function is called to determine what state the timer is in: +* +* OS_TMR_STATE_UNUSED the timer has not been created +* OS_TMR_STATE_STOPPED the timer has been created but has not been started or has been stopped +* OS_TMR_COMPLETED the timer is in ONE-SHOT mode and has completed it's timeout +* OS_TMR_RUNNING the timer is currently running +* +* Arguments : ptmr Is a pointer to the desired timer +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE if the timer is not in a valid state +* +* Returns : The current state of the timer (see description). +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT8U state; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0); + } + OSTmr_Lock(); + state = ptmr->OSTmrState; + switch (state) { + case OS_TMR_STATE_UNUSED: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + case OS_TMR_STATE_RUNNING: + *perr = OS_ERR_NONE; + break; + + default: + *perr = OS_ERR_TMR_INVALID_STATE; + break; + } + OSTmr_Unlock(); + return (state); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* START A TIMER +* +* Description: This function is called by your application code to start a timer. +* +* Arguments : ptmr Is a pointer to an OS_TMR +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE if the timer was started +* OS_FALSE if an error was detected +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr) +{ +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: /* Restart the timer */ + OSTmr_Unlink(ptmr); /* ... Stop the timer */ + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Start the timer */ + case OS_TMR_STATE_COMPLETED: + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer not created */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* STOP A TIMER +* +* Description: This function is called by your application code to stop a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop. +* +* opt Allows you to specify an option to this functions which can be: +* +* OS_TMR_OPT_NONE Do nothing special but stop the timer +* OS_TMR_OPT_CALLBACK Execute the callback function, pass it the callback argument +* specified when the timer was created. +* OS_TMR_OPT_CALLBACK_ARG Execute the callback function, pass it the callback argument +* specified in THIS function call +* +* callback_arg Is a pointer to a 'new' callback argument that can be passed to the callback function +* instead of the timer's callback argument. In other words, use 'callback_arg' passed in +* THIS function INSTEAD of ptmr->OSTmrCallbackArg +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_OPT if you specified an invalid option for 'opt' +* OS_ERR_TMR_STOPPED if the timer was already stopped +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* OS_ERR_TMR_NO_CALLBACK if the timer does not have a callback function defined +* +* Returns : OS_TRUE If we stopped the timer (if the timer is already stopped, we also return OS_TRUE) +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr) +{ + OS_TMR_CALLBACK pfnct; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + *perr = OS_ERR_NONE; + switch (opt) { + case OS_TMR_OPT_CALLBACK: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); /* Use callback arg when timer was created */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_CALLBACK_ARG: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, callback_arg); /* ... using the 'callback_arg' provided in call */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_NONE: + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + break; + } + OSTmr_Unlock(); + return (OS_TRUE); + + case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or ... */ + case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_STOPPED; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer was not created */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* SIGNAL THAT IT'S TIME TO UPDATE THE TIMERS +* +* Description: This function is typically called by the ISR that occurs at the timer tick rate and is used to signal to +* OSTmr_Task() that it's time to update the timers. +* +* Arguments : none +* +* Returns : OS_ERR_NONE The call was successful and the timer task was signaled. +* OS_ERR_SEM_OVF If OSTmrSignal() was called more often than OSTmr_Task() can handle the timers. +* This would indicate that your system is heavily loaded. +* OS_ERR_EVENT_TYPE Unlikely you would get this error because the semaphore used for signaling is created +* by uC/OS-II. +* OS_ERR_PEVENT_NULL Again, unlikely you would ever get this error because the semaphore used for signaling +* is created by uC/OS-II. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT8U OSTmrSignal (void) +{ + INT8U err; + + + err = OSSemPost(OSTmrSemSignal); + return (err); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* ALLOCATE AND FREE A TIMER +* +* Description: This function is called to allocate a timer. +* +* Arguments : none +* +* Returns : a pointer to a timer if one is available +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static OS_TMR *OSTmr_Alloc (void) +{ + OS_TMR *ptmr; + + + if (OSTmrFreeList == (OS_TMR *)0) { + return ((OS_TMR *)0); + } + ptmr = (OS_TMR *)OSTmrFreeList; + OSTmrFreeList = (OS_TMR *)ptmr->OSTmrNext; + ptmr->OSTmrNext = (OS_TCB *)0; + ptmr->OSTmrPrev = (OS_TCB *)0; + OSTmrUsed++; + OSTmrFree--; + return (ptmr); +} +#endif + + +/* +************************************************************************************************************************ +* RETURN A TIMER TO THE FREE LIST +* +* Description: This function is called to return a timer object to the free list of timers. +* +* Arguments : ptmr is a pointer to the timer to free +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Free (OS_TMR *ptmr) +{ + ptmr->OSTmrState = OS_TMR_STATE_UNUSED; /* Clear timer object fields */ + ptmr->OSTmrOpt = OS_TMR_OPT_NONE; + ptmr->OSTmrPeriod = 0; + ptmr->OSTmrMatch = 0; + ptmr->OSTmrCallback = (OS_TMR_CALLBACK)0; + ptmr->OSTmrCallbackArg = (void *)0; +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr->OSTmrName[0] = '?'; /* Unknown name */ + ptmr->OSTmrName[1] = OS_ASCII_NUL; +#endif + + ptmr->OSTmrPrev = (OS_TCB *)0; /* Chain timer to free list */ + ptmr->OSTmrNext = OSTmrFreeList; + OSTmrFreeList = ptmr; + + OSTmrUsed--; /* Update timer object statistics */ + OSTmrFree++; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TIMERS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TMRs. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +void OSTmr_Init (void) +{ +#if OS_EVENT_NAME_SIZE > 10 + INT8U err; +#endif + INT16U i; + OS_TMR *ptmr1; + OS_TMR *ptmr2; + + + OS_MemClr((INT8U *)&OSTmrTbl[0], sizeof(OSTmrTbl)); /* Clear all the TMRs */ + OS_MemClr((INT8U *)&OSTmrWheelTbl[0], sizeof(OSTmrWheelTbl)); /* Clear the timer wheel */ + + ptmr1 = &OSTmrTbl[0]; + ptmr2 = &OSTmrTbl[1]; + for (i = 0; i < (OS_TMR_CFG_MAX - 1); i++) { /* Init. list of free TMRs */ + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)ptmr2; /* Link to next timer */ +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr1->OSTmrName[0] = '?'; /* Unknown name */ + ptmr1->OSTmrName[1] = OS_ASCII_NUL; +#endif + ptmr1++; + ptmr2++; + } + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)0; /* Last OS_TMR */ +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr1->OSTmrName[0] = '?'; /* Unknown name */ + ptmr1->OSTmrName[1] = OS_ASCII_NUL; +#endif + OSTmrTime = 0; + OSTmrUsed = 0; + OSTmrFree = OS_TMR_CFG_MAX; + OSTmrFreeList = &OSTmrTbl[0]; + OSTmrSem = OSSemCreate(1); + OSTmrSemSignal = OSSemCreate(0); + +#if OS_EVENT_NAME_SIZE > 18 + OSEventNameSet(OSTmrSem, (INT8U *)"uC/OS-II TmrLock", &err);/* Assign names to semaphores */ +#else +#if OS_EVENT_NAME_SIZE > 10 + OSEventNameSet(OSTmrSem, (INT8U *)"OS-TmrLock", &err); +#endif +#endif + +#if OS_EVENT_NAME_SIZE > 18 + OSEventNameSet(OSTmrSemSignal, (INT8U *)"uC/OS-II TmrSignal", &err); +#else +#if OS_EVENT_NAME_SIZE > 10 + OSEventNameSet(OSTmrSemSignal, (INT8U *)"OS-TmrSig", &err); +#endif +#endif + + OSTmr_InitTask(); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZE THE TIMER MANAGEMENT TASK +* +* Description: This function is called by OSTmrInit() to create the timer management task. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_InitTask (void) +{ +#if OS_TASK_NAME_SIZE > 6 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[0], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], + OS_TASK_TMR_PRIO); + #else + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[0], + OS_TASK_TMR_PRIO); + #endif +#endif + +#if OS_TASK_NAME_SIZE > 12 + OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"uC/OS-II Tmr", &err); +#else +#if OS_TASK_NAME_SIZE > 6 + OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"OS-Tmr", &err); +#endif +#endif +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INSERT A TIMER INTO THE TIMER WHEEL +* +* Description: This function is called to insert the timer into the timer wheel. The timer is always inserted at the +* beginning of the list. +* +* Arguments : ptmr Is a pointer to the timer to insert. +* +* type Is either: +* OS_TMR_LINK_PERIODIC Means to re-insert the timer after a period expired +* OS_TMR_LINK_DLY Means to insert the timer the first time +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Link (OS_TMR *ptmr, INT8U type) +{ + OS_TMR *ptmr1; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + ptmr->OSTmrState = OS_TMR_STATE_RUNNING; + if (type == OS_TMR_LINK_PERIODIC) { /* Determine when timer will expire */ + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + if (ptmr->OSTmrDly == 0) { + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + ptmr->OSTmrMatch = ptmr->OSTmrDly + OSTmrTime; + } + } + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == (OS_TMR *)0) { /* Link into timer wheel */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (OS_TMR *)0; + pspoke->OSTmrEntries = 1; + } else { + ptmr1 = pspoke->OSTmrFirst; /* Point to first timer in the spoke */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (void *)ptmr1; + ptmr1->OSTmrPrev = (void *)ptmr; + pspoke->OSTmrEntries++; + } + ptmr->OSTmrPrev = (void *)0; /* Timer always inserted as first node in list */ +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* REMOVE A TIMER FROM THE TIMER WHEEL +* +* Description: This function is called to remove the timer from the timer wheel. +* +* Arguments : ptmr Is a pointer to the timer to remove. +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Unlink (OS_TMR *ptmr) +{ + OS_TMR *ptmr1; + OS_TMR *ptmr2; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == ptmr) { /* See if timer to remove is at the beginning of list */ + ptmr1 = (OS_TMR *)ptmr->OSTmrNext; + pspoke->OSTmrFirst = (void *)ptmr1; + if (ptmr1 != (OS_TMR *)0) { + ptmr1->OSTmrPrev = (void *)0; + } + } else { + ptmr1 = (OS_TMR *)ptmr->OSTmrPrev; /* Remove timer from somewhere in the list */ + ptmr2 = (OS_TMR *)ptmr->OSTmrNext; + ptmr1->OSTmrNext = ptmr2; + if (ptmr2 != (OS_TMR *)0) { + ptmr2->OSTmrPrev = (void *)ptmr1; + } + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; + ptmr->OSTmrNext = (void *)0; + ptmr->OSTmrPrev = (void *)0; + pspoke->OSTmrEntries--; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER MANAGER DATA STRUCTURE LOCKING MECHANISM +* +* Description: These functions are used to gain exclusive access to timer management data structures. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Lock (void) +{ + INT8U err; + + + OSSemPend(OSTmrSem, 0, &err); + (void)err; +} +#endif + + + +#if OS_TMR_EN > 0 +static void OSTmr_Unlock (void) +{ + (void)OSSemPost(OSTmrSem); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER MANAGEMENT TASK +* +* Description: This task is created by OSTmrInit(). +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Task (void *p_arg) +{ + INT8U err; + OS_TMR *ptmr; + OS_TMR *ptmr_next; + OS_TMR_CALLBACK pfnct; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + (void)p_arg; /* Not using 'p_arg', prevent compiler warning */ + for (;;) { + OSSemPend(OSTmrSemSignal, 0, &err); /* Wait for signal indicating time to update timers */ + OSTmr_Lock(); + OSTmrTime++; /* Increment the current time */ + spoke = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE); /* Position on current timer wheel entry */ + pspoke = &OSTmrWheelTbl[spoke]; + ptmr = pspoke->OSTmrFirst; + while (ptmr != (OS_TMR *)0) { + ptmr_next = (OS_TMR *)ptmr->OSTmrNext; /* Point to next timer to update because current ... */ + /* ... timer could get unlinked from the wheel. */ + if (OSTmrTime == ptmr->OSTmrMatch) { /* Process each timer that expires */ + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); + } + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) { + OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC); /* Recalculate new position of timer in wheel */ + } else { + ptmr->OSTmrState = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ + } + } + ptmr = ptmr_next; + } + OSTmr_Unlock(); + } +} +#endif diff --git a/.svn/pristine/9e/9e83995850b7881438dfcf3ff39157a0133f7a26.svn-base b/.svn/pristine/9e/9e83995850b7881438dfcf3ff39157a0133f7a26.svn-base new file mode 100644 index 0000000..6c04aa3 --- /dev/null +++ b/.svn/pristine/9e/9e83995850b7881438dfcf3ff39157a0133f7a26.svn-base @@ -0,0 +1,725 @@ +#include +#include "CCRSProtocol.h" +#include "VMCConst.h" +#include "validator.h" +#include "uart1.h" +#include +#include +#include + +int iCmdDelay=20; +int iLastError=0; + +// crc +unsigned short crc16_ccitt(unsigned char data, unsigned short crc) +{ register unsigned short a=0x8408, d = crc, i; + d^= data; + for (i=0; i<8; i++) + {if (d & 0x0001) + {d>>= 1; + d^=a;} + else d>>=1; + } + return d; +} + +// crc +unsigned short CalculateCRC(unsigned char *pBuffer) +{ + unsigned short wCRC=0; + int Len = (pBuffer[2]) ? pBuffer[2] : ((unsigned short)pBuffer[4]<<8)+pBuffer[5]; + for (int i=0;i0) + { + if(COMPort_Recieve(BufIn+iBytesToRecieve, iLen)) + { + iRecievingError=RE_NONE; + break; + } + else + { + iRecievingError=RE_DATA; + PurgeComm(); + } + } + else + { + iRecievingError=RE_NONE; + break; + } + } + } + } + return iRecievingError; +} + + +/** + + crc + + + The function is a simple wrapper for the CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function + and performs the following actions: + -# Complementing the output frame with the device address and CRC16 + -# Sending the frame and receiving a response using CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function + -# Checking received frame integrity (by CRC16 value) + -# Returning the response wrapped in the CCommand object + + \param Cmd a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC) + \param Addr a parameter of type BYTE containing the device address used for communication. + Refer to \link Addr Device address list \endlink for the valid values + + +*/ +unsigned char tmpBuffer[256]; + +int TransmitCMD(unsigned char *Cmd, unsigned char Addr, unsigned char **data) +{ + int i=(Cmd[2]) ? Cmd[2] + : ((unsigned short)Cmd[4]<<8)+Cmd[5]; + Cmd[1] = Addr; + unsigned short wCRC=CalculateCRC(Cmd); + Cmd[i-2] = (unsigned char)wCRC; + Cmd[i-1] = (unsigned char)(wCRC>>8); + + int iErrCode=SendCommand(Cmd, tmpBuffer); + if((!iErrCode)&&(Cmd[3])&&(0xFF!=Cmd[3])) + { + if (tmpBuffer[2]) + { + wCRC = (unsigned short)tmpBuffer[tmpBuffer[2]-2]; + wCRC += (unsigned short)((unsigned short)tmpBuffer[tmpBuffer[2]-1])<<8; + } + else + { + wCRC = 0; + //wCRC=tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]: + // (((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-2]+ + // (tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]:(((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-1]<<8); + } + if(CalculateCRC(tmpBuffer)!=wCRC) iErrCode=RE_CRC; + } + *data = tmpBuffer; + return iErrCode; +} + +/** \brief The CCCRSProtocol::Transmit function carries complete protocol exchange + + The function is a simple wrapper for the CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function + and performs the following actions: + -# Sending the frame and receiving a response using CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function + -# Checking the device response and determining whether ACK or NAK should be sent + -# Sending ACK or NAK message to the device or retransmitting the command up to 3 times untill communication is successfully completed + -# Returning the response wrapped in the CCommand object + + \param CMD a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC) + \param Addr a parameter of type BYTE containing the device address used for communication. + Refer to \link Addr Device address list \endlink for the valid values + + \return CCommand - an object containing response data and communication error code + + +*/ +// , ACK , +int Transmit(unsigned char *CMD, unsigned char Addr) +{ + unsigned char *cmdRes, cmdACK[16]; + int error; + + VPend(); + for (int i=0; i<3; i++) + { + error=TransmitCMD(CMD, Addr, &cmdRes); + cmdACK[0] = SYNC; + cmdACK[2] = 6; + cmdACK[3] = ACK; + + if (error == RE_NONE) + { + if((ACK==cmdRes[3]) && (cmdRes[2]==6)) + { // + VPost(); + return error; + } + if((NAK==cmdRes[3]) && (cmdRes[2]==6)) + { + if (iCmdDelay) Sleep(iCmdDelay);//5 + } + else + { + cmdACK[3] = ACK; + TransmitCMD(cmdACK, Addr, &cmdRes); + if (iCmdDelay) Sleep(iCmdDelay);//5 + break; + } + } + else + { + if(error != RE_TIMEOUT) + { + cmdACK[3] = NAK; + TransmitCMD(cmdACK, Addr, &cmdRes); + if (iCmdDelay) Sleep(iCmdDelay);//5 + } + } + } + + VPost(); + return error; +} + +////////////////////////////////////////////////////////////////////// +// CCNET Commands implementation +/** \defgroup CCNETCommands CCNET protocol commands and requests + + The group contains member functions providing interface to CCNET commands and requests. + All functions return a bool result showing whether operation was successfully completed. + In the case of error the error code (refer to \link ErrCode Possible error codes \endlink) + is stored in the CCCRSProtocol::iLastError member variable, which can be used in further analysis. + + @{ +*/ + +/** \brief The CCCRSProtocol::CmdReset function sends a RESET command to the device + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if command was acknowledged + + +*/ + +unsigned char cc_buf[256]; + +int CC_CmdReset(unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,6,RESET,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response = Transmit(cc_buf, Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack != ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD; + return 0; + } + else + { + return 1; + } + + } + else + { + return 0; + } +} + + +/** \brief The CCCRSProtocol::CmdPoll function sends POLL command to the device + + The function sends POLL command and fills bytes Z1 and Z2 of the response into the CCCRSProtocol::PollResults structure. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange was successfully completed + + +*/ +int CC_CmdPoll(unsigned char Addr, TPollResults *PollResults) +{ + const unsigned char Data[]={SYNC,0,6,POLL,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + if(!Response) + { + PollResults->Z1 = tmpBuffer[3]; + PollResults->Z2 = tmpBuffer[4]; + return 1; + } + else + { + PollResults->Z1=0; + PollResults->Z2=0; + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdStatus function sends STATUS REQUEST to the device + + The response status data is stored in the CCCRSProtocol::BillStatus member structure. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange was successfully completed + + +*/ +int CC_CmdStatus(unsigned char Addr, TBillStatus* BillStatus) +{ + const unsigned char Data[]={SYNC,0,6,GET_STATUS,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + BillStatus->Enabled=0; + BillStatus->Security=0; + BillStatus->Routing=0; + return 0; + } + BillStatus->Enabled=tmpBuffer[5]+((unsigned long)tmpBuffer[4]<<8)+((unsigned long)tmpBuffer[3]<<16); + BillStatus->Security=tmpBuffer[8]+((unsigned long)tmpBuffer[7]<<8)+((unsigned long)tmpBuffer[6]<<16); + BillStatus->Routing=tmpBuffer[11]+((unsigned long)tmpBuffer[10]<<8)+((unsigned long)tmpBuffer[9]<<16); + return 1; + } + else + { + return 0; + } + +} + +/** \brief The CCCRSProtocol::CmdIdentification function sends IDENTIFICATION request + + The function sends IDENTIFICATION request and stores device identification in the member CCCRSProtocol::Ident structure. + The function supports both new and old identification formats of Bill-To-Bill units. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the exchange was successfully completed and data received + + +*/ +int CC_CmdIdentification(unsigned char Addr, TIdent* Ident) +{ + const unsigned char Data[]={SYNC,0,6,IDENTIFICATION,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if (!Response) + { + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + return 0; + } + strcpy(Ident->BCCPUBoot,"N/A"); + strcpy(Ident->BCCPUVersion,"N/A"); + strcpy(Ident->BCCS1Boot,"N/A"); + strcpy(Ident->BCCS2Boot,"N/A"); + strcpy(Ident->BCCS3Boot,"N/A"); + strcpy(Ident->BCCSVersion,"N/A"); + strcpy(Ident->BCDispenserBoot,"N/A"); + strcpy(Ident->BCDispenserVersion,"N/A"); + strcpy(Ident->BVBootVersion,"N/A"); + strcpy(Ident->BVVersion,"N/A"); + strcpy(Ident->PartNumber,"N/A"); + char sTemp[64]; + int iPos=3,iLen=15; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->PartNumber,sTemp); + iLen=12; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->SN,sTemp); + char *strTemp=(char*)tmpBuffer+iPos; + + + Ident->DS1=0;iPos+=8; + for(int i=0;i<7;i++) + { + Ident->DS1<<=8; + Ident->DS1+=strTemp[i]; + } + if(tmpBuffer[2]<109) return 1; + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BVBootVersion,sTemp); + + iLen=20; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BVVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCPUBoot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCPUVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCDispenserBoot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCDispenserVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS1Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS2Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS3Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCSVersion,sTemp); + return 1; + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdHold function sends HOLD command to the device + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange successfully completed + + +*/ +int CC_CmdHold(unsigned char Addr) +{ + const unsigned char Data[256]={SYNC,0,6,HOLD,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack!=ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdSetSecurity function sends SET SECURITY LEVELS command + + \param wS a parameter of type DWORD - a bitmap containing security levels to set + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange successfully completed + + +*/ +int CC_CmdSetSecurity(unsigned long wS, unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,9,SET_SECURITY,0,0,0,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + cc_buf[4]=(unsigned char)(wS>>16); + cc_buf[5]=(unsigned char)(wS>>8); + cc_buf[6]=(unsigned char)(wS); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdBillType function sends ENABLE BILL TYPE command + + \param enBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to the enabled bill types + \param escBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to bill type processed with escrow + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool- true if the command was acknowledged + + +*/ +int CC_CmdBillType(unsigned long enBill, unsigned long escBill, unsigned char Addr) +{ + unsigned char Data[]={SYNC,0,12,BILL_TYPE, + (unsigned char)(enBill>>16),(unsigned char)(enBill>>8),(unsigned char)enBill, + (unsigned char)(escBill>>16),(unsigned char)(escBill>>8),(unsigned char)escBill, + 0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdPack function sends PACK command + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the command was acknowledged + + +*/ +int CC_CmdPack(unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,6,PACK,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdReturn function sends RETURN command + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the command was acknowledged + + +*/ +int CC_CmdReturn(unsigned char Addr) +{ + const unsigned char Data[256]={SYNC,0,6,RETURN,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + + +/** \brief The CCCRSProtocol::CmdGetBillTable function sends BILL TABLE request + + \param BillTable a parameter of type _BillRecord * containing pointer to the _BillRecord array receiving the bill table. + Position in the array corresponds to the bill type and the structure at the position describes that bill type. + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the response was successfully received + + +*/ +int CC_CmdGetBillTable(unsigned char Addr, TBillRecord *BillTable) +{ + const unsigned char Data[]={SYNC,0,6,GET_BILL_TABLE,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + int i; + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + for(int i=0;i<24;i++) + { + BillTable[i].Denomination=0; + strcpy(BillTable[i].sCountryCode,""); + } + return 0; + } + for(i=0;i>24),(unsigned char)(dwOpt>>16),(unsigned char)(dwOpt>>8),(unsigned char)dwOpt, + 0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + unsigned char ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + + + +/** \brief The CCCRSProtocol::CmdGetCRC32 function sends CRC32 request + + \param dwCRC a parameter of type DWORD & containing a reference to the variable receiving CRC32 of the firmware. + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the request was answered + + +*/ +int CC_CmdGetCRC32(unsigned long *dwCRC, unsigned char Addr) +{ + unsigned char Data[]={SYNC,0,6,CRC32,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + dwCRC=0; + return 0; + } + *dwCRC=tmpBuffer[6]+((unsigned long)tmpBuffer[5]<<8)+((unsigned long)tmpBuffer[4]<<16)+((unsigned long)tmpBuffer[3]<<24); + return 1; + } + else + { + dwCRC=0; + return 0; + } +} + + + + + + + +/** @} */ \ No newline at end of file diff --git a/.svn/pristine/9f/9f4ca976d41c121e94a58358851f8d21d7bd5f23.svn-base b/.svn/pristine/9f/9f4ca976d41c121e94a58358851f8d21d7bd5f23.svn-base new file mode 100644 index 0000000..b0d6485 --- /dev/null +++ b/.svn/pristine/9f/9f4ca976d41c121e94a58358851f8d21d7bd5f23.svn-base @@ -0,0 +1,42 @@ +#include "cpu.h" +#include "datadesc.h" +#include "journal.h" + + +typedef struct{ + + CPU_INT32U SerialNum; + + TChannelConfig ChannelConfig; + + TDeviceConfig DeviceConfig; + + // + TCounters Counters; + + // CRC16 + TCountersLong CountersLong; + + CPU_INT32U FRAM_AcceptedMoney; + CPU_INT32U crc_AcceptedMoney; + + // + TErrorRecord ErrorRecords[ERROR_RECORDS_NUM]; + // + TEventRecord EventRecords[EVENT_RECORDS_NUM]; + + CPU_INT32U Pass; + CPU_INT32U crc_Pass; + + CPU_INT32U LastEmailTime; + + CPU_INT32U IncasEmailFlag; + CPU_INT32U IncasMoney; + CPU_INT32U IncasTime; + + CPU_INT32U StartButtonName; + + CPU_INT32U DefferedStartEnabled[CHANNELS_NUM]; + +}TFramMap; + diff --git a/.svn/pristine/a0/a00279d897cd8289e711375bb5c0d9e70e4df40c.svn-base b/.svn/pristine/a0/a00279d897cd8289e711375bb5c0d9e70e4df40c.svn-base new file mode 100644 index 0000000..eac3241 --- /dev/null +++ b/.svn/pristine/a0/a00279d897cd8289e711375bb5c0d9e70e4df40c.svn-base @@ -0,0 +1,4 @@ +execUserPreload() +{ + __writeMemory32(0x00000001, 0xE01FC040, "Memory"); // MEMMAP = 1; +} diff --git a/.svn/pristine/a2/a2246f12f4128cb819448a0a9ba83a36b6cc5474.svn-base b/.svn/pristine/a2/a2246f12f4128cb819448a0a9ba83a36b6cc5474.svn-base new file mode 100644 index 0000000..391057d --- /dev/null +++ b/.svn/pristine/a2/a2246f12f4128cb819448a0a9ba83a36b6cc5474.svn-base @@ -0,0 +1,23 @@ +#ifndef _FRAM_H_ +#define _FRAM_H_ + +#define FRAM_WRITE 0x02 +#define FRAM_READ 0x03 + +#define FRAM_WRITE_ON 0x06 +#define FRAM_WRITE_OFF 0x04 + +#define FRAM_READ_STATUS 0x05 +#define FRAM_WRITE_STATUS 0x01 + +extern void WriteByteFram(unsigned short adress,unsigned char byte); +extern unsigned char ReadByteFram(unsigned short adress); + +extern unsigned char Read_Status_Register(unsigned short adress); +extern void Write_Status_Register(unsigned char byte, unsigned short address); + +extern void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array); +extern void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array); +extern void SetArrayFram(unsigned short uAddress, unsigned short uBytesNumber, unsigned char byte); + +#endif diff --git a/.svn/pristine/a2/a22abde10fdf269e25f14bd37cdbd5dd34080e6f.svn-base b/.svn/pristine/a2/a22abde10fdf269e25f14bd37cdbd5dd34080e6f.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..c635e169ab2fd187e7a805e02b34cffdeece6eb1 GIT binary patch literal 14336 zcmeHOYj9mv6<+7&BuyXCw2+>X()P5a?CTS>rrY6CnqR^I>hlOG(iVq~b ze4`*JK2U}ke#mr2aa8KJdenSFgmdH( z&d6H^cMT5r?RZXS+DGJ{6ET$B^<+$(-BA1=)5BS9J^smXmRgVh_QfB8O=EV?Ue3T7{kS@@!Z4A@M*%9`H+rw_4aaag*w$l~l^+U6Q)E#!nItiBIH6Lz- z%C2w=s6C(-pw^2!3*T&?Wndc>@6tlZ8IkSME<0t1?8dy6m7EmeBpt9*uwWUBU`_p? z&oMv`USnY+O5rw?+l@3!g2f6jv)X{U63j;j2DNqU3hQInNb7k#(&sXFWz)8JUi(Yi8cJM5kl8GV=Lm-&Sc1V6Y%;gN@6ua314MTN_u2 zF~Xx5=d7eL;(17X-;Pn=gSVW#6L>6ZBnxd0U_VBug6CkEK{@>>kIu$%FN8%P9Q6&* z*ew0fY}aQFau0ChG*y30!z=p{uS4NlwNy8?@1u&0LRy2->PAHa zI@R@|>g_rWX7Mz0Ml9W@Xi^&fWG&0_V5MdF(^lD~t?Ne%O*I)*un7h&tC_PJ7F5*^ z=h5NrFkLH5bzs_r4s3#hK~Tbb)kd@zr`iI-jv=?j4&X34&Opl{nWkpk=;X`GB^Z@U z5jrtAF+#7}ZLS0xwd?)b<}UPr<#Xya6EF>9nr_Q={*donCc*Hea-A`aX1#LF+EXnv z9j=yO>Qcl-ik+Og6k#;OgQ;KO-?Sc|Z z9{r`Y2jDWCs;aAyKDl{oOP%AS}*9`D6}8TYPEtv zH7cE+F~=&|9PTYxRzahXt7Z{iS^2)4Om}3=<5umsTnMBOwNy|S_sYj{0*i5U-CrG$$f0lTJkDKyN#wYu?x3{pr=W z;J+7o*Vep0jIY3%XqBK%JQ>*#YzSsQeg*z}uGc*StkWsz+@fc+uCu zIR)mnvXLdlGhV^+%Zq(!PVqa4-%R$XKbWgnPzNL5=V2(PVDP;u7 zO6*xA9D5^?$x$~FnX#1^OOY%~Br=yL5}7NkM2ob_1-NtkS|*Jj?GwpL%bcg9vMP~S z%4#by{vxc>rY+buL0X$gWUjLk?HbAYL?UxTB9Yl{CE7f~DT^r+8$d`GCK8!xD{(v` zY_klLJ{{p>!bxQ2ti-X3@NIAM7AUijNMshR#Bq$Ilt?VIoJeGLT8U%aDjRX91s9^s zY8-LIBk8hC>@Og7ClX8Pu@b!@l1+(3W^W>qS+Np5CBmNF^kI>f*`G*c4p@m^)QXQM z)3Wm?wTwO$;fvFhvRF&GD3Mso7Aw);B3-ZOXV_vv+M48%xy?%S#a3*2O?~)UwwB-u z7X$TYK>DYT(Mx@dzUpK2*uYyc>8U=C{_11&S|6kD`WQXf$LPmCMsM~p`m~SHvwe*I z?PK(EAEU4P7(L#{==VNG@AomrfR8Z}e2noB%E|x_7~Jek7!^Lo*zhq%h>tN&e2nqo zV~i3XW32cXBgV%VH?z$O;(X##0iBBii~3|WcZ z8R2xsF!9|7=^cqg=CGCMv#t1cH1**m+r|RhLf@T>gBMc@y|xv*NyA(@iAnE`aPnxF ztF*p7iNyLYwGw?g!oiba;%EZWyAz4b_gIOZ9^scq!(5}x_a+jV@3Rv9Kf=MEVXjr? z6^TUVUMn#wT4f*ZoCDW^S)BtJ9g*y}%=KEzm5Ibs4p@mX6Uo6uVjr$bBr>nI5+f@Qb5ib|~|@L?ZKgD>3RKoFW?Lh044kk;wdjl^BZ=e!VnI zoQpxaF_FkTY9&T!tK5V;?SkXJ8oMx3Bl)0ZX0?XZ{5&MA?6!m>J5=aY#< zoq1NLGtuFk6UnD6YoqFXI+3VzuGQI?=x|Poi8_m|PEVr4IWLlXENheM+?z<$i6L=(HYGZo z6C?SeW%a7geThUJ&REpxRUNL`6(Ih4&<8B#tq1*euz@<*<~rD59c&9QeCY@Juxrl6 zb+D~65{Y`>g!Bi@PmCU3JX@hLQ}{k> z)Mtx+331dHs(ikFais7yu~g+)VtuYqufTZgS3n9gJ7@Y7W-`ufDa;$3M^dmsMW27c z+K989agG+wamIC?z&n;>;0@!PIp<2Kzaa-QbG(Il-j$MBsz)8Rc2jD;Jl@3hty05W z%<>9wPdKeMqoLs{{D^!NYqS@-&A;BEGz;nNc>3f{lWdRis2zd0b_8IU*F6HzNk%}c zs8lP$yoBBQWPQMgTf*<_Odb-F!~Kxc-W_w<`hO7e^I7)xo8odJFnS)Ai6n~`xAp3J`iiJCVfagDeWi7{{w66Z7SUKk7CLSj68ABijXlSqt<6G&XMe~rZN zhTkJ$DwJ^~*6}hD%m33WqUWKklh+cYH|w3{bC**=8XFzpMqc0f9(EZp?#@^sQwtJx+2@nt$UbxZ zk67T%{QG|$e{T+{*G+ztj?qbQ?ZH{b5uAhU!}GA7hZuai_xbQP7R9*b95x+2^6y_| zm;uhA56g9!3x?2!Yp0_=iNpFicd%|=lQK^sn6E;{%n;6f4xEB{>a1C)-_&gGr)Ha6 z_Mc}7yc%)(cN6-59Zt#k|9))6Nz*|c6Cy`(dUaUOo(y~HeT}W3^W}8=PkWW^4Ah8| s|HC+UV;c_W|AF%Q+EYG_{&NmLI<+gOjl5p_*Z%((r(J1{;v1>|-*LCiQ~&?~ literal 0 HcmV?d00001 diff --git a/.svn/pristine/a6/a63ea37d548d8a1d4efc0c644fe34d45642780b7.svn-base b/.svn/pristine/a6/a63ea37d548d8a1d4efc0c644fe34d45642780b7.svn-base new file mode 100644 index 0000000..9815a66 --- /dev/null +++ b/.svn/pristine/a6/a63ea37d548d8a1d4efc0c644fe34d45642780b7.svn-base @@ -0,0 +1,44 @@ +#ifndef _TIME_H_ +#define _TIME_H_ + + +#define visocosn(year) ((year % 4) ? 0 : 1) + +typedef struct{ + CPU_INT08U sec; + CPU_INT08U min; + CPU_INT08U hour; + CPU_INT08U day; + CPU_INT08U date; + CPU_INT08U mon; + CPU_INT08U year; +}TRTC_Data; + +#define SEC_TYPE 1 +#define MIN_TYPE 2 +#define HOUR_TYPE 3 +#define DAY_TYPE 4 +#define MONTH_TYPE 5 +#define YEAR_TYPE 6 + +extern void InitRTC(void); +extern void RTC_ReadTime(TRTC_Data *rtc); +extern void RTC_SetTime(TRTC_Data *rtc); +extern void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec); +extern void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec); +extern CPU_INT32U GetSec(TRTC_Data *pData); +extern CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType); +extern void PrintSecToMinSec(char *str, int seconds); +extern void PrintRTSTimeString(char *str, TRTC_Data *rtc); +extern void PrintRTCDateTimeString(char *str, TRTC_Data *rtc); +extern void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc); +extern void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc); +extern void GetDayText(char* str, char day); +extern CPU_INT32U GetTimeSec(void); +int RTCCheckTime(TRTC_Data *rtc); +extern void PrintTimeString(char *str, CPU_INT32U time); +extern void PrintSecToHourMinSec(char *str, int seconds); +extern void PrintSecToBigHourMinSec(char *str, int seconds); + + +#endif //#ifndef _TIME_H_ diff --git a/.svn/pristine/ac/acbbf9ac48af8d299f2bb8623cb0db9911e086e4.svn-base b/.svn/pristine/ac/acbbf9ac48af8d299f2bb8623cb0db9911e086e4.svn-base new file mode 100644 index 0000000..626dbb3 --- /dev/null +++ b/.svn/pristine/ac/acbbf9ac48af8d299f2bb8623cb0db9911e086e4.svn-base @@ -0,0 +1,61 @@ +#ifndef _APP_SERV_H_ +#define _APP_SERV_H_ + +#include "app_cfg.h" + +extern CPU_INT32U incas_bill_nom_counter[24]; +extern CPU_INT32U incas_common_bill_counter; + +#define KBRD_TASK_STK_SIZE 256 +#define USER_TASK_STK_SIZE 384 +#define MENU_TASK_STK_SIZE 512 +#define COIN_TASK_STK_SIZE 384 +#define VALIDATOR_TASK_STK_SIZE 384 +#define FISCAL_TASK_STK_SIZE 384 +#define MODEM_TASK_STK_SIZE 768 + + +#define VALIDATOR_TASK_PRIO USER_HIGHEST_PRIO +#define USER_TASK_PRIO (USER_HIGHEST_PRIO+1) +#define COIN_TASK_PRIO (USER_HIGHEST_PRIO+2) +#define KBRD_TASK_PRIO (USER_HIGHEST_PRIO+3) +#define FISCAL_TASK_PRIO (USER_HIGHEST_PRIO+4) +#define MENU_TASK_PRIO (USER_HIGHEST_PRIO+5) +#define MODEM_TASK_PRIO USER_LOWEST_PRIO + +enum{ + EVENT_SEC = 1, + EVENT_STARTUP, + + EVENT_COIN_INSERTED, + EVENT_BILL_ESCROW, + EVENT_BILL_STACKED, + + EVENT_MODE_CHANGE, + + EVENT_KEY_EMPTY, + EVENT_KEY_F1, + EVENT_KEY_F2, + EVENT_KEY_F3, + EVENT_KEY_LEFT, + EVENT_KEY_UP, + EVENT_KEY_RIGHT, + EVENT_KEY_STOP, + EVENT_KEY_DOWN, + EVENT_KEY_START, + EVENT_KEY_USER_START, + + EVENT_INCASSATION, + EVENT_INCASSATION_FINISH +}; + +#define LED_on() {FIO1SET_bit.P1_21= 1;} +#define LED_off() {FIO1CLR_bit.P1_21= 1;} + +extern void UserStartupFunc(void); +extern void PostUserEvent(int event); + +extern void InitUserMenu(void); +extern int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time); + +#endif //#ifndef _APP_SERV_H_ diff --git a/.svn/pristine/ad/adfa546f7885927f9ec2af434c61d604058c30ee.svn-base b/.svn/pristine/ad/adfa546f7885927f9ec2af434c61d604058c30ee.svn-base new file mode 100644 index 0000000..2bd0ca8 --- /dev/null +++ b/.svn/pristine/ad/adfa546f7885927f9ec2af434c61d604058c30ee.svn-base @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\solarium.ewp + + + + + diff --git a/.svn/pristine/ae/ae4148ad8faa056b85845c66c50c38468fffb7fd.svn-base b/.svn/pristine/ae/ae4148ad8faa056b85845c66c50c38468fffb7fd.svn-base new file mode 100644 index 0000000..8823af0 --- /dev/null +++ b/.svn/pristine/ae/ae4148ad8faa056b85845c66c50c38468fffb7fd.svn-base @@ -0,0 +1,133 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/CPU in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/CPU. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION DEFINES +* +* Filename : cpu_def.h +* Version : V1.17 +* Programmer(s) : ITJ +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (b) Ideally, CPU_WORD_SIZE #define's would be calculated at compile-time through use of +* the sizeof() operator. However, some compilers do NOT allow pre-processor directives +* to include run-time macro's -- e.g. 'sizeof()'. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order : +* +* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* ----------------------- CPU WORD SIZE ---------------------- */ +#define CPU_WORD_SIZE_08 1 /* 8-bit word size = sizeof(CPU_INT08x). */ +#define CPU_WORD_SIZE_16 2 /* 16-bit word size = sizeof(CPU_INT16x). */ +#define CPU_WORD_SIZE_32 4 /* 32-bit word size = sizeof(CPU_INT32x). */ +#define CPU_WORD_SIZE_64 8 /* 64-bit word size = sizeof(CPU_INT64x) [see Note #1a]. */ + + + /* ------------------- CPU WORD-ENDIAN ORDER ------------------ */ +#define CPU_ENDIAN_TYPE_NONE 0 /* */ +#define CPU_ENDIAN_TYPE_BIG 1 /* Big- endian word order (CPU words' most significant ... */ + /* ... octet @ lowest mem addr). */ +#define CPU_ENDIAN_TYPE_LITTLE 2 /* Little-endian word order (CPU words' least significant ... */ + /* ... octet @ lowest mem addr). */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler allows in-line +* assembly AND will correctly modify the local stack pointer when interrupt status is +* pushed/popped onto the stack. +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (a) Save interrupt status into a local variable +* (b) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (c) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to +* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure +* 'CPU_SR' data type in 'cpu.h' with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* --------------- CPU CRITICAL SECTION METHODS --------------- */ +#define CPU_CRITICAL_METHOD_NONE 0 /* */ +#define CPU_CRITICAL_METHOD_INT_DIS_EN 1 /* DIS/EN ints. */ +#define CPU_CRITICAL_METHOD_STATUS_STK 2 /* Push/Pop int status onto stk. */ +#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3 /* Save/Restore int status to local var. */ + diff --git a/.svn/pristine/b0/b06d17bbf88b2baace4100423a73fb773fe6651b.svn-base b/.svn/pristine/b0/b06d17bbf88b2baace4100423a73fb773fe6651b.svn-base new file mode 100644 index 0000000..ea6294e --- /dev/null +++ b/.svn/pristine/b0/b06d17bbf88b2baace4100423a73fb773fe6651b.svn-base @@ -0,0 +1,63 @@ +#ifndef __MODEM_H__ +#define __MODEM_H__ + +#define MODEM_REPEAT_RX 5 +#define MODEM_RX_TIMEOUT 5000 +#define MODEM_OPEN_SERVICE_TIMEOUT 30000 + +/* + strings.append("[receiver]=" + config.get('Receiver', 'email')) + strings.append("[ap_dns]=" + config.get('AccessPoint', 'dns', '')) + strings.append("[ap_password]=" + config.get('AccessPoint', 'password', '')) + strings.append("[ap_ip]=" + config.get('AccessPoint', 'ip', '')) + strings.append("[ap_user]=" + config.get('AccessPoint', 'user', '')) + strings.append("[ap_apn]=" + config.get('AccessPoint', 'apn', '')) + strings.append("[smtp_user]=" + config.get('Smtp', 'user', '')) + strings.append("[smtp_password]=" + config.get('Smtp', 'password', '')) + strings.append("[smtp_mail]=" + config.get('Smtp', 'mail', '')) + strings.append("[smtp_server]=" + config.get('Smtp', 'smtp_server', '')) + strings.append("[smtp_port]=" + config.get('Smtp', 'port', '25')) +*/ +typedef struct +{ + char receiver[64]; + char ap_dns[64]; + char ap_password[64]; + char ap_ip[64]; + char ap_user[64]; + char ap_apn[64]; + char smtp_user[64]; + char smtp_password[64]; + char smtp_mail[64]; + char smtp_server[64]; + char smtp_port[64]; + + CPU_INT08U valid; +} EmailOptions; +static EmailOptions email_options; + +#define EMAIL_CFG_ELEM_COUNT 11 + + +typedef int (*TextCallbackFunc)(char *str); + + +extern int InitModem(void); +extern void ModemWriteStr(char const *str); +extern int ModemSendOKCommand(char *str, unsigned long timeout); +extern int ModemDeleteSMS(unsigned char index); +extern int ModemWriteSMS(char const* text, unsigned char *index); +extern int ModemSendSMS(char const* number, unsigned char index); +extern int ModemReadSMS(char *text, int index); +extern int ModemSendSMSMessage(char const* number, char const* text); +extern int ModemRxNewSMS(unsigned long *num); +extern int ModemSendCommand(char *str, unsigned long timeout); +extern CPU_INT08U IsModemConn(void); +extern CPU_INT08U IsModemConf(void); + +extern int InitModemEmailParams(void); +extern int ModemSendEmail(char *subj, TextCallbackFunc text_callback); +extern CPU_INT08U IsModemValid(void); +extern void ResetModemValid(void); + +#endif //#ifndef __MODEM_H__ diff --git a/.svn/pristine/b1/b1cd9dd10391ced7ab58fdff5e119d4b0d3ef96a.svn-base b/.svn/pristine/b1/b1cd9dd10391ced7ab58fdff5e119d4b0d3ef96a.svn-base new file mode 100644 index 0000000..fb5098f --- /dev/null +++ b/.svn/pristine/b1/b1cd9dd10391ced7ab58fdff5e119d4b0d3ef96a.svn-base @@ -0,0 +1,24 @@ +#ifndef _CONTROL_H_ +#define _CONTROL_H_ + +#define CHANNELS_NUM 10 + +#define CHANNEL_1 0 +#define CHANNEL_2 1 +#define CHANNEL_3 2 +#define CHANNEL_4 3 +#define CHANNEL_5 4 +#define CHANNEL_6 5 +#define CHANNEL_7 6 +#define CHANNEL_8 7 +#define CHANNEL_9 8 +#define CHANNEL_10 9 + + +extern void InitChannels(void); +extern void ChannelOn(CPU_INT08U ch); +extern void ChannelOff(CPU_INT08U ch); +extern int IsChannelOn(CPU_INT08U ch); + + +#endif //#ifndef _CONTROL_H_ diff --git a/.svn/pristine/b2/b2b77ada15fbdb127f8087f8a67c2a2516409754.svn-base b/.svn/pristine/b2/b2b77ada15fbdb127f8087f8a67c2a2516409754.svn-base new file mode 100644 index 0000000..90fad2f --- /dev/null +++ b/.svn/pristine/b2/b2b77ada15fbdb127f8087f8a67c2a2516409754.svn-base @@ -0,0 +1,62 @@ +#ifndef _MENUDESC_H_ +#define _MENUDESC_H_ + +#include "journal.h" + +#define START_MENU StartMenuPanel +#define WORK_MENU FirstMenuPanel +#define SERVICE_MENU ServiceMenuPanel + +extern char FlagForPrintReport; +extern CPU_INT08U str_IncasMenu_3[32]; + +extern const TMenuPanel ChannelCountersLongPanel[]; +extern const TMenuPanel ChanStatMenuPanel[]; +extern const TMenuPanel CommStatMenuPanel[]; +extern const TMenuPanel MasterPassMenuPanel[]; +extern const TMenuPanel IncasMenuPanel[]; +extern const TMenuPanel CommonCountersLongPanel[]; +extern const TMenuPanel BillCountersPanel[]; +extern const TMenuPanel ModemSetupPanel[]; +extern const TMenuPanel CoinSetupPanel[]; +extern const TMenuPanel JournalIsReset[]; +extern const TMenuPanel ClearJournalMenuPanel[]; +extern const TMenuPanel StatIsReset[]; +extern const TMenuPanel ClearStatMenu[]; +extern const TMenuPanel SettingsIsReset[]; +extern const TMenuPanel ResetSettingsMenuPanel[]; +extern const TMenuPanel ErrorPassPanel[]; +extern const TMenuPanel SetNewPassMenuPanel[]; +extern const TMenuPanel SetPassMenuPanel[]; +extern const TMenuPanel FrMenuPanel[]; +extern const TMenuPanel FrIsOffMenuPanel[]; +extern const TMenuPanel zReportMenuPanel[]; +extern const TMenuPanel xReportMenuPanel[]; +extern const TMenuPanel ReportMenuPanel[]; +extern const TMenuPanel FirstMenuPanel[]; +extern const TMenuPanel ServiceMenuPanel[]; +extern const TMenuPanel StartMenuPanel[]; +extern const TMenuPanel SettingsMenuPanel[]; +extern const TMenuPanel ChannelMenuPanel[]; +extern const TMenuPanel DeviceMenuPanel[]; +extern const TMenuPanel GetMoneyMenuPanel[]; +extern const TMenuPanel PriceWeekdaysMenuPanel[]; +extern const TMenuPanel PriceWeekendMenuPanel[]; +extern const TMenuPanel StatisticsMenuPanel[]; +extern const TMenuPanel ErrorJournalMenuPanel[]; +extern const TMenuPanel SelectJournalMenuPanel[]; +extern const TMenuPanel TimeSetupMenuPanel[]; +extern const TMenuPanel EventJournalMenuPanel[]; +extern const TMenuPanel JournalEmptyMenuPanel[]; +extern const TMenuPanel ChannelCountersPanel[]; +extern const TMenuPanel CommonCountersPanel[]; +extern const TMenuPanel bufReportMenuPanel[]; + +extern void PrintUserMenuStr(char* str, CPU_INT08U n); +extern void PrintEventJournalRecord(TEventRecord *record); + +extern char str_EventNumber[24]; +extern char str_EventData[24]; + + +#endif //#ifndef _MENUDESC_H_ diff --git a/.svn/pristine/b3/b3e6d069d76cb6c10b7ec3d4a4c4ff6d76cc8348.svn-base b/.svn/pristine/b3/b3e6d069d76cb6c10b7ec3d4a4c4ff6d76cc8348.svn-base new file mode 100644 index 0000000..252a936 --- /dev/null +++ b/.svn/pristine/b3/b3e6d069d76cb6c10b7ec3d4a4c4ff6d76cc8348.svn-base @@ -0,0 +1,802 @@ +/* + - +*/ +#include +#include "uart0.h" +#include "fiscal.h" +#include "fr.h" + +CPU_INT08U fisc_buf[256]; + + +int FiscPollExt(void) +{ + CPU_INT08U ack; + int byte; + FiscUartSendByte(FISC_ENQ); + byte = FiscUartRecieveByte(&ack, FISC_TIMEOUT); + if (!byte) return FISC_UNDEF;; + if (ack == FISC_NACK) return FISC_READY; + else if (ack == FISC_ACK) return FISC_BUSY; + return FISC_UNDEF; +} + + +// +int FiscPoll(void) +{ + CPU_INT08U ack; + FiscUartSendByte(FISC_ENQ); + if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_UNDEF;; + if (ack == FISC_NACK) return FISC_READY; + else if (ack == FISC_ACK) return FISC_BUSY; + return FISC_UNDEF; +} + +// +int FiscSendCommand(CPU_INT08U cmd, CPU_INT08U *dat, CPU_INT08U len) +{ + CPU_INT08U lrc,ack; + + FiscPurgeRx(); + + FiscUartSendByte(FISC_STX); + FiscUartSendByte(len+1); + + lrc = len+1; + FiscUartSendByte(cmd); + lrc ^= cmd; + while(len--) + { + FiscUartSendByte(*dat); + lrc ^= *dat++; + } + FiscUartSendByte(lrc); + + if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_ERR; + + if (ack == FISC_NACK) + { // 5 , + for (int i=0; i<100; i++) + { + FiscSleep(FISC_TIMEOUT); + int poll = FiscPoll(); + if (poll == FISC_READY) return FISC_OK; + else if (poll == FISC_BUSY) continue; + return FISC_ERR; + } + } + else if (ack == FISC_ACK) return FISC_OK; + + return FISC_ERR; +} + + +// +// , +int FiscReceiveAnswer(CPU_INT08U **dat, CPU_INT08U *len, CPU_INT32U timeout) +{ + CPU_INT08U byte, lrc, num; + + *dat = NULL; + *len = 0; + + // + if (!FiscUartRecieveByte(&byte, timeout)) return FISC_ERR; + if (byte != FISC_STX) return FISC_ERR; + + // + if (!FiscUartRecieveByte(&byte, FISC_TIMEOUT)) return FISC_ERR; + if (!byte) return FISC_ERR; + num = byte; + + // = byte + if (!FiscUartRecieve(fisc_buf, num, FISC_BYTE_TIMEOUT)) return FISC_ERR; + + // + if (!FiscUartRecieveByte(&byte, FISC_BYTE_TIMEOUT)) return FISC_ERR; + + // + lrc = num; + for (CPU_INT08U i=0; i 20) len = 20; + memcpy(&fisc_buf[5], str, len); + + if (FiscSendCommand(FISC_PRINT_BOLD_STRING, fisc_buf, 25) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_BOLD_STRING) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscBeep(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_BEEP, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_BEEP) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// (. 40 ) +// flags: 0 - , 1 - +int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + memset(&fisc_buf[5], 0, 40); + len = strlen((char const*)str); + if (len > 40) len = 40; + memcpy(&fisc_buf[5], str, len); + + if (FiscSendCommand(FISC_PRINT_STRING, fisc_buf, 45) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_STRING) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memset(&fisc_buf[4], 0, 30); + len = strlen((char const*)str); + if (len > 30) len = 30; + memcpy(&fisc_buf[4], str, len); + memcpy(&fisc_buf[34], &number, 2); + + if (FiscSendCommand(FISC_PRINT_DOC_HEADER, fisc_buf, 36) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 5) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DOC_HEADER) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +// 6 - long long +int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = reg; + + if (FiscSendCommand(FISC_GET_MONEY_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (9 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_MONEY_REG) || (rxdat[1] != 0)) {return FISC_ERR;} + + *value = 0; + memcpy(value, &rxdat[3], 6); + + return FISC_OK; +} + + +// +// 2 +int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = reg; + + if (FiscSendCommand(FISC_GET_OPER_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_OPER_REG) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(value, &rxdat[3], 2); + + return FISC_OK; +} + +// +int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = type; + + if (FiscSendCommand(FISC_BILL_CUT, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_BILL_CUT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + fisc_buf[5] = strnum; + + if (FiscSendCommand(FISC_PULL_OUT_TAPE, fisc_buf, 6) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PULL_OUT_TAPE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +// +int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = dir; + + if (FiscSendCommand(FISC_EJECT_UNDERLAY_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_EJECT_UNDERLAY_DOC) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// (. 40 ) +// flags: 0 - , 1 - +int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + fisc_buf[5] = flags; + memset(&fisc_buf[6], 0, 40); + len = strlen((char const*)str); + if (len > 40) len = 40; + memcpy(&fisc_buf[6], str, len); + + if (FiscSendCommand(FISC_PRINT_STRING_BY_FONT, fisc_buf, 46) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_STRING_BY_FONT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_NO_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_NO_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + + +// c +int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + +// c +int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_TO_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_TO_BUF) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(100); + + return FISC_OK; +} + +// c +int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_FROM_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_FROM_BUF) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + + +// +int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_SECTION_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_SECTION_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_TAXES_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_TAXES_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +// - , doc - +int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4); + fisc_buf[8] = 0; + + if (FiscSendCommand(FISC_MAKE_DEPOSIT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_DEPOSIT) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(doc, (CPU_INT08U*)&rxdat[3], 2); + + return FISC_OK; +} + +// +int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4); + fisc_buf[8] = 0; + + if (FiscSendCommand(FISC_MAKE_PAYOUT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_PAYOUT) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(doc, (CPU_INT08U*)&rxdat[3], 2); + + return FISC_OK; +} + +// +// +int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_CLICHE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_CLICHE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = param; + + if (FiscSendCommand(FISC_END_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_END_DOC) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_ADV_TEXT, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_ADV_TEXT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_GET_DEVICE_TYPE, NULL, 0) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if ((sizeof(TFiscDevType)+2) < len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_DEVICE_TYPE) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(dev, &rxdat[2], sizeof(TFiscDevType)); + + return FISC_OK; +} + +// +int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = type; + + if (FiscSendCommand(FISC_OPEN_BILL, fisc_buf, 5) != FISC_OK) + { + return FISC_ERR; + } + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) + { + return FISC_ERR; + } + + *err = rxdat[1]; + + if (3 != len) + { + return FISC_ERR; + } + + if ((rxdat[0] != FISC_OPEN_BILL) || (rxdat[1] != 0)) + { + return FISC_ERR; + } + + return FISC_OK; +} + +// +int FiscMakeSell(CPU_INT32U pass, + CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department, + CPU_INT08U* tax, char* text, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)count, 5); + memcpy(&fisc_buf[9], (CPU_INT08U*)price, 5); + fisc_buf[14] = department; + memcpy(&fisc_buf[15], (CPU_INT08U*)tax, 4); + memset(&fisc_buf[19], 0, 40); + strcpy((char*)&fisc_buf[19], text); + + if (FiscSendCommand(FISC_MAKE_SELL, fisc_buf, 59) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_SELL) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], cash, 5); + memset(&fisc_buf[9], 0, 15+2); + memcpy(&fisc_buf[26], tax, 4); + memset(&fisc_buf[30], 0, 40); + strcpy((char*)&fisc_buf[70], text); + + if (FiscSendCommand(FISC_CLOSE_BILL, fisc_buf, 70) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (8 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_CLOSE_BILL) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// ( ) +int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + *err = 0; + + if (FiscSendCommand(FISC_PRINT_CONTINUE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_CONTINUE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + diff --git a/.svn/pristine/b7/b71983062bec67c4c3fe939fd4e8330a4a47fed1.svn-base b/.svn/pristine/b7/b71983062bec67c4c3fe939fd4e8330a4a47fed1.svn-base new file mode 100644 index 0000000..15927de --- /dev/null +++ b/.svn/pristine/b7/b71983062bec67c4c3fe939fd4e8330a4a47fed1.svn-base @@ -0,0 +1,395 @@ +#ifndef _FISCAL_H_ +#define _FISCAL_H_ + +extern CPU_INT08U FiscalState; +#define FISCAL_NOCONN 0 +#define FISCAL_CONN 1 + +// +#define FISC_ENQ 0x05 +#define FISC_STX 0x02 +#define FISC_ACK 0x06 +#define FISC_NACK 0x15 + +// +#define FISC_SPEED 115200 + +// +#define FISC_TIMEOUT 105 +#define FISC_BYTE_TIMEOUT 10 +#define FISC_ANSWER_TIMEOUT 5000 + +// +#define FISC_GET_FACTORY_NUMBER 0x0f +#define FISC_GET_SHORT_STATUS 0x10 +#define FISC_GET_FULL_STATUS 0x11 +#define FISC_PRINT_BOLD_STRING 0x12 + #define FISC_CONTROL_TAPE 0x01 + #define FISC_BILL_TAPE 0x02 + #define FISC_UNDERLAY_DOC 0x04 +#define FISC_BEEP 0x13 +#define FISC_PRINT_STRING 0x17 +#define FISC_PRINT_DOC_HEADER 0x18 +#define FISC_GET_MONEY_REG 0x1A +#define FISC_GET_OPER_REG 0x1B +#define FISC_BILL_CUT 0x25 + #define FISC_FULL_CUT 0 + #define FISC_HALF_CUT 1 +#define FISC_PULL_OUT_TAPE 0x29 +#define FISC_EJECT_UNDERLAY_DOC 0x2A + #define FISC_EJECT_DOWN 0 + #define FISC_EJECT_UP 1 +#define FISC_PRINT_STRING_BY_FONT 0x2F +#define FISC_PRINT_DAY_REPORT_NO_CLEAR 0x40 +#define FISC_PRINT_DAY_REPORT_CLEAR 0x41 +#define FISC_PRINT_SECTION_REPORT 0x42 +#define FISC_PRINT_TAXES_REPORT 0x43 +#define FISC_MAKE_DEPOSIT 0x50 +#define FISC_MAKE_PAYOUT 0x51 +#define FISC_PRINT_CLICHE 0x52 +#define FISC_END_DOC 0x53 + #define FISC_WITHOUT_ADV 0 // + #define FISC_WITH_ADV 1 // +#define FISC_PRINT_ADV_TEXT 0x54 +#define FISC_GET_DEVICE_TYPE 0xFC + +#define FISC_OPEN_BILL 0x8D + #define FISC_BILL_SELL 0 + #define FISC_BILL_BUY 1 + +#define FISC_MAKE_SELL 0x80 +#define FISC_CLOSE_BILL 0x85 + +#define FISC_PRINT_CONTINUE 0xB0 + +#define FISC_PRINT_DAY_REPORT_TO_BUF 0xC6 +#define FISC_PRINT_DAY_REPORT_FROM_BUF 0xC7 + +// +#define FiscPurgeRx Uart0_Flush +#define FiscUartSend Uart0_Send +#define FiscUartRecieve Uart0_Receive +#define FiscUartRecieveByte Uart0_RdByteWithTimeOut +#define FiscUartSendByte Uart0_WrByte +#define FiscSleep(x) OSTimeDly(x) + +// FiscPoll() +#define FISC_READY 0 +#define FISC_BUSY -1 +#define FISC_UNDEF -2 + +// +#define FISC_OK 0 +#define FISC_ERR -1 + +// +#define FR_ERROR_CODE_1 0x1 // 1, 2 +#define FR_ERROR_CODE_2 0x2 // 1 +#define FR_ERROR_CODE_3 0x3 // 2 +#define FR_ERROR_CODE_4 0x4 // +#define FR_ERROR_CODE_5 0x5 // +#define FR_ERROR_CODE_6 0x6 // +#define FR_ERROR_CODE_7 0x7 // +#define FR_ERROR_CODE_8 0x8 // +#define FR_ERROR_CODE_9 0x9 // +#define FR_ERROR_CODE_a 0x0A // BCD +#define FR_ERROR_CODE_b 0x0B // +#define FR_ERROR_CODE_11 0x11 // +#define FR_ERROR_CODE_12 0x12 // +#define FR_ERROR_CODE_13 0x13 // +#define FR_ERROR_CODE_14 0x14 // +#define FR_ERROR_CODE_15 0x15 // +#define FR_ERROR_CODE_16 0x16 // // +#define FR_ERROR_CODE_17 0x17 // // +#define FR_ERROR_CODE_18 0x18 // // +#define FR_ERROR_CODE_19 0x19 // // +#define FR_ERROR_CODE_1a 0x1A // // +#define FR_ERROR_CODE_1b 0x1B // // +#define FR_ERROR_CODE_1c 0x1C // // +#define FR_ERROR_CODE_1d 0x1D // // +#define FR_ERROR_CODE_1f 0x1F // // +#define FR_ERROR_CODE_20 0x20 // // +#define FR_ERROR_CODE_21 0x21 // // +#define FR_ERROR_CODE_22 0x22 // // +#define FR_ERROR_CODE_23 0x23 // // +#define FR_ERROR_CODE_24 0x24 // // +#define FR_ERROR_CODE_25 0x25 // // +#define FR_ERROR_CODE_28 0x28 // 2 // +#define FR_ERROR_CODE_33 0x33 // // +#define FR_ERROR_CODE_35 0x35 // // +#define FR_ERROR_CODE_36 0x36 // // +#define FR_ERROR_CODE_37 0x37 // // +#define FR_ERROR_CODE_38 0x38 // //+ +#define FR_ERROR_CODE_39 0x39 // // +#define FR_ERROR_CODE_3a 0x3A // // +#define FR_ERROR_CODE_3c 0x3C //: // +#define FR_ERROR_CODE_3e 0x3E // // +#define FR_ERROR_CODE_3f 0x3F // // +#define FR_ERROR_CODE_40 0x40 // // +#define FR_ERROR_CODE_41 0x41 // // +#define FR_ERROR_CODE_42 0x42 // 2 // +#define FR_ERROR_CODE_43 0x43 // 3 // +#define FR_ERROR_CODE_44 0x44 // 4 +#define FR_ERROR_CODE_45 0x45 //C // +#define FR_ERROR_CODE_46 0x46 // // +#define FR_ERROR_CODE_47 0x47 // // +#define FR_ERROR_CODE_48 0x48 // // +#define FR_ERROR_CODE_4a 0x4A // - // +#define FR_ERROR_CODE_4b 0x4B // // +#define FR_ERROR_CODE_4c 0x4C // // +#define FR_ERROR_CODE_4d 0x4D // // +#define FR_ERROR_CODE_4e 0x4E // 24 // +#define FR_ERROR_CODE_4f 0x4F // // +#define FR_ERROR_CODE_50 0x50 // // +#define FR_ERROR_CODE_51 0x51 // // +#define FR_ERROR_CODE_52 0x52 // 2 // +#define FR_ERROR_CODE_53 0x53 // 3 // +#define FR_ERROR_CODE_54 0x54 // 4 // +#define FR_ERROR_CODE_56 0x56 // // +#define FR_ERROR_CODE_57 0x57 //: // +#define FR_ERROR_CODE_58 0x58 // // +#define FR_ERROR_CODE_59 0x59 // // +#define FR_ERROR_CODE_5b 0x5B // // +#define FR_ERROR_CODE_5c 0x5C // 24 +#define FR_ERROR_CODE_5d 0x5D // // +#define FR_ERROR_CODE_5e 0x5E // // +#define FR_ERROR_CODE_5f 0x5F // // +#define FR_ERROR_CODE_60 0x60 // // +#define FR_ERROR_CODE_61 0x61 // // +#define FR_ERROR_CODE_62 0x62 // // +#define FR_ERROR_CODE_63 0x63 // // +#define FR_ERROR_CODE_64 0x64 // //+ +#define FR_ERROR_CODE_65 0x65 // // +#define FR_ERROR_CODE_66 0x66 // // +#define FR_ERROR_CODE_67 0x67 // //+ +#define FR_ERROR_CODE_68 0x68 // // +#define FR_ERROR_CODE_69 0x69 // // +#define FR_ERROR_CODE_6a 0x6A // I +#define FR_ERROR_CODE_6b 0x6B // // +#define FR_ERROR_CODE_6c 0x6C // // +#define FR_ERROR_CODE_6d 0x6D // // +#define FR_ERROR_CODE_6e 0x6E // // +#define FR_ERROR_CODE_6f 0x6F // // +#define FR_ERROR_CODE_70 0x70 // // +#define FR_ERROR_CODE_71 0x71 // //+ +#define FR_ERROR_CODE_72 0x72 // // +#define FR_ERROR_CODE_73 0x73 // // +#define FR_ERROR_CODE_74 0x74 // // +#define FR_ERROR_CODE_75 0x75 // //+ +#define FR_ERROR_CODE_76 0x76 // : //+ +#define FR_ERROR_CODE_77 0x77 // : //+ +#define FR_ERROR_CODE_78 0x78 // // +#define FR_ERROR_CODE_79 0x79 // // +#define FR_ERROR_CODE_7a 0x7A // +#define FR_ERROR_CODE_7b 0x7B // // +#define FR_ERROR_CODE_7c 0x7C // // +#define FR_ERROR_CODE_7d 0x7D // // +#define FR_ERROR_CODE_7e 0x7E // // +#define FR_ERROR_CODE_7f 0x7F // // +#define FR_ERROR_CODE_80 0x80 // //+ +#define FR_ERROR_CODE_81 0x81 // //+ +#define FR_ERROR_CODE_82 0x82 // //+ +#define FR_ERROR_CODE_83 0x83 // //+ +#define FR_ERROR_CODE_84 0x84 // // +#define FR_ERROR_CODE_85 0x85 // // +#define FR_ERROR_CODE_86 0x86 // // +#define FR_ERROR_CODE_87 0x87 // // +#define FR_ERROR_CODE_88 0x88 // // +#define FR_ERROR_CODE_89 0x89 // // +#define FR_ERROR_CODE_8a 0x8A // // +#define FR_ERROR_CODE_8b 0x8B // // +#define FR_ERROR_CODE_8c 0x8C // // +#define FR_ERROR_CODE_8d 0x8D // // +#define FR_ERROR_CODE_8e 0x8E // // +#define FR_ERROR_CODE_8f 0x8F // // // +#define FR_ERROR_CODE_90 0x90 // , +#define FR_ERROR_CODE_91 0x91 // +#define FR_ERROR_CODE_92 0x92 // +#define FR_ERROR_CODE_93 0x93 // +#define FR_ERROR_CODE_94 0x94 // +#define FR_ERROR_CODE_a0 0xA0 // +#define FR_ERROR_CODE_a1 0xA1 // +#define FR_ERROR_CODE_a2 0xA2 //: +#define FR_ERROR_CODE_a3 0xA3 // +#define FR_ERROR_CODE_a4 0xA4 // +#define FR_ERROR_CODE_a5 0xA5 // +#define FR_ERROR_CODE_a6 0xA6 // +#define FR_ERROR_CODE_a7 0xA7 // +#define FR_ERROR_CODE_a8 0xA8 //: +#define FR_ERROR_CODE_a9 0xA9 //: +#define FR_ERROR_CODE_aa 0xAA // ( ) +#define FR_ERROR_CODE_b0 0xB0 //: +#define FR_ERROR_CODE_b1 0xB1 //: +#define FR_ERROR_CODE_b2 0xB2 //: +#define FR_ERROR_CODE_c0 0xC0 // ( ) +#define FR_ERROR_CODE_c1 0xC1 //: ? +#define FR_ERROR_CODE_c2 0xC2 // +#define FR_ERROR_CODE_c3 0xC3 // +#define FR_ERROR_CODE_c4 0xC4 // +//#define FR_ERROR_CODE_c5 0xC5 // +//#define FR_ERROR_CODE_c6 0xC6 // // +//#define FR_ERROR_CODE_c7 0xC7 // +//#define FR_ERROR_CODE_c8 0xC8 // // + +#define FR_ERROR_NUMBER 143 + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U FactoryNumber[7]; + CPU_INT08U RNM[7]; +}TFiscFactoryNumber; + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U OperatorNumber; // 1..30 + CPU_INT16U Flags; // + /* + ( ): + 0 (0 , 1 ) + 1 (0 , 1 ) + 2 (0 , 1 ) + 3 (0 , 1 ) + 4 (0 0 , 1 2 ) + 5 (0 , 1 ) + 6 (0 , 1 ) + 7 (0 , 1 ) + 8 (0 , 1 ) + 9 (0 , 1 ) + 10 (0 , 1 ) + 11 (0 , 1 ) + 12 (0 , 1 ) + 12 (0 , 1 ) + 13 (0 , 1 ) + 13 (0 , 1 ) + 14 (0 , 1 ) + 15 (0 , 1 + ) [ ]. (1 , 0 + ) + 15 (0 , 1 ) + */ + CPU_INT08U Mode; // + CPU_INT08U SubMode; // + CPU_INT08U BillOperationNumber_L; // - , . + CPU_INT08U BatteryVoltage; // + CPU_INT08U PowerSupplyVoltage; // + CPU_INT08U ErrorCodeFP; // + CPU_INT08U ErrorCodeEKLZ; // + CPU_INT08U BillOperationNumber_H; // - , . + CPU_INT08U Reserve[3]; // +}TFiscShortStatus; + +// +#pragma pack(1) +typedef struct{ +/* + (1 ) 130 + (2 ) + (2 ) + (3 ) -- + (1 ) + (2 ) + (2 ) + (1 ) + (1 ) + (1 ) + (2 ) + (2 ) + (3 ) -- + (3 ) -- + (3 ) -- + (1 ) + ( ): +0 1 (0 , 1 ) +1 2 (0 , 1 ) +2 (0 , 1 ) +3 (0 , 1 ) +4 (0 >80%, 1 <80%) +5 (0 , 1 ) +6 (0 , 1 ) +7 24 (0 , 1 ) + (4 ) + (2 ) + (2 ) + () (1 ) + () (1 ) + (6 ) +*/ + CPU_INT08U OperatorNumber; // 1..30 + CPU_INT08U version[4]; + CPU_INT08U version_date[3]; + CPU_INT08U nomer_v_zale; + CPU_INT16U document_number; + CPU_INT16U Flags; // + CPU_INT08U Mode; // + CPU_INT08U SubMode; // + CPU_INT08U port; + CPU_INT08U ver_fp[4]; + CPU_INT08U date_fp[3]; + CPU_INT08U date[3]; + CPU_INT08U time[3]; + CPU_INT08U fp_flags; + CPU_INT32U FactoryNumber; + CPU_INT16U LastSmena; + CPU_INT16U FpFreePlace; + CPU_INT08U perereg; + CPU_INT08U perereg_free; + CPU_INT08U inn[6]; + +}TFiscFullStatus; + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U Type; // (1 ) 0255 + CPU_INT08U Subtype; // (1 ) 0255 + CPU_INT08U ProtocolVersion; // (1 ) 0255 + CPU_INT08U ProtocolSubVersion; // (1 ) 0255 + CPU_INT08U Model; // (1 ) 0255 + CPU_INT08U Language; // (1 ) 0255 0; 1; + #define FISC_LANG_RUS 0 + #define FISC_LANG_ENG 1 + CPU_INT08U Name[32]; // WIN1251. + // , , + // (X ) +}TFiscDevType; +extern TFiscDevType FiscDevInfo; + +// +extern int FiscPoll(void); +extern int FiscGetFactoryNumber(CPU_INT32U pass, TFiscFactoryNumber* fnum, CPU_INT08U* err); +extern int FiscGetShortStatus(CPU_INT32U pass, TFiscShortStatus* stat, CPU_INT08U* err); +extern int FiscGetFullStatus(CPU_INT32U pass, TFiscFullStatus* stat, CPU_INT08U* err); +extern int FiscPrintBoldString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscBeep(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err); +extern int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err); +extern int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err); +extern int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err); +extern int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err); +extern int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err); +extern int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err); +extern int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err); +extern int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err); +extern int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err); +extern int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err); + +extern int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err); +extern int FiscMakeSell(CPU_INT32U pass, CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department, CPU_INT08U* tax, char* text, CPU_INT08U* err); +extern int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err); + +extern int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err); + +extern int FiscPollExt(void); + +#endif //#ifndef _FISCAL_H_ diff --git a/.svn/pristine/b7/b7dcedd6a34c0714d8b47143eaa15b1153fdf7fa.svn-base b/.svn/pristine/b7/b7dcedd6a34c0714d8b47143eaa15b1153fdf7fa.svn-base new file mode 100644 index 0000000..32b5c1c --- /dev/null +++ b/.svn/pristine/b7/b7dcedd6a34c0714d8b47143eaa15b1153fdf7fa.svn-base @@ -0,0 +1,56 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000044; +define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x40000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x40007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_svcstack__ = 0x100; +define symbol __ICFEDIT_size_irqstack__ = 0x100; +define symbol __ICFEDIT_size_fiqstack__ = 0x40; +define symbol __ICFEDIT_size_undstack__ = 0x10; +define symbol __ICFEDIT_size_abtstack__ = 0x10; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000; +define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF; +define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__]; + +define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000; +define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF; +define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; +define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; +define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; +define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; +define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section USB_DMA_RAM }; +do not initialize { section EMAC_DMA_RAM }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, + block UND_STACK, block ABT_STACK, block HEAP }; +place in USB_DMA_RAM_region + { readwrite data section USB_DMA_RAM }; +place in EMAC_DMA_RAM_region + { readwrite data section EMAC_DMA_RAM }; diff --git a/.svn/pristine/b8/b81093eafe0a4d81761b531104a0499abc2b60c7.svn-base b/.svn/pristine/b8/b81093eafe0a4d81761b531104a0499abc2b60c7.svn-base new file mode 100644 index 0000000..744d0a4 --- /dev/null +++ b/.svn/pristine/b8/b81093eafe0a4d81761b531104a0499abc2b60c7.svn-base @@ -0,0 +1,292 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* DEBUGGER CONSTANTS +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_DBG.C +* Version : V1.82 +* By : Jean J. Labrosse +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#include + + /* The following #define tells the IAR compiler to 'not' optimize these ... */ + /* ... 'const' out since they are not used elsewhere. */ +#define OS_COMPILER_OPT __root + +/* +********************************************************************************************************* +* DEBUG DATA +********************************************************************************************************* +*/ + +OS_COMPILER_OPT INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */ + +#if OS_DEBUG_EN > 0 + +OS_COMPILER_OPT INT32U const OSEndiannessTest = 0x12345678L; /* Variable to test CPU endianness */ + +OS_COMPILER_OPT INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */ +OS_COMPILER_OPT INT16U const OSEventNameSize = OS_EVENT_NAME_SIZE; /* Size (in bytes) of event names */ +OS_COMPILER_OPT INT16U const OSEventEn = OS_EVENT_EN; +#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0) +OS_COMPILER_OPT INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */ +OS_COMPILER_OPT INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */ +#else +OS_COMPILER_OPT INT16U const OSEventSize = 0; +OS_COMPILER_OPT INT16U const OSEventTblSize = 0; +#endif + +OS_COMPILER_OPT INT16U const OSFlagEn = OS_FLAG_EN; +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +OS_COMPILER_OPT INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */ +OS_COMPILER_OPT INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */ +OS_COMPILER_OPT INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */ +#else +OS_COMPILER_OPT INT16U const OSFlagGrpSize = 0; +OS_COMPILER_OPT INT16U const OSFlagNodeSize = 0; +OS_COMPILER_OPT INT16U const OSFlagWidth = 0; +#endif +OS_COMPILER_OPT INT16U const OSFlagMax = OS_MAX_FLAGS; +OS_COMPILER_OPT INT16U const OSFlagNameSize = OS_FLAG_NAME_SIZE; /* Size (in bytes) of flag names */ + +OS_COMPILER_OPT INT16U const OSLowestPrio = OS_LOWEST_PRIO; + +OS_COMPILER_OPT INT16U const OSMboxEn = OS_MBOX_EN; + +OS_COMPILER_OPT INT16U const OSMemEn = OS_MEM_EN; +OS_COMPILER_OPT INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */ +OS_COMPILER_OPT INT16U const OSMemNameSize = OS_MEM_NAME_SIZE; /* Size (in bytes) of partition names */ +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +OS_COMPILER_OPT INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */ +OS_COMPILER_OPT INT16U const OSMemTblSize = sizeof(OSMemTbl); +#else +OS_COMPILER_OPT INT16U const OSMemSize = 0; +OS_COMPILER_OPT INT16U const OSMemTblSize = 0; +#endif +OS_COMPILER_OPT INT16U const OSMutexEn = OS_MUTEX_EN; + +OS_COMPILER_OPT INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */ + +OS_COMPILER_OPT INT16U const OSQEn = OS_Q_EN; +OS_COMPILER_OPT INT16U const OSQMax = OS_MAX_QS; /* Number of queues */ +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +OS_COMPILER_OPT INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */ +#else +OS_COMPILER_OPT INT16U const OSQSize = 0; +#endif + +OS_COMPILER_OPT INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */ + +OS_COMPILER_OPT INT16U const OSSemEn = OS_SEM_EN; + +OS_COMPILER_OPT INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */ + +OS_COMPILER_OPT INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN; +OS_COMPILER_OPT INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN; +OS_COMPILER_OPT INT16U const OSTaskDelEn = OS_TASK_DEL_EN; +OS_COMPILER_OPT INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE; +OS_COMPILER_OPT INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN; +OS_COMPILER_OPT INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */ +OS_COMPILER_OPT INT16U const OSTaskNameSize = OS_TASK_NAME_SIZE; /* Size (in bytes) of task names */ +OS_COMPILER_OPT INT16U const OSTaskStatEn = OS_TASK_STAT_EN; +OS_COMPILER_OPT INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE; +OS_COMPILER_OPT INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN; +OS_COMPILER_OPT INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN; + +OS_COMPILER_OPT INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1; /* Number of entries in OSTCBPrioTbl[] */ +OS_COMPILER_OPT INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */ +OS_COMPILER_OPT INT16U const OSTicksPerSec = OS_TICKS_PER_SEC; +OS_COMPILER_OPT INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN; +OS_COMPILER_OPT INT16U const OSVersionNbr = OS_VERSION; + +OS_COMPILER_OPT INT16U const OSTmrEn = OS_TMR_EN; +OS_COMPILER_OPT INT16U const OSTmrCfgMax = OS_TMR_CFG_MAX; +OS_COMPILER_OPT INT16U const OSTmrCfgNameSize = OS_TMR_CFG_NAME_SIZE; +OS_COMPILER_OPT INT16U const OSTmrCfgWheelSize = OS_TMR_CFG_WHEEL_SIZE; +OS_COMPILER_OPT INT16U const OSTmrCfgTicksPerSec = OS_TMR_CFG_TICKS_PER_SEC; + +#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0) +OS_COMPILER_OPT INT16U const OSTmrSize = sizeof(OS_TMR); +OS_COMPILER_OPT INT16U const OSTmrTblSize = sizeof(OSTmrTbl); +OS_COMPILER_OPT INT16U const OSTmrWheelSize = sizeof(OS_TMR_WHEEL); +OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = sizeof(OSTmrWheelTbl); +#else +OS_COMPILER_OPT INT16U const OSTmrSize = 0; +OS_COMPILER_OPT INT16U const OSTmrTblSize = 0; +OS_COMPILER_OPT INT16U const OSTmrWheelSize = 0; +OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = 0; +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEBUG DATA +* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II +********************************************************************************************************* +*/ +#if OS_DEBUG_EN > 0 + +OS_COMPILER_OPT INT16U const OSDataSize = sizeof(OSCtxSwCtr) +#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0) + + sizeof(OSEventFreeList) + + sizeof(OSEventTbl) +#endif +#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + + sizeof(OSFlagTbl) + + sizeof(OSFlagFreeList) +#endif +#if OS_TASK_STAT_EN > 0 + + sizeof(OSCPUUsage) + + sizeof(OSIdleCtrMax) + + sizeof(OSIdleCtrRun) + + sizeof(OSStatRdy) + + sizeof(OSTaskStatStk) +#endif +#if OS_TICK_STEP_EN > 0 + + sizeof(OSTickStepState) +#endif +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + + sizeof(OSMemFreeList) + + sizeof(OSMemTbl) +#endif +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + + sizeof(OSQFreeList) + + sizeof(OSQTbl) +#endif +#if OS_TIME_GET_SET_EN > 0 + + sizeof(OSTime) +#endif +#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0) + + sizeof(OSTmrFree) + + sizeof(OSTmrUsed) + + sizeof(OSTmrTime) + + sizeof(OSTmrSem) + + sizeof(OSTmrSemSignal) + + sizeof(OSTmrFreeList) + + sizeof(OSTmrTbl) + + sizeof(OSTmrWheelTbl) +#endif + + sizeof(OSIntNesting) + + sizeof(OSLockNesting) + + sizeof(OSPrioCur) + + sizeof(OSPrioHighRdy) + + sizeof(OSRdyGrp) + + sizeof(OSRdyTbl) + + sizeof(OSRunning) + + sizeof(OSTaskCtr) + + sizeof(OSIdleCtr) + + sizeof(OSTaskIdleStk) + + sizeof(OSTCBCur) + + sizeof(OSTCBFreeList) + + sizeof(OSTCBHighRdy) + + sizeof(OSTCBList) + + sizeof(OSTCBPrioTbl) + + sizeof(OSTCBTbl); + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* OS DEBUG INITIALIZAZTION +* +* Description: This function is used to make sure that debug variables that are unused in the application +* are not optimized away. This function might not be necessary for all compilers. In this +* case, you should simply DELETE the code in this function while still leaving the declaration +* of the function itself. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out +* the 'const' variables which are declared in this file. +********************************************************************************************************* +*/ + +#if OS_VERSION >= 270 && OS_DEBUG_EN > 0 +void OSDebugInit (void) +{ + void *ptemp; + + + ptemp = (void *)&OSDebugEn; + + ptemp = (void *)&OSEndiannessTest; + + ptemp = (void *)&OSEventMax; + ptemp = (void *)&OSEventNameSize; + ptemp = (void *)&OSEventEn; + ptemp = (void *)&OSEventSize; + ptemp = (void *)&OSEventTblSize; + + ptemp = (void *)&OSFlagEn; + ptemp = (void *)&OSFlagGrpSize; + ptemp = (void *)&OSFlagNodeSize; + ptemp = (void *)&OSFlagWidth; + ptemp = (void *)&OSFlagMax; + ptemp = (void *)&OSFlagNameSize; + + ptemp = (void *)&OSLowestPrio; + + ptemp = (void *)&OSMboxEn; + + ptemp = (void *)&OSMemEn; + ptemp = (void *)&OSMemMax; + ptemp = (void *)&OSMemNameSize; + ptemp = (void *)&OSMemSize; + ptemp = (void *)&OSMemTblSize; + + ptemp = (void *)&OSMutexEn; + + ptemp = (void *)&OSPtrSize; + + ptemp = (void *)&OSQEn; + ptemp = (void *)&OSQMax; + ptemp = (void *)&OSQSize; + + ptemp = (void *)&OSRdyTblSize; + + ptemp = (void *)&OSSemEn; + + ptemp = (void *)&OSStkWidth; + + ptemp = (void *)&OSTaskCreateEn; + ptemp = (void *)&OSTaskCreateExtEn; + ptemp = (void *)&OSTaskDelEn; + ptemp = (void *)&OSTaskIdleStkSize; + ptemp = (void *)&OSTaskProfileEn; + ptemp = (void *)&OSTaskMax; + ptemp = (void *)&OSTaskNameSize; + ptemp = (void *)&OSTaskStatEn; + ptemp = (void *)&OSTaskStatStkSize; + ptemp = (void *)&OSTaskStatStkChkEn; + ptemp = (void *)&OSTaskSwHookEn; + + ptemp = (void *)&OSTCBPrioTblMax; + ptemp = (void *)&OSTCBSize; + + ptemp = (void *)&OSTicksPerSec; + ptemp = (void *)&OSTimeTickHookEn; + + ptemp = (void *)&OSVersionNbr; + + ptemp = (void *)&OSDataSize; + + ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */ +} +#endif diff --git a/.svn/pristine/bb/bbd54324413d9765a67e97dfa4e9b3bfe5e2f105.svn-base b/.svn/pristine/bb/bbd54324413d9765a67e97dfa4e9b3bfe5e2f105.svn-base new file mode 100644 index 0000000..0284545 --- /dev/null +++ b/.svn/pristine/bb/bbd54324413d9765a67e97dfa4e9b3bfe5e2f105.svn-base @@ -0,0 +1,228 @@ +#include +#include "uart2.h" + + +static unsigned char UART2TXBuffer[UART2_TX_BUFSIZE]; +static unsigned short UART2TXhead = 0; +static unsigned short UART2TXtail = 0; +static unsigned short UART2TXcount = 0; +static unsigned char UART2RXBuffer[UART2_RX_BUFSIZE]; +static unsigned short UART2RXhead = 0; +static unsigned short UART2RXtail = 0; +static unsigned short UART2RXcount = 0; + + +void Uart2_Flush(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + UART2TXcount = UART2TXhead = UART2TXtail = 0; + UART2RXcount = UART2RXhead = UART2RXtail = 0; + U2IER_bit.THREIE = 0; + U2FCR = 0x06; + OS_EXIT_CRITICAL(); +} + +int Uart2_Getc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = -1; + + if (UART2RXcount > 0) + { + UART2RXcount--; + res = UART2RXBuffer[UART2RXhead++]; + UART2RXhead %= UART2_RX_BUFSIZE; + } + OS_EXIT_CRITICAL(); + + return res; +} + +int Uart2_Gotc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART2RXcount > 0) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart2_Ready(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART2TXcount < UART2_TX_BUFSIZE) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart2_Putc(unsigned char ch) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + + if (UART2TXcount < UART2_TX_BUFSIZE) + { + if (UART2TXcount == 0) + { + if (U2LSR_bit.THRE) + { + U2THR = ch; + } + else + { + UART2TXcount++; + UART2TXBuffer[UART2TXtail++] = ch; + UART2TXtail %= UART2_TX_BUFSIZE; + U2IER = 3; + } + } + else + { + UART2TXcount++; + UART2TXBuffer[UART2TXtail++] = ch; + UART2TXtail %= UART2_TX_BUFSIZE; + U2IER = 3; + } + } + else + { + res = -1; + } + OS_EXIT_CRITICAL(); + return res; +} + +static void Uart2_Isr(void) +{ + CPU_INT08U IIRValue; + CPU_INT08U u1lsr; + volatile CPU_INT08U Dummy; + + IIRValue = U2IIR; + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + + if (IIRValue == 2) /* Receive Data Available */ + { + /* Receive Data Available */ + if (U2LSR_bit.DR) + { + if (UART2RXcount < UART2_RX_BUFSIZE) + { + UART2RXBuffer[UART2RXtail++] = U2RBR; + UART2RXtail %= UART2_RX_BUFSIZE; + UART2RXcount++; + } + else + { + Dummy = U2RBR; + } + } + } + else if (IIRValue == 1) /* THRE, transmit holding register empty */ + { + /* THRE interrupt */ + if (UART2TXcount > 0) + { + U2THR = UART2TXBuffer[UART2TXhead++]; + UART2TXhead %= UART2_TX_BUFSIZE; + UART2TXcount--; + } + else + { + U2IER = 1; + } + } + else + { + Dummy = U2RBR; + u1lsr = U2LSR; + u1lsr = u1lsr; + } + +} + +void Uart2_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(PCLK_UART2); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */ + + U2IER = 0; + + U2FCR = 0x06; // enable and reset fifo + + U2ACR = 0; + + //U1FCR = 0x01; // enable and reset fifo + + U2LCR = 0x80; /* Enable acces to Divisor latches */ + + U2DLL = divlo; /* Load divisor */ + U2DLM = divhi; + U2FDR = 0x10; + + U2LCR = 0; + + U2LCR_bit.WLS = 0x03; // 8 bit + U2LCR_bit.SBS = 0; // 1 stop bit + + U2IER = 1; + + PINSEL0_bit.P0_10 = 0x1; + PINSEL0_bit.P0_11 = 0x1; + + PINMODE0_bit.P0_10 = 0; + PINMODE0_bit.P0_11 = 0; + + FIO0DIR_bit.P0_10 = 1; + FIO0DIR_bit.P0_11 = 0; + + FIO0MASK_bit.P0_10 = 1; + FIO0MASK_bit.P0_11 = 1; + + VICINTSELECT &= ~(1 << VIC_UART2); + VICVECTADDR28 = (CPU_INT32U)Uart2_Isr; + VICINTENABLE = (1 << VIC_UART2); + + Uart2_Flush(); + + OS_EXIT_CRITICAL(); +} + + + diff --git a/.svn/pristine/bd/bdce684bc2031853e38b58bd7465417fc3ffaa53.svn-base b/.svn/pristine/bd/bdce684bc2031853e38b58bd7465417fc3ffaa53.svn-base new file mode 100644 index 0000000000000000000000000000000000000000..e1523edd4acd129d9d4a4b12910749faaff7ec5e GIT binary patch literal 12800 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 literal 0 HcmV?d00001 diff --git a/.svn/pristine/c1/c1d58908f6e28fb33bf78b775a2137aaa9507e26.svn-base b/.svn/pristine/c1/c1d58908f6e28fb33bf78b775a2137aaa9507e26.svn-base new file mode 100644 index 0000000..ee14e6d --- /dev/null +++ b/.svn/pristine/c1/c1d58908f6e28fb33bf78b775a2137aaa9507e26.svn-base @@ -0,0 +1,89 @@ +#include +#include "crc16.h" + +#if (CRC16_MODEL_TYPE==CRC16_SMALL) +/* +unsigned short CRC16_small(unsigned char *pBuf, unsigned char ucLength) +{ + register unsigned char Lo, Hi, ucSym; + if (!ucLength) return 1; + + Lo = 0xFF; + Hi = 0xFF; + + do{ + ucSym = *(pBuf++); + ucSym ^= Hi; + Hi = ( ucSym & 0x02 ) ? (Lo - 0x80) : Lo; + if ( ucSym & 0x01 ) + Hi ^= 0xC0; + + Lo = ucSym; + Lo >>= 1; + Lo ^= ucSym; + Lo >>= 1; + ucSym ^= Lo; + + if ( ucSym & 0x08 ) --ucSym; + if ( ucSym & 0x40 ) --ucSym; + + ucSym &= 0x01; + + if (ucSym) Lo ^= 0xC0; + Hi ^= ucSym; + }while(--ucLength); + + return (unsigned short)((((unsigned short)Hi)<<8) | Lo); +} +*/ +#else //(CRC16_MODEL_TYPE==CRC16_LARGE) +unsigned short CRC16_large(unsigned char *pBuf, unsigned char ucLength) +{ + unsigned char ucCRCHi = 0xFF; // high CRC byte initialized + unsigned char ucCRCLo = 0xFF; // low CRC byte initialized + unsigned char table_addr; + +static const unsigned short CRC_Table[8*32]={ +0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011, +0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022, +0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072, +0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041, +0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2, +0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1, +0x00A0,0x80A5,0x80AF,0x00AA,0x80BB,0x00BE,0x00B4,0x80B1, +0x8093,0x0096,0x009C,0x8099,0x0088,0x808D,0x8087,0x0082, +0x8183,0x0186,0x018C,0x8189,0x0198,0x819D,0x8197,0x0192, +0x01B0,0x81B5,0x81BF,0x01BA,0x81AB,0x01AE,0x01A4,0x81A1, +0x01E0,0x81E5,0x81EF,0x01EA,0x81FB,0x01FE,0x01F4,0x81F1, +0x81D3,0x01D6,0x01DC,0x81D9,0x01C8,0x81CD,0x81C7,0x01C2, +0x0140,0x8145,0x814F,0x014A,0x815B,0x015E,0x0154,0x8151, +0x8173,0x0176,0x017C,0x8179,0x0168,0x816D,0x8167,0x0162, +0x8123,0x0126,0x012C,0x8129,0x0138,0x813D,0x8137,0x0132, +0x0110,0x8115,0x811F,0x011A,0x810B,0x010E,0x0104,0x8101, +0x8303,0x0306,0x030C,0x8309,0x0318,0x831D,0x8317,0x0312, +0x0330,0x8335,0x833F,0x033A,0x832B,0x032E,0x0324,0x8321, +0x0360,0x8365,0x836F,0x036A,0x837B,0x037E,0x0374,0x8371, +0x8353,0x0356,0x035C,0x8359,0x0348,0x834D,0x8347,0x0342, +0x03C0,0x83C5,0x83CF,0x03CA,0x83DB,0x03DE,0x03D4,0x83D1, +0x83F3,0x03F6,0x03FC,0x83F9,0x03E8,0x83ED,0x83E7,0x03E2, +0x83A3,0x03A6,0x03AC,0x83A9,0x03B8,0x83BD,0x83B7,0x03B2, +0x0390,0x8395,0x839F,0x039A,0x838B,0x038E,0x0384,0x8381, +0x0280,0x8285,0x828F,0x028A,0x829B,0x029E,0x0294,0x8291, +0x82B3,0x02B6,0x02BC,0x82B9,0x02A8,0x82AD,0x82A7,0x02A2, +0x82E3,0x02E6,0x02EC,0x82E9,0x02F8,0x82FD,0x82F7,0x02F2, +0x02D0,0x82D5,0x82DF,0x02DA,0x82CB,0x02CE,0x02C4,0x82C1, +0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252, +0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261, +0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231, +0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202}; + + while(ucLength--){ + table_addr=(*pBuf++ ^ ucCRCHi); + ucCRCHi=(CRC_Table[table_addr] >> 8) ^ ucCRCLo; + ucCRCLo=(CRC_Table[table_addr] & 0x00FF); + } + + return (unsigned short)((((unsigned short)ucCRCHi)<<8) | (unsigned short)ucCRCLo); +} +#endif + diff --git a/.svn/pristine/c3/c35ce57c51d7aeb30e7c9cbd130d6534e0cc9a75.svn-base b/.svn/pristine/c3/c35ce57c51d7aeb30e7c9cbd130d6534e0cc9a75.svn-base new file mode 100644 index 0000000..e4445ae --- /dev/null +++ b/.svn/pristine/c3/c35ce57c51d7aeb30e7c9cbd130d6534e0cc9a75.svn-base @@ -0,0 +1,1174 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* EVENT FLAG MANAGEMENT +* +* (c) Copyright 2001-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_FLAG.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +/* +********************************************************************************************************* +* LOCAL PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_FlagBlock(OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout); +static BOOLEAN OS_FlagTaskRdy(OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy); + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP +* +* Description: This function is called to check the status of a combination of bits to be set or cleared +* in an event flag group. Your application can check for ANY bit to be set/cleared or ALL +* bits to be set/cleared. +* +* This call does not block if the desired flags are not present. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE No error +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag +* group handle. +* OS_ERR_FLAG_NOT_RDY The desired flags you are waiting for are not +* available. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task or ISR +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +#if OS_FLAG_ACCEPT_EN > 0 +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *perr) +{ + OS_FLAGS flags_rdy; + INT8U result; + BOOLEAN consume; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= ~OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + *perr = OS_ERR_NONE; /* Assume NO error until proven otherwise. */ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + break; + } + return (flags_rdy); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE AN EVENT FLAG +* +* Description: This function is called to create an event flag group. +* +* Arguments : flags Contains the initial value to store in the event flag group. +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an +* ISR. +* OS_ERR_FLAG_GRP_DEPLETED if there are no more event flag groups +* +* Returns : A pointer to an event flag group or a NULL pointer if no more groups are available. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *perr) +{ + OS_FLAG_GRP *pgrp; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAG_GRP *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */ + return ((OS_FLAG_GRP *)0); + } + OS_ENTER_CRITICAL(); + pgrp = OSFlagFreeList; /* Get next free event flag */ + if (pgrp != (OS_FLAG_GRP *)0) { /* See if we have event flag groups available */ + /* Adjust free list */ + OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList; + pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* Set to event flag group type */ + pgrp->OSFlagFlags = flags; /* Set to desired initial value */ + pgrp->OSFlagWaitList = (void *)0; /* Clear list of tasks waiting on flags */ +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_GRP_DEPLETED; + } + return (pgrp); /* Return pointer to event flag group */ +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE AN EVENT FLAG GROUP +* +* Description: This function deletes an event flag group and readies all tasks pending on the event flag +* group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the event flag group even if tasks are +* waiting. In this case, all the tasks pending will be +* readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the event flag group was +* deleted +* OS_ERR_DEL_ISR If you attempted to delete the event flag group from +* an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag +* group. +* +* Returns : pgrp upon error +* (OS_EVENT *)0 if the event flag group was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend(). +* 2) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the event flag group. +********************************************************************************************************* +*/ + +#if OS_FLAG_DEL_EN > 0 +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_FLAG_NODE *pnode; + OS_FLAG_GRP *pgrp_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pgrp); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return (pgrp); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pgrp); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event group type */ + *perr = OS_ERR_EVENT_TYPE; + return (pgrp); + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagWaitList != (void *)0) { /* See if any tasks waiting on event flags */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete group if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; /* Unknown name */ + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pgrp_return = pgrp; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the event flag group */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Ready ALL tasks waiting for flags */ + (void)OS_FlagTaskRdy(pnode, (OS_FLAGS)0); + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + } +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; /* Unknown name */ + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pgrp_return = pgrp; + break; + } + return (pgrp_return); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF AN EVENT FLAG GROUP +* +* Description: This function is used to obtain the name assigned to an event flag group +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is a pointer to an ASCII string that will receive the name of the event flag +* group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_GET_ISR if you called this function from an ISR +* +* Returns : The length of the string or 0 if the 'pgrp' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_SIZE > 1 +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + len = OS_StrCopy(pname, pgrp->OSFlagName); /* Copy name from OS_FLAG_GRP */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO AN EVENT FLAG GROUP +* +* Description: This function assigns a name to an event flag group. +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is a pointer to an ASCII string that will be used as the name of the event flag +* group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_SIZE > 1 +void OSFlagNameSet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return; + } + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_FLAG_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pgrp->OSFlagName, pname); /* Yes, copy name from OS_FLAG_GRP */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* WAIT ON AN EVENT FLAG GROUP +* +* Description: This function is called to wait for a combination of bits to be set in an event flag +* group. Your application can wait for ANY bit to be set or ALL bits to be set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set or ANY of the bits to be set. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will wait for ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will wait for ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_CLR_ANY You will wait for ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ANY You will wait for ANY bit in 'mask' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* timeout is an optional timeout (in clock ticks) that your task will wait for the +* desired bit combination. If you specify 0, however, your task will wait +* forever at the specified event flag group or, until a message arrives. +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The desired bits have been set within the specified +* 'timeout'. +* OS_ERR_PEND_ISR If you tried to PEND from an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_TIMEOUT The bit(s) have not been set in the specified +* 'timeout'. +* OS_ERR_PEND_ABORT The wait on the flag was aborted. +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task ONLY +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *perr) +{ + OS_FLAG_NODE node; + OS_FLAGS flags_rdy; + INT8U result; + INT8U pend_stat; + BOOLEAN consume; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((OS_FLAGS)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((OS_FLAGS)0); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= ~(INT8U)OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + return (flags_rdy); + } +/*$PAGE*/ + OS_Sched(); /* Find next HPT ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* Have we timed-out or aborted? */ + pend_stat = OSTCBCur->OSTCBStatPend; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OS_FlagUnlink(&node); + OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Yes, make task ready-to-run */ + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that we timed-out waiting */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted waiting */ + break; + } + return (flags_rdy); + } + flags_rdy = OSTCBCur->OSTCBFlagsRdy; + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: + case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */ + pgrp->OSFlagFlags &= ~flags_rdy; + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: + case OS_FLAG_WAIT_CLR_ANY: /* Set ONLY the flags we got */ + pgrp->OSFlagFlags |= flags_rdy; + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; /* Event(s) must have occurred */ + return (flags_rdy); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET FLAGS WHO CAUSED TASK TO BECOME READY +* +* Description: This function is called to obtain the flags that caused the task to become ready to run. +* In other words, this function allows you to tell "Who done it!". +* +* Arguments : None +* +* Returns : The flags that caused the task to be ready. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPendGetFlagsRdy (void) +{ + OS_FLAGS flags; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + flags = OSTCBCur->OSTCBFlagsRdy; + OS_EXIT_CRITICAL(); + return (flags); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST EVENT FLAG BIT(S) +* +* Description: This function is called to set or clear some bits in an event flag group. The bits to +* set or clear are specified by a 'bit mask'. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags If 'opt' (see below) is OS_FLAG_SET, each bit that is set in 'flags' will +* set the corresponding bit in the event flag group. e.g. to set bits 0, 4 +* and 5 you would set 'flags' to: +* +* 0x31 (note, bit 0 is least significant bit) +* +* If 'opt' (see below) is OS_FLAG_CLR, each bit that is set in 'flags' will +* CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0, +* 4 and 5 you would specify 'flags' as: +* +* 0x31 (note, bit 0 is least significant bit) +* +* opt indicates whether the flags will be: +* set (OS_FLAG_SET) or +* cleared (OS_FLAG_CLR) +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_INVALID_OPT You specified an invalid option +* +* Returns : the new value of the event flags bits that are still set. +* +* Called From: Task or ISR +* +* WARNING(s) : 1) The execution time of this function depends on the number of tasks waiting on the event +* flag group. +* 2) The amount of time interrupts are DISABLED depends on the number of tasks waiting on +* the event flag group. +********************************************************************************************************* +*/ +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *perr) +{ + OS_FLAG_NODE *pnode; + BOOLEAN sched; + OS_FLAGS flags_cur; + OS_FLAGS flags_rdy; + BOOLEAN rdy; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (opt) { + case OS_FLAG_CLR: + pgrp->OSFlagFlags &= ~flags; /* Clear the flags specified in the group */ + break; + + case OS_FLAG_SET: + pgrp->OSFlagFlags |= flags; /* Set the flags specified in the group */ + break; + + default: + OS_EXIT_CRITICAL(); /* INVALID option */ + *perr = OS_ERR_FLAG_INVALID_OPT; + return ((OS_FLAGS)0); + } + sched = OS_FALSE; /* Indicate that we don't need rescheduling */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Go through all tasks waiting on event flag(s) */ + switch (pnode->OSFlagNodeWaitType) { + case OS_FLAG_WAIT_SET_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_SET_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_CLR_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */ + } + OS_EXIT_CRITICAL(); + if (sched == OS_TRUE) { + OS_Sched(); + } + OS_ENTER_CRITICAL(); + flags_cur = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags_cur); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY EVENT FLAG +* +* Description: This function is used to check the value of the event flag group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* perr is a pointer to an error code returned to the called: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* +* Returns : The current value of the event flag group. +* +* Called From: Task or ISR +********************************************************************************************************* +*/ + +#if OS_FLAG_QUERY_EN > 0 +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *perr) +{ + OS_FLAGS flags; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + OS_ENTER_CRITICAL(); + flags = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags); /* Return the current value of the event flags */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS +* +* Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired +* event flag bit(s) are set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'mask' to be set (1) +* +* timeout is the desired amount of time that the task will wait for the event flag +* bit(s) to be set. +* +* Returns : none +* +* Called by : OSFlagPend() OS_FLAG.C +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static void OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout) +{ + OS_FLAG_NODE *pnode_next; + INT8U y; + + + OSTCBCur->OSTCBStat |= OS_STAT_FLAG; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store timeout in task's TCB */ +#if OS_TASK_DEL_EN > 0 + OSTCBCur->OSTCBFlagNode = pnode; /* TCB to link to node */ +#endif + pnode->OSFlagNodeFlags = flags; /* Save the flags that we need to wait for */ + pnode->OSFlagNodeWaitType = wait_type; /* Save the type of wait we are doing */ + pnode->OSFlagNodeTCB = (void *)OSTCBCur; /* Link to task's TCB */ + pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */ + pnode->OSFlagNodePrev = (void *)0; + pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* Link to Event Flag Group */ + pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + if (pnode_next != (void *)0) { /* Is this the first NODE to insert? */ + pnode_next->OSFlagNodePrev = pnode; /* No, link in doubly linked list */ + } + pgrp->OSFlagWaitList = (void *)pnode; + + y = OSTCBCur->OSTCBY; /* Suspend current task until flag(s) received */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0x00) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE THE EVENT FLAG MODULE +* +* Description: This function is called by uC/OS-II to initialize the event flag module. Your application +* MUST NOT call this function. In other words, this function is internal to uC/OS-II. +* +* Arguments : none +* +* Returns : none +* +* WARNING : You MUST NOT call this function from your code. This is an INTERNAL function to uC/OS-II. +********************************************************************************************************* +*/ + +void OS_FlagInit (void) +{ +#if OS_MAX_FLAGS == 1 + OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */ + OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED; + OSFlagFreeList->OSFlagWaitList = (void *)0; + OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0; +#if OS_FLAG_NAME_SIZE > 1 + OSFlagFreeList->OSFlagName[0] = '?'; + OSFlagFreeList->OSFlagName[1] = OS_ASCII_NUL; +#endif +#endif + +#if OS_MAX_FLAGS >= 2 + INT16U i; + OS_FLAG_GRP *pgrp1; + OS_FLAG_GRP *pgrp2; + + + OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); /* Clear the flag group table */ + pgrp1 = &OSFlagTbl[0]; + pgrp2 = &OSFlagTbl[1]; + for (i = 0; i < (OS_MAX_FLAGS - 1); i++) { /* Init. list of free EVENT FLAGS */ + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)pgrp2; +#if OS_FLAG_NAME_SIZE > 1 + pgrp1->OSFlagName[0] = '?'; /* Unknown name */ + pgrp1->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp1++; + pgrp2++; + } + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)0; +#if OS_FLAG_NAME_SIZE > 1 + pgrp1->OSFlagName[0] = '?'; /* Unknown name */ + pgrp1->OSFlagName[1] = OS_ASCII_NUL; +#endif + OSFlagFreeList = &OSFlagTbl[0]; +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED +* +* Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the +* desired event flag bits have been set. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags_rdy contains the bit pattern of the event flags that cause the task to become +* ready-to-run. +* +* Returns : OS_TRUE If the task has been placed in the ready list and thus needs scheduling +* OS_FALSE The task is still not ready to run and thus scheduling is not necessary +* +* Called by : OSFlagsPost() OS_FLAG.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy) +{ + OS_TCB *ptcb; + BOOLEAN sched; + + + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* Point to TCB of waiting task */ + ptcb->OSTCBDly = 0; + ptcb->OSTCBFlagsRdy = flags_rdy; + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_FLAG; + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Task now ready? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* Put task into ready list */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + sched = OS_TRUE; + } else { + sched = OS_FALSE; + } + OS_FlagUnlink(pnode); + return (sched); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* UNLINK EVENT FLAG NODE FROM WAITING LIST +* +* Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a +* list of tasks waiting for the event flag. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* Returns : none +* +* Called by : OS_FlagTaskRdy() OS_FLAG.C +* OSFlagPend() OS_FLAG.C +* OSTaskDel() OS_TASK.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_FlagUnlink (OS_FLAG_NODE *pnode) +{ +#if OS_TASK_DEL_EN > 0 + OS_TCB *ptcb; +#endif + OS_FLAG_GRP *pgrp; + OS_FLAG_NODE *pnode_prev; + OS_FLAG_NODE *pnode_next; + + + pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev; + pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */ + pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp; + pgrp->OSFlagWaitList = (void *)pnode_next; /* Update list for new 1st node */ + if (pnode_next != (OS_FLAG_NODE *)0) { + pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* Link new 1st node PREV to NULL */ + } + } else { /* No, A node somewhere in the list */ + pnode_prev->OSFlagNodeNext = pnode_next; /* Link around the node to unlink */ + if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */ + pnode_next->OSFlagNodePrev = pnode_prev; /* No, Link around current node */ + } + } +#if OS_TASK_DEL_EN > 0 + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; +#endif +} +#endif diff --git a/.svn/pristine/c3/c361b81d78d4f529057b8b4771ef12aa6949d4ce.svn-base b/.svn/pristine/c3/c361b81d78d4f529057b8b4771ef12aa6949d4ce.svn-base new file mode 100644 index 0000000..89cd007 --- /dev/null +++ b/.svn/pristine/c3/c361b81d78d4f529057b8b4771ef12aa6949d4ce.svn-base @@ -0,0 +1,17 @@ +#ifndef _MODE_H_ +#define _MODE_H_ + +#include "cpu.h" + +// +#define MODE_WORK 0 +#define MODE_SERVICE 1 + +// +extern CPU_INT08U GetMode(void); +// , +extern CPU_INT08U CheckMode(void); +// +extern void InitMode(void); + +#endif //#ifndef _MODE_H_ diff --git a/.svn/pristine/c5/c5693094af0bf4b33ab59a4b20f5e5fe037df6de.svn-base b/.svn/pristine/c5/c5693094af0bf4b33ab59a4b20f5e5fe037df6de.svn-base new file mode 100644 index 0000000..5689d37 --- /dev/null +++ b/.svn/pristine/c5/c5693094af0bf4b33ab59a4b20f5e5fe037df6de.svn-base @@ -0,0 +1,2748 @@ +#include +#include "data.h" +#include "datadesc.h" +#include "menu.h" +#include "menudesc.h" +#include "fram_map.h" +#include +#include +#include +#include +#include "control.h" +#include "fiscal.h" +#include "time.h" +#include "CRC16.h" +#include "modem_task.h" +#include "modem.h" + +extern CPU_INT32U modem_status; + +/************************************* + +*************************************/ +CPU_INT32U ChannelIndex=0; +TRangeValueULONG const ChannelIndexRange = {0, CHANNELS_NUM-1}; +CPU_INT08U const ChannelIndexName[] = " "; +CPU_INT08U const* ChannelItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; + +TDataDescStruct const ChannelIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStIndexName[] = ".."; + +TDataDescStruct const ChannelStIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStLongIndexName[] = ".."; + +TDataDescStruct const ChannelStLongIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStLongIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + email +*************************************/ +extern TRangeValueULONG const WorkTimeRange; + +TDataDescStruct const LastEmailSendTime = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, LastEmailTime), // FRAM + (void*)&WorkTimeRange, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableChannelRange = {0, 1}; +CPU_INT08U const EnableChannelName[] = ""; +CPU_INT08U const EnableChannelList_str0[] = "."; +CPU_INT08U const EnableChannelList_str1[] = "."; +CPU_INT08U const *EnableChannelList[] = {EnableChannelList_str0, EnableChannelList_str1}; + + +TDataDescStruct const EnableChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Enable), // FRAM + (void*)&EnableChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableChannelName, // + DATA_IS_INDEX, // ( ) + EnableChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const NameChannelRange = {0, 1}; +CPU_INT08U const NameChannelName[] = ""; +CPU_INT08U const NameChannelList_str0[] = "#"; +CPU_INT08U const NameChannelList_str1[] = ""; +CPU_INT08U const *NameChannelList[] = {NameChannelList_str0, NameChannelList_str1}; + + +TDataDescStruct const NameChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Name), // FRAM + (void*)&NameChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + NameChannelName, // + DATA_IS_INDEX, // ( ) + NameChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableValidatorRange = {0, 1}; +CPU_INT08U const EnableValidatorName[] = "-"; +CPU_INT08U const OnOffList_str0[] = "."; +CPU_INT08U const OnOffList_str1[] = "."; +CPU_INT08U const *EnableValidatorList[] = {OnOffList_str0, OnOffList_str1}; + + +TDataDescStruct const EnableValidatorDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableValidator), // FRAM + (void*)&EnableValidatorRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableValidatorName, // + DATA_IS_INDEX, // ( ) + EnableValidatorList, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableModemRange = {0, 1}; +CPU_INT08U const EnableModemName[] = ""; +CPU_INT08U const *EnableModemList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableModem(void) +{ + CPU_INT32U en = 0; + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + + if (en) + { + CPU_INT32U en_coin = 0; + SetData(&EnableCoinDesc, &en_coin, 0, DATA_FLAG_SYSTEM_INDEX); + + if (!IsModemConn()) + { + modem_status = 2; + } + else if (!IsModemConf()) + { + modem_status = 1; + } + PostModemTask(MODEM_TASK_RECONNECT); + } +} + +TDataDescStruct const EnableModemDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableModem), // FRAM + (void*)&EnableModemRange, // + OnchangeEnableModem, // + sizeof(CPU_INT32U), // + EnableModemName, // + DATA_IS_INDEX, // ( ) + EnableModemList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +TRangeValueULONG const EnableEmailErrorSendRange = {0, 1}; +CPU_INT08U const EnableEmailErrorSendName[] = ". ."; +CPU_INT08U const *EnableEmailErrorSendList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableEmailErrorSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailErrorSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailErrorSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ModemStatusName[] = ""; +CPU_INT08U const *ModemStatusList[] = {"", "..", " "}; + +TDataDescStruct const ModemStatusDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + &modem_status, // FRAM + NULL, // + NULL, // + 0, // + ModemStatusName, // + DATA_IS_INDEX, // ( ) + ModemStatusList,// + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const EnableEmailJournalSendName[] = "."; + +TDataDescStruct const EnableEmailJournalSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailJournalSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailJournalSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const ClearJournalAfterSendName[] = "."; + +TDataDescStruct const ClearJournalAfterSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ClearJournalAfterSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + ClearJournalAfterSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + , : +*************************************/ +TRangeValueULONG const StatSendHourRange = {0, 60*24 - 1}; +CPU_INT08U const StatSendHourName[] = "T."; + +TDataDescStruct const StatSendHourMinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_HOUR_MIN, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.StatSendHourMin), // FRAM + (void*)&StatSendHourRange, // + NULL, // + 0, // + StatSendHourName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 9 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableCoinRange = {0, 1}; +CPU_INT08U const EnableCoinName[] = "-"; +CPU_INT08U const *EnableCoinList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableCoin(void) +{ + CPU_INT32U enable; + GetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable) + { + CPU_INT32U en_modem = 0; + SetData(&EnableModemDesc, &en_modem, 0, DATA_FLAG_SYSTEM_INDEX); + } +} + +TDataDescStruct const EnableCoinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableCoinAcceptor), // FRAM + (void*)&EnableCoinRange, // + OnchangeEnableCoin, // + sizeof(CPU_INT32U), // + EnableCoinName, // + DATA_IS_INDEX, // ( ) + EnableCoinList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const CoinPerPulseRange = {1, 9999}; +CPU_INT08U const CoinPerPulseName[] = "./."; + +TDataDescStruct const CoinPerPulseDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.CoinPerPulse), // FRAM + (void*)&CoinPerPulseRange, // + NULL, // + 0, // + CoinPerPulseName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalRange = {0, 1}; +CPU_INT08U const EnableFiscalName[] = ""; +CPU_INT08U const *EnableFiscalList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableFiscalDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscal), // FRAM + (void*)&EnableFiscalRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalName, // + DATA_IS_INDEX, // ( ) + EnableFiscalList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const DisableFiscalErrorsRange = {0, 1}; +CPU_INT08U const DisableFiscalErrorsName[] = ".."; +CPU_INT08U const DisableFiscalErrorsList_str0[] = ""; +CPU_INT08U const DisableFiscalErrorsList_str1[] = ""; +CPU_INT08U const *DisableFiscalErrorsList[] = {DisableFiscalErrorsList_str0, DisableFiscalErrorsList_str1}; + +TDataDescStruct const DisableFiscalErrorsDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DisableFiscalErrors), // FRAM + (void*)&DisableFiscalErrorsRange, // + NULL, // + sizeof(CPU_INT32U), // + DisableFiscalErrorsName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U WorkTime[CHANNELS_NUM]; +TRangeValueULONG const WorkTimeRange = {0, 0xffffffffL}; +CPU_INT08U const WorkTimeName[] = "."; + +TDataDescStruct const WorkTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + &WorkTime, // FRAM + (void*)&WorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + WorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutBeforeRange = {0, 999}; +CPU_INT08U const TimeOutBeforeName[] = " ,."; + +TDataDescStruct const TimeOutBeforeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutBefore), // FRAM + (void*)&TimeOutBeforeRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutBeforeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 30 +}; + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutAfterRange = {0, 99}; +CPU_INT08U const TimeOutAfterName[] = " ,."; + +TDataDescStruct const TimeOutAfterDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutAfter), // FRAM + (void*)&TimeOutAfterRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutAfterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 3 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MaxWorkTimeRange = {1, 999}; +CPU_INT08U const MaxWorkTimeName[] = "Tmax,."; + +TDataDescStruct const MaxWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MaxWorkTime), // FRAM + (void*)&MaxWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MaxWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 20 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MinWorkTimeRange = {1, 999}; +CPU_INT08U const MinWorkTimeName[] = "Tmin,."; + +TDataDescStruct const MinWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MinWorkTime), // FRAM + (void*)&MinWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MinWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 5 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const WeekEndRange = {0, 4}; +CPU_INT08U const WeekEndName[] = ":"; +CPU_INT08U const WeekEndList_str0[] = ""; +CPU_INT08U const WeekEndList_str1[] = "-"; +CPU_INT08U const WeekEndList_str2[] = "-"; +CPU_INT08U const WeekEndList_str3[] = "-"; +CPU_INT08U const WeekEndList_str4[] = "-"; +CPU_INT08U const *WeekEndList[] = {WeekEndList_str0, WeekEndList_str1, WeekEndList_str2, WeekEndList_str3, WeekEndList_str4, NULL}; + +TDataDescStruct const WeekEndDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.WeekEnd), // FRAM + (void*)&WeekEndRange, // + NULL, // + sizeof(CPU_INT32U), // + WeekEndName, // + DATA_IS_INDEX, // ( ) + WeekEndList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PeriodIndexRange = {0, 0xffffffff/*CHANNELS_NUM*PRICE_PERIODS_NUM-1*/}; +CPU_INT08U const PeriodIndexName[] = ""; +CPU_INT08U const *PeriodWeekendIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; + +CPU_INT32U PeriodIndex = 0; + +void OnChangePeriodIndex(void) +{ + if ((PeriodIndex == 0xffffffff) || (PeriodIndex < ChannelIndex*PRICE_PERIODS_NUM)) PeriodIndex = (ChannelIndex+1)*PRICE_PERIODS_NUM-1; + else if (PeriodIndex >= (ChannelIndex+1)*PRICE_PERIODS_NUM) PeriodIndex = (ChannelIndex)*PRICE_PERIODS_NUM; +} + +TDataDescStruct const PeriodWeekendIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekendIndexList, // + DATA_INIT_ENABLE, + 0 +}; + +CPU_INT08U const *PeriodWeekdaysIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; +TDataDescStruct const PeriodWeekdaysIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekdaysIndexList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekendRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekendName[] = ",."; + +TDataDescStruct const PriceWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekend), // FRAM + (void*)&PriceWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekdaysRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekdaysName[] = ",."; + +TDataDescStruct const PriceWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekdays), // FRAM + (void*)&PriceWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekendRange = {1, 999}; +CPU_INT08U const PriceTimeWeekendName[] = " ,."; + +TDataDescStruct const PriceTimeWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekend), // FRAM + (void*)&PriceTimeWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekdaysRange = {1, 999}; +CPU_INT08U const PriceTimeWeekdaysName[] = " ,."; + +TDataDescStruct const PriceTimeWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekdays), // FRAM + (void*)&PriceTimeWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekdaysRange = {0, 24}; +CPU_INT08U const T_Start_WeekdaysName[] = ","; + +TDataDescStruct const T_Start_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekdays), // FRAM + (void*)&T_Start_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekdaysRange = {0, 24}; +CPU_INT08U const T_End_WeekdaysName[] = ","; + +TDataDescStruct const T_End_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekdays), // FRAM + (void*)&T_End_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekendRange = {0, 24}; +CPU_INT08U const T_Start_WeekendName[] = ","; + +TDataDescStruct const T_Start_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekend), // FRAM + (void*)&T_Start_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekendRange = {0, 24}; +CPU_INT08U const T_End_WeekendName[] = ","; + +TDataDescStruct const T_End_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekend), // FRAM + (void*)&T_End_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +CPU_INT32U InitByDefault = 0; + +TRangeValueULONG const InitByDefaultRange = {0, 1}; +CPU_INT08U const InitByDefaultName[] = ""; +CPU_INT08U const InitByDefaultList_str0[] = ""; +CPU_INT08U const InitByDefaultList_str1[] = ""; +CPU_INT08U const *InitByDefaultList[] = {InitByDefaultList_str0, InitByDefaultList_str1}; + + +void OnChangeInitByDefault(void) +{ + int i = 0; + if (InitByDefault == 0) return; + while (AllDataArray[i].ptr != NULL) + { + InitDescByDefault(AllDataArray[i].ptr); + i++; + } + InitByDefault = 0; +} + + +TDataDescStruct const InitByDefaultDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&InitByDefault, // FRAM + (void*)&InitByDefaultRange, // + OnChangeInitByDefault, // + 0, // + InitByDefaultName, // + DATA_IS_INDEX, // ( ) + InitByDefaultList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + Z- +*************************************/ +CPU_INT32U PrintZReportCmd = 0; + +CPU_INT08U const PrintZReportName[] = "Z-"; +CPU_INT08U const PrintZReportList_str0[] = ""; +CPU_INT08U const PrintZReportList_str1[] = ""; +CPU_INT08U const *PrintZReportList[] = {PrintZReportList_str0, PrintZReportList_str1}; + + +void OnChangePrintZReportCmd(void) +{ +} + +TDataDescStruct const PrintZReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintZReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintZReportCmd, // + 0, // + PrintZReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + X- +*************************************/ +CPU_INT32U PrintXReportCmd = 0; + +CPU_INT08U const PrintXReportName[] = "X-"; + +void OnChangePrintXReportCmd(void) +{ +} + +TDataDescStruct const PrintXReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintXReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintXReportCmd, // + 0, // + PrintXReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const ErrorJournalIndexName[] = " #"; +CPU_INT32U ErrorJournalIndex = 0; + +void OnChangeErrorJournalIndex(void) +{ + if (ErrorJournalIndex == 0xffffffff) ErrorJournalIndex = ERROR_RECORDS_NUM-1; + else if (ErrorJournalIndex > ERROR_RECORDS_NUM-1) ErrorJournalIndex = 0; +} + +TDataDescStruct const ErrorJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ErrorJournalIndex, // FRAM + (void*)&ErrorJournalIndexRange, // + OnChangeErrorJournalIndex, // + 0, // + ErrorJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorNumberRange = {0, ERRORS_NUM-1}; +CPU_INT08U const *ErrorNumberList0[ERRORS_NUM] = {"", + " ", + " ", + "1Ch60h-.", + "1Ch61h-.", + "1Ch64h-.", + "1Ch65h-.", + "1Ch66h-.", + "1Ch67h-.", + "1Ch68h-.", + "1Ch69h-.", + "1Ch6Ch-.", + "/:41h-", + "/:42h-", + "/:43h- ", + "/:44h-", + "/:45h-", + "/:50h-", + "/:51h- .", + "/:52h-", + "/:53h- .", + "/:54h-", + "/:65h-", + "/:66h-", + "/:67h- .", + "", + "", + + ":01h-", + ":02h-", + ":03h-", + ":04h-.-", + ":05h-", + ":06h- ", + ":07h-.-", + ":08h-", + ":09h-.", + ":0Ah- ", + ":0Bh-.", + ":11h- ", + ":12h-", + ":13h- ", + ":14h-", + ":15h-", + ":16h-", + ":17h- ", + ":18h- ", + ":19h- ", + ":1Ah- ", + ":1Bh-", + ":1Ch-", + ":1Dh-", + ":1Fh-", + ":20h-", + ":21h- ", + ":22h- ", + ":23h- ", + ":24h-", + ":25h-", + ":28h- ", + ":33h-", + ":35h-", + ":36h-", + ":37h-", + ":38h- ", + ":39h-", + ":3Ah-", + ":3Ch-:", + ":3Eh-", + ":3Fh-", + ":40h-", + ":41h-", + ":42h-", + ":43h-", + ":44h-", + ":45h-C", + ":46h- ", + ":47h-", + ":48h-", + ":4Ah- ", + ":4Bh- ", + ":4Ch-", + ":4Dh-", + ":4Eh-", + ":4Fh- ", + ":50h- ", + ":51h-", + ":52h-", + ":53h-", + ":54h-", + ":56h- .", + ":57h-:", + ":58h-", + ":59h-", + ":5Bh-", + ":5Ch-", + ":5Dh-", + ":5Eh-", + ":5Fh-.", + ":60h-", + ":61h-", + ":62h-", + ":63h-", + ":64h- ", + ":65h- ", + ":66h-", + ":67h- ", + ":68h- ", + ":69h-", + ":6Ah-", + ":6Bh- ", + ":6Ch- .", + ":6Dh- ", + ":6Eh-", + ":6Fh-", + ":70h-", + ":71h-", + ":72h- ", + ":73h- ", + ":74h- ", + ":75h-", + ":76h-:", + ":77h-:", + ":78h- ", + ":79h- ", + ":7Ah- ", + ":7Bh-", + ":7Ch- ", + ":7Dh-", + ":7Eh-", + ":7Fh-", + ":80h-", + ":81h-", + ":82h-", + ":83h-", + ":84h-", + ":85h-", + ":86h-", + ":87h-", + ":88h-", + ":89h-", + ":8Ah-", + ":8Bh-", + ":8Ch-.", + ":8Dh-", + ":8Eh- ", + ":8Fh- ", + ":90h- .", + ":91h- ", + ":92h-", + ":93h-", + ":94h-", + ":A0h- ", + ":A1h-", + ":A2h-: ", + ":A3h-", + ":A4h- ", + ":A5h- ", + ":A6h-", + ":A7h-", + ":A8h-:", + ":A9h-:", + ":AAh-", + ":B0h-:", + ":B1h-:", + ":B2h-:", + ":C0h-", + ":C1h-:", + ":C2h-", + ":C3h-", + ":C4h-", + //":5h-", + //":C6h-", + //":C7h- ", + //":8h-", + +}; + +TDataDescStruct const JournalErrorNumberDesc0 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList0, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const *ErrorNumberList1[ERRORS_NUM] = {"", + "", + "", + " ", + " .", + " .", + " ", + " ", + " . ", + " ", + " .", + " ", + "", + "", + "", + " ", + "", + " ", + ".", + ".", + "", + "", + "", + ".", + "", + "", + " ", + "1,2 ", + " 1", + " 2", + " ", + " ", + " ", + " ", + " .", + " ", + " BCD", + " ", + "", + " ", + " ", + "", + " ", + " ", + "", + "", + " ", + "", + " ", + ". ", + " ", + " ", + " ", + "", + "", + "", + ".", + "", + "2 ", + " ", + "", + "", + " .", + "", + " ", + " ", + " .", + ". ", + ". ", + " ", + " ", + " 2", + " 3", + " 4", + " ", + " ", + " ", + " ", + " ", + "", + ". ", + ". ", + " 24 ", + "", + ".", + " ", + " 2 ", + " 3 ", + " 4 ", + " ", + " - ", + " ", + " .", + " ", + " 24", + " ", + "", + " ", + " ", + " ", + " -", + " ", + "", + " ", + " ", + " ", + " ", + " ", + "", + "", + "", + " ", + " ", + " ", + "", + "", + ".", + ".", + "", + "", + " ", + " ", + "", + "", + "", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + "", + " ", + " ", + "", + " ", + " ", + " ", + "", + ". ", + " ", + "", + " ", + ". ", + "", + " ", + " ", + "", + " -", + " ", + " ", + " ", + " ", + "", + " ", + " ", + //".. ", + //".", + //"", + //"" + +}; + +TDataDescStruct const JournalErrorNumberDesc1 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList1, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + - +*************************************/ +CPU_INT08U const *ErrorNumberListEng[ERRORS_NUM] = +{ + "Net oshibki", + "Oshibka svyazi c kupuropriemnikom", + "Kriticheskaya oshibka kupuropriemnika", + "Vybros kupury po mag.datchiku", + "Vybros kupury pri transportirovke", + "Vybros kupury po identifikacii", + "Vybros kupury po verifikacii", + "Vybros kupury po opt.datchiku", + "Vybros kupury po zapretu", + "Vybros kupury po emk.datchiku", + "Vybros kupury po dline", + "Kasseta zapolnena", + "Kasseta otsutstvuet", + "Zamin v kupuropriemnike", + "Zamin v kassete", + "Popytka obmana", + "Oshibka stekernogo motora", + "Oshibka skorosti transp.motora", + "Oshibka transp.motora", + "Oshibka mehanizmavyravnivaniya", + "Kasseta otsutstvuet", + "Oshibka optiki", + "Oshibka magn.datchika", + "Oshibka emk.datchika", + "Nekriticheskaya oshibka kupuropriemnika", + + "Oshibka svyazi s modemom", + "Oshibka svyazi s FR", + "Oshibka FR 0x01", + "Oshibka FR 0x02", + "Oshibka FR 0x03", + "Oshibka FR 0x04", + "Oshibka FR 0x05", + "Oshibka FR 0x06", + "Oshibka FR 0x07", + "Oshibka FR 0x08", + "Oshibka FR 0x09", + "Oshibka FR 0x0A", + "Oshibka FR 0x0B", + "Oshibka FR 0x11", + "Oshibka FR 0x12", + "Oshibka FR 0x13", + "Oshibka FR 0x14", + "Oshibka FR 0x15", + "Oshibka FR 0x16", + "Oshibka FR 0x17", + "Oshibka FR 0x18", + "Oshibka FR 0x19", + "Oshibka FR 0x1A", + "Oshibka FR 0x1B", + "Oshibka FR 0x1C", + "Oshibka FR 0x1D", + "Oshibka FR 0x1F", + "Oshibka FR 0x20", + "Oshibka FR 0x21", + "Oshibka FR 0x22", + "Oshibka FR 0x23", + "Oshibka FR 0x24", + "Oshibka FR 0x25", + "Oshibka FR 0x28", + "Oshibka FR 0x33", + "Oshibka FR 0x35", + "Oshibka FR 0x36", + "Oshibka FR 0x37", + "Oshibka FR 0x38", + "Oshibka FR 0x39", + "Oshibka FR 0x3A", + "Oshibka FR 0x3C", + "Oshibka FR 0x3E", + "Oshibka FR 0x3F", + "Oshibka FR 0x40", + "Oshibka FR 0x41", + "Oshibka FR 0x42", + "Oshibka FR 0x43", + "Oshibka FR 0x44", + "Oshibka FR 0x45", + "Oshibka FR 0x46", + "Oshibka FR 0x47", + "Oshibka FR 0x48", + "Oshibka FR 0x4A", + "Oshibka FR 0x4B", + "Oshibka FR 0x4C", + "Oshibka FR 0x4D", + "Oshibka FR 0x4E", + "Oshibka FR 0x4F", + "Oshibka FR 0x50", + "Oshibka FR 0x51", + "Oshibka FR 0x52", + "Oshibka FR 0x53", + "Oshibka FR 0x54", + "Oshibka FR 0x56", + "Oshibka FR 0x57", + "Oshibka FR 0x58", + "Oshibka FR 0x59", + "Oshibka FR 0x5B", + "Oshibka FR 0x5C", + "Oshibka FR 0x5D", + "Oshibka FR 0x5E", + "Oshibka FR 0x5F", + "Oshibka FR 0x60", + "Oshibka FR 0x61", + "Oshibka FR 0x62", + "Oshibka FR 0x63", + "Oshibka FR 0x64", + "Oshibka FR 0x65", + "Oshibka FR 0x66", + "Oshibka FR 0x67", + "Oshibka FR 0x68", + "Oshibka FR 0x69", + "Oshibka FR 0x6A", + "Oshibka FR 0x6B", + "Oshibka FR 0x6C", + "Oshibka FR 0x6D", + "Oshibka FR 0x6E", + "Oshibka FR 0x6F", + "Oshibka FR 0x70", + "Oshibka FR 0x71", + "Oshibka FR 0x72", + "Oshibka FR 0x73", + "Oshibka FR 0x74", + "Oshibka FR 0x75", + "Oshibka FR 0x76", + "Oshibka FR 0x77", + "Oshibka FR 0x78", + "Oshibka FR 0x79", + "Oshibka FR 0x7A", + "Oshibka FR 0x7B", + "Oshibka FR 0x7C", + "Oshibka FR 0x7D", + "Oshibka FR 0x7E", + "Oshibka FR 0x7F", + "Oshibka FR 0x80", + "Oshibka FR 0x81", + "Oshibka FR 0x82", + "Oshibka FR 0x83", + "Oshibka FR 0x84", + "Oshibka FR 0x85", + "Oshibka FR 0x86", + "Oshibka FR 0x87", + "Oshibka FR 0x88", + "Oshibka FR 0x89", + "Oshibka FR 0x8A", + "Oshibka FR 0x8B", + "Oshibka FR 0x8C", + "Oshibka FR 0x8D", + "Oshibka FR 0x8E", + "Oshibka FR 0x8F", + "Oshibka FR 0x90", + "Oshibka FR 0x91", + "Oshibka FR 0x92", + "Oshibka FR 0x93", + "Oshibka FR 0x94", + "Oshibka FR 0xA0", + "Oshibka FR 0xA1", + "Oshibka FR 0xA2", + "Oshibka FR 0xA3", + "Oshibka FR 0xA4", + "Oshibka FR 0xA5", + "Oshibka FR 0xA6", + "Oshibka FR 0xA7", + "Oshibka FR 0xA8", + "Oshibka FR 0xA9", + "Oshibka FR 0xAA", + "Oshibka FR 0xB0", + "Oshibka FR 0xB1", + "Oshibka FR 0xB2", + "Oshibka FR 0xC0", + "Oshibka FR 0xC1", + "Oshibka FR 0xC2", + "Oshibka FR 0xC3" + "Oshibka FR 0xC4" +}; + +TDataDescStruct const JournalErrorNumberDescEng = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberListEng, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalErrorTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EventJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const EventJournalIndexName[] = " #"; +CPU_INT32U EventJournalIndex = 0; + +void OnChangeEventJournalIndex(void) +{ + TEventRecord record; + + if (EventJournalIndex == 0xffffffff) EventJournalIndex = EVENT_RECORDS_NUM-1; + else if (EventJournalIndex > ERROR_RECORDS_NUM-1) EventJournalIndex = 0; + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +TDataDescStruct const EventJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&EventJournalIndex, // FRAM + (void*)&EventJournalIndexRange, // + OnChangeEventJournalIndex, // + 0, // + EventJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalEventTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &EventJournalIndexDesc, // + (void*)offsetof(TFramMap, EventRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TEventRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U SystemTime; + +TDataDescStruct const SystemTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +void OnSetTime(void) +{ + TRTC_Data rtc; + Sec2Date(&rtc, SystemTime); + RTC_SetTime(&rtc); +} + +TDataDescStruct const SystemTimeEditDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + OnSetTime, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U ClearJournalCmd = 0; + +CPU_INT08U const ClearJournalCmdName[] = ""; +CPU_INT08U const ClearJournalCmdList_str0[] = ""; +CPU_INT08U const ClearJournalCmdList_str1[] = ""; +CPU_INT08U const *ClearJournalCmdList[] = {ClearJournalCmdList_str0, ClearJournalCmdList_str1}; + +void OnChangeClearJournalCmd(void) +{ + if (ClearJournalCmd) + { + ClearErrorJournal(); + ClearEventJournal(); + ClearJournalCmd = 0; + } +} + +TDataDescStruct const ClearJournalCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearJournalCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearJournalCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT08U const CounterRunName[] = ""; + +TDataDescStruct const CounterRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterRun), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterMoneyName[] = ",."; + +TDataDescStruct const CounterMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterMoney), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterTimeName[] = ".."; + +TDataDescStruct const CounterTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterTime), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterRunLong), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterMoneyLong), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterTimeLong), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelRun[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelMoney[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelRunLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelMoneyLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelTimeLong), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U ClearStatCmd = 0; + +CPU_INT08U const ClearStatCmdName[] = ""; + +void OnChangeClearStatCmd(void) +{ + if (ClearStatCmd) + { + ClearCounters(); + ClearStatCmd = 0; + } +} + +TDataDescStruct const ClearStatCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearStatCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearStatCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalDayClearRange = {0, 2}; +CPU_INT08U const EnableFiscalDayClearName[] = "."; +CPU_INT08U const *EnableFiscalDayClearList[] = {".", "", ""}; + +TDataDescStruct const EnableFiscalDayClearDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscalDayClear), // FRAM + (void*)&EnableFiscalDayClearRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalDayClearName, // + DATA_IS_INDEX, // ( ) + EnableFiscalDayClearList, // + DATA_INIT_ENABLE, + 1 // +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const BillFormatRange = {0, 1}; +CPU_INT08U const BillFormatName[] = ":"; +CPU_INT08U const BillFormatList_str0[] = "-*"; +CPU_INT08U const BillFormatList_str1[] = ""; +CPU_INT08U const *BillFormatList[] = {BillFormatList_str0, BillFormatList_str1}; + +TDataDescStruct const BillFormatDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.BillFormat), // FRAM + (void*)&BillFormatRange, // + NULL, // + sizeof(CPU_INT32U), // + BillFormatName, // + DATA_IS_INDEX, // ( ) + BillFormatList, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ServiceNameRange = {0, 0}; +CPU_INT08U const ServiceNameName[] = ""; +CPU_INT08U const *ServiceNameList[] = {" "}; + +TDataDescStruct const ServiceNameDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ServiceName), // FRAM + (void*)&ServiceNameRange, // + NULL, // + sizeof(CPU_INT32U), // + ServiceNameName, // + DATA_IS_INDEX, // ( ) + ServiceNameList, // + DATA_INIT_DISABLE, + 0 // +}; + +/************************************* + +*************************************/ +TDataDescStruct const AcceptedMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, FRAM_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + Crc16 +*************************************/ +TDataDescStruct const AcceptedMoneyCRC16Desc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PassRange = {0, 9999}; +CPU_INT08U const PassName[] = " b"; + +void OnChangePass(void) +{ + // CRC + CPU_INT32U pass,crc; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); +} + +TDataDescStruct const PassDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Pass), // FRAM + (void*)&PassRange, // + OnChangePass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + DEFAULT_PASSWORD +}; + +/************************************* + CRC +*************************************/ +TDataDescStruct const PassCRCDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_Pass), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U TempPass = 0; + +void OnChangeTempPass(void) +{ + CPU_INT32U pass; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + + if (GetCurrentMenu() == SetPassMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {GoToPreviousMenu(); GoToMenu(SetNewPassMenuPanel);} + } + else if (GetCurrentMenu() == ResetSettingsMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {InitByDefault = 1; OnChangeInitByDefault(); GoToPreviousMenu(); GoToMenu(SettingsIsReset);} + } + else if (GetCurrentMenu() == ClearStatMenu) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearStatCmd = 1; OnChangeClearStatCmd(); GoToPreviousMenu(); GoToMenu(StatIsReset);} + } + else if (GetCurrentMenu() == ClearJournalMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearJournalCmd = 1; OnChangeClearJournalCmd(); GoToPreviousMenu(); GoToMenu(JournalIsReset);} + } + +} + +TDataDescStruct const PassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +CPU_INT08U const PassTempName1[] = " b"; + +TDataDescStruct const PassTempDesc1 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName1, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +TRangeValueULONG const MasterPassRange = {0, 99999999}; +CPU_INT08U const MasterPassTempName[] = "b"; + +void OnChangeMasterPass(void) +{ + CPU_INT32U pass, crc; + + if (TempPass == MASTER_PASSWORD) + { + TempPass = 0; + pass = DEFAULT_PASSWORD; + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); + + GoToPreviousMenu(); + GoToPreviousMenu(); + GoToMenu(SetNewPassMenuPanel); + } +} + +TDataDescStruct const MasterPassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&MasterPassRange, // + OnChangeMasterPass, // + 0, // + (void*)&MasterPassTempName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const PassTempName2[] = " b"; + +TDataDescStruct const PassTempDesc2 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName2, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const SendTestEmailName[] = "."; +CPU_INT32U send_test; + +void OnChangeSendTestEmail(void) +{ + if (send_test) + { + PostModemTask(MODEM_TASK_SEND_TEST_MSG); + send_test = 0; + } +} + +TDataDescStruct const SendTestEmailDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)&send_test, // FRAM + (void*)&EnableEmailErrorSendRange, // + OnChangeSendTestEmail, // + sizeof(CPU_INT32U), // + SendTestEmailName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U BillnomViewIndex; +TRangeValueULONG const BillnomIndexRange = {0, 23}; +CPU_INT08U const BillnomName[] = " #"; +CPU_INT08U const* BillnomItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}; + +TDataDescStruct const BillnomIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &BillnomViewIndex, // FRAM + (void*)&BillnomIndexRange, // + NULL, // + 0, // + BillnomName, // + DATA_IS_INDEX, // ( ) + BillnomItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U BillNominals[24]; +CPU_INT08U const BillnomValName[] = ",."; + +TDataDescStruct const BillnomDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + 24, // + (void*)&BillnomIndexDesc, // + (void*)&BillNominals, // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomValName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillnomCountersName[] = "-"; + +TDataDescStruct const BillnomCountersDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + 24, // + &BillnomIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterBillNominals[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomCountersName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillCounterName[] = " "; + +TDataDescStruct const BillCounterDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.BillsCount), // FRAM + NULL, // + NULL, // + 0, // + BillCounterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + ID +*************************************/ +CPU_INT08U const DeviceIDName[] = "ID -"; +TRangeValueULONG const DeviceIDRange = {0, 9999}; + +TDataDescStruct const DeviceIDDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DeviceId), // FRAM + (void*)&DeviceIDRange, // + NULL, // + 0, // + DeviceIDName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasSendFlagDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasEmailFlag), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasMoney), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +//************************************************** +//************************************************** +//************************************************** +const TDataDescArrayStruct AllDataArray[] = { + &WorkTimeDesc, + &ChannelIndexDesc, + &EnableChannelDesc, + &EnableValidatorDesc, + &EnableModemDesc, + &EnableFiscalDesc, + &EnableCoinDesc, + &TimeOutBeforeDesc, + &TimeOutAfterDesc, + &MaxWorkTimeDesc, + &MinWorkTimeDesc, + &WeekEndDesc, + &PeriodWeekendIndexDesc, + &PeriodWeekdaysIndexDesc, + + &PriceWeekendDesc, + &PriceWeekdaysDesc, + + &PriceTimeWeekendDesc, + &PriceTimeWeekdaysDesc, + &T_Start_WeekdaysDesc, + &T_End_WeekdaysDesc, + &T_Start_WeekendDesc, + &T_End_WeekendDesc, + + &PrintZReportDesc, + &PrintXReportDesc, + &ErrorJournalIndexDesc, + &SystemTimeDesc, + &SystemTimeEditDesc, + &CoinPerPulseDesc, + + &BillFormatDesc, + &NameChannelDesc, + + &PassDesc, + &DeviceIDDesc, + + &EnableEmailErrorSendDesc, + &EnableEmailJournalSendDesc, + &ClearJournalAfterSendDesc, + &StatSendHourMinDesc, + &SendTestEmailDesc, + &BillnomIndexDesc, + + NULL +}; + + diff --git a/.svn/pristine/c6/c609119021e0d873107658ec2166d2ba27606fc0.svn-base b/.svn/pristine/c6/c609119021e0d873107658ec2166d2ba27606fc0.svn-base new file mode 100644 index 0000000..c49496c --- /dev/null +++ b/.svn/pristine/c6/c609119021e0d873107658ec2166d2ba27606fc0.svn-base @@ -0,0 +1,460 @@ +#include +#include +#include "journal.h" +#include "fram.h" +#include "fram_map.h" +#include "time.h" +#include "fr.h" +#include "crc16.h" +#include "mode.h" + +static CPU_INT32U GlobalErrorsFlags[8] = {0,0,0,0,0,0,0,0}; + +void SetErrorFlag(CPU_INT08U error) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + GlobalErrorsFlags[error/32] |= (1L << (error%32)); + OS_EXIT_CRITICAL(); +} + +void ClrErrorFlag(CPU_INT08U error) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + GlobalErrorsFlags[error/32] &= ~(1L << (error%32)); + OS_EXIT_CRITICAL(); +} + +int TstErrorFlag(CPU_INT08U error) +{ + CPU_INT32U temp = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + temp = GlobalErrorsFlags[error/32] & (1L << (error%32)); + OS_EXIT_CRITICAL(); + return temp; +} + +int TstCriticalErrors(void) +{ + CPU_INT32U errors = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT32U ignore_fiscal = 0; + + GetData(&DisableFiscalErrorsDesc, &ignore_fiscal, 0, DATA_FLAG_SYSTEM_INDEX); + + OS_ENTER_CRITICAL(); + + if (!ignore_fiscal) + { + errors |= TstCriticalFiscalError(); + errors |= TstErrorFlag(ERROR_FR_CONN); + /* + if (!FReportTest()) + { // + errors |= 0x1; + } + */ + } + + errors |= TstErrorFlag(ERROR_VALIDATOR_CONN); + + OS_EXIT_CRITICAL(); + if (errors) return 1; + return 0; +} + + +int TstCriticalValidatorErrors(void) +{ + return 0; +} + +void ClrValidatorErrors(void) +{ + for (CPU_INT08U i=ERROR_VALIDATOR_FAILURE; i= maxtime) {maxtime = record.time; indm = i;} + } + + if (i >= ERROR_RECORDS_NUM) + { // - + ind = (indm+1)%ERROR_RECORDS_NUM; + } + + record.time = GetTimeSec(); + record.error = error; + WriteArrayFram(offsetof(TFramMap, ErrorRecords[0])+ind*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)&record); +} + +// +int GetErrorRecord(TErrorRecord* record, CPU_INT32U index) +{ + if (index >= ERROR_RECORDS_NUM) return -1; + + ReadArrayFram(offsetof(TFramMap, ErrorRecords[0])+index*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)record); + + return 0; +} + +// +int GetEventRecord(TEventRecord* record, CPU_INT32U index) +{ + if (index >= EVENT_RECORDS_NUM) return -1; + + ReadArrayFram(offsetof(TFramMap, EventRecords[0])+index*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)record); + + return 0; +} + +// +void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT32U data) +{ + TEventRecord record; + + // + CPU_INT32U i, ind=0, indm = 0, maxtime = 0; + for (i=0; i= maxtime) {maxtime = record.time; indm = i;} + } + + if (i >= ERROR_RECORDS_NUM) + { // - + ind = (indm+1)%ERROR_RECORDS_NUM; + } + + record.time = GetTimeSec(); + record.channel = channel; + record.event = event; + record.data = data; + WriteArrayFram(offsetof(TFramMap, EventRecords[0])+ind*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)&record); +} + + +void ClearErrorJournal(void) +{ + SetArrayFram(offsetof(TFramMap, ErrorRecords), sizeof(TErrorRecord)*ERROR_RECORDS_NUM, 0x00); +} + +void ClearEventJournal(void) +{ + SetArrayFram(offsetof(TFramMap, EventRecords), sizeof(TEventRecord)*EVENT_RECORDS_NUM, 0x00); +} + +void GetEventStr(char* str, char event) +{ + switch (event){ + case JOURNAL_EVENT_MONEY_NOTE: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_MONEY_COIN: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_START_SESSION: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_END_SESSION: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_DEVICE_ON: + sprintf(str, ""); + break; + case JOURNAL_EVENT_PRINT_BILL: + sprintf(str, " "); + break; + case JOURNAL_EVENT_PRINT_Z: + sprintf(str, " Z-"); + break; + case JOURNAL_EVENT_PRINT_X: + sprintf(str, " X-"); + break; + case JOURNAL_EVENT_PRINT_BUF: + sprintf(str, " . ."); + break; + case JOURNAL_EVENT_CHANGE_MODE: + sprintf(str, " "); + break; + case JOURNAL_EVENT_INCASSATION: + sprintf(str, ""); + break; + case JOURNAL_EVENT_PASS_FAIL: + sprintf(str, " "); + break; + case JOURNAL_EVENT_EMAIL_FAIL: + sprintf(str, " .e-mail"); + break; + case JOURNAL_EVENT_EMAIL_OK: + sprintf(str, "E-mail ."); + break; + default: + sprintf(str, ""); + break; + } +} + +void GetEventStrEng(char* str, char event) +{ + switch (event){ + case JOURNAL_EVENT_MONEY_NOTE: + sprintf(str, " | Vnesena kupura "); + break; + case JOURNAL_EVENT_MONEY_COIN: + sprintf(str, " | Vneseny monety "); + break; + case JOURNAL_EVENT_START_SESSION: + sprintf(str, " | Nachalo seansa "); + break; + case JOURNAL_EVENT_END_SESSION: + sprintf(str, " | Kone seansa "); + break; + case JOURNAL_EVENT_DEVICE_ON: + sprintf(str, " | Vkluchenie "); + break; + case JOURNAL_EVENT_PRINT_BILL: + sprintf(str, " | Pechat' checka "); + break; + case JOURNAL_EVENT_PRINT_Z: + sprintf(str, " | Pechat' Z-otcheta "); + break; + case JOURNAL_EVENT_PRINT_X: + sprintf(str, " | Pechat' X-otcheta "); + break; + case JOURNAL_EVENT_PRINT_BUF: + sprintf(str, " | Pechat' otcheta iz bufera "); + break; + case JOURNAL_EVENT_CHANGE_MODE: + sprintf(str, " | Smena rejima "); + break; + case JOURNAL_EVENT_INCASSATION: + sprintf(str, " | Incassaciya "); + break; + case JOURNAL_EVENT_PASS_FAIL: + sprintf(str, " | Neverniy parol' "); + break; + case JOURNAL_EVENT_EMAIL_FAIL: + sprintf(str, " | Oshibka otpravki e-mail "); + break; + case JOURNAL_EVENT_EMAIL_OK: + sprintf(str, " | E-mail otpravleno uspeshno "); + break; + default: + sprintf(str, " | Net sobytiya "); + break; + } +} + +void PrintEventJournalRecordEng(char* str, TEventRecord *record) +{ + if (record->event) + { + TRTC_Data rtc_data; + + // + Sec2Date(&rtc_data, record->time); + sprintf(str, "| "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc_data); + // + GetEventStrEng(&str[strlen(str)], record->event); + + // + if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN)) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + sprintf(&str[strlen(str)], "%d rub.", record->data); + } + else if (record->event == JOURNAL_EVENT_START_SESSION) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + PrintSecToHourMinSec(&str[strlen(str)], record->data); + } + else if (record->event == JOURNAL_EVENT_END_SESSION) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_DEVICE_ON) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BILL) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + } + else if (record->event == JOURNAL_EVENT_PRINT_Z) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_X) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BUF) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_CHANGE_MODE) + { + if (record->data == MODE_WORK) sprintf(&str[strlen(str)], "rabota"); + else sprintf(&str[strlen(str)], "nastroika"); + } + else if (record->event == JOURNAL_EVENT_INCASSATION) + { + sprintf(&str[strlen(str)], "%u rub.", record->data); + } + else if (record->event == JOURNAL_EVENT_PASS_FAIL) + { + sprintf(&str[strlen(str)], "%u", record->data); + } + else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL)) + { + sprintf(&str[strlen(str)], ""); + } + sprintf(&str[strlen(str)], "\r\n"); + } + else + { // + sprintf(str, "net zapisi\r\n"); + } +} + +void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money) +{ + CPU_INT32U r, t, m; + TCountersLong long_ctrs; + + // + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r); + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t); + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m); + r++; + t+=time; + m+=money; + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r); + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t); + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m); + + // + ReadArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r); + ReadArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t); + ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m); + r++; + t+=time; + m+=money; + WriteArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r); + WriteArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t); + WriteArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m); + + // + ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + long_ctrs.CounterChannelRunLong[ch]++; + long_ctrs.CounterChannelTimeLong[ch] += time; + long_ctrs.CounterChannelMoneyLong[ch] += money; + long_ctrs.CounterRunLong++; + long_ctrs.CounterTimeLong += time; + long_ctrs.CounterMoneyLong += money; + long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); +} + +CPU_INT32U GetShortMoney() +{ + CPU_INT32U money; + ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&money); + return money; +} + +void CheckLongCounters(void) +{ + TCountersLong long_ctrs; + CPU_INT16U crc; + ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + if (crc != long_ctrs.crc) + { + memset(&long_ctrs, 0, sizeof(TCountersLong)); + long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + /// + ClearCounters(); + ClearBillnomCounter(); + } +} + +void ClearCounters(void) +{ + SetArrayFram(offsetof(TFramMap, Counters), sizeof(CPU_INT32U)*(CHANNELS_NUM+1)*3, 0x00); +} + +/// +void IncBillnomCounter(CPU_INT32U index) +{ + CPU_INT32U counter; + if (index >= 24) return; + ReadArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter); + counter++; + WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter); + + ReadArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); + counter++; + WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); +} + +/// +void ClearBillnomCounter(void) +{ + CPU_INT32U counter = 0; + CPU_INT32U i; + + for (i = 0; i < 24; i++) + { + WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*i, sizeof(CPU_INT32U), (unsigned char*)&counter); + } + + WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); +} + +// ( ) +void ErrorServer(void) +{ + static CPU_INT32U PrevFlags[8] = {0,0,0,0,0,0,0,0}; + + for (int i=0; i +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +/* +********************************************************************************************************* +* CREATE A MEMORY PARTITION +* +* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II. +* +* Arguments : addr is the starting address of the memory partition +* +* nblks is the number of memory blocks to create from the partition. +* +* blksize is the size (in bytes) of each block in the memory partition. +* +* perr is a pointer to a variable containing an error message which will be set by +* this function to either: +* +* OS_ERR_NONE if the memory partition has been created correctly. +* OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory +* storage of the partition or, the block does not align +* on a pointer boundary +* OS_ERR_MEM_INVALID_PART no free partitions available +* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2) +* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size +* - must be greater than the size of a pointer +* - must be able to hold an integral number of pointers +* Returns : != (OS_MEM *)0 is the partition was created +* == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no +* free partition is available. +********************************************************************************************************* +*/ + +OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *perr) +{ + OS_MEM *pmem; + INT8U *pblk; + void **plink; + INT32U i; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_MEM *)0); + } + if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/ + *perr = OS_ERR_MEM_INVALID_ADDR; + return ((OS_MEM *)0); + } + if (((INT32U)addr & (sizeof(void *) - 1)) != 0){ /* Must be pointer size aligned */ + *perr = OS_ERR_MEM_INVALID_ADDR; + return ((OS_MEM *)0); + } + if (nblks < 2) { /* Must have at least 2 blocks per partition */ + *perr = OS_ERR_MEM_INVALID_BLKS; + return ((OS_MEM *)0); + } + if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */ + *perr = OS_ERR_MEM_INVALID_SIZE; + return ((OS_MEM *)0); + } +#endif + OS_ENTER_CRITICAL(); + pmem = OSMemFreeList; /* Get next free memory partition */ + if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */ + OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; + } + OS_EXIT_CRITICAL(); + if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */ + *perr = OS_ERR_MEM_INVALID_PART; + return ((OS_MEM *)0); + } + plink = (void **)addr; /* Create linked list of free memory blocks */ + pblk = (INT8U *)((INT32U)addr + blksize); + for (i = 0; i < (nblks - 1); i++) { + *plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */ + plink = (void **)pblk; /* Position to NEXT block */ + pblk = (INT8U *)((INT32U)pblk + blksize); /* Point to the FOLLOWING block */ + } + *plink = (void *)0; /* Last memory block points to NULL */ + pmem->OSMemAddr = addr; /* Store start address of memory partition */ + pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */ + pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */ + pmem->OSMemNBlks = nblks; + pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */ + *perr = OS_ERR_NONE; + return (pmem); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET A MEMORY BLOCK +* +* Description : Get a memory block from a partition +* +* Arguments : pmem is a pointer to the memory partition control block +* +* perr is a pointer to a variable containing an error message which will be set by this +* function to either: +* +* OS_ERR_NONE if the memory partition has been created correctly. +* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* +* Returns : A pointer to a memory block if no error is detected +* A pointer to NULL if an error is detected +********************************************************************************************************* +*/ + +void *OSMemGet (OS_MEM *pmem, INT8U *perr) +{ + void *pblk; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return ((void *)0); + } +#endif + OS_ENTER_CRITICAL(); + if (pmem->OSMemNFree > 0) { /* See if there are any free memory blocks */ + pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */ + pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */ + pmem->OSMemNFree--; /* One less memory block in this partition */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; /* No error */ + return (pblk); /* Return memory block to caller */ + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */ + return ((void *)0); /* Return NULL pointer to caller */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A MEMORY PARTITION +* +* Description: This function is used to obtain the name assigned to a memory partition. +* +* Arguments : pmem is a pointer to the memory partition +* +* pname is a pointer to an ASCII string that will receive the name of the memory partition. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_NAME_GET_ISR You called this function from an ISR +* +* Returns : The length of the string or 0 if 'pmem' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_MEM_NAME_SIZE > 1 +INT8U OSMemNameGet (OS_MEM *pmem, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + len = OS_StrCopy(pname, pmem->OSMemName); /* Copy name from OS_MEM */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A MEMORY PARTITION +* +* Description: This function assigns a name to a memory partition. +* +* Arguments : pmem is a pointer to the memory partition +* +* pname is a pointer to an ASCII string that contains the name of the memory partition. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_MEM_NAME_SIZE > 1 +void OSMemNameSet (OS_MEM *pmem, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_MEM_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_MEM_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pmem->OSMemName, pname); /* Yes, copy name to the memory partition header */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* RELEASE A MEMORY BLOCK +* +* Description : Returns a memory block to a partition +* +* Arguments : pmem is a pointer to the memory partition control block +* +* pblk is a pointer to the memory block being released. +* +* Returns : OS_ERR_NONE if the memory block was inserted into the partition +* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory +* partition (You freed more blocks than you allocated!) +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release. +********************************************************************************************************* +*/ + +INT8U OSMemPut (OS_MEM *pmem, void *pblk) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + return (OS_ERR_MEM_INVALID_PMEM); + } + if (pblk == (void *)0) { /* Must release a valid block */ + return (OS_ERR_MEM_INVALID_PBLK); + } +#endif + OS_ENTER_CRITICAL(); + if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MEM_FULL); + } + *(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */ + pmem->OSMemFreeList = pblk; + pmem->OSMemNFree++; /* One more memory block in this partition */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); /* Notify caller that memory block was released */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY MEMORY PARTITION +* +* Description : This function is used to determine the number of free memory blocks and the number of +* used memory blocks from a memory partition. +* +* Arguments : pmem is a pointer to the memory partition control block +* +* p_mem_data is a pointer to a structure that will contain information about the memory +* partition. +* +* Returns : OS_ERR_NONE if no errors were found. +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient. +********************************************************************************************************* +*/ + +#if OS_MEM_QUERY_EN > 0 +INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *p_mem_data) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + return (OS_ERR_MEM_INVALID_PMEM); + } + if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */ + return (OS_ERR_MEM_INVALID_PDATA); + } +#endif + OS_ENTER_CRITICAL(); + p_mem_data->OSAddr = pmem->OSMemAddr; + p_mem_data->OSFreeList = pmem->OSMemFreeList; + p_mem_data->OSBlkSize = pmem->OSMemBlkSize; + p_mem_data->OSNBlks = pmem->OSMemNBlks; + p_mem_data->OSNFree = pmem->OSMemNFree; + OS_EXIT_CRITICAL(); + p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree; + return (OS_ERR_NONE); +} +#endif /* OS_MEM_QUERY_EN */ +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE MEMORY PARTITION MANAGER +* +* Description : This function is called by uC/OS-II to initialize the memory partition manager. Your +* application MUST NOT call this function. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_MemInit (void) +{ +#if OS_MAX_MEM_PART == 1 + OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ + OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */ +#if OS_MEM_NAME_SIZE > 1 + OSMemFreeList->OSMemName[0] = '?'; /* Unknown name */ + OSMemFreeList->OSMemName[1] = OS_ASCII_NUL; +#endif +#endif + +#if OS_MAX_MEM_PART >= 2 + OS_MEM *pmem; + INT16U i; + + + OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ + pmem = &OSMemTbl[0]; /* Point to memory control block (MCB) */ + for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { /* Init. list of free memory partitions */ + pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions */ +#if OS_MEM_NAME_SIZE > 1 + pmem->OSMemName[0] = '?'; /* Unknown name */ + pmem->OSMemName[1] = OS_ASCII_NUL; +#endif + pmem++; + } + pmem->OSMemFreeList = (void *)0; /* Initialize last node */ +#if OS_MEM_NAME_SIZE > 1 + pmem->OSMemName[0] = '?'; /* Unknown name */ + pmem->OSMemName[1] = OS_ASCII_NUL; +#endif + + OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */ +#endif +} +#endif /* OS_MEM_EN */ diff --git a/.svn/pristine/c8/c8224411f75133d8f7e24d3e2f3f3580908d9fc4.svn-base b/.svn/pristine/c8/c8224411f75133d8f7e24d3e2f3f3580908d9fc4.svn-base new file mode 100644 index 0000000..8556a0c --- /dev/null +++ b/.svn/pristine/c8/c8224411f75133d8f7e24d3e2f3f3580908d9fc4.svn-base @@ -0,0 +1,1315 @@ + + + + 2 + 2335931049 + + Flash + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + $PROJ_DIR$\DRIVERS\ccnet\VMCConst.h + $PROJ_DIR$\DRIVERS\ccnet\uart1.h + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.h + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + $PROJ_DIR$\DRIVERS\fiscal\fiscal.h + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + $PROJ_DIR$\DRIVERS\fiscal\uart0.h + $PROJ_DIR$\DRIVERS\fram\fram.c + $PROJ_DIR$\DRIVERS\fram\fram.h + $PROJ_DIR$\DRIVERS\fram\spi.c + $PROJ_DIR$\DRIVERS\fram\spi.h + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + $PROJ_DIR$\DRIVERS\keyboard\keyboard.h + $PROJ_DIR$\DRIVERS\lcd\lcd.c + $PROJ_DIR$\DRIVERS\lcd\lcd.h + $PROJ_DIR$\DRIVERS\modem\modem.c + $PROJ_DIR$\DRIVERS\modem\modem.h + $PROJ_DIR$\DRIVERS\modem\uart2.c + $PROJ_DIR$\DRIVERS\modem\uart2.h + $PROJ_DIR$\OS\app\app.c + $PROJ_DIR$\OS\app\app_cfg.h + $PROJ_DIR$\OS\app\includes.h + $PROJ_DIR$\OS\app\os_cfg.h + $PROJ_DIR$\OS\bsp\bsp.c + $PROJ_DIR$\OS\bsp\bsp.h + $PROJ_DIR$\OS\bsp\cstartup.s + $PROJ_DIR$\OS\bsp\iolpc2368.h + $PROJ_DIR$\OS\bsp\LPC2368_Flash.icf + $PROJ_DIR$\OS\uc\cpu\cpu.h + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + $PROJ_DIR$\OS\uc\cpu\cpu_def.h + $PROJ_DIR$\OS\uc\lib\lib_def.h + $PROJ_DIR$\OS\uc\lib\lib_mem.c + $PROJ_DIR$\OS\uc\lib\lib_mem.h + $PROJ_DIR$\OS\uc\lib\lib_str.c + $PROJ_DIR$\OS\uc\lib\lib_str.h + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu.h + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + $PROJ_DIR$\Flash\Obj\Command.pbi + $TOOLKIT_DIR$\inc\c\wchar.h + $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $PROJ_DIR$\Flash\Obj\data.pbi + $TOOLKIT_DIR$\inc\stdarg.h + $PROJ_DIR$\Flash\Obj\os_sem.pbi + $PROJ_DIR$\Flash\Obj\uart2.pbi + $TOOLKIT_DIR$\inc\xlocale_c.h + $PROJ_DIR$\Flash\Obj\control.pbi + $TOOLKIT_DIR$\inc\c\xmtx.h + $PROJ_DIR$\Flash\Obj\menu.pbi + $PROJ_DIR$\Flash\Obj\solarium.pbd + $TOOLKIT_DIR$\inc\DLib_Product_string.h + $PROJ_DIR$\Flash\Obj\os_core.pbi + $TOOLKIT_DIR$\inc\c\yvals.h + $TOOLKIT_DIR$\inc\stdlib.h + $PROJ_DIR$\Flash\Obj\bsp.pbi + $TOOLKIT_DIR$\inc\errno.h + $TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h + $TOOLKIT_DIR$\inc\ysizet.h + $TOOLKIT_DIR$\inc\xtls.h + $PROJ_DIR$\Flash\Obj\os_dbg.pbi + $PROJ_DIR$\Flash\Obj\app.o + $PROJ_DIR$\Flash\Obj\os_cpu_c.pbi + $PROJ_DIR$\Flash\Obj\os_q.o + $PROJ_DIR$\Flash\Obj\os_task.o + $PROJ_DIR$\Flash\Obj\os_dbg.o + $TOOLKIT_DIR$\inc\DLib_Defaults.h + $TOOLKIT_DIR$\inc\ycheck.h + $PROJ_DIR$\Flash\Obj\os_flag.o + $PROJ_DIR$\DRIVERS\lcd.h + $TOOLKIT_DIR$\inc\intrinsics.h + $PROJ_DIR$\Flash\Obj\modem.pbi + $PROJ_DIR$\Flash\Obj\os_mem.pbi + $TOOLKIT_DIR$\inc\ctype.h + $PROJ_DIR$\Flash\Obj\app.pbi + $PROJ_DIR$\Flash\Obj\journal.o + $TOOLKIT_DIR$\inc\c\DLib_Product_string.h + $TOOLKIT_DIR$\inc\c\xlocale.h + $TOOLKIT_DIR$\inc\io_macros.h + $TOOLKIT_DIR$\inc\c\ctype.h + $PROJ_DIR$\Flash\Obj\menu.o + $PROJ_DIR$\Flash\Obj\lib_mem.pbi + $PROJ_DIR$\Flash\Obj\crc16.pbi + $PROJ_DIR$\Flash\Obj\os_dcc.o + $TOOLKIT_DIR$\inc\xmtx.h + $TOOLKIT_DIR$\inc\c\limits.h + $TOOLKIT_DIR$\inc\c\ymath.h + $PROJ_DIR$\Flash\Obj\os_core.o + $TOOLKIT_DIR$\inc\c\math.h + $TOOLKIT_DIR$\inc\c\errno.h + $TOOLKIT_DIR$\lib\m4t_tl.a + $TOOLKIT_DIR$\inc\c\xtgmath.h + $PROJ_DIR$\Flash\Obj\fr.o + $TOOLKIT_DIR$\inc\xlocale.h + $TOOLKIT_DIR$\inc\c\DLib_Threads.h + $TOOLKIT_DIR$\lib\dl4t_tln.a + $TOOLKIT_DIR$\inc\c\ystdio.h + $TOOLKIT_DIR$\inc\DLib_Threads.h + $TOOLKIT_DIR$\inc\c\stddef.h + $PROJ_DIR$\Flash\Obj\os_mutex.pbi + $TOOLKIT_DIR$\inc\DLib_Product.h + $PROJ_DIR$\Flash\Obj\datadesc.o + $PROJ_DIR$\Flash\Obj\uart2.o + $TOOLKIT_DIR$\inc\c\ysizet.h + $TOOLKIT_DIR$\inc\xencoding_limits.h + $PROJ_DIR$\DRIVERS\modem\uart.h + $PROJ_DIR$\Flash\Exe\solarium.hex + $PROJ_DIR$\Flash\Obj\lcd.pbi + $TOOLKIT_DIR$\inc\c\intrinsics.h + $PROJ_DIR$\Flash\Obj\os_q.pbi + $PROJ_DIR$\Flash\Obj\os_dcc.pbi + $PROJ_DIR$\Flash\Obj\modem.o + $PROJ_DIR$\Flash\Obj\keyboard.pbi + $PROJ_DIR$\Flash\Obj\fram.o + $PROJ_DIR$\Flash\Obj\lib_str.pbi + $TOOLKIT_DIR$\inc\c\string.h + $PROJ_DIR$\DRIVERS\lcd.c + $PROJ_DIR$\Flash\Obj\fram.pbi + $PROJ_DIR$\Flash\Obj\control.o + $PROJ_DIR$\Flash\Obj\uart1.o + $PROJ_DIR$\Flash\Obj\cpu_a.o + $PROJ_DIR$\DRIVERS\ccnet\Command.c + $PROJ_DIR$\Flash\Obj\spi.pbi + $PROJ_DIR$\Flash\Obj\spi.o + $TOOLKIT_DIR$\lib\shs_l.a + $TOOLKIT_DIR$\inc\yvals.h + $PROJ_DIR$\DRIVERS\ccnet\Command.h + $PROJ_DIR$\Flash\Obj\os_flag.pbi + $PROJ_DIR$\Flash\Obj\app_serv.o + $TOOLKIT_DIR$\inc\c\stdio.h + $TOOLKIT_DIR$\inc\c\xencoding_limits.h + $TOOLKIT_DIR$\inc\c\DLib_Product.h + $PROJ_DIR$\Flash\Obj\menudesc.o + $PROJ_DIR$\Flash\Obj\uart0.o + $TOOLKIT_DIR$\inc\stdio.h + $TOOLKIT_DIR$\inc\DLib_Config_Normal.h + $PROJ_DIR$\Flash\Obj\modem_task.o + $PROJ_DIR$\Flash\Obj\os_cpu_a.o + $PROJ_DIR$\Flash\Obj\app_serv.pbi + $PROJ_DIR$\Flash\Obj\time.o + $PROJ_DIR$\Flash\Obj\os_mem.o + $PROJ_DIR$\Flash\Obj\fr.pbi + $TOOLKIT_DIR$\inc\wchar.h + $TOOLKIT_DIR$\inc\xlocaleuse.h + $PROJ_DIR$\Flash\Obj\lib_str.o + $TOOLKIT_DIR$\inc\c\xlocale_c.h + $TOOLKIT_DIR$\inc\c\io_macros.h + $TOOLKIT_DIR$\inc\c\stdarg.h + $PROJ_DIR$\Flash\Obj\bsp.o + $TOOLKIT_DIR$\inc\c\xtls.h + $PROJ_DIR$\Flash\Obj\mode.pbi + $PROJ_DIR$\Flash\Obj\coin.pbi + $TOOLKIT_DIR$\inc\c\stdlib.h + $PROJ_DIR$\Flash\Obj\CCRSProtocol.o + $PROJ_DIR$\Flash\Obj\modem_task.pbi + $PROJ_DIR$\Flash\Obj\uart1.pbi + $PROJ_DIR$\Flash\Obj\fiscal.pbi + $PROJ_DIR$\Flash\Exe\solarium.out + $PROJ_DIR$\Flash\Obj\os_tmr.pbi + $PROJ_DIR$\Flash\Obj\validator.pbi + $PROJ_DIR$\Flash\Obj\uart0.pbi + $PROJ_DIR$\Flash\Obj\fiscal.o + $PROJ_DIR$\Flash\Obj\os_time.o + $TOOLKIT_DIR$\inc\limits.h + $PROJ_DIR$\Flash\Obj\uart.pbi + $PROJ_DIR$\DRIVERS\modem\uart.c + $PROJ_DIR$\Flash\Obj\cstartup.o + $PROJ_DIR$\Flash\Obj\uart.o + $PROJ_DIR$\Flash\Obj\crc16.o + $PROJ_DIR$\Flash\Obj\datadesc.pbi + $PROJ_DIR$\Flash\Obj\os_mbox.o + $PROJ_DIR$\Flash\Obj\lcd.o + $TOOLKIT_DIR$\lib\rt4t_al.a + $PROJ_DIR$\Flash\Obj\os_mbox.pbi + $PROJ_DIR$\Flash\Obj\mode.o + $PROJ_DIR$\Flash\Obj\data.o + $PROJ_DIR$\Flash\Obj\CCRSProtocol.pbi + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + $PROJ_DIR$\OS\uc\os_ii\source\ucos_ii.h + $PROJ_DIR$\PROJECT\app\app_serv.c + $PROJ_DIR$\PROJECT\app\app_serv.h + $PROJ_DIR$\PROJECT\app\control.c + $PROJ_DIR$\PROJECT\app\control.h + $PROJ_DIR$\PROJECT\app\journal.c + $PROJ_DIR$\PROJECT\app\journal.h + $PROJ_DIR$\PROJECT\app\modem_task.c + $PROJ_DIR$\PROJECT\app\modem_task.h + $PROJ_DIR$\PROJECT\data\data.c + $PROJ_DIR$\PROJECT\data\data.h + $PROJ_DIR$\PROJECT\data\datadesc.c + $PROJ_DIR$\PROJECT\data\datadesc.h + $PROJ_DIR$\PROJECT\data\fram_map.h + $PROJ_DIR$\PROJECT\menu\menu.c + $PROJ_DIR$\PROJECT\menu\menu.h + $PROJ_DIR$\PROJECT\menu\menudesc.c + $PROJ_DIR$\PROJECT\menu\menudesc.h + $PROJ_DIR$\PROJECT\service\coin.c + $PROJ_DIR$\PROJECT\service\coin.h + $PROJ_DIR$\PROJECT\service\fr.c + $PROJ_DIR$\PROJECT\service\fr.h + $PROJ_DIR$\PROJECT\service\mode.c + $PROJ_DIR$\PROJECT\service\mode.h + $PROJ_DIR$\PROJECT\service\time.c + $PROJ_DIR$\PROJECT\service\time.h + $PROJ_DIR$\PROJECT\service\validator.c + $PROJ_DIR$\PROJECT\service\validator.h + $PROJ_DIR$\PROJECT\tools\crc16.c + $PROJ_DIR$\PROJECT\tools\crc16.h + $PROJ_DIR$\PROJECT\version.h + $PROJ_DIR$\Flash\Obj\os_task.pbi + $PROJ_DIR$\Flash\Obj\os_time.pbi + $PROJ_DIR$\Flash\Obj\os_tmr.o + $PROJ_DIR$\Flash\Obj\menudesc.pbi + $PROJ_DIR$\Flash\Obj\journal.pbi + $PROJ_DIR$\Flash\Obj\lib_mem.o + $PROJ_DIR$\Flash\Obj\coin.o + $PROJ_DIR$\Flash\Obj\os_cpu_c.o + $PROJ_DIR$\Flash\Obj\os_sem.o + $PROJ_DIR$\Flash\Obj\os_mutex.o + $PROJ_DIR$\Flash\Obj\validator.o + $PROJ_DIR$\Flash\Obj\time.pbi + $TOOLKIT_DIR$\inc\string.h + $PROJ_DIR$\Flash\Obj\keyboard.o + $TOOLKIT_DIR$\inc\c\ycheck.h + $TOOLKIT_DIR$\inc\c\xlocaleuse.h + + + [ROOT_NODE] + + + ILINK + 160 + + + + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + + + ICCARM + 156 + + + BICOMP + 179 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 4 2 218 3 91 89 94 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 4 2 218 3 91 89 94 + + + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + + + ICCARM + 122 + + + BICOMP + 158 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 3 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 3 + + + + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + + + ICCARM + 164 + + + BICOMP + 159 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 8 6 212 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 8 6 212 + + + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + + + ICCARM + 136 + + + BICOMP + 163 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 8 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 8 + + + + + $PROJ_DIR$\DRIVERS\fram\fram.c + + + ICCARM + 116 + + + BICOMP + 120 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 12 10 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 12 10 + + + + + $PROJ_DIR$\DRIVERS\fram\spi.c + + + ICCARM + 126 + + + BICOMP + 125 + + + + + ICCARM + 28 149 191 22 24 38 155 236 56 44 60 134 133 97 106 30 32 12 + + + BICOMP + 28 149 191 22 24 38 155 236 56 44 134 133 97 106 30 32 12 + + + + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + + + ICCARM + 235 + + + BICOMP + 115 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 14 193 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 14 193 + + + + + $PROJ_DIR$\DRIVERS\lcd\lcd.c + + + ICCARM + 174 + + + BICOMP + 110 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 111 16 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 111 16 + + + + + $PROJ_DIR$\DRIVERS\modem\modem.c + + + ICCARM + 114 + + + BICOMP + 74 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 18 199 193 201 203 195 20 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 18 199 193 201 203 195 20 + + + + + $PROJ_DIR$\DRIVERS\modem\uart2.c + + + ICCARM + 105 + + + BICOMP + 48 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 20 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 20 + + + + + $PROJ_DIR$\OS\app\app.c + + + ICCARM + 64 + + + BICOMP + 77 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 16 12 14 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 16 12 14 + + + + + $PROJ_DIR$\OS\bsp\bsp.c + + + ICCARM + 151 + + + BICOMP + 58 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 + + + + + $PROJ_DIR$\OS\bsp\cstartup.s + + + AARM + 169 + + + + + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + + + AARM + 123 + + + + + $PROJ_DIR$\OS\uc\lib\lib_mem.c + + + ICCARM + 227 + + + BICOMP + 84 + + + + + ICCARM + 35 30 32 33 22 + + + BICOMP + 35 30 32 33 22 + + + + + $PROJ_DIR$\OS\uc\lib\lib_str.c + + + ICCARM + 147 + + + BICOMP + 117 + + + + + ICCARM + 37 30 32 33 22 155 236 56 44 60 134 133 97 106 82 80 152 51 237 148 43 92 88 132 99 + + + BICOMP + 37 30 32 33 22 155 236 56 44 134 133 97 106 82 80 152 51 237 148 43 92 88 132 99 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + + + AARM + 140 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + + + ICCARM + 229 + + + BICOMP + 65 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + + + ICCARM + 68 + + + BICOMP + 63 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\Flash\Obj\solarium.pbd + + + BILINK + 179 77 141 58 154 50 85 45 172 159 144 120 226 115 110 84 117 52 225 153 74 157 55 65 63 113 130 176 75 102 112 47 222 223 161 125 233 163 158 48 162 + + + + + $PROJ_DIR$\DRIVERS\lcd.c + + + ICCARM + 174 + + + BICOMP + 110 + + + + + ICCARM + 23 137 70 128 69 138 103 107 100 61 234 54 76 96 62 87 57 146 49 145 46 28 81 191 22 24 38 30 32 33 35 37 59 166 26 73 72 + + + BICOMP + 23 137 70 128 69 103 107 100 61 234 54 76 96 62 87 57 146 49 145 46 28 81 191 22 24 38 30 32 33 35 37 59 166 26 73 72 + + + + + $PROJ_DIR$\DRIVERS\ccnet\Command.c + + + BICOMP + 42 + + + + + ICCARM + 129 137 70 128 69 138 103 107 100 61 + + + BICOMP + 129 137 70 128 69 103 107 100 61 + + + + + $PROJ_DIR$\Flash\Exe\solarium.out + + + OBJCOPY + 109 + + + + + ILINK + 29 156 64 131 151 228 121 123 171 169 178 104 164 95 116 78 235 174 227 147 83 135 177 114 139 90 140 229 68 86 71 173 143 231 66 230 67 165 224 126 142 136 122 105 232 127 175 93 98 + + + + + $PROJ_DIR$\DRIVERS\modem\uart.c + + + ICCARM + 170 + + + BICOMP + 167 + + + + + ICCARM + 23 137 70 128 69 138 103 107 100 61 234 54 76 96 62 87 57 146 49 145 46 28 81 191 22 24 38 30 32 33 35 37 59 166 26 108 + + + BICOMP + 23 137 70 128 69 103 107 100 61 234 54 76 96 62 87 57 146 49 145 46 28 81 191 22 24 38 30 32 33 35 37 59 166 26 108 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + + + ICCARM + 86 + + + BICOMP + 113 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + + + ICCARM + 90 + + + BICOMP + 55 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + + + ICCARM + 71 + + + BICOMP + 130 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + + + ICCARM + 173 + + + BICOMP + 176 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + + + ICCARM + 143 + + + BICOMP + 75 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + + + ICCARM + 231 + + + BICOMP + 102 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + + + ICCARM + 66 + + + BICOMP + 112 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + + + ICCARM + 230 + + + BICOMP + 47 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + + + ICCARM + 67 + + + BICOMP + 222 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + + + ICCARM + 165 + + + BICOMP + 223 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + + + ICCARM + 224 + + + BICOMP + 161 + + + + + ICCARM + 191 22 24 38 + + + BICOMP + 191 22 24 38 + + + + + $PROJ_DIR$\PROJECT\app\app_serv.c + + + ICCARM + 131 + + + BICOMP + 141 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 18 218 210 216 6 206 201 214 208 197 195 203 4 212 220 199 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 18 218 210 216 6 206 201 214 208 197 195 203 4 212 220 199 + + + + + $PROJ_DIR$\PROJECT\app\control.c + + + ICCARM + 121 + + + BICOMP + 50 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 195 201 203 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 195 201 203 + + + + + $PROJ_DIR$\PROJECT\app\journal.c + + + ICCARM + 78 + + + BICOMP + 226 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 101 197 195 6 10 204 203 201 216 212 220 214 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 101 197 195 6 10 204 203 201 216 212 220 214 + + + + + $PROJ_DIR$\PROJECT\app\modem_task.c + + + ICCARM + 139 + + + BICOMP + 157 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 197 195 6 18 199 193 201 203 216 + + + + + $PROJ_DIR$\PROJECT\data\data.c + + + ICCARM + 178 + + + BICOMP + 45 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 201 203 195 10 216 101 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 201 203 195 10 216 101 + + + + + $PROJ_DIR$\PROJECT\data\datadesc.c + + + ICCARM + 104 + + + BICOMP + 172 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 201 203 195 206 208 197 6 204 101 216 220 199 193 18 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 201 203 195 206 208 197 6 204 101 216 220 199 193 18 + + + + + $PROJ_DIR$\PROJECT\menu\menu.c + + + ICCARM + 83 + + + BICOMP + 52 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 206 208 197 195 6 201 14 16 214 193 216 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 206 208 197 195 6 201 14 16 214 193 216 + + + + + $PROJ_DIR$\PROJECT\menu\menudesc.c + + + ICCARM + 135 + + + BICOMP + 225 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 206 208 197 195 6 201 203 216 214 221 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 206 208 197 195 6 201 203 216 214 221 + + + + + $PROJ_DIR$\PROJECT\service\coin.c + + + ICCARM + 228 + + + BICOMP + 154 + + + + + ICCARM + 28 149 191 22 24 38 30 32 193 210 201 203 195 18 + + + BICOMP + 28 149 191 22 24 38 30 32 193 210 201 203 195 18 + + + + + $PROJ_DIR$\PROJECT\service\fr.c + + + ICCARM + 95 + + + BICOMP + 144 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 6 212 8 201 203 195 197 216 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 193 6 212 8 201 203 195 197 216 + + + + + $PROJ_DIR$\PROJECT\service\mode.c + + + ICCARM + 177 + + + BICOMP + 153 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 214 193 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 214 193 + + + + + $PROJ_DIR$\PROJECT\service\time.c + + + ICCARM + 142 + + + BICOMP + 233 + + + + + ICCARM + 28 149 191 22 24 38 30 32 193 216 155 236 56 44 60 134 133 97 106 132 99 118 79 + + + BICOMP + 28 149 191 22 24 38 30 32 193 216 155 236 56 44 134 133 97 106 132 99 118 79 + + + + + $PROJ_DIR$\PROJECT\service\validator.c + + + ICCARM + 232 + + + BICOMP + 162 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 218 4 3 193 197 195 6 201 203 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 218 4 3 193 197 195 6 201 203 + + + + + $PROJ_DIR$\PROJECT\tools\crc16.c + + + ICCARM + 171 + + + BICOMP + 85 + + + + + ICCARM + 23 132 236 56 44 60 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 220 + + + BICOMP + 23 132 236 56 44 134 133 97 106 99 118 79 82 80 152 51 155 237 148 43 150 28 149 191 22 24 38 30 32 33 35 37 92 88 26 220 + + + + + + + diff --git a/.svn/pristine/c9/c9639f2f1bd663d2e2513d763834516c0a8616d3.svn-base b/.svn/pristine/c9/c9639f2f1bd663d2e2513d763834516c0a8616d3.svn-base new file mode 100644 index 0000000..4f16231 --- /dev/null +++ b/.svn/pristine/c9/c9639f2f1bd663d2e2513d763834516c0a8616d3.svn-base @@ -0,0 +1,160 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include "cpu.h" +#include "app_serv.h" +#include "coin.h" +#include "data.h" +#include "datadesc.h" +#include "modem.h" + + +OS_STK CoinTaskStk[COIN_TASK_STK_SIZE]; + +void InitImpInput(void); + +CPU_INT32U CoinImpCounter; + +void CoinTask(void *p_arg) +{ + + while(1) + { + CPU_INT32U enable_coin; + OSTimeDly(100); + GetData(&EnableCoinDesc, &enable_coin, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable_coin) + { + if (GetCoinCount()) + { + PostUserEvent(EVENT_COIN_INSERTED); + } + } + else + { + CoinDisable(); + GetResetCoinCount(); + } + } + +} + +void CoinDisable(void) +{ + +} + +void CoinEnable(void) +{ + +} + +// +CPU_INT32U GetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +CPU_INT32U GetResetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + CoinImpCounter = 0; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +void InitCoin(void) +{ + CoinImpCounter = 0; + InitImpInput(); + + OSTaskCreate(CoinTask, (void *)0, (OS_STK *)&CoinTaskStk[COIN_TASK_STK_SIZE-1], COIN_TASK_PRIO); +} + + +void InputCapture_ISR(void) +{ + CPU_INT08U ir = T3IR; + static CPU_INT32U period = 0; + T3IR = 0xFF; + + if (ir & 0x10) + {// CR0 interrupt + + if (FIO0PIN_bit.P0_23) + {// + CPU_INT32U cr=T3CR0; + if (((cr-period) > COIN_IMP_MIN_LEN) + && ((cr-period) < COIN_IMP_MAX_LEN)) + CoinImpCounter++; + } + else + {// + period = T3CR0; + } + } +} + + +extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk); + +/* +P0.23 MK_P9 IMPULSE OUTPUT ( ) +P0.24 MK_P8 INHIBIT () +*/ +// +// CAP3.0 +void InitImpInput (void) +{ + #define INPUT_CAPTURE_FREQ 100000 // + + CPU_INT32U pclk_freq; + CPU_INT32U rld_cnts; + + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + PCONP_bit.PCTIM3 = 1; + PCLKSEL1_bit.PCLK_TIMER3 = 2; + + PINSEL1_bit.P0_23 = 0x3; + PINMODE1_bit.P0_23 = 0; + FIO0DIR_bit.P0_23 = 0; + FIO0MASK_bit.P0_23 = 0; + + pclk_freq = BSP_CPU_PclkFreq(23); + rld_cnts = pclk_freq / INPUT_CAPTURE_FREQ; + + T3CTCR_bit.CTM = 0; + T3CTCR_bit.CIS = 0; // select CAP3.0 input + T3PR = rld_cnts-1; + T3MCR = 0; + T3CCR = 0x07; + T3EMR = 0; + T3TCR = 0x03; + T3TCR = 0x01; + + VICINTSELECT &= ~(1 << VIC_TIMER3); + VICVECTADDR27 = (CPU_INT32U)InputCapture_ISR; + VICVECTPRIORITY27 = 10; + VICINTENABLE = (1 << VIC_TIMER3); + + T3IR = 0xFF; + + OS_EXIT_CRITICAL(); +} + diff --git a/.svn/pristine/cd/cd2b95272ebc90e94d6dee8f5c2f2913801e17bb.svn-base b/.svn/pristine/cd/cd2b95272ebc90e94d6dee8f5c2f2913801e17bb.svn-base new file mode 100644 index 0000000..04f4ce3 --- /dev/null +++ b/.svn/pristine/cd/cd2b95272ebc90e94d6dee8f5c2f2913801e17bb.svn-base @@ -0,0 +1,187 @@ +#include +#include "control.h" +#include "data.h" +#include "datadesc.h" +#include +#include + +/* +P2.2 MK_P73 1 +P0.9 MK_P76 2 +P0.8 MK_P77 3 +P0.7 MK_P78 4 +P0.6 MK_P79 5 +P0.5 MK_P80 6 +P0.4 MK_P81 7 +P4.28 MK_P82 8 +P1.27 MK_P43 9 +P1.28 MK_P44 10 +*/ + +CPU_INT16U ChannelStatus; // + + + +// +void ChannelOn(CPU_INT08U ch) +{ + ChannelStatus |= (1L << ch); + switch (ch) + { + case 0: + FIO2SET_bit.P2_2 = 1; + break; + case 1: + FIO0SET_bit.P0_9 = 1; + break; + case 2: + FIO0SET_bit.P0_8 = 1; + break; + case 3: + FIO0SET_bit.P0_7 = 1; + break; + case 4: + FIO0SET_bit.P0_6 = 1; + break; + case 5: + FIO0SET_bit.P0_5 = 1; + break; + case 6: + FIO0SET_bit.P0_4 = 1; + break; + case 7: + FIO4SET_bit.P4_28 = 1; + break; + case 8: + FIO1SET_bit.P1_27 = 1; + break; + case 9: + FIO1SET_bit.P1_28 = 1; + break; + } +} + +// +void ChannelOff(CPU_INT08U ch) +{ + ChannelStatus &= ~(1L << ch); + switch (ch) + { + case 0: + FIO2CLR_bit.P2_2 = 1; + break; + case 1: + FIO0CLR_bit.P0_9 = 1; + break; + case 2: + FIO0CLR_bit.P0_8 = 1; + break; + case 3: + FIO0CLR_bit.P0_7 = 1; + break; + case 4: + FIO0CLR_bit.P0_6 = 1; + break; + case 5: + FIO0CLR_bit.P0_5 = 1; + break; + case 6: + FIO0CLR_bit.P0_4 = 1; + break; + case 7: + FIO4CLR_bit.P4_28 = 1; + break; + case 8: + FIO1CLR_bit.P1_27 = 1; + break; + case 9: + FIO1CLR_bit.P1_28 = 1; + break; + } +} + + + +// +void InitChannels(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + // 1 + PINSEL4_bit.P2_2 = 0x0; + PINMODE4_bit.P2_2 = 0; + FIO2DIR_bit.P2_2 = 1; + FIO2MASK_bit.P2_2 = 0; + FIO2CLR_bit.P2_2 = 1; + + // 2 + PINSEL0_bit.P0_9 = 0x0; + PINMODE0_bit.P0_9 = 0; + FIO0DIR_bit.P0_9 = 1; + FIO0MASK_bit.P0_9 = 0; + FIO0CLR_bit.P0_9 = 1; + + // 3 + PINSEL0_bit.P0_8 = 0x0; + PINMODE0_bit.P0_8 = 0; + FIO0DIR_bit.P0_8 = 1; + FIO0MASK_bit.P0_8 = 0; + FIO0CLR_bit.P0_8 = 1; + + // 4 + PINSEL0_bit.P0_7 = 0x0; + PINMODE0_bit.P0_7 = 0; + FIO0DIR_bit.P0_7 = 1; + FIO0MASK_bit.P0_7 = 0; + FIO0CLR_bit.P0_7 = 1; + + // 5 + PINSEL0_bit.P0_6 = 0x0; + PINMODE0_bit.P0_6 = 0; + FIO0DIR_bit.P0_6 = 1; + FIO0MASK_bit.P0_6 = 0; + FIO0CLR_bit.P0_6 = 1; + + // 6 + PINSEL0_bit.P0_5 = 0x0; + PINMODE0_bit.P0_5 = 0; + FIO0DIR_bit.P0_5 = 1; + FIO0MASK_bit.P0_5 = 0; + FIO0CLR_bit.P0_5 = 1; + + // 7 + PINSEL0_bit.P0_4 = 0x0; + PINMODE0_bit.P0_4 = 0; + FIO0DIR_bit.P0_4 = 1; + FIO0MASK_bit.P0_4 = 0; + FIO0CLR_bit.P0_4 = 1; + + // 8 + PINSEL9_bit.P4_28 = 0x0; + PINMODE9_bit.P4_28 = 0; + FIO4DIR_bit.P4_28 = 1; + FIO4MASK_bit.P4_28 = 0; + FIO4CLR_bit.P4_28 = 1; + + // 9 + PINSEL3_bit.P1_27 = 0x0; + PINMODE3_bit.P1_27 = 0; + FIO1DIR_bit.P1_27 = 1; + FIO1MASK_bit.P1_27 = 0; + FIO1CLR_bit.P1_27 = 1; + + // 10 + PINSEL3_bit.P1_28= 0x0; + PINMODE3_bit.P1_28 = 0; + FIO1DIR_bit.P1_28 = 1; + FIO1MASK_bit.P1_28 = 0; + FIO1CLR_bit.P1_28 = 1; + + OS_EXIT_CRITICAL(); +} + + diff --git a/.svn/pristine/cd/cd652f769469213541991ccf2bdebe991b120469.svn-base b/.svn/pristine/cd/cd652f769469213541991ccf2bdebe991b120469.svn-base new file mode 100644 index 0000000..5803042 --- /dev/null +++ b/.svn/pristine/cd/cd652f769469213541991ccf2bdebe991b120469.svn-base @@ -0,0 +1,333 @@ +#include +#include +#include "lcd.h" + +const unsigned char rus_sym_table[64]= + { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, + 0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, + 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, + 0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1, + 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, + 0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0, + 0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 }; + + +void us_delay(unsigned long x) +{ + while (x--) + { + for (int i=0; i<5; i++) __no_operation(); + } +} + + +void LCD_putch(unsigned char data) +{ + if (data >= 0xC0) data = rus_sym_table[data-0xC0]; + + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(100); +// OSTimeDly(1); // Wait for busy flag (BF) +} + +void LCD_putch_table(unsigned char data) +{ + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(100); +// OSTimeDly(1); // Wait for busy flag (BF) +} + +unsigned char LCD_getch() +{ + unsigned char data_h, data_l; + LCD_SET_DATA_IN(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_SET_RW_PIN(); + + us_delay(1); + data_h = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + data_l = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(100); + + return (data_h << 4) | data_l; +} + + +unsigned char LCD_get_status() +{ + unsigned char data_h, data_l; + LCD_SET_DATA_IN(); + // LCD Upper 4 bits data + LCD_CLR_RS_PIN(); // RS = 0, E = 1 + LCD_SET_E_PIN(); + LCD_SET_RW_PIN(); + + us_delay(1); + data_h = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 0, E = 1 + us_delay(1); + data_l = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(100); + + return (data_h << 4) | data_l; +} + +void LCD_putcmd(unsigned char data,unsigned char cmdtype) +{ + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_CLR_RS_PIN(); // RS = 0, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + // E=0; write data + LCD_CLR_E_PIN(); + + // cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes + if (cmdtype == LCD_2CYCLE) { + // LCD Lower 4 bits data + us_delay(1); + LCD_SET_E_PIN(); // RS = 0, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + // E=0; write data + LCD_CLR_E_PIN(); + + us_delay(1); + + //while(LCD_get_status() & 0x80); + OSTimeDly(2); // Wait for busy flag (BF) + + //LCD_get_status(); + } +} + + +void InitLcdPins() +{ + /* +P2.8 MK_P65 A0 +P2.7 MK_P66 E +P2.6 MK_P67 R_W +P0.19 MK_P59 DB4 +P0.20 MK_P58 DB5 +P0.21 MK_P57 DB6 +P0.22 MK_P56 DB7 + */ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + + PINSEL4_bit.P2_8 = 0x0; + PINSEL4_bit.P2_7 = 0x0; + PINSEL4_bit.P2_6 = 0x0; + + PINMODE4_bit.P2_8 = 0; + PINMODE4_bit.P2_7 = 0; + PINMODE4_bit.P2_6 = 0; + + FIO2DIR_bit.P2_8 = 1; + FIO2DIR_bit.P2_7 = 1; + FIO2DIR_bit.P2_6 = 1; + + FIO2MASK_bit.P2_8 = 0; + FIO2MASK_bit.P2_7 = 0; + FIO2MASK_bit.P2_6 = 0; + + PINSEL1_bit.P0_19 = 0x0; + PINSEL1_bit.P0_20 = 0x0; + PINSEL1_bit.P0_21 = 0x0; + PINSEL1_bit.P0_22 = 0x0; + + PINMODE1_bit.P0_19 = 0; + PINMODE1_bit.P0_20 = 0; + PINMODE1_bit.P0_21 = 0; + PINMODE1_bit.P0_22 = 0; + + FIO0DIR_bit.P0_19 = 1; + FIO0DIR_bit.P0_20 = 1; + FIO0DIR_bit.P0_21 = 1; + FIO0DIR_bit.P0_22 = 1; + + FIO0MASK_bit.P0_19 = 0; + FIO0MASK_bit.P0_20 = 0; + FIO0MASK_bit.P0_21 = 0; + FIO0MASK_bit.P0_22 = 0; + + LCD_CLR_E_PIN(); + LCD_CLR_RW_PIN(); + LCD_CLR_RS_PIN(); + + OS_EXIT_CRITICAL(); +} + +unsigned char test = 0; + +void InitLcd() +{ + InitLcdPins(); + + // Wait for more than 15 ms after VCC rises to 4.5 V + OSTimeDly(30); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Function set: Set interface to be 4 bits long (only 1 cycle write). + LCD_putcmd(0x20,LCD_1CYCLE); + us_delay(40); + // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font) + LCD_putcmd(0x28,LCD_2CYCLE); + // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off + LCD_putcmd(0x08,LCD_2CYCLE); + // Display Clear + LCD_putcmd(0x01,LCD_2CYCLE); + // Entry Mode Set: I/D=1; Increment, S=0; No shift + LCD_putcmd(0x06,LCD_2CYCLE); + // Display On, Cursor Off + LCD_putcmd(0x0C,LCD_2CYCLE); + + +} + +void LCD_gotoline(unsigned char n) +{ + switch (n){ + case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); break; + case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); break; + case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); break; + case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); break; + default: return; + } +} + +// n +void LCD_puts(unsigned char *s, unsigned char n) +{ + unsigned char i; + LCD_gotoline(n); + + i=0; + while((*s != 0) && (*s != '\n') && (i<20)) + { + LCD_putch(*s); + s++; + i++; + } + + while(i<20) + { + LCD_putch(' '); + i++; + } +} + + +void LCD_goto(unsigned char m, unsigned char n) +{ + switch (n){ + case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); break; + case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); break; + case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); break; + case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); break; + default: return; + } +} + +// n m +void LCD_putc(unsigned char c, unsigned char m, unsigned char n) +{ + LCD_goto(m, n); + LCD_putch(c); +} + +// n m +void LCD_putc_embed(unsigned char c, unsigned char m, unsigned char n) +{ + LCD_goto(m, n); + LCD_putch_table(c); +} + + +void LCD_clear(void) +{ + // Display Clear + LCD_putcmd(0x01,LCD_2CYCLE); +} + +void LCD_cursor_on(void) +{ + LCD_putcmd(0x0F,LCD_2CYCLE); +} + +void LCD_cursor_off(void) +{ + LCD_putcmd(0x0C,LCD_2CYCLE); +} + diff --git a/.svn/pristine/d1/d1fb2da8a6aab19207d286c6671850857e05c271.svn-base b/.svn/pristine/d1/d1fb2da8a6aab19207d286c6671850857e05c271.svn-base new file mode 100644 index 0000000..fa4dcdc --- /dev/null +++ b/.svn/pristine/d1/d1fb2da8a6aab19207d286c6671850857e05c271.svn-base @@ -0,0 +1,626 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MESSAGE MAILBOX MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_MBOX.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if OS_MBOX_EN > 0 +/* +********************************************************************************************************* +* ACCEPT MESSAGE FROM MAILBOX +* +* Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(), +* OSMboxAccept() does not suspend the calling task if a message is not available. +* +* Arguments : pevent is a pointer to the event control block +* +* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared +* so the next time OSMboxAccept() is called, the mailbox will be empty. +* == (void *)0 if the mailbox is empty or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass the proper event pointer. +********************************************************************************************************* +*/ + +#if OS_MBOX_ACCEPT_EN > 0 +void *OSMboxAccept (OS_EVENT *pevent) +{ + void *pmsg; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pmsg = pevent->OSEventPtr; + pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ + OS_EXIT_CRITICAL(); + return (pmsg); /* Return the message received (or NULL) */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MESSAGE MAILBOX +* +* Description: This function creates a message mailbox if free event control blocks are available. +* +* Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If +* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox +* will be considered empty. +* +* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created mailbox +* == (OS_EVENT *)0 if no event control blocks were available +********************************************************************************************************* +*/ + +OS_EVENT *OSMboxCreate (void *pmsg) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { + pevent->OSEventType = OS_EVENT_TYPE_MBOX; + pevent->OSEventCnt = 0; + pevent->OSEventPtr = pmsg; /* Deposit message in event control block */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); + } + return (pevent); /* Return pointer to event control block */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MAIBOX +* +* Description: This function deletes a mailbox and readies all tasks pending on the mailbox. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mailbox. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the mailbox was deleted +* OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the mailbox was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the mailbox MUST check the return code of OSMboxPend(). +* 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted! +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the mailbox. +* 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in +* applications where the mailbox is used for mutual exclusion because the resource(s) +* will no longer be guarded by the mailbox. +********************************************************************************************************* +*/ + +#if OS_MBOX_DEL_EN > 0 +OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mailbox */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the mailbox */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mailbox */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON MAILBOX FOR A MESSAGE +* +* Description: This function waits for a message to be sent to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for a message to arrive at the mailbox up to the amount of time +* specified by this argument. If you specify 0, however, your task will wait +* forever at the specified mailbox or, until a message arrives. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the mailbox was aborted. +* OS_ERR_EVENT_TYPE Invalid event type +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : != (void *)0 is a pointer to the message received +* == (void *)0 if no message was received or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass the proper pointer to the event control block. +********************************************************************************************************* +*/ + +void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + void *pmsg; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((void *)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pmsg = pevent->OSEventPtr; + if (pmsg != (void *)0) { /* See if there is already a message */ + pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return the message received (or NULL) */ + } + OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we weren't given the message */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); /* Timed out, Make task ready */ + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that a timeout occured */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return ((void *)0); /* Return a NULL message */ + } + pmsg = OSTCBCur->OSTCBMsg; + OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */ + OSTCBCur->OSTCBStat = OS_STAT_RDY; + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return the message received */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A MESSAGE MAILBOX +* +* Description: This function aborts & readies any tasks currently waiting on a mailbox. This function +* should be used to fault-abort the wait on the mailbox, rather than to normally signal +* the mailbox via OSMboxPost() or OSMboxPostOpt(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* mailbox +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* mailbox +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the mailbox. +* OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the mailbox +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the mailbox, or upon error. +* > 0 if one or more tasks waiting on the mailbox are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_MBOX_PEND_ABORT_EN > 0 +INT8U OSMboxPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on mailbox? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on mailbox */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on mailbox */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on mailbox */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A MAILBOX +* +* Description: This function sends a message to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one +* message at a time and thus, the message MUST be consumed before you +* are allowed to send another one. +* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer +* +* Note(s) : 1) HPT means Highest Priority Task +********************************************************************************************************* +*/ + +#if OS_MBOX_POST_EN > 0 +INT8U OSMboxPost (OS_EVENT *pevent, void *pmsg) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ + return (OS_ERR_POST_NULL_PTR); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ + /* Ready HPT waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MBOX_FULL); + } + pevent->OSEventPtr = pmsg; /* Place message in mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A MAILBOX +* +* Description: This function sends a message to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. +* +* opt determines the type of POST performed: +* OS_POST_OPT_NONE POST to a single waiting task +* (Identical to OSMboxPost()) +* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox +* +* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one +* message at a time and thus, the message MUST be consumed before you +* are allowed to send another one. +* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer +* +* Note(s) : 1) HPT means Highest Priority Task +* +* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the +* interrupt disable time is proportional to the number of tasks waiting on the mailbox. +********************************************************************************************************* +*/ + +#if OS_MBOX_POST_OPT_EN > 0 +INT8U OSMboxPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ + return (OS_ERR_POST_NULL_PTR); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ + if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ + while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on mailbox */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + } + } else { /* No, Post to HPT waiting on mbox */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + } + OS_EXIT_CRITICAL(); + if ((opt & OS_POST_OPT_NO_SCHED) == 0) { /* See if scheduler needs to be invoked */ + OS_Sched(); /* Find HPT ready to run */ + } + return (OS_ERR_NONE); + } + if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MBOX_FULL); + } + pevent->OSEventPtr = pmsg; /* Place message in mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MESSAGE MAILBOX +* +* Description: This function obtains information about a message mailbox. +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* p_mbox_data is a pointer to a structure that will contain information about the message +* mailbox. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_MBOX_QUERY_EN > 0 +INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *p_mbox_data) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_mbox_data == (OS_MBOX_DATA *)0) { /* Validate 'p_mbox_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_mbox_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_mbox_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + p_mbox_data->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_MBOX_QUERY_EN */ +#endif /* OS_MBOX_EN */ diff --git a/.svn/pristine/d3/d39b196932415327da777405536bfe94b57f9a32.svn-base b/.svn/pristine/d3/d39b196932415327da777405536bfe94b57f9a32.svn-base new file mode 100644 index 0000000..318c379 --- /dev/null +++ b/.svn/pristine/d3/d39b196932415327da777405536bfe94b57f9a32.svn-base @@ -0,0 +1,189 @@ +#ifndef _DATADESC_H_ +#define _DATADESC_H_ + +#include "data.h" +#include "control.h" + +#define INCAS_SEND_FLAG 0x87654321 + +#define MAX_PRICE 9999 + +#define DEFAULT_PASSWORD 1111 +#define MASTER_PASSWORD 11300045//1234567890L + +// +typedef struct{ + // + CPU_INT32U Enable[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutBefore[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutAfter[CHANNELS_NUM]; + // , . + CPU_INT32U MaxWorkTime[CHANNELS_NUM]; + // , . + CPU_INT32U MinWorkTime[CHANNELS_NUM]; + // , + CPU_INT32U WeekEnd[CHANNELS_NUM]; + #define WEEKEND_NO 0 + #define WEEKEND_FRIDAY_SUNDAY 1 + #define WEEKEND_SATURDAY_SUNDAY 2 + #define WEEKEND_FRIDAY_SATURDAY 3 + #define WEEKEND_FRIDAY_MONDAY 4 + // + CPU_INT32U Name[CHANNELS_NUM]; + + // + #define PRICE_PERIODS_NUM 4 + CPU_INT32U T_Start_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_Start_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + // + CPU_INT32U Price_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U Price_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + + + +}TChannelConfig; + + + +// +typedef struct{ + CPU_INT32U EnableValidator; + CPU_INT32U EnableCoinAcceptor; + CPU_INT32U EnableModem; + CPU_INT32U EnableFiscal; + CPU_INT32U EnableFiscalDayClear; + CPU_INT32U ServiceName; + + CPU_INT32U CoinPerPulse; // + CPU_INT32U BillFormat; + + CPU_INT32U DisableFiscalErrors; // + + CPU_INT32U EnableEmailErrorSend; + CPU_INT32U EnableEmailStatSend; + CPU_INT32U EnableEmailJournalSend; + CPU_INT32U ClearJournalAfterSend; + CPU_INT32U StatSendHourMin; + + CPU_INT32U DeviceId; +}TDeviceConfig; + + +extern CPU_INT32U PeriodIndex; +extern CPU_INT32U ChannelIndex; +extern TDataDescStruct const DeviceIDDesc; + +extern TDataDescStruct const LastEmailSendTime; + +extern TDataDescStruct const ChannelIndexDesc; +extern TDataDescStruct const EnableChannelDesc; +extern TDataDescStruct const TimeOutBeforeDesc; +extern TDataDescStruct const TimeOutAfterDesc; +extern TDataDescStruct const MaxWorkTimeDesc; +extern TDataDescStruct const MinWorkTimeDesc; +extern TDataDescStruct const WeekEndDesc; +extern TDataDescStruct const DeferredStartDesc; + +extern TDataDescStruct const PeriodWeekendIndexDesc; +extern TDataDescStruct const PeriodWeekdaysIndexDesc; +extern TDataDescStruct const ServiceNameDesc; +extern TDataDescStruct const PassDesc; +extern TDataDescStruct const PassCRCDesc; +extern TDataDescStruct const PassTempDesc; +extern CPU_INT32U TempPass; +extern TDataDescStruct const PassTempDesc1; +extern TDataDescStruct const PassTempDesc2; + +extern TDataDescStruct const PriceWeekendDesc; +extern TDataDescStruct const PriceWeekdaysDesc; +extern TDataDescStruct const PriceTimeWeekendDesc; +extern TDataDescStruct const PriceTimeWeekdaysDesc; +extern TDataDescStruct const T_Start_WeekdaysDesc; +extern TDataDescStruct const T_End_WeekdaysDesc; +extern TDataDescStruct const T_Start_WeekendDesc; +extern TDataDescStruct const T_End_WeekendDesc; + +extern TDataDescStruct const EnableFiscalDesc; +extern TDataDescStruct const EnableCoinDesc; +extern TDataDescStruct const EnableModemDesc; +extern TDataDescStruct const EnableValidatorDesc; +extern TDataDescStruct const CoinPerPulseDesc; +extern TDataDescStruct const EnableFiscalDayClearDesc; + +extern TDataDescStruct const InitByDefaultDesc; +extern TDataDescStruct const PrintZReportDesc; +extern TDataDescStruct const PrintXReportDesc; + +extern TDataDescStruct const ErrorJournalIndexDesc; +extern TDataDescStruct const EventJournalIndexDesc; +extern TDataDescStruct const JournalEventTimeDesc; + +extern TDataDescStruct const JournalErrorNumberDesc0; +extern TDataDescStruct const JournalErrorNumberDesc1; +extern TDataDescStruct const JournalErrorTimeDesc; +extern TDataDescStruct const ClearJournalCmdDesc; + + +extern TDataDescStruct const SystemTimeDesc; +extern TDataDescStruct const SystemTimeEditDesc; + +extern const TDataDescArrayStruct AllDataArray[]; + +extern CPU_INT32U ErrorJournalIndex; +extern CPU_INT32U EventJournalIndex; + +extern TDataDescStruct const CounterRunDesc; +extern TDataDescStruct const CounterMoneyDesc; +extern TDataDescStruct const CounterTimeDesc; +extern TDataDescStruct const CounterChannelRunDesc; +extern TDataDescStruct const CounterChannelMoneyDesc; +extern TDataDescStruct const CounterChannelTimeDesc; +extern TDataDescStruct const ChannelStIndexDesc; +extern TDataDescStruct const ClearStatCmdDesc; +extern TDataDescStruct const BillFormatDesc; +extern TDataDescStruct const NameChannelDesc; + +extern TDataDescStruct const AcceptedMoneyDesc; +extern TDataDescStruct const AcceptedMoneyCRC16Desc; + +extern TDataDescStruct const DisableFiscalErrorsDesc; + +extern TDataDescStruct const StartButtonNameDesc; + +extern TDataDescStruct const EnableEmailErrorSendDesc; +extern TDataDescStruct const EnableEmailJournalSendDesc; +extern TDataDescStruct const ClearJournalAfterSendDesc; +extern TDataDescStruct const StatSendPeriodDesc; +extern TDataDescStruct const JournalErrorNumberDescEng; +extern TDataDescStruct const SendTestEmailDesc; +extern TDataDescStruct const ModemStatusDesc; + +extern TDataDescStruct const BillnomIndexDesc; +extern TDataDescStruct const BillnomDesc; +extern TDataDescStruct const BillnomCountersDesc; +extern TDataDescStruct const BillCounterDesc; + +extern TDataDescStruct const CounterLongRunDesc; +extern TDataDescStruct const CounterLongMoneyDesc; +extern TDataDescStruct const CounterLongTimeDesc; + +extern TDataDescStruct const MasterPassTempDesc; + +extern TDataDescStruct const CounterChannelRunLongDesc; +extern TDataDescStruct const CounterChannelMoneyLongDesc; +extern TDataDescStruct const CounterChannelTimeLongDesc; +extern TDataDescStruct const ChannelStLongIndexDesc; + +extern TDataDescStruct const StatSendHourMinDesc; +extern TDataDescStruct const IncasSendFlagDesc; +extern TDataDescStruct const IncasMoneyDesc; +extern TDataDescStruct const IncasTimeDesc; + + +#endif //#ifndef _DATADESC_H_ diff --git a/.svn/pristine/d4/d4ed29ba51d660b28eeda8c0fe14e0c0afa74c7a.svn-base b/.svn/pristine/d4/d4ed29ba51d660b28eeda8c0fe14e0c0afa74c7a.svn-base new file mode 100644 index 0000000..81a9f01 --- /dev/null +++ b/.svn/pristine/d4/d4ed29ba51d660b28eeda8c0fe14e0c0afa74c7a.svn-base @@ -0,0 +1,94 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include +#include "cpu.h" +#include "spi.h" + +OS_EVENT *SpiLock = NULL; + +unsigned char SpiExchange(unsigned char spi, unsigned char ch) +{ + SSP0DR = ch; + while(SSP0SR_bit.BSY); + return SSP0DR; +} + +void SpiInit(void) +{ + // on spi power + PCONP_bit.PCSSP0 = 1; + + // clk = cclk + PCLKSEL1_bit.PCLK_SSP0 = 1; + + // pin select + PINSEL0_bit.P0_15 = 0x2; + PINSEL1_bit.P0_16 = 0x0; // FRAM CS + PINSEL1_bit.P0_17 = 0x2; + PINSEL1_bit.P0_18 = 0x2; + + PINMODE0_bit.P0_15 = 2; + PINMODE1_bit.P0_16 = 0; + PINMODE1_bit.P0_17 = 2; + PINMODE1_bit.P0_18 = 2; + + // Chip select + FIO0MASK_bit.P0_16 = 0; + FIO0DIR_bit.P0_16 = 1; + FIO0SET_bit.P0_16 = 1; + + FIO0MASK_bit.P0_15 = 1; + FIO0MASK_bit.P0_17 = 1; + FIO0MASK_bit.P0_18 = 1; + + SSP0CR0_bit.DSS = 7; // 8-bit + SSP0CR0_bit.FRF = 0; // spi + SSP0CR0_bit.SPO = 0; + SSP0CR0_bit.SPH = 0; + SSP0CR0_bit.SCR = 1; + + SSP0CR1_bit.LBM = 0; + SSP0CR1_bit.SSE = 1; + SSP0CR1_bit.MS = 0; // master + SSP0CR1_bit.SOD = 0; + + SSP0CPSR_bit.CPSDVSR = 2; + + SSP0IMSC = 0; + SSP0DMACR = 0; + + if (!SpiLock) SpiLock = OSSemCreate(1); +} + + +unsigned char spi_selectChip(unsigned char spi) +{ + if (spi == FM25_SPI){ + FIO0CLR_bit.P0_16 = 1; + } + return 0; +} + +unsigned char spi_unselectChip(unsigned char spi) +{ + if (spi == FM25_SPI){ + FIO0SET_bit.P0_16 = 1; + } + return 0; +} + +void spi_getSem() +{ + CPU_INT08U err; + do{ + OSSemPend(SpiLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +void spi_freeSem() +{ + OSSemPost(SpiLock); +} + diff --git a/.svn/pristine/d7/d74b48545189b48d5cd436cc977bab84ff94f1f6.svn-base b/.svn/pristine/d7/d74b48545189b48d5cd436cc977bab84ff94f1f6.svn-base new file mode 100644 index 0000000..f6f4af1 --- /dev/null +++ b/.svn/pristine/d7/d74b48545189b48d5cd436cc977bab84ff94f1f6.svn-base @@ -0,0 +1,357 @@ +#include +#include "data.h" +#include "datadesc.h" +#include "fram.h" +#include "time.h" +#include +#include + + +// +int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + CPU_INT32U ofst = 0; + + // . + if (desc->IsArray) + { + if (flags == DATA_FLAG_DIRECT_INDEX) + { + ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index; + } + else + { + GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX); + ofst *= desc->ArrayOffset; + } + } + + // + if (desc->Location == DATA_LOC_RAM) + { + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + memcpy(&Val, (CPU_INT08U*)desc->Data+ofst, sizeof(CPU_INT32U)); + OS_EXIT_CRITICAL(); + } + else if (desc->Location == DATA_LOC_FRAM) + { + ReadArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val); + } + else return DATA_ERR; + + // + memcpy(buf, &Val, sizeof(CPU_INT32U)); + + return DATA_OK; +} + +// +int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + CPU_INT32U ofst = 0; + + if (desc->Desc == DATA_DESC_VIEW) return DATA_ERR; + + // + if (desc->RangeValue) + { + TVariant32 ValMin, ValMax; + TRangeValueULONG* RVal = desc->RangeValue; + + memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U)); + memcpy(&Val, buf, sizeof(CPU_INT32U)); + + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_TIME) + { + + } + else if (desc->Type == DATA_TYPE_HOUR_MIN) + { + if (Val.Val32U >= 24*60) return DATA_ERR; + } + else return DATA_ERR; + } + else + { + memcpy(&Val, buf, sizeof(CPU_INT32U)); + } + // . + if (desc->IsArray) + { + if (flags == DATA_FLAG_DIRECT_INDEX) + { + ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index; + } + else + { + GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX); + ofst *= desc->ArrayOffset; + } + } + + // + if (desc->Location == DATA_LOC_RAM) + { + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + memcpy((CPU_INT08U*)desc->Data+ofst, &Val, sizeof(CPU_INT32U)); + OS_EXIT_CRITICAL(); + } + else if (desc->Location == DATA_LOC_FRAM) + { + WriteArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val); + } + else return DATA_ERR; + + // + if (desc->OnchangeFunc) desc->OnchangeFunc(); + + // + return DATA_OK; +} + +// +int GetDataMax(const TDataDescStruct* desc, void* buf) +{ + if (desc->RangeValue) + { + TRangeValueULONG* RVal = desc->RangeValue; + memcpy(buf, &RVal->Max, sizeof(CPU_INT32U)); + } + else + { + *(CPU_INT32U*)&buf = 0; + } + return DATA_OK; +} + +// +int GetDataMin(const TDataDescStruct* desc, void* buf) +{ + if (desc->RangeValue) + { + TRangeValueULONG* RVal = desc->RangeValue; + memcpy(buf, &RVal->Min, sizeof(CPU_INT32U)); + } + else + { + *(CPU_INT32U*)&buf = 0; + } + return DATA_OK; +} + +// +int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + GetData(desc, &Val, index, flags); + + if (desc->Type == DATA_TYPE_ULONG) + { + if (desc->IsIndex) + { // + if (desc->RangeValue) + { + TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue; + if ((Val.Val32U >= range->Min) && (Val.Val32U <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]); + else {strcpy((char*)buf, ""); return DATA_ERR;} + } + else if (desc->Desc == DATA_DESC_VIEW) + { + strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]); + } + else + { + strcpy((char*)buf, ""); + } + } + else + { + sprintf((char*)buf, "%d", Val.Val32U); + } + } + else if (desc->Type == DATA_TYPE_SLONG) + { + sprintf((char*)buf, "%d", Val.Val32S); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + sprintf((char*)buf, "%0.3f", Val.ValFloat); + } + else if (desc->Type == DATA_TYPE_TIME) + { + PrintTimeString((char*)buf, Val.Val32U); + } + else if (desc->Type == DATA_TYPE_TIME_COUNT) + { + PrintSecToBigHourMinSec((char*)buf, Val.Val32U); + } + else if (desc->Type == DATA_TYPE_HOUR_MIN) + { + int min_ = Val.Val32U % 60; + int hour_ = Val.Val32U / 60; + sprintf((char*)buf, "%02d:%02d", hour_, min_); + } + else return DATA_ERR; + + return DATA_OK; +} + +// +int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags) +{ + GetDataNameStr(desc, buf); + if (desc->Name) + { + if (desc->IsIndex) strcat((char*)&buf[strlen((char*)buf)], " "); + else strcat((char*)&buf[strlen((char*)buf)], "="); + } + GetDataStr(desc, &buf[strlen((char*)buf)], index, flags); + return DATA_OK; +} + +// +int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf) +{ + if (desc->Name) strcpy((char*)buf, (char const*)desc->Name); + else strcpy((char*)buf, ""); + return DATA_OK; +} + + +// +int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex) +{ + if (!desc->IsIndex) {buf[0]=0;return DATA_ERR;} + + if (desc->Type != DATA_TYPE_ULONG) {buf[0]=0;return DATA_ERR;} + + // + if (desc->RangeValue) + { + TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue; + if ((itemindex >= range->Min) && (itemindex <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[itemindex]); + else return DATA_ERR; + } + else + { + strcpy((char*)buf, ""); + } + + return DATA_OK; +} + +// +int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index) +{ + SetData(desc, (void*)&desc->DefaultValue, index, DATA_FLAG_DIRECT_INDEX); + return DATA_OK; +} + +// +int InitData(const TDataDescStruct* desc) +{ + return DATA_OK; +} + +// +int CheckDataRange(const TDataDescStruct* desc) +{ + TVariant32 ValMin, ValMax, Val; + TRangeValueULONG* RVal = desc->RangeValue; + + if (!desc->RangeValue) return DATA_OK; + + memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U)); + + if (desc->IsArray) + { + for (int i = 0; i < desc->ArraySize; i++) + { + GetData(desc, &Val, i, DATA_FLAG_DIRECT_INDEX); + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, i); + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, i); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, i); + } + else return DATA_ERR; + } + } + else + { + GetData(desc, &Val, 0, DATA_FLAG_DIRECT_INDEX); + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, 0); + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, 0); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, 0); + } + else return DATA_ERR; + + } + + + return DATA_OK; +} + +// , +int InitDescByDefault(const TDataDescStruct* desc) +{ + if (desc->IsArray) + { + for (int i = 0; i < desc->ArraySize; i++) InitDataByDefault(desc, i); + } + else + { + InitDataByDefault(desc, 0); + } + + return DATA_OK; +} + +// +int CheckAllData(void) +{ + int i = 0; + while (AllDataArray[i].ptr != NULL) + { + CheckDataRange(AllDataArray[i].ptr); + i++; + } + + return DATA_OK; +} diff --git a/.svn/pristine/db/db30e0aced3e22c8591906a098ebb4039c299326.svn-base b/.svn/pristine/db/db30e0aced3e22c8591906a098ebb4039c299326.svn-base new file mode 100644 index 0000000..8a82785 --- /dev/null +++ b/.svn/pristine/db/db30e0aced3e22c8591906a098ebb4039c299326.svn-base @@ -0,0 +1,20 @@ +#ifndef _VALIDATOR_H_ +#define _VALIDATOR_H_ + +#define CC_VALIDATOR_SPEED 9600 +#define CC_POLL_TIME_OUT 150 +#define CC_BUS_RESET_TIME_OUT 100 + +#define VCONN_STATUS_CONN 0 +#define VCONN_STATUS_NOCONN 1 + +// +#define V_BILLS_NUMBER 24 + +extern void StartUpValidator(void); +extern int IsValidatorConnected(void); +extern void VPend(void); +extern void VPost(void); +extern CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index); + +#endif //#define _VALIDATOR_H_ diff --git a/.svn/pristine/db/db318d95ae10f93200cddb6618457ea06e3f0768.svn-base b/.svn/pristine/db/db318d95ae10f93200cddb6618457ea06e3f0768.svn-base new file mode 100644 index 0000000..bd09677 --- /dev/null +++ b/.svn/pristine/db/db318d95ae10f93200cddb6618457ea06e3f0768.svn-base @@ -0,0 +1,1070 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* TASK MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_TASK.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHANGE PRIORITY OF A TASK +* +* Description: This function allows you to change the priority of a task dynamically. Note that the new +* priority MUST be available. +* +* Arguments : oldp is the old priority +* +* newp is the new priority +* +* Returns : OS_ERR_NONE is the call was successful +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_PRIO_EXIST if the new priority already exist. +* OS_ERR_PRIO there is no task with the specified OLD priority (i.e. the OLD task does +* not exist. +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP. +********************************************************************************************************* +*/ + +#if OS_TASK_CHANGE_PRIO_EN > 0 +INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) +{ +#if OS_EVENT_EN + OS_EVENT *pevent; +#endif + OS_TCB *ptcb; + INT8U x; + INT8U y; +#if OS_LOWEST_PRIO <= 63 + INT8U bitx; + INT8U bity; +#else + INT16U bitx; + INT16U bity; +#endif + INT8U y_old; +#if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; /* Storage for CPU status register */ +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (oldprio >= OS_LOWEST_PRIO) { + if (oldprio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (newprio >= OS_LOWEST_PRIO) { + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); + } + if (oldprio == OS_PRIO_SELF) { /* See if changing self */ + oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ + } + ptcb = OSTCBPrioTbl[oldprio]; + if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Is task assigned to Mutex */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_TASK_NOT_EXIST); + } +#if OS_LOWEST_PRIO <= 63 + y = (INT8U)(newprio >> 3); /* Yes, compute new TCB fields */ + x = (INT8U)(newprio & 0x07); + bity = (INT8U)(1 << y); + bitx = (INT8U)(1 << x); +#else + y = (INT8U)((newprio >> 4) & 0x0F); + x = (INT8U)( newprio & 0x0F); + bity = (INT16U)(1 << y); + bitx = (INT16U)(1 << x); +#endif + + OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ + OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ + y_old = ptcb->OSTCBY; + if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0) { /* If task is ready make it not */ + OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y_old] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + OSRdyGrp |= bity; /* Make new priority ready to run */ + OSRdyTbl[y] |= bitx; + } +#if OS_EVENT_EN + pevent = ptcb->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { /* ... remove from event wait list */ + pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX; + if (pevent->OSEventTbl[y_old] == 0) { + pevent->OSEventGrp &= ~ptcb->OSTCBBitY; + } + pevent->OSEventGrp |= bity; /* Add new priority to wait list */ + pevent->OSEventTbl[y] |= bitx; + } +#endif + ptcb->OSTCBPrio = newprio; /* Set new task priority */ + ptcb->OSTCBY = y; + ptcb->OSTCBX = x; + ptcb->OSTCBBitY = bity; + ptcb->OSTCBBitX = bitx; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pstk' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EN > 0 +INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio) +{ + OS_STK *psp; + INT8U err; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + psp = OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK (Extended Version) +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. This function is similar to OSTaskCreate() except that it allows +* additional information about a task to be specified. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'ptos' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'ptos' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. 'ptos' MUST point to a valid 'free' data item. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* id is the task's ID (0..65535) +* +* pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* HIGHEST memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U, +* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to +* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if +* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries +* available on the stack. +* +* pext is a pointer to a user supplied memory location which is used as a TCB extension. +* For example, this user memory can hold the contents of floating-point registers +* during a context switch, the time each task takes to execute, the number of times +* the task has been switched-in, etc. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. Current choices are: +* +* OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task +* OS_TASK_OPT_STK_CLR Clear the stack when the task is created +* OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them +* during a context switch. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt) +{ + OS_STK *psp; + INT8U err; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + +#if OS_TASK_STAT_STK_CHK_EN > 0 + OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */ +#endif + + psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A TASK +* +* Description: This function allows you to delete a task. The calling task can delete itself by +* its own priority number. The deleted task is returned to the dormant state and can be +* re-activated by creating the deleted task again. +* +* Arguments : prio is the priority of the task to delete. Note that you can explicitely delete +* the current task without knowing its priority level by setting 'prio' to +* OS_PRIO_SELF. +* +* Returns : OS_ERR_NONE if the call is successful +* OS_ERR_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex PIP. +* OS_ERR_TASK_NOT_EXIST if the task you want to delete does not exist. +* OS_ERR_TASK_DEL_ISR if you tried to delete a task from an ISR +* +* Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task: +* a) by making it not ready +* b) by removing it from any wait lists +* c) by preventing OSTimeTick() from making the task ready to run. +* The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II. +* 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors, +* the next instruction following the enable interrupt instruction is ignored. +* 3) An ISR cannot delete a task. +* 4) The lock nesting counter is incremented because, for a brief instant, if the current +* task is being deleted, the current task would not be able to be rescheduled because it +* is removed from the ready list. Incrementing the nesting counter prevents another task +* from being schedule. This means that an ISR would return to the current task which is +* being deleted. The rest of the deletion would thus be able to be completed. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDel (INT8U prio) +{ +#if OS_EVENT_EN + OS_EVENT *pevent; +#endif +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + OS_FLAG_NODE *pnode; +#endif + OS_TCB *ptcb; + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if trying to delete from ISR */ + return (OS_ERR_TASK_DEL_ISR); + } + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */ + prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { /* Must not be assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + y = ptcb->OSTCBY; + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y] == 0) { /* Make task not ready */ + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + +#if OS_EVENT_EN + pevent = ptcb->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */ + pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX; + if (pevent->OSEventTbl[y] == 0) { /* ... remove task from ... */ + pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */ + } + } +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + pnode = ptcb->OSTCBFlagNode; + if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */ + OS_FlagUnlink(pnode); /* Remove from wait list */ + } +#endif + + ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (OSLockNesting < 255u) { /* Make sure we don't context switch */ + OSLockNesting++; + } + OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */ + OS_Dummy(); /* ... Dummy ensures that INTs will be */ + OS_ENTER_CRITICAL(); /* ... disabled HERE! */ + if (OSLockNesting > 0) { /* Remove context switch lock */ + OSLockNesting--; + } + OSTaskDelHook(ptcb); /* Call user defined hook */ + OSTaskCtr--; /* One less task being managed */ + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */ + if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */ + ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; + OSTCBList = ptcb->OSTCBNext; + } else { + ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; + ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; + } + ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */ + OSTCBFreeList = ptcb; +#if OS_TASK_NAME_SIZE > 1 + ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* REQUEST THAT A TASK DELETE ITSELF +* +* Description: This function is used to: +* a) notify a task to delete itself. +* b) to see if a task requested that the current task delete itself. +* This function is a little tricky to understand. Basically, you have a task that needs +* to be deleted however, this task has resources that it has allocated (memory buffers, +* semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these +* resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that +* the task needs to be deleted. Deleting of the task is however, deferred to the task to +* be deleted. For example, suppose that task #10 needs to be deleted. The requesting task +* example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls +* this function by specifying OS_PRIO_SELF and monitors the returned value. If the return +* value is OS_ERR_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like +* this: +* +* void Task(void *p_arg) +* { +* . +* . +* while (1) { +* OSTimeDly(1); +* if (OSTaskDelReq(OS_PRIO_SELF) == OS_ERR_TASK_DEL_REQ) { +* Release any owned resources; +* De-allocate any dynamic memory; +* OSTaskDel(OS_PRIO_SELF); +* } +* } +* } +* +* Arguments : prio is the priority of the task to request the delete from +* +* Returns : OS_ERR_NONE if the task exist and the request has been registered +* OS_ERR_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether +* the request has been executed. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex. +* OS_ERR_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL_REQ if a task (possibly another task) requested that the running task be +* deleted. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDelReq (INT8U prio) +{ + INT8U stat; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */ + OS_ENTER_CRITICAL(); /* ... this task to delete itself */ + stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */ + OS_EXIT_CRITICAL(); + return (stat); + } + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* Task must already be deleted */ + } + if (ptcb == OS_TCB_RESERVED) { /* Must NOT be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + ptcb->OSTCBDelReq = OS_ERR_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A TASK +* +* Description: This function is called to obtain the name of a task. +* +* Arguments : prio is the priority of the task that you want to obtain the name from. +* +* pname is a pointer to an ASCII string that will receive the name of the task. The +* string must be able to hold at least OS_TASK_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_NAME_GET_ISR You called this function from an ISR +* +* +* Returns : The length of the string or 0 if the task does not exist. +********************************************************************************************************* +*/ + +#if OS_TASK_NAME_SIZE > 1 +INT8U OSTaskNameGet (INT8U prio, INT8U *pname, INT8U *perr) +{ + OS_TCB *ptcb; + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return (0); + } + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if caller desires it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0); + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0); + } + len = OS_StrCopy(pname, ptcb->OSTCBTaskName); /* Yes, copy name from TCB */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A TASK +* +* Description: This function is used to set the name of a task. +* +* Arguments : prio is the priority of the task that you want the assign a name to. +* +* pname is a pointer to an ASCII string that contains the name of the task. The ASCII +* string must be NUL terminated. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_TASK_NAME_TOO_LONG if the name you are giving to the task exceeds the +* storage capacity of a task name as specified by +* OS_TASK_NAME_SIZE. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ +#if OS_TASK_NAME_SIZE > 1 +void OSTaskNameSet (INT8U prio, INT8U *pname, INT8U *perr) +{ + INT8U len; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return; + } + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + len = OS_StrLen(pname); /* Yes, Can we fit the string in the TCB? */ + if (len > (OS_TASK_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(ptcb->OSTCBTaskName, pname); /* Yes, copy to TCB */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* RESUME A SUSPENDED TASK +* +* Description: This function is called to resume a previously suspended task. This is the only call that +* will remove an explicit task suspension. +* +* Arguments : prio is the priority of the task to resume. +* +* Returns : OS_ERR_NONE if the requested task is resumed +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_RESUME_PRIO if the task to resume does not exist +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_TASK_NOT_SUSPENDED if the task to resume has not been suspended +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskResume (INT8U prio) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_RESUME_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */ + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_SUSPEND; /* Remove suspension */ + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is now ready */ + if (ptcb->OSTCBDly == 0) { + OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + } else { + OS_EXIT_CRITICAL(); + } + } else { /* Must be pending on event */ + OS_EXIT_CRITICAL(); + } + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_SUSPENDED); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* STACK CHECKING +* +* Description: This function is called to check the amount of free memory left on the specified task's +* stack. +* +* Arguments : prio is the task priority +* +* p_stk_data is a pointer to a data structure of type OS_STK_DATA. +* +* Returns : OS_ERR_NONE upon success +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP +* OS_ERR_TASK_OPT if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created +* OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer +********************************************************************************************************* +*/ +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data) +{ + OS_TCB *ptcb; + OS_STK *pchk; + INT32U free; + INT32U size; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_stk_data == (OS_STK_DATA *)0) { /* Validate 'p_stk_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + p_stk_data->OSFree = 0; /* Assume failure, set to 0 size */ + p_stk_data->OSUsed = 0; + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if check for SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Make sure task exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_OPT); + } + free = 0; + size = ptcb->OSTCBStkSize; + pchk = ptcb->OSTCBStkBottom; + OS_EXIT_CRITICAL(); +#if OS_STK_GROWTH == 1 + while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */ + free++; + } +#else + while (*pchk-- == (OS_STK)0) { + free++; + } +#endif + p_stk_data->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */ + p_stk_data->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */ + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND A TASK +* +* Description: This function is called to suspend a task. The task can be the calling task if the +* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF. +* +* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the +* calling task will suspend itself and rescheduling will occur. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed. +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_SUSPEND_PRIO if the task to suspend does not exist +* OS_ERR_TASK_NOT_EXITS if the task is assigned to a Mutex PIP +* +* Note : You should use this function with great care. If you suspend a task that is waiting for +* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from +* running when the event arrives. +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskSuspend (INT8U prio) +{ + BOOLEAN self; + OS_TCB *ptcb; + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to suspend idle task */ + return (OS_ERR_TASK_SUSPEND_IDLE); + } + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + self = OS_TRUE; + } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */ + self = OS_TRUE; + } else { + self = OS_FALSE; /* No suspending another task */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_SUSPEND_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + y = ptcb->OSTCBY; + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready */ + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */ + OS_EXIT_CRITICAL(); + if (self == OS_TRUE) { /* Context switch only if SELF */ + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A TASK +* +* Description: This function is called to obtain a copy of the desired task's TCB. +* +* Arguments : prio is the priority of the task to obtain information from. +* +* p_task_data is a pointer to where the desired task's OS_TCB will be stored. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_PRIO if the desired task has not been created +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_PDATA_NULL if 'p_task_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_TASK_QUERY_EN > 0 +INT8U OSTaskQuery (INT8U prio, OS_TCB *p_task_data) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_task_data == (OS_TCB *)0) { /* Validate 'p_task_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to query must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Task to query must not be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + /* Copy TCB into user storage area */ + OS_MemCopy((INT8U *)p_task_data, (INT8U *)ptcb, sizeof(OS_TCB)); + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR TASK STACK +* +* Description: This function is used to clear the stack of a task (i.e. write all zeros) +* +* Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the lowest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* highest memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* size is the number of 'stack elements' to clear. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. +* +* Returns : none +********************************************************************************************************* +*/ +#if OS_TASK_CREATE_EXT_EN > 0 +void OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt) +{ + if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000) { /* See if stack checking has been enabled */ + if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000) { /* See if stack needs to be cleared */ +#if OS_STK_GROWTH == 1 + while (size > 0) { /* Stack grows from HIGH to LOW memory */ + size--; + *pbos++ = (OS_STK)0; /* Clear from bottom of stack and up! */ + } +#else + while (size > 0) { /* Stack grows from LOW to HIGH memory */ + size--; + *pbos-- = (OS_STK)0; /* Clear from bottom of stack and down */ + } +#endif + } + } +} + +#endif diff --git a/.svn/pristine/dc/dc4804b90c7fe7025041acbb23d64c7d16602222.svn-base b/.svn/pristine/dc/dc4804b90c7fe7025041acbb23d64c7d16602222.svn-base new file mode 100644 index 0000000..69d63f4 --- /dev/null +++ b/.svn/pristine/dc/dc4804b90c7fe7025041acbb23d64c7d16602222.svn-base @@ -0,0 +1,52 @@ +#ifndef __APP_CFG_H__ +#define __APP_CFG_H__ + +/* +********************************************************************************************************* +* TASK PRIORITIES +********************************************************************************************************* +*/ + +#define APP_TASK_START_PRIO 5 +#define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2) + +#define USER_LOWEST_PRIO (OS_LOWEST_PRIO - 3) +#define USER_HIGHEST_PRIO 6 + + +/* +********************************************************************************************************* +* TASK STACK SIZES +********************************************************************************************************* +*/ + +#define APP_TASK_START_STK_SIZE 256 + +/* +********************************************************************************************************* +* uC/OS-II DCC CONFIGURATION +********************************************************************************************************* +*/ + +#define OS_CPU_ARM_DCC_EN 0 + +/* +********************************************************************************************************* +* TRACE / DEBUG CONFIGURATION +********************************************************************************************************* +*/ + +#define TRACE_LEVEL_OFF 0 +#define TRACE_LEVEL_INFO 1 +#define TRACE_LEVEL_DEBUG 2 + +#define APP_TRACE_LEVEL TRACE_LEVEL_DEBUG +#define APP_TRACE printf + +#define APP_TRACE_INFO(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(APP_TRACE x) : (void)0) +#define APP_TRACE_DEBUG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG) ? (void)(APP_TRACE x) : (void)0) + + + + +#endif diff --git a/.svn/pristine/dd/dd7db2bbe08cd7d495fd5d977d7e4d44b30852e4.svn-base b/.svn/pristine/dd/dd7db2bbe08cd7d495fd5d977d7e4d44b30852e4.svn-base new file mode 100644 index 0000000..6a63deb --- /dev/null +++ b/.svn/pristine/dd/dd7db2bbe08cd7d495fd5d977d7e4d44b30852e4.svn-base @@ -0,0 +1,93 @@ +[JLinkDriver] +WatchCond=_ 0 +Watch0=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0 +Watch1=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0 +[DebugChecksum] +Checksum=-1172248610 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Breakpoints] +Count=0 +[TraceHelper] +Enabled=0 +ShowSource=1 +[InterruptLog] +LogEnabled=0 +SumEnabled=0 +GraphEnabled=0 +ShowTimeLog=1 +ShowTimeSum=1 +SumSortOrder=0 +[Stack] +FillEnabled=0 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnLogOnly=1 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[Trace1] +Enabled=0 +ShowSource=1 +[Exceptions] +StopOnUncaught=_ 0 +StopOnThrow=_ 0 +[CallStack] +ShowArgs=0 +[Disassembly] +MixedMode=1 +[struct_types] +Fmt0=TFiscShortStatus-Mode 4 0 +Fmt1=TFiscShortStatus-OperatorNumber 4 0 +Fmt2=TFiscShortStatus-SubMode 4 0 +[array_types] +Fmt0=CPU_INT32U[8] 4 0 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[CallStackLog] +Enabled=0 +[DriverProfiling] +Enabled=0 +Mode=0 +Graph=0 +Symbiont=0 +[Disassemble mode] +mode=0 +[Breakpoints2] +Count=0 +[Aliases] +Count=0 +SuppressDialog=0 diff --git a/.svn/pristine/de/deb2b62607794fab47efe22fa6804994cf933c82.svn-base b/.svn/pristine/de/deb2b62607794fab47efe22fa6804994cf933c82.svn-base new file mode 100644 index 0000000..034b869 --- /dev/null +++ b/.svn/pristine/de/deb2b62607794fab47efe22fa6804994cf933c82.svn-base @@ -0,0 +1,106 @@ +#include +#include "uart1.h" + + +void Uart1_Send(unsigned char *buf, int len) +{ + while (len--) Uart1_WrByte(*buf++); +} + + +int Uart1_Receive(unsigned char *buf, int len, int timeout) +{ + while (len--) + { + if (!Uart1_RdByteWithTimeOut(buf++, timeout)) return 0; + } + return 1; +} + + +void Uart1_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(PCLK_UART1); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART1 = 1; /* Enable the power bit for UART0 */ + + U1LCR = 0x80; /* Enable acces to Divisor latches */ + + U1DLL = divlo; /* Load divisor */ + U1DLM = divhi; + + U1FDR = 0x10; + + U1LCR = 0; + + U1MCR = 0; + U1ACR = 0; + + U1FCR_bit.FCRFE = 1; // enable fifo + + U1LCR_bit.WLS = 0x03; // 8 bit + U1LCR_bit.SBS = 0; // 1 stop bit + + U1IER = 0; + + PINSEL4_bit.P2_0 = 0x2; + PINSEL4_bit.P2_1 = 0x2; + + PINMODE4_bit.P2_0 = 0; + PINMODE4_bit.P2_1 = 0; + + FIO2DIR_bit.P2_0 = 1; + FIO2DIR_bit.P2_1 = 0; + + FIO2MASK_bit.P2_0 = 1; + FIO2MASK_bit.P2_1 = 1; + + OS_EXIT_CRITICAL(); +} + +void Uart1_WrByte(CPU_INT08U tx_byte) +{ + while (!U1LSR_bit.THRE) { + OSTimeDly(1); + } + + U1THR = tx_byte; +} + +void Uart1_Purge(void) +{ + // + U1FCR_bit.RFR = 1; +} + +int Uart1_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout) +{ + CPU_INT32U ctr = 0; + + while (!U1LSR_bit.DR) { + OSTimeDly(1); + if (++ctr > timeout) return 0; + } + + //error = U1LSR; + *byte = (CPU_INT08U)(U1RBR & 0x00FF); /* Remove the data from the holding register */ + return 1; +} diff --git a/.svn/pristine/e0/e08eaa492f8c7c7dc1e0d421c2727fbb4454eb46.svn-base b/.svn/pristine/e0/e08eaa492f8c7c7dc1e0d421c2727fbb4454eb46.svn-base new file mode 100644 index 0000000..f3137d1 --- /dev/null +++ b/.svn/pristine/e0/e08eaa492f8c7c7dc1e0d421c2727fbb4454eb46.svn-base @@ -0,0 +1,77 @@ + + + + + + solarium/Flash + + + + + + + + + 283272727 + + + + + + 50362754 + + + + + + 2091624461 + 201222 + + + + + + + TabID-4922-2358 + Workspace + Workspace + + + solariumsolarium/DRIVERSsolarium/PROJECT + + + + 0 + + + TabID-31733-19868 + Find in Files + Find-in-Files + + + + TabID-17681-20541 + Build + Build + + + TabID-13605-29828Debug LogDebug-LogTabID-31897-1342BreakpointsBreakpoints + + 1 + + + + + + TextEditor$WS_DIR$\DRIVERS\fiscal\fiscal.h014887158715TextEditor$WS_DIR$\PROJECT\service\fr.c08812496224962TextEditor$WS_DIR$\PROJECT\data\datadesc.c04452034220342TextEditor$WS_DIR$\PROJECT\app\modem_task.c026196179617TextEditor$WS_DIR$\PROJECT\service\fr.h00299299TextEditor$WS_DIR$\DRIVERS\fiscal\fiscal.c07119141914TextEditor$WS_DIR$\PROJECT\app\app_serv.c04181587615876TextEditor$WS_DIR$\PROJECT\app\journal.c041894911TextEditor$WS_DIR$\PROJECT\menu\menudesc.c08943754337543TextEditor$WS_DIR$\PROJECT\data\datadesc.h013651025102TextEditor$WS_DIR$\PROJECT\version.h007777100100000010000001 + + + + + + + iaridepm.enu1-2-2673357-2-222401166670186979688776-2-22591922-2-2192426110020832663271166670 + + + + diff --git a/.svn/pristine/e3/e391c6b737a1e6b5b9f785b60123083c4670a8e7.svn-base b/.svn/pristine/e3/e391c6b737a1e6b5b9f785b60123083c4670a8e7.svn-base new file mode 100644 index 0000000..d744b19 --- /dev/null +++ b/.svn/pristine/e3/e391c6b737a1e6b5b9f785b60123083c4670a8e7.svn-base @@ -0,0 +1,1186 @@ +#include +#include "app_serv.h" +#include "modem.h" +#include "validator.h" +#include "coin.h" +#include "time.h" +#include "fiscal.h" +#include "menu.h" +#include "data.h" +#include "mode.h" +#include "menudesc.h" +#include "datadesc.h" +#include "control.h" +#include "validator.h" +#include "CCRSProtocol.h" +#include "menu.h" +#include "journal.h" +#include "fr.h" +#include "CRC16.h" +#include "modem_task.h" + +// , F1 +//#define _DEBUG_MONEY + +CPU_INT32U SystemTime; +CPU_INT08U EnabledChannelsNum; +CPU_INT08U RecentChannel; +CPU_INT08U UserMenuState; + #define USER_STATE_FIRST_PAGE 0 + #define USER_STATE_ACCEPT_MONEY 1 + #define USER_STATE_SHOW_THANKS 2 +CPU_INT08U ThanksCtr; + +CPU_INT08U ChannelsState[CHANNELS_NUM]; + #define CHANNEL_STATE_EMPTY 0 + #define CHANNEL_STATE_PAUSE_BEFORE 1 + #define CHANNEL_STATE_WORK 2 + #define CHANNEL_STATE_PAUSE_AFTER 3 +CPU_INT32U ChannelsCounters[CHANNELS_NUM]; +CPU_INT32U ChannelsPayedTime[CHANNELS_NUM]; +CPU_INT32U ChannelsWaitDeffered[CHANNELS_NUM] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +extern CPU_INT32U BillNominals[24]; +CPU_INT32U incas_bill_nom_counter[24]; +CPU_INT32U incas_common_bill_counter; + +CPU_INT08U max_msg = 0; + +#define USER_QUERY_LEN 64 + +OS_STK UserTaskStk[USER_TASK_STK_SIZE]; +OS_EVENT *UserQuery = NULL; +void *UserTbl[USER_QUERY_LEN]; + +int GetUserEvent(int* event); +void UserPrintMoneyMenu(void); +void IncRecentChannel(void); +void DecRecentChannel(void); +void WorkServer(void); +void UserPrintThanksMenu(void); +void UserPrintFirstMenu(CPU_INT08U recentchannel); +void UserPrintErrorMenu(void); +CPU_INT32U GetChannelsTimeForFree(CPU_INT08U ch); +void LoadAcceptedMoney(void); +void SetAcceptedMoney(CPU_INT32U money); +void ClearAcceptedMoney(void); +CPU_INT32U GetAcceptedMoney(void); +void InitPass(void); +void UserPrintDeferredWaitMenu(int channel); + +static char incassation; +static char was_critical_error; +/*! + +*/ +void UserAppTask(void *p_arg) +{ + int event; + CPU_INT32U temp; + static CPU_INT08U fr_conn_ctr = 0; + + { + CPU_INT32U m=0; + GetData(&AcceptedMoneyDesc, &m, 0, DATA_FLAG_SYSTEM_INDEX); + if (m) + { + EnabledChannelsNum = 0; + for (CPU_INT08U i=0; i maxtime*60) + { + CoinDisable(); + } + else + { + CoinEnable(); + } + was_critical_error = 0; + } + } + else if (UserMenuState == USER_STATE_SHOW_THANKS) + { // "" + LED_off(); + CoinDisable(); + if (ThanksCtr) {UserPrintThanksMenu(); ThanksCtr--;} + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + else if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + LED_off(); + CoinDisable(); + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + break; + case EVENT_INCASSATION: + { + CPU_INT32U incas_sum = 0, temp; + for (CPU_INT32U i = 0; i < 24; i++) + { + CPU_INT32U val = 0; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + incas_sum += val*BillNominals[i]; + } + incassation = 1; + sprintf((char*)str_IncasMenu_3, " %u .", incas_sum); + // + GoToMenu(IncasMenuPanel); + // + SaveEventRecord(0, JOURNAL_EVENT_INCASSATION, incas_sum); + GetData(&BillCounterDesc, &incas_common_bill_counter, 0, DATA_FLAG_SYSTEM_INDEX); + for (CPU_INT32U i = 0; i < 24; i++) + { + GetData(&BillnomCountersDesc, &incas_bill_nom_counter[i], i, DATA_FLAG_DIRECT_INDEX); + } + + SetData(&IncasMoneyDesc, &incas_sum, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = GetTimeSec(); + SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = INCAS_SEND_FLAG; + SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + PostModemTask(MODEM_TASK_SEND_INCAS); + // + ClearBillnomCounter(); + } + break; + case EVENT_INCASSATION_FINISH: + incassation = 0; + GoToPreviousMenu(); + break; + case EVENT_MODE_CHANGE: + ReInitMenu(); + SaveEventRecord(0, JOURNAL_EVENT_CHANGE_MODE, GetMode()); + break; + case EVENT_COIN_INSERTED: + { + CPU_INT32U cpp = 1; + CPU_INT32U money, accmoney; + GetData(&CoinPerPulseDesc, &cpp, 0, DATA_FLAG_SYSTEM_INDEX); + money = cpp*GetResetCoinCount(); + accmoney = GetAcceptedMoney(); + accmoney += money; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_COIN, money); + + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if ((pricetime*accmoney*60)/price > maxtime*60) + { + CoinDisable(); + } + } + break; + case EVENT_BILL_ESCROW: + // + { + CPU_INT32U billnom_index; + CPU_INT32U billnom = GetResetBillCount(&billnom_index); + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff, accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + accmoney = GetAcceptedMoney(); + if ((pricetime*(accmoney+billnom)*60)/price > maxtime*60) + { + max_msg = 3; + if (IsValidatorConnected()) if (!CC_CmdReturn(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + else + { + max_msg = 0; + if (IsValidatorConnected()) if (!CC_CmdPack(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + } + break; + case EVENT_BILL_STACKED: + // + { + CPU_INT32U billnom_index; + CPU_INT32U note,accmoney; + note = GetResetBillCount(&billnom_index); + accmoney = GetAcceptedMoney(); + accmoney += note; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_NOTE, note); + IncBillnomCounter(billnom_index); + } + break; + + case EVENT_KEY_F1: + #ifdef _DEBUG_MONEY + { + CPU_INT32U accmoney; + accmoney = GetAcceptedMoney(); + accmoney += 10; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + } + #endif + break; + case EVENT_KEY_F2: + break; + case EVENT_KEY_F3: + break; + + case EVENT_KEY_LEFT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + DecRecentChannel(); + if (ChannelsWaitDeffered[RecentChannel] != 0) + { + UserPrintDeferredWaitMenu(RecentChannel); + RefreshMenu(); + } + else + { + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + break; + case EVENT_KEY_RIGHT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + IncRecentChannel(); + if (ChannelsWaitDeffered[RecentChannel] != 0) + { + UserPrintDeferredWaitMenu(RecentChannel); + RefreshMenu(); + } + else + { + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + break; + case EVENT_KEY_DOWN: + break; + case EVENT_KEY_UP: + break; + + case EVENT_KEY_STOP: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + break; + case EVENT_KEY_DEFERRED_CH1: + case EVENT_KEY_DEFERRED_CH2: + case EVENT_KEY_DEFERRED_CH3: + case EVENT_KEY_DEFERRED_CH4: + case EVENT_KEY_DEFERRED_CH5: + case EVENT_KEY_DEFERRED_CH6: + case EVENT_KEY_DEFERRED_CH7: + case EVENT_KEY_DEFERRED_CH8: + case EVENT_KEY_DEFERRED_CH9: + case EVENT_KEY_DEFERRED_CH10: + if (ChannelsWaitDeffered[event - EVENT_KEY_DEFERRED_CH1] != 0) + { + // + ChannelsWaitDeffered[event - EVENT_KEY_DEFERRED_CH1] = 0; + ChannelOn(event - EVENT_KEY_DEFERRED_CH1); + ChannelsCounters[event - EVENT_KEY_DEFERRED_CH1] = ChannelsPayedTime[event - EVENT_KEY_DEFERRED_CH1]; + ChannelsState[event - EVENT_KEY_DEFERRED_CH1] = CHANNEL_STATE_WORK; + // + SaveEventRecord(event - EVENT_KEY_DEFERRED_CH1, JOURNAL_EVENT_START_SESSION, ChannelsPayedTime[event - EVENT_KEY_DEFERRED_CH1]); + // "" + if (IsFiscalConnected()) + { + UserPrintThanksMenu(); + RefreshMenu(); + UserMenuState = USER_STATE_SHOW_THANKS; + } + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + } + ThanksCtr = 3; + LED_off(); + } + break; + case EVENT_KEY_START: + case EVENT_KEY_USER_START: + if (incassation) break; + if (GetMode() != MODE_WORK) + { + if (!FlagForPrintReport) break; + if (GetCurrentMenu() == xReportMenuPanel) + { // X- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportNoClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_X, GetTimeSec()); + GoToPreviousMenu(); + } + } + else if (GetCurrentMenu() == zReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec()); + GoToPreviousMenu(); + ClrFiscalErrorByCode(FR_ERROR_CODE_4e); + } + } + else if (GetCurrentMenu() == bufReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportsFromBuf(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec()); + GoToPreviousMenu(); + } + } + break; + } + + if (TstCriticalErrors()) + { + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + + // -------------------------- + // + // -------------------------- + + if (EnabledChannelsNum == 0) break; + + if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + if (IsChannelOn(RecentChannel)) break; + FPend(); + if ((CheckFiscalStatus() < 0) && (TstCriticalErrors())) + { + FPost(); + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + FPost(); + UserMenuState = USER_STATE_ACCEPT_MONEY; + UserPrintMoneyMenu(); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + CoinEnable(); + max_msg = 0; + break; + } + + + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { // + CPU_INT32U price=1, pricetime=0, mintime=0,accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + accmoney = GetAcceptedMoney(); + ChannelsPayedTime[RecentChannel] = (pricetime*accmoney*60)/price; + GetData(&MinWorkTimeDesc, &mintime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (ChannelsPayedTime[RecentChannel] >= mintime*60) + { // , + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + // + if (IsFiscalConnected()) + { + if (PrintFiscalBill(accmoney, ChannelsPayedTime[RecentChannel]) == 0) + { + SaveEventRecord(RecentChannel, JOURNAL_EVENT_PRINT_BILL, GetTimeSec()); + } + else + { + // + + } + } + IncCounter(RecentChannel, ChannelsPayedTime[RecentChannel], accmoney); + SetAcceptedMoney(0); + // + + CPU_INT32U deferred = 0; + GetData(&DeferredStartDesc, &deferred, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (deferred) + { + ChannelsCounters[RecentChannel] = 0; + ChannelsState[RecentChannel] = CHANNEL_STATE_PAUSE_BEFORE; + ChannelsWaitDeffered[RecentChannel] = 1; + LED_off(); + UserMenuState = USER_STATE_FIRST_PAGE; + } + else + { + ChannelsWaitDeffered[RecentChannel] = 0; + GetData(&TimeOutBeforeDesc, &ChannelsCounters[RecentChannel], RecentChannel, DATA_FLAG_DIRECT_INDEX); + ChannelsState[RecentChannel] = CHANNEL_STATE_PAUSE_BEFORE; + // "" + if (IsFiscalConnected()) + { + UserPrintThanksMenu(); + RefreshMenu(); + UserMenuState = USER_STATE_SHOW_THANKS; + } + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + } + ThanksCtr = 5; + } + } + else + { // + + + + } + break; + } + + + break; + + } + } + else + { + OSTimeDly(1); + } + } +} + +/*! + +*/ +void UserStartupFunc(void) +{ + // + InitMode(); + + // + CheckAllData(); + + // + CheckLongCounters(); + + // + LoadAcceptedMoney(); + + // + InitPass(); + + // + InitChannels(); + + // + PINSEL3_bit.P1_21 = 0x0; + PINMODE3_bit.P1_21 = 0; + FIO1DIR_bit.P1_21= 1; + FIO1MASK_bit.P1_21 = 0; + LED_off(); + + // + InitMenu(); + + OSTimeDly(1000); + + // + StartUpValidator(); + + OSTimeDly(10000); + InitFiscal(); + + // + InitRTC(); + + // + SaveEventRecord(0, JOURNAL_EVENT_DEVICE_ON, GetTimeSec()); + + CPU_INT32U enable; + GetData(&EnableModemDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + + // - + if (InitModem() != 0) + { + SetErrorFlag(ERROR_MODEM_CONN); + } + else + { + ClrErrorFlag(ERROR_MODEM_CONN); + } + + // + InitCoin(); + + // + if (UserQuery == NULL) + { + UserQuery = OSQCreate(&UserTbl[0], USER_QUERY_LEN); + OSTaskCreate(UserAppTask, (void *)0, (OS_STK *)&UserTaskStk[USER_TASK_STK_SIZE-1], USER_TASK_PRIO); + } + + SystemTime = GetTimeSec(); + + // , + if (GetMode() == MODE_WORK) {SetMenu(WORK_MENU);} + else SetMenu(SERVICE_MENU); +} + +int GetUserEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(UserQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + + +void PostUserEvent(int event) +{ + OSQPost(UserQuery, (void *)event); +} + + +void InitUserMenu(void) +{ + for (RecentChannel=0; RecentChannel 1) + { + GetDataStr(&NameChannelDesc, (CPU_INT08U*)buf, channel, DATA_FLAG_DIRECT_INDEX); + sprintf(&buf[strlen(buf)], " %d", channel+1); + } + else + { + sprintf(buf, " "); + } + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + + if (EnabledChannelsNum > 1) + { + sprintf(buf, " ."); + } + else + { + sprintf(buf, " "); + } + PrintUserMenuStr(buf, 3); + } +} + +void UserPrintMoneyMenu(void) +{ + char buf[32]; + CPU_INT32U accmoney; + + sprintf(buf, " "); + PrintUserMenuStr(buf, 0); + accmoney = GetAcceptedMoney(); + sprintf(buf, " %d .", accmoney); + PrintUserMenuStr(buf, 1); + + CPU_INT32U price=1, pricetime=0, time=0; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + time = (pricetime*accmoney*60)/price; + sprintf(buf, " %d:%02d", time/60, time%60); + PrintUserMenuStr(buf, 2); + + if (max_msg) + { + --max_msg; + sprintf(buf, " .."); + } + else + { + CPU_INT32U mintime=0, maxtime=0; + GetData(&MinWorkTimeDesc, &mintime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (EnabledChannelsNum > 1) sprintf(buf, ".%d ", RecentChannel+1); + else sprintf(buf, ""); + if (time >= mintime*60) + { + LED_on(); + if (time >= maxtime*60) sprintf(&buf[strlen(buf)], "."); + else sprintf(&buf[strlen(buf)], "."); + } + else + { + LED_off(); + sprintf(&buf[strlen(buf)], "."); + } + } + PrintUserMenuStr(buf, 3); +} + +// +void UserPrintErrorMenu(void) +{ + char buf[32]; + + if (TstErrorFlag(ERROR_VALIDATOR_CONN) || TstCriticalValidatorErrors()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + if (TstErrorFlag(ERROR_VALIDATOR_CONN)) + { + sprintf(buf, " "); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + } + else if (TstErrorFlag(ERROR_FR_CONN)) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + PrintUserMenuStr(buf, 3); + } + else if (TstCriticalFiscalError()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + CPU_INT08U errcode = 0; + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + GetFirstCriticalFiscalError(&errcode); + GetDataItem(&JournalErrorNumberDesc0, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 2); + GetDataItem(&JournalErrorNumberDesc1, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 3); + } + /* + else if (!FReportTest()) + { + sprintf(buf, "b "); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + */ +} + +// +int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time) +{ + TRTC_Data rtc; + + if (EnabledChannelsNum == 0) return -1; + + RTC_ReadTime(&rtc); + + // , + CPU_INT32U wend = 0; + CPU_INT08U iswend = 0; // + GetData(&WeekEndDesc, &wend, RecentChannel, DATA_FLAG_DIRECT_INDEX); + + switch (wend) + { + case WEEKEND_FRIDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day > 4)) iswend = 1; + break; + case WEEKEND_SATURDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_SATURDAY: + if ((rtc.day == 5) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_MONDAY: + if ((rtc.day > 4) || (rtc.day < 2)) iswend = 1; + break; + default: + iswend = 0; + break; + } + + // + CPU_INT08U i; + for (i=0; i= start) && (rtc.hour < end)){break;} + } + + if (i >= PRICE_PERIODS_NUM) return -2; + + // + if (iswend) + { + GetData(&PriceTimeWeekendDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekendDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + else + { + GetData(&PriceTimeWeekdaysDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekdaysDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + + return 0; +} + + +void IncRecentChannel(void) +{ + CPU_INT08U i; + + for (i=RecentChannel+1; i=0; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {break;} + } + + if (i>=0) {RecentChannel = i; return;} + + for (i=CHANNELS_NUM-1; i>RecentChannel; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {RecentChannel = i; return;} + } + +} + + +void WorkServer(void) +{ + for (CPU_INT08U i=0; i +#include +#include + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifdef OS_GLOBALS +#define OS_EXT +#else +#define OS_EXT extern +#endif + +#ifndef OS_FALSE +#define OS_FALSE 0u +#endif + +#ifndef OS_TRUE +#define OS_TRUE 1u +#endif + +#define OS_ASCII_NUL (INT8U)0 + +#define OS_PRIO_SELF 0xFFu /* Indicate SELF priority */ + +#if OS_TASK_STAT_EN > 0 +#define OS_N_SYS_TASKS 2u /* Number of system tasks */ +#else +#define OS_N_SYS_TASKS 1u +#endif + +#define OS_TASK_STAT_PRIO (OS_LOWEST_PRIO - 1) /* Statistic task priority */ +#define OS_TASK_IDLE_PRIO (OS_LOWEST_PRIO) /* IDLE task priority */ + +#if OS_LOWEST_PRIO <= 63 +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) /* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) /* Size of ready table */ +#else +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 16 + 1) /* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 16 + 1) /* Size of ready table */ +#endif + +#define OS_TASK_IDLE_ID 65535u /* ID numbers for Idle, Stat and Timer tasks */ +#define OS_TASK_STAT_ID 65534u +#define OS_TASK_TMR_ID 65533u + +#define OS_EVENT_EN (((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)) + +#define OS_TCB_RESERVED ((OS_TCB *)1) + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK STATUS (Bit definition for OSTCBStat) +********************************************************************************************************* +*/ +#define OS_STAT_RDY 0x00u /* Ready to run */ +#define OS_STAT_SEM 0x01u /* Pending on semaphore */ +#define OS_STAT_MBOX 0x02u /* Pending on mailbox */ +#define OS_STAT_Q 0x04u /* Pending on queue */ +#define OS_STAT_SUSPEND 0x08u /* Task is suspended */ +#define OS_STAT_MUTEX 0x10u /* Pending on mutual exclusion semaphore */ +#define OS_STAT_FLAG 0x20u /* Pending on event flag group */ + +#define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_FLAG) + +/* +********************************************************************************************************* +* TASK PEND STATUS (Status codes for OSTCBStatPend) +********************************************************************************************************* +*/ +#define OS_STAT_PEND_OK 0u /* Pending status OK, not pending, or pending complete */ +#define OS_STAT_PEND_TO 1u /* Pending timed out */ +#define OS_STAT_PEND_ABORT 2u /* Pending aborted */ + +/* +********************************************************************************************************* +* OS_EVENT types +********************************************************************************************************* +*/ +#define OS_EVENT_TYPE_UNUSED 0u +#define OS_EVENT_TYPE_MBOX 1u +#define OS_EVENT_TYPE_Q 2u +#define OS_EVENT_TYPE_SEM 3u +#define OS_EVENT_TYPE_MUTEX 4u +#define OS_EVENT_TYPE_FLAG 5u + +#define OS_TMR_TYPE 100u /* Used to identify Timers ... */ + /* ... (Must be different value than OS_EVENT_TYPE_xxx) */ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ +#define OS_FLAG_WAIT_CLR_ALL 0u /* Wait for ALL the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_AND 0u + +#define OS_FLAG_WAIT_CLR_ANY 1u /* Wait for ANY of the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_OR 1u + +#define OS_FLAG_WAIT_SET_ALL 2u /* Wait for ALL the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_AND 2u + +#define OS_FLAG_WAIT_SET_ANY 3u /* Wait for ANY of the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_OR 3u + + +#define OS_FLAG_CONSUME 0x80u /* Consume the flags if condition(s) satisfied */ + + +#define OS_FLAG_CLR 0u +#define OS_FLAG_SET 1u + +/* +********************************************************************************************************* +* Values for OSTickStepState +* +* Note(s): This feature is used by uC/OS-View. +********************************************************************************************************* +*/ + +#if OS_TICK_STEP_EN > 0 +#define OS_TICK_STEP_DIS 0u /* Stepping is disabled, tick runs as mormal */ +#define OS_TICK_STEP_WAIT 1u /* Waiting for uC/OS-View to set OSTickStepState to _ONCE */ +#define OS_TICK_STEP_ONCE 2u /* Process tick once and wait for next cmd from uC/OS-View */ +#endif + +/* +********************************************************************************************************* +* Possible values for 'opt' argument of OSSemDel(), OSMboxDel(), OSQDel() and OSMutexDel() +********************************************************************************************************* +*/ +#define OS_DEL_NO_PEND 0u +#define OS_DEL_ALWAYS 1u + +/* +********************************************************************************************************* +* OS???Pend() OPTIONS +* +* These #defines are used to establish the options for OS???PendAbort(). +********************************************************************************************************* +*/ +#define OS_PEND_OPT_NONE 0u /* NO option selected */ +#define OS_PEND_OPT_BROADCAST 1u /* Broadcast action to ALL tasks waiting */ + +/* +********************************************************************************************************* +* OS???PostOpt() OPTIONS +* +* These #defines are used to establish the options for OSMboxPostOpt() and OSQPostOpt(). +********************************************************************************************************* +*/ +#define OS_POST_OPT_NONE 0x00u /* NO option selected */ +#define OS_POST_OPT_BROADCAST 0x01u /* Broadcast message to ALL tasks waiting */ +#define OS_POST_OPT_FRONT 0x02u /* Post to highest priority task waiting */ +#define OS_POST_OPT_NO_SCHED 0x04u /* Do not call the scheduler if this option is selected */ + +/* +********************************************************************************************************* +* TASK OPTIONS (see OSTaskCreateExt()) +********************************************************************************************************* +*/ +#define OS_TASK_OPT_NONE 0x0000u /* NO option selected */ +#define OS_TASK_OPT_STK_CHK 0x0001u /* Enable stack checking for the task */ +#define OS_TASK_OPT_STK_CLR 0x0002u /* Clear the stack when the task is create */ +#define OS_TASK_OPT_SAVE_FP 0x0004u /* Save the contents of any floating-point registers */ + +/* +********************************************************************************************************* +* TIMER OPTIONS (see OSTmrStart() and OSTmrStop()) +********************************************************************************************************* +*/ +#define OS_TMR_OPT_NONE 0u /* No option selected */ + +#define OS_TMR_OPT_ONE_SHOT 1u /* Timer will not automatically restart when it expires */ +#define OS_TMR_OPT_PERIODIC 2u /* Timer will automatically restart when it expires */ + +#define OS_TMR_OPT_CALLBACK 3u /* OSTmrStop() option to call 'callback' w/ timer arg. */ +#define OS_TMR_OPT_CALLBACK_ARG 4u /* OSTmrStop() option to call 'callback' w/ new arg. */ + +/* +********************************************************************************************************* +* TIMER STATES +********************************************************************************************************* +*/ +#define OS_TMR_STATE_UNUSED 0u +#define OS_TMR_STATE_STOPPED 1u +#define OS_TMR_STATE_COMPLETED 2u +#define OS_TMR_STATE_RUNNING 3u + +/* +********************************************************************************************************* +* ERROR CODES +********************************************************************************************************* +*/ +#define OS_ERR_NONE 0u + +#define OS_ERR_EVENT_TYPE 1u +#define OS_ERR_PEND_ISR 2u +#define OS_ERR_POST_NULL_PTR 3u +#define OS_ERR_PEVENT_NULL 4u +#define OS_ERR_POST_ISR 5u +#define OS_ERR_QUERY_ISR 6u +#define OS_ERR_INVALID_OPT 7u +#define OS_ERR_PDATA_NULL 9u + +#define OS_ERR_TIMEOUT 10u +#define OS_ERR_EVENT_NAME_TOO_LONG 11u +#define OS_ERR_PNAME_NULL 12u +#define OS_ERR_PEND_LOCKED 13u +#define OS_ERR_PEND_ABORT 14u +#define OS_ERR_DEL_ISR 15u +#define OS_ERR_CREATE_ISR 16u +#define OS_ERR_NAME_GET_ISR 17u +#define OS_ERR_NAME_SET_ISR 18u + +#define OS_ERR_MBOX_FULL 20u + +#define OS_ERR_Q_FULL 30u +#define OS_ERR_Q_EMPTY 31u + +#define OS_ERR_PRIO_EXIST 40u +#define OS_ERR_PRIO 41u +#define OS_ERR_PRIO_INVALID 42u + +#define OS_ERR_SEM_OVF 50u + +#define OS_ERR_TASK_CREATE_ISR 60u +#define OS_ERR_TASK_DEL 61u +#define OS_ERR_TASK_DEL_IDLE 62u +#define OS_ERR_TASK_DEL_REQ 63u +#define OS_ERR_TASK_DEL_ISR 64u +#define OS_ERR_TASK_NAME_TOO_LONG 65u +#define OS_ERR_TASK_NO_MORE_TCB 66u +#define OS_ERR_TASK_NOT_EXIST 67u +#define OS_ERR_TASK_NOT_SUSPENDED 68u +#define OS_ERR_TASK_OPT 69u +#define OS_ERR_TASK_RESUME_PRIO 70u +#define OS_ERR_TASK_SUSPEND_IDLE 71u +#define OS_ERR_TASK_SUSPEND_PRIO 72u +#define OS_ERR_TASK_WAITING 73u + +#define OS_ERR_TIME_NOT_DLY 80u +#define OS_ERR_TIME_INVALID_MINUTES 81u +#define OS_ERR_TIME_INVALID_SECONDS 82u +#define OS_ERR_TIME_INVALID_MS 83u +#define OS_ERR_TIME_ZERO_DLY 84u +#define OS_ERR_TIME_DLY_ISR 85u + +#define OS_ERR_MEM_INVALID_PART 90u +#define OS_ERR_MEM_INVALID_BLKS 91u +#define OS_ERR_MEM_INVALID_SIZE 92u +#define OS_ERR_MEM_NO_FREE_BLKS 93u +#define OS_ERR_MEM_FULL 94u +#define OS_ERR_MEM_INVALID_PBLK 95u +#define OS_ERR_MEM_INVALID_PMEM 96u +#define OS_ERR_MEM_INVALID_PDATA 97u +#define OS_ERR_MEM_INVALID_ADDR 98u +#define OS_ERR_MEM_NAME_TOO_LONG 99u + +#define OS_ERR_NOT_MUTEX_OWNER 100u + +#define OS_ERR_FLAG_INVALID_PGRP 110u +#define OS_ERR_FLAG_WAIT_TYPE 111u +#define OS_ERR_FLAG_NOT_RDY 112u +#define OS_ERR_FLAG_INVALID_OPT 113u +#define OS_ERR_FLAG_GRP_DEPLETED 114u +#define OS_ERR_FLAG_NAME_TOO_LONG 115u + +#define OS_ERR_PIP_LOWER 120u + +#define OS_ERR_TMR_INVALID_DLY 130u +#define OS_ERR_TMR_INVALID_PERIOD 131u +#define OS_ERR_TMR_INVALID_OPT 132u +#define OS_ERR_TMR_INVALID_NAME 133u +#define OS_ERR_TMR_NON_AVAIL 134u +#define OS_ERR_TMR_INACTIVE 135u +#define OS_ERR_TMR_INVALID_DEST 136u +#define OS_ERR_TMR_INVALID_TYPE 137u +#define OS_ERR_TMR_INVALID 138u +#define OS_ERR_TMR_ISR 139u +#define OS_ERR_TMR_NAME_TOO_LONG 140u +#define OS_ERR_TMR_INVALID_STATE 141u +#define OS_ERR_TMR_STOPPED 142u +#define OS_ERR_TMR_NO_CALLBACK 143u + +/* +********************************************************************************************************* +* OLD ERROR CODE NAMES (< V2.84) +********************************************************************************************************* +*/ +#define OS_NO_ERR OS_ERR_NONE +#define OS_TIMEOUT OS_ERR_TIMEOUT +#define OS_TASK_NOT_EXIST OS_ERR_TASK_NOT_EXIST +#define OS_MBOX_FULL OS_ERR_MBOX_FULL +#define OS_Q_FULL OS_ERR_Q_FULL +#define OS_Q_EMPTY OS_ERR_Q_EMPTY +#define OS_PRIO_EXIST OS_ERR_PRIO_EXIST +#define OS_PRIO_ERR OS_ERR_PRIO +#define OS_PRIO_INVALID OS_ERR_PRIO_INVALID +#define OS_SEM_OVF OS_ERR_SEM_OVF +#define OS_TASK_DEL_ERR OS_ERR_TASK_DEL +#define OS_TASK_DEL_IDLE OS_ERR_TASK_DEL_IDLE +#define OS_TASK_DEL_REQ OS_ERR_TASK_DEL_REQ +#define OS_TASK_DEL_ISR OS_ERR_TASK_DEL_ISR +#define OS_NO_MORE_TCB OS_ERR_TASK_NO_MORE_TCB +#define OS_TIME_NOT_DLY OS_ERR_TIME_NOT_DLY +#define OS_TIME_INVALID_MINUTES OS_ERR_TIME_INVALID_MINUTES +#define OS_TIME_INVALID_SECONDS OS_ERR_TIME_INVALID_SECONDS +#define OS_TIME_INVALID_MS OS_ERR_TIME_INVALID_MS +#define OS_TIME_ZERO_DLY OS_ERR_TIME_ZERO_DLY +#define OS_TASK_SUSPEND_PRIO OS_ERR_TASK_SUSPEND_PRIO +#define OS_TASK_SUSPEND_IDLE OS_ERR_TASK_SUSPEND_IDLE +#define OS_TASK_RESUME_PRIO OS_ERR_TASK_RESUME_PRIO +#define OS_TASK_NOT_SUSPENDED OS_ERR_TASK_NOT_SUSPENDED +#define OS_MEM_INVALID_PART OS_ERR_MEM_INVALID_PART +#define OS_MEM_INVALID_BLKS OS_ERR_MEM_INVALID_BLKS +#define OS_MEM_INVALID_SIZE OS_ERR_MEM_INVALID_SIZE +#define OS_MEM_NO_FREE_BLKS OS_ERR_MEM_NO_FREE_BLKS +#define OS_MEM_FULL OS_ERR_MEM_FULL +#define OS_MEM_INVALID_PBLK OS_ERR_MEM_INVALID_PBLK +#define OS_MEM_INVALID_PMEM OS_ERR_MEM_INVALID_PMEM +#define OS_MEM_INVALID_PDATA OS_ERR_MEM_INVALID_PDATA +#define OS_MEM_INVALID_ADDR OS_ERR_MEM_INVALID_ADDR +#define OS_MEM_NAME_TOO_LONG OS_ERR_MEM_NAME_TOO_LONG +#define OS_TASK_OPT_ERR OS_ERR_TASK_OPT +#define OS_FLAG_INVALID_PGRP OS_ERR_FLAG_INVALID_PGRP +#define OS_FLAG_ERR_WAIT_TYPE OS_ERR_FLAG_WAIT_TYPE +#define OS_FLAG_ERR_NOT_RDY OS_ERR_FLAG_NOT_RDY +#define OS_FLAG_INVALID_OPT OS_ERR_FLAG_INVALID_OPT +#define OS_FLAG_GRP_DEPLETED OS_ERR_FLAG_GRP_DEPLETED + +/*$PAGE*/ +/* +********************************************************************************************************* +* EVENT CONTROL BLOCK +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +typedef struct os_event { + INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */ + void *OSEventPtr; /* Pointer to message or queue structure */ + INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ +#else + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ +#endif + +#if OS_EVENT_NAME_SIZE > 1 + INT8U OSEventName[OS_EVENT_NAME_SIZE]; +#endif +} OS_EVENT; +#endif + + +/* +********************************************************************************************************* +* EVENT FLAGS CONTROL BLOCK +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + +#if OS_FLAGS_NBITS == 8 /* Determine the size of OS_FLAGS (8, 16 or 32 bits) */ +typedef INT8U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 16 +typedef INT16U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 32 +typedef INT32U OS_FLAGS; +#endif + + +typedef struct os_flag_grp { /* Event Flag Group */ + INT8U OSFlagType; /* Should be set to OS_EVENT_TYPE_FLAG */ + void *OSFlagWaitList; /* Pointer to first NODE of task waiting on event flag */ + OS_FLAGS OSFlagFlags; /* 8, 16 or 32 bit flags */ +#if OS_FLAG_NAME_SIZE > 1 + INT8U OSFlagName[OS_FLAG_NAME_SIZE]; +#endif +} OS_FLAG_GRP; + + + +typedef struct os_flag_node { /* Event Flag Wait List Node */ + void *OSFlagNodeNext; /* Pointer to next NODE in wait list */ + void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */ + void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */ + void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */ + OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */ + INT8U OSFlagNodeWaitType; /* Type of wait: */ + /* OS_FLAG_WAIT_AND */ + /* OS_FLAG_WAIT_ALL */ + /* OS_FLAG_WAIT_OR */ + /* OS_FLAG_WAIT_ANY */ +} OS_FLAG_NODE; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE MAILBOX DATA +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0 +typedef struct os_mbox_data { + void *OSMsg; /* Pointer to message in mailbox */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_MBOX_DATA; +#endif + +/* +********************************************************************************************************* +* MEMORY PARTITION DATA STRUCTURES +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +typedef struct os_mem { /* MEMORY CONTROL BLOCK */ + void *OSMemAddr; /* Pointer to beginning of memory partition */ + void *OSMemFreeList; /* Pointer to list of free memory blocks */ + INT32U OSMemBlkSize; /* Size (in bytes) of each block of memory */ + INT32U OSMemNBlks; /* Total number of blocks in this partition */ + INT32U OSMemNFree; /* Number of memory blocks remaining in this partition */ +#if OS_MEM_NAME_SIZE > 1 + INT8U OSMemName[OS_MEM_NAME_SIZE]; /* Memory partition name */ +#endif +} OS_MEM; + + +typedef struct os_mem_data { + void *OSAddr; /* Pointer to the beginning address of the memory partition */ + void *OSFreeList; /* Pointer to the beginning of the free list of memory blocks */ + INT32U OSBlkSize; /* Size (in bytes) of each memory block */ + INT32U OSNBlks; /* Total number of blocks in the partition */ + INT32U OSNFree; /* Number of memory blocks free */ + INT32U OSNUsed; /* Number of memory blocks used */ +} OS_MEM_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0 +typedef struct os_mutex_data { +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif + BOOLEAN OSValue; /* Mutex value (OS_FALSE = used, OS_TRUE = available) */ + INT8U OSOwnerPrio; /* Mutex owner's task priority or 0xFF if no owner */ + INT8U OSMutexPIP; /* Priority Inheritance Priority or 0xFF if no owner */ +} OS_MUTEX_DATA; +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUE DATA +********************************************************************************************************* +*/ + +#if OS_Q_EN > 0 +typedef struct os_q { /* QUEUE CONTROL BLOCK */ + struct os_q *OSQPtr; /* Link to next queue control block in list of free blocks */ + void **OSQStart; /* Pointer to start of queue data */ + void **OSQEnd; /* Pointer to end of queue data */ + void **OSQIn; /* Pointer to where next message will be inserted in the Q */ + void **OSQOut; /* Pointer to where next message will be extracted from the Q */ + INT16U OSQSize; /* Size of queue (maximum number of entries) */ + INT16U OSQEntries; /* Current number of entries in the queue */ +} OS_Q; + + +typedef struct os_q_data { + void *OSMsg; /* Pointer to next message to be extracted from queue */ + INT16U OSNMsgs; /* Number of messages in message queue */ + INT16U OSQSize; /* Size of message queue */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_Q_DATA; +#endif + +/* +********************************************************************************************************* +* SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_SEM_EN > 0 +typedef struct os_sem_data { + INT16U OSCnt; /* Semaphore count */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_SEM_DATA; +#endif + +/* +********************************************************************************************************* +* TASK STACK DATA +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EXT_EN > 0 +typedef struct os_stk_data { + INT32U OSFree; /* Number of free bytes on the stack */ + INT32U OSUsed; /* Number of bytes used on the stack */ +} OS_STK_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK CONTROL BLOCK +********************************************************************************************************* +*/ + +typedef struct os_tcb { + OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */ + +#if OS_TASK_CREATE_EXT_EN > 0 + void *OSTCBExtPtr; /* Pointer to user definable data for TCB extension */ + OS_STK *OSTCBStkBottom; /* Pointer to bottom of stack */ + INT32U OSTCBStkSize; /* Size of task stack (in number of stack elements) */ + INT16U OSTCBOpt; /* Task options as passed by OSTaskCreateExt() */ + INT16U OSTCBId; /* Task ID (0..65535) */ +#endif + + struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list */ + struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list */ + +#if OS_EVENT_EN || (OS_FLAG_EN > 0) + OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */ +#endif + +#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) + void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +#if OS_TASK_DEL_EN > 0 + OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */ +#endif + OS_FLAGS OSTCBFlagsRdy; /* Event flags that made task ready to run */ +#endif + + INT16U OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */ + INT8U OSTCBStat; /* Task status */ + INT8U OSTCBStatPend; /* Task PEND status */ + INT8U OSTCBPrio; /* Task priority (0 == highest) */ + + INT8U OSTCBX; /* Bit position in group corresponding to task priority */ + INT8U OSTCBY; /* Index into ready table corresponding to task priority */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSTCBBitX; /* Bit mask to access bit position in ready table */ + INT8U OSTCBBitY; /* Bit mask to access bit position in ready group */ +#else + INT16U OSTCBBitX; /* Bit mask to access bit position in ready table */ + INT16U OSTCBBitY; /* Bit mask to access bit position in ready group */ +#endif + +#if OS_TASK_DEL_EN > 0 + INT8U OSTCBDelReq; /* Indicates whether a task needs to delete itself */ +#endif + +#if OS_TASK_PROFILE_EN > 0 + INT32U OSTCBCtxSwCtr; /* Number of time the task was switched in */ + INT32U OSTCBCyclesTot; /* Total number of clock cycles the task has been running */ + INT32U OSTCBCyclesStart; /* Snapshot of cycle counter at start of task resumption */ + OS_STK *OSTCBStkBase; /* Pointer to the beginning of the task stack */ + INT32U OSTCBStkUsed; /* Number of bytes used from the stack */ +#endif + +#if OS_TASK_NAME_SIZE > 1 + INT8U OSTCBTaskName[OS_TASK_NAME_SIZE]; +#endif +} OS_TCB; + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER DATA TYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +typedef void (*OS_TMR_CALLBACK)(void *ptmr, void *parg); + + + +typedef struct os_tmr { + INT8U OSTmrType; /* Should be set to OS_TMR_TYPE */ + OS_TMR_CALLBACK OSTmrCallback; /* Function to call when timer expires */ + void *OSTmrCallbackArg; /* Argument to pass to function when timer expires */ + void *OSTmrNext; /* Double link list pointers */ + void *OSTmrPrev; + INT32U OSTmrMatch; /* Timer expires when OSTmrTime == OSTmrMatch */ + INT32U OSTmrDly; /* Delay time before periodic update starts */ + INT32U OSTmrPeriod; /* Period to repeat timer */ +#if OS_TMR_CFG_NAME_SIZE > 0 + INT8U OSTmrName[OS_TMR_CFG_NAME_SIZE]; /* Name to give the timer */ +#endif + INT8U OSTmrOpt; /* Options (see OS_TMR_OPT_xxx) */ + INT8U OSTmrState; /* Indicates the state of the timer: */ + /* OS_TMR_STATE_UNUSED */ + /* OS_TMR_STATE_RUNNING */ + /* OS_TMR_STATE_STOPPED */ +} OS_TMR; + + + +typedef struct os_tmr_wheel { + OS_TMR *OSTmrFirst; /* Pointer to first timer in linked list */ + INT16U OSTmrEntries; +} OS_TMR_WHEEL; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + +OS_EXT INT32U OSCtxSwCtr; /* Counter of number of context switches */ + +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +OS_EXT OS_EVENT *OSEventFreeList; /* Pointer to list of free EVENT control blocks */ +OS_EXT OS_EVENT OSEventTbl[OS_MAX_EVENTS];/* Table of EVENT control blocks */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +OS_EXT OS_FLAG_GRP OSFlagTbl[OS_MAX_FLAGS]; /* Table containing event flag groups */ +OS_EXT OS_FLAG_GRP *OSFlagFreeList; /* Pointer to free list of event flag groups */ +#endif + +#if OS_TASK_STAT_EN > 0 +OS_EXT INT8S OSCPUUsage; /* Percentage of CPU used */ +OS_EXT INT32U OSIdleCtrMax; /* Max. value that idle ctr can take in 1 sec. */ +OS_EXT INT32U OSIdleCtrRun; /* Val. reached by idle ctr at run time in 1 sec. */ +OS_EXT BOOLEAN OSStatRdy; /* Flag indicating that the statistic task is rdy */ +OS_EXT OS_STK OSTaskStatStk[OS_TASK_STAT_STK_SIZE]; /* Statistics task stack */ +#endif + +OS_EXT INT8U OSIntNesting; /* Interrupt nesting level */ + +OS_EXT INT8U OSLockNesting; /* Multitasking lock nesting level */ + +OS_EXT INT8U OSPrioCur; /* Priority of current task */ +OS_EXT INT8U OSPrioHighRdy; /* Priority of highest priority task */ + +#if OS_LOWEST_PRIO <= 63 +OS_EXT INT8U OSRdyGrp; /* Ready list group */ +OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ +#else +OS_EXT INT16U OSRdyGrp; /* Ready list group */ +OS_EXT INT16U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ +#endif + +OS_EXT BOOLEAN OSRunning; /* Flag indicating that kernel is running */ + +OS_EXT INT8U OSTaskCtr; /* Number of tasks created */ + +OS_EXT volatile INT32U OSIdleCtr; /* Idle counter */ + +OS_EXT OS_STK OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE]; /* Idle task stack */ + + +OS_EXT OS_TCB *OSTCBCur; /* Pointer to currently running TCB */ +OS_EXT OS_TCB *OSTCBFreeList; /* Pointer to list of free TCBs */ +OS_EXT OS_TCB *OSTCBHighRdy; /* Pointer to highest priority TCB R-to-R */ +OS_EXT OS_TCB *OSTCBList; /* Pointer to doubly linked list of TCBs */ +OS_EXT OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];/* Table of pointers to created TCBs */ +OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]; /* Table of TCBs */ + +#if OS_TICK_STEP_EN > 0 +OS_EXT INT8U OSTickStepState; /* Indicates the state of the tick step feature */ +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +OS_EXT OS_MEM *OSMemFreeList; /* Pointer to free list of memory partitions */ +OS_EXT OS_MEM OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager */ +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +OS_EXT OS_Q *OSQFreeList; /* Pointer to list of free QUEUE control blocks */ +OS_EXT OS_Q OSQTbl[OS_MAX_QS]; /* Table of QUEUE control blocks */ +#endif + +#if OS_TIME_GET_SET_EN > 0 +OS_EXT volatile INT32U OSTime; /* Current value of system time (in ticks) */ +#endif + +#if OS_TMR_EN > 0 +OS_EXT INT16U OSTmrFree; /* Number of free entries in the timer pool */ +OS_EXT INT16U OSTmrUsed; /* Number of timers used */ +OS_EXT INT32U OSTmrTime; /* Current timer time */ + +OS_EXT OS_EVENT *OSTmrSem; /* Sem. used to gain exclusive access to timers */ +OS_EXT OS_EVENT *OSTmrSemSignal; /* Sem. used to signal the update of timers */ + +OS_EXT OS_TMR OSTmrTbl[OS_TMR_CFG_MAX]; /* Table containing pool of timers */ +OS_EXT OS_TMR *OSTmrFreeList; /* Pointer to free list of timers */ +OS_EXT OS_STK OSTmrTaskStk[OS_TASK_TMR_STK_SIZE]; + +OS_EXT OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]; +#endif + +extern INT8U const OSUnMapTbl[256]; /* Priority->Index lookup table */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Independent Functions) +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +INT8U OSEventNameGet (OS_EVENT *pevent, + INT8U *pname, + INT8U *perr); + +void OSEventNameSet (OS_EVENT *pevent, + INT8U *pname, + INT8U *perr); +#endif + +/* +********************************************************************************************************* +* EVENT FLAGS MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + +#if OS_FLAG_ACCEPT_EN > 0 +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT8U *perr); +#endif + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, + INT8U *perr); + +#if OS_FLAG_DEL_EN > 0 +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, + INT8U opt, + INT8U *perr); +#endif + +#if (OS_FLAG_EN > 0) && (OS_FLAG_NAME_SIZE > 1) +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, + INT8U *pname, + INT8U *perr); + +void OSFlagNameSet (OS_FLAG_GRP *pgrp, + INT8U *pname, + INT8U *perr); +#endif + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT16U timeout, + INT8U *perr); + +OS_FLAGS OSFlagPendGetFlagsRdy (void); +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U opt, + INT8U *perr); + +#if OS_FLAG_QUERY_EN > 0 +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, + INT8U *perr); +#endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOX MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0 + +#if OS_MBOX_ACCEPT_EN > 0 +void *OSMboxAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSMboxCreate (void *pmsg); + +#if OS_MBOX_DEL_EN > 0 +OS_EVENT *OSMboxDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void *OSMboxPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_MBOX_PEND_ABORT_EN > 0 +INT8U OSMboxPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_MBOX_POST_EN > 0 +INT8U OSMboxPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_MBOX_POST_OPT_EN > 0 +INT8U OSMboxPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_MBOX_QUERY_EN > 0 +INT8U OSMboxQuery (OS_EVENT *pevent, + OS_MBOX_DATA *p_mbox_data); +#endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + +OS_MEM *OSMemCreate (void *addr, + INT32U nblks, + INT32U blksize, + INT8U *perr); + +void *OSMemGet (OS_MEM *pmem, + INT8U *perr); +#if OS_MEM_NAME_SIZE > 1 +INT8U OSMemNameGet (OS_MEM *pmem, + INT8U *pname, + INT8U *perr); + +void OSMemNameSet (OS_MEM *pmem, + INT8U *pname, + INT8U *perr); +#endif +INT8U OSMemPut (OS_MEM *pmem, + void *pblk); + +#if OS_MEM_QUERY_EN > 0 +INT8U OSMemQuery (OS_MEM *pmem, + OS_MEM_DATA *p_mem_data); +#endif + +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0 + +#if OS_MUTEX_ACCEPT_EN > 0 +BOOLEAN OSMutexAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSMutexCreate (INT8U prio, + INT8U *perr); + +#if OS_MUTEX_DEL_EN > 0 +OS_EVENT *OSMutexDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSMutexPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +INT8U OSMutexPost (OS_EVENT *pevent); + +#if OS_MUTEX_QUERY_EN > 0 +INT8U OSMutexQuery (OS_EVENT *pevent, + OS_MUTEX_DATA *p_mutex_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE QUEUE MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + +#if OS_Q_ACCEPT_EN > 0 +void *OSQAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSQCreate (void **start, + INT16U size); + +#if OS_Q_DEL_EN > 0 +OS_EVENT *OSQDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_FLUSH_EN > 0 +INT8U OSQFlush (OS_EVENT *pevent); +#endif + +void *OSQPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_Q_PEND_ABORT_EN > 0 +INT8U OSQPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_POST_EN > 0 +INT8U OSQPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_FRONT_EN > 0 +INT8U OSQPostFront (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_OPT_EN > 0 +INT8U OSQPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_Q_QUERY_EN > 0 +INT8U OSQQuery (OS_EVENT *pevent, + OS_Q_DATA *p_q_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ +#if OS_SEM_EN > 0 + +#if OS_SEM_ACCEPT_EN > 0 +INT16U OSSemAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSSemCreate (INT16U cnt); + +#if OS_SEM_DEL_EN > 0 +OS_EVENT *OSSemDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSSemPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_SEM_PEND_ABORT_EN > 0 +INT8U OSSemPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +INT8U OSSemPost (OS_EVENT *pevent); + +#if OS_SEM_QUERY_EN > 0 +INT8U OSSemQuery (OS_EVENT *pevent, + OS_SEM_DATA *p_sem_data); +#endif + +#if OS_SEM_SET_EN > 0 +void OSSemSet (OS_EVENT *pevent, + INT16U cnt, + INT8U *perr); +#endif + +INT16U OSSemCheck (OS_EVENT *pevent); + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ +#if OS_TASK_CHANGE_PRIO_EN > 0 +INT8U OSTaskChangePrio (INT8U oldprio, + INT8U newprio); +#endif + +#if OS_TASK_CREATE_EN > 0 +INT8U OSTaskCreate (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt); +#endif + +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDel (INT8U prio); +INT8U OSTaskDelReq (INT8U prio); +#endif + +#if OS_TASK_NAME_SIZE > 1 +INT8U OSTaskNameGet (INT8U prio, + INT8U *pname, + INT8U *perr); + +void OSTaskNameSet (INT8U prio, + INT8U *pname, + INT8U *perr); +#endif + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskResume (INT8U prio); +INT8U OSTaskSuspend (INT8U prio); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskStkChk (INT8U prio, + OS_STK_DATA *p_stk_data); +#endif + +#if OS_TASK_QUERY_EN > 0 +INT8U OSTaskQuery (INT8U prio, + OS_TCB *p_task_data); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +void OSTimeDly (INT16U ticks); + +#if OS_TIME_DLY_HMSM_EN > 0 +INT8U OSTimeDlyHMSM (INT8U hours, + INT8U minutes, + INT8U seconds, + INT16U milli); +#endif + +#if OS_TIME_DLY_RESUME_EN > 0 +INT8U OSTimeDlyResume (INT8U prio); +#endif + +#if OS_TIME_GET_SET_EN > 0 +INT32U OSTimeGet (void); +void OSTimeSet (INT32U ticks); +#endif + +void OSTimeTick (void); + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_TMR_EN > 0 +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr); + +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr); + +#if OS_TMR_CFG_NAME_SIZE > 0 +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U *pdest, + INT8U *perr); +#endif +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr); + +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr); + +INT8U OSTmrSignal (void); +#endif + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +void OSInit (void); + +void OSIntEnter (void); +void OSIntExit (void); + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedLock (void); +void OSSchedUnlock (void); +#endif + +void OSStart (void); + +void OSStatInit (void); + +INT16U OSVersion (void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* INTERNAL FUNCTION PROTOTYPES +* (Your application MUST NOT call these functions) +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0 +void OS_Dummy (void); +#endif + +#if OS_EVENT_EN +INT8U OS_EventTaskRdy (OS_EVENT *pevent, + void *pmsg, + INT8U msk, + INT8U pend_stat); + +void OS_EventTaskWait (OS_EVENT *pevent); + +void OS_EventTOAbort (OS_EVENT *pevent); + +void OS_EventWaitListInit (OS_EVENT *pevent); +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +void OS_FlagInit (void); +void OS_FlagUnlink (OS_FLAG_NODE *pnode); +#endif + +void OS_MemClr (INT8U *pdest, + INT16U size); + +void OS_MemCopy (INT8U *pdest, + INT8U *psrc, + INT16U size); + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +void OS_MemInit (void); +#endif + +#if OS_Q_EN > 0 +void OS_QInit (void); +#endif + +void OS_Sched (void); + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) +INT8U OS_StrCopy (INT8U *pdest, + INT8U *psrc); + +INT8U OS_StrLen (INT8U *psrc); +#endif + +void OS_TaskIdle (void *p_arg); + +#if OS_TASK_STAT_EN > 0 +void OS_TaskStat (void *p_arg); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +void OS_TaskStkClr (OS_STK *pbos, + INT32U size, + INT16U opt); +#endif + +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) +void OS_TaskStatStkChk (void); +#endif + +INT8U OS_TCBInit (INT8U prio, + OS_STK *ptos, + OS_STK *pbos, + INT16U id, + INT32U stk_size, + void *pext, + INT16U opt); + +#if OS_TMR_EN > 0 +void OSTmr_Init(void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Specific Functions) +********************************************************************************************************* +*/ + +#if OS_DEBUG_EN > 0 +void OSDebugInit (void); +#endif + +void OSInitHookBegin (void); +void OSInitHookEnd (void); + +void OSTaskCreateHook (OS_TCB *ptcb); +void OSTaskDelHook (OS_TCB *ptcb); + +void OSTaskIdleHook (void); + +void OSTaskStatHook (void); +OS_STK *OSTaskStkInit (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT16U opt); + +#if OS_TASK_SW_HOOK_EN > 0 +void OSTaskSwHook (void); +#endif + +void OSTCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0 +void OSTimeTickHook (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Application Specific Functions) +********************************************************************************************************* +*/ + +#if OS_APP_HOOKS_EN > 0 +void App_TaskCreateHook (OS_TCB *ptcb); +void App_TaskDelHook (OS_TCB *ptcb); +void App_TaskIdleHook (void); + +void App_TaskStatHook (void); + +#if OS_TASK_SW_HOOK_EN > 0 +void App_TaskSwHook (void); +#endif + +void App_TCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0 +void App_TimeTickHook (void); +#endif +#endif + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* IMPORTANT: These prototypes MUST be placed in OS_CPU.H +********************************************************************************************************* +*/ + +#if 0 +void OSStartHighRdy (void); +void OSIntCtxSw (void); +void OSCtxSw (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOOK FOR MISSING #define CONSTANTS +* +* This section is used to generate ERROR messages at compile time if certain #define constants are +* MISSING in OS_CFG.H. This allows you to quickly determine the source of the error. +* +* You SHOULD NOT change this section UNLESS you would like to add more comments as to the source of the +* compile time error. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ + +#ifndef OS_FLAG_EN +#error "OS_CFG.H, Missing OS_FLAG_EN: Enable (1) or Disable (0) code generation for Event Flags" +#else + #ifndef OS_MAX_FLAGS + #error "OS_CFG.H, Missing OS_MAX_FLAGS: Max. number of Event Flag Groups in your application" + #else + #if OS_MAX_FLAGS > 65500u + #error "OS_CFG.H, OS_MAX_FLAGS must be <= 65500" + #endif + #endif + + #ifndef OS_FLAGS_NBITS + #error "OS_CFG.H, Missing OS_FLAGS_NBITS: Determine #bits used for event flags, MUST be either 8, 16 or 32" + #endif + + #ifndef OS_FLAG_WAIT_CLR_EN + #error "OS_CFG.H, Missing OS_FLAG_WAIT_CLR_EN: Include code for Wait on Clear EVENT FLAGS" + #endif + + #ifndef OS_FLAG_ACCEPT_EN + #error "OS_CFG.H, Missing OS_FLAG_ACCEPT_EN: Include code for OSFlagAccept()" + #endif + + #ifndef OS_FLAG_DEL_EN + #error "OS_CFG.H, Missing OS_FLAG_DEL_EN: Include code for OSFlagDel()" + #endif + + #ifndef OS_FLAG_NAME_SIZE + #error "OS_CFG.H, Missing OS_FLAG_NAME_SIZE: Determines the size of flag group names" + #endif + + #ifndef OS_FLAG_QUERY_EN + #error "OS_CFG.H, Missing OS_FLAG_QUERY_EN: Include code for OSFlagQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOXES +********************************************************************************************************* +*/ + +#ifndef OS_MBOX_EN +#error "OS_CFG.H, Missing OS_MBOX_EN: Enable (1) or Disable (0) code generation for MAILBOXES" +#else + #ifndef OS_MBOX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MBOX_ACCEPT_EN: Include code for OSMboxAccept()" + #endif + + #ifndef OS_MBOX_DEL_EN + #error "OS_CFG.H, Missing OS_MBOX_DEL_EN: Include code for OSMboxDel()" + #endif + + #ifndef OS_MBOX_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_MBOX_PEND_ABORT_EN: Include code for OSMboxPendAbort()" + #endif + + #ifndef OS_MBOX_POST_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_EN: Include code for OSMboxPost()" + #endif + + #ifndef OS_MBOX_POST_OPT_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_OPT_EN: Include code for OSMboxPostOpt()" + #endif + + #ifndef OS_MBOX_QUERY_EN + #error "OS_CFG.H, Missing OS_MBOX_QUERY_EN: Include code for OSMboxQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MEM_EN +#error "OS_CFG.H, Missing OS_MEM_EN: Enable (1) or Disable (0) code generation for MEMORY MANAGER" +#else + #ifndef OS_MAX_MEM_PART + #error "OS_CFG.H, Missing OS_MAX_MEM_PART: Max. number of memory partitions" + #else + #if OS_MAX_MEM_PART > 65500u + #error "OS_CFG.H, OS_MAX_MEM_PART must be <= 65500" + #endif + #endif + + #ifndef OS_MEM_NAME_SIZE + #error "OS_CFG.H, Missing OS_MEM_NAME_SIZE: Determines the size of memory partition names" + #endif + + #ifndef OS_MEM_QUERY_EN + #error "OS_CFG.H, Missing OS_MEM_QUERY_EN: Include code for OSMemQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_MUTEX_EN +#error "OS_CFG.H, Missing OS_MUTEX_EN: Enable (1) or Disable (0) code generation for MUTEX" +#else + #ifndef OS_MUTEX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MUTEX_ACCEPT_EN: Include code for OSMutexAccept()" + #endif + + #ifndef OS_MUTEX_DEL_EN + #error "OS_CFG.H, Missing OS_MUTEX_DEL_EN: Include code for OSMutexDel()" + #endif + + #ifndef OS_MUTEX_QUERY_EN + #error "OS_CFG.H, Missing OS_MUTEX_QUERY_EN: Include code for OSMutexQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUES +********************************************************************************************************* +*/ + +#ifndef OS_Q_EN +#error "OS_CFG.H, Missing OS_Q_EN: Enable (1) or Disable (0) code generation for QUEUES" +#else + #ifndef OS_MAX_QS + #error "OS_CFG.H, Missing OS_MAX_QS: Max. number of queue control blocks" + #else + #if OS_MAX_QS > 65500u + #error "OS_CFG.H, OS_MAX_QS must be <= 65500" + #endif + #endif + + #ifndef OS_Q_ACCEPT_EN + #error "OS_CFG.H, Missing OS_Q_ACCEPT_EN: Include code for OSQAccept()" + #endif + + #ifndef OS_Q_DEL_EN + #error "OS_CFG.H, Missing OS_Q_DEL_EN: Include code for OSQDel()" + #endif + + #ifndef OS_Q_FLUSH_EN + #error "OS_CFG.H, Missing OS_Q_FLUSH_EN: Include code for OSQFlush()" + #endif + + #ifndef OS_Q_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_Q_PEND_ABORT_EN: Include code for OSQPendAbort()" + #endif + + #ifndef OS_Q_POST_EN + #error "OS_CFG.H, Missing OS_Q_POST_EN: Include code for OSQPost()" + #endif + + #ifndef OS_Q_POST_FRONT_EN + #error "OS_CFG.H, Missing OS_Q_POST_FRONT_EN: Include code for OSQPostFront()" + #endif + + #ifndef OS_Q_POST_OPT_EN + #error "OS_CFG.H, Missing OS_Q_POST_OPT_EN: Include code for OSQPostOpt()" + #endif + + #ifndef OS_Q_QUERY_EN + #error "OS_CFG.H, Missing OS_Q_QUERY_EN: Include code for OSQQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_SEM_EN +#error "OS_CFG.H, Missing OS_SEM_EN: Enable (1) or Disable (0) code generation for SEMAPHORES" +#else + #ifndef OS_SEM_ACCEPT_EN + #error "OS_CFG.H, Missing OS_SEM_ACCEPT_EN: Include code for OSSemAccept()" + #endif + + #ifndef OS_SEM_DEL_EN + #error "OS_CFG.H, Missing OS_SEM_DEL_EN: Include code for OSSemDel()" + #endif + + #ifndef OS_SEM_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_SEM_PEND_ABORT_EN: Include code for OSSemPendAbort()" + #endif + + #ifndef OS_SEM_QUERY_EN + #error "OS_CFG.H, Missing OS_SEM_QUERY_EN: Include code for OSSemQuery()" + #endif + + #ifndef OS_SEM_SET_EN + #error "OS_CFG.H, Missing OS_SEM_SET_EN: Include code for OSSemSet()" + #endif +#endif + +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MAX_TASKS +#error "OS_CFG.H, Missing OS_MAX_TASKS: Max. number of tasks in your application" +#else + #if OS_MAX_TASKS < 2 + #error "OS_CFG.H, OS_MAX_TASKS must be >= 2" + #endif + + #if OS_MAX_TASKS > ((OS_LOWEST_PRIO - OS_N_SYS_TASKS) + 1) + #error "OS_CFG.H, OS_MAX_TASKS must be <= OS_LOWEST_PRIO - OS_N_SYS_TASKS + 1" + #endif + +#endif + +#if OS_LOWEST_PRIO > 254 +#error "OS_CFG.H, OS_LOWEST_PRIO must be <= 254 in V2.8x and higher" +#endif + +#ifndef OS_TASK_IDLE_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_IDLE_STK_SIZE: Idle task stack size" +#endif + +#ifndef OS_TASK_STAT_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_EN: Enable (1) or Disable(0) the statistics task" +#endif + +#ifndef OS_TASK_STAT_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_SIZE: Statistics task stack size" +#endif + +#ifndef OS_TASK_STAT_STK_CHK_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_CHK_EN: Check task stacks from statistics task" +#endif + +#ifndef OS_TASK_CHANGE_PRIO_EN +#error "OS_CFG.H, Missing OS_TASK_CHANGE_PRIO_EN: Include code for OSTaskChangePrio()" +#endif + +#ifndef OS_TASK_CREATE_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EN: Include code for OSTaskCreate()" +#endif + +#ifndef OS_TASK_CREATE_EXT_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EXT_EN: Include code for OSTaskCreateExt()" +#endif + +#ifndef OS_TASK_DEL_EN +#error "OS_CFG.H, Missing OS_TASK_DEL_EN: Include code for OSTaskDel()" +#endif + +#ifndef OS_TASK_NAME_SIZE +#error "OS_CFG.H, Missing OS_TASK_NAME_SIZE: Determine the size of task names" +#endif + +#ifndef OS_TASK_SUSPEND_EN +#error "OS_CFG.H, Missing OS_TASK_SUSPEND_EN: Include code for OSTaskSuspend() and OSTaskResume()" +#endif + +#ifndef OS_TASK_QUERY_EN +#error "OS_CFG.H, Missing OS_TASK_QUERY_EN: Include code for OSTaskQuery()" +#endif + +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TICKS_PER_SEC +#error "OS_CFG.H, Missing OS_TICKS_PER_SEC: Sets the number of ticks in one second" +#endif + +#ifndef OS_TIME_DLY_HMSM_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_HMSM_EN: Include code for OSTimeDlyHMSM()" +#endif + +#ifndef OS_TIME_DLY_RESUME_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_RESUME_EN: Include code for OSTimeDlyResume()" +#endif + +#ifndef OS_TIME_GET_SET_EN +#error "OS_CFG.H, Missing OS_TIME_GET_SET_EN: Include code for OSTimeGet() and OSTimeSet()" +#endif + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TMR_EN +#error "OS_CFG.H, Missing OS_TMR_EN: When (1) enables code generation for Timer Management" +#elif OS_TMR_EN > 0 + #if OS_SEM_EN == 0 + #error "OS_CFG.H, Semaphore management is required (set OS_SEM_EN to 1) when enabling Timer Management." + #error " Timer management require TWO semaphores." + #endif + + #ifndef OS_TMR_CFG_MAX + #error "OS_CFG.H, Missing OS_TMR_CFG_MAX: Determines the total number of timers in an application (2 .. 65500)" + #else + #if OS_TMR_CFG_MAX < 2 + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + + #if OS_TMR_CFG_MAX > 65500 + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + #endif + + #ifndef OS_TMR_CFG_WHEEL_SIZE + #error "OS_CFG.H, Missing OS_TMR_CFG_WHEEL_SIZE: Sets the size of the timer wheel (1 .. 1023)" + #else + #if OS_TMR_CFG_WHEEL_SIZE < 2 + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + + #if OS_TMR_CFG_WHEEL_SIZE > 1024 + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + #endif + + #ifndef OS_TMR_CFG_NAME_SIZE + #error "OS_CFG.H, Missing OS_TMR_CFG_NAME_SIZE: Determines the number of characters used for Timer names" + #endif + + #ifndef OS_TMR_CFG_TICKS_PER_SEC + #error "OS_CFG.H, Missing OS_TMR_CFG_TICKS_PER_SEC: Determines the rate at which tiem timer management task will run (Hz)" + #endif + + #ifndef OS_TASK_TMR_STK_SIZE + #error "OS_CFG.H, Missing OS_TASK_TMR_STK_SIZE: Determines the size of the Timer Task's stack" + #endif +#endif + + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifndef OS_ARG_CHK_EN +#error "OS_CFG.H, Missing OS_ARG_CHK_EN: Enable (1) or Disable (0) argument checking" +#endif + + +#ifndef OS_CPU_HOOKS_EN +#error "OS_CFG.H, Missing OS_CPU_HOOKS_EN: uC/OS-II hooks are found in the processor port files when 1" +#endif + + +#ifndef OS_APP_HOOKS_EN +#error "OS_CFG.H, Missing OS_APP_HOOKS_EN: Application-defined hooks are called from the uC/OS-II hooks" +#endif + + +#ifndef OS_DEBUG_EN +#error "OS_CFG.H, Missing OS_DEBUG_EN: Allows you to include variables for debugging or not" +#endif + + +#ifndef OS_LOWEST_PRIO +#error "OS_CFG.H, Missing OS_LOWEST_PRIO: Defines the lowest priority that can be assigned" +#endif + + +#ifndef OS_MAX_EVENTS +#error "OS_CFG.H, Missing OS_MAX_EVENTS: Max. number of event control blocks in your application" +#else + #if OS_MAX_EVENTS > 65500u + #error "OS_CFG.H, OS_MAX_EVENTS must be <= 65500" + #endif +#endif + + +#ifndef OS_SCHED_LOCK_EN +#error "OS_CFG.H, Missing OS_SCHED_LOCK_EN: Include code for OSSchedLock() and OSSchedUnlock()" +#endif + + +#ifndef OS_TASK_PROFILE_EN +#error "OS_CFG.H, Missing OS_TASK_PROFILE_EN: Include data structure for run-time task profiling" +#endif + + +#ifndef OS_TASK_SW_HOOK_EN +#error "OS_CFG.H, Missing OS_TASK_SW_HOOK_EN: Allows you to include the code for OSTaskSwHook() or not" +#endif + + +#ifndef OS_TICK_STEP_EN +#error "OS_CFG.H, Missing OS_TICK_STEP_EN: Allows to 'step' one tick at a time with uC/OS-View" +#endif + + +#ifndef OS_TIME_TICK_HOOK_EN +#error "OS_CFG.H, Missing OS_TIME_TICK_HOOK_EN: Allows you to include the code for OSTimeTickHook() or not" +#endif + +/* +********************************************************************************************************* +* SAFETY CRITICAL USE +********************************************************************************************************* +*/ + +#ifdef SAFETY_CRITICAL_RELEASE + +#if OS_ARG_CHK_EN < 1 +#error "OS_CFG.H, OS_ARG_CHK_EN must be enabled for safety-critical release code" +#endif + +#if OS_APP_HOOKS_EN > 0 +#error "OS_CFG.H, OS_APP_HOOKS_EN must be disabled for safety-critical release code" +#endif + +#if OS_DEBUG_EN > 0 +#error "OS_CFG.H, OS_DEBUG_EN must be disabled for safety-critical release code" +#endif + +#ifdef CANTATA +#error "OS_CFG.H, CANTATA must be disabled for safety-critical release code" +#endif + +#ifdef OS_SCHED_LOCK_EN +#error "OS_CFG.H, OS_SCHED_LOCK_EN must be disabled for safety-critical release code" +#endif + +#ifdef VSC_VALIDATION_MODE +#error "OS_CFG.H, VSC_VALIDATION_MODE must be disabled for safety-critical release code" +#endif + +#if OS_TASK_STAT_EN > 0 +#error "OS_CFG.H, OS_TASK_STAT_EN must be disabled for safety-critical release code" +#endif + +#if OS_TICK_STEP_EN > 0 +#error "OS_CFG.H, OS_TICK_STEP_EN must be disabled for safety-critical release code" +#endif + +#if OS_FLAG_EN > 0 + #if OS_FLAG_DEL_EN > 0 + #error "OS_CFG.H, OS_FLAG_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MBOX_EN > 0 + #if OS_MBOX_DEL_EN > 0 + #error "OS_CFG.H, OS_MBOX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MUTEX_EN > 0 + #if OS_MUTEX_DEL_EN > 0 + #error "OS_CFG.H, OS_MUTEX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_Q_EN > 0 + #if OS_Q_DEL_EN > 0 + #error "OS_CFG.H, OS_Q_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_SEM_EN > 0 + #if OS_SEM_DEL_EN > 0 + #error "OS_CFG.H, OS_SEM_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_TASK_EN > 0 + #if OS_TASK_DEL_EN > 0 + #error "OS_CFG.H, OS_TASK_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_CRITICAL_METHOD != 3 +#error "OS_CPU.H, OS_CRITICAL_METHOD must be type 3 for safety-critical release code" +#endif + +#endif /* ------------------------ SAFETY_CRITICAL_RELEASE ------------------------ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/.svn/pristine/f2/f24bce3c0298d04b4b1d81f3beb32fa90a26425a.svn-base b/.svn/pristine/f2/f24bce3c0298d04b4b1d81f3beb32fa90a26425a.svn-base new file mode 100644 index 0000000..369a22c --- /dev/null +++ b/.svn/pristine/f2/f24bce3c0298d04b4b1d81f3beb32fa90a26425a.svn-base @@ -0,0 +1,629 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* SEMAPHORE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_SEM.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if OS_SEM_EN > 0 +/*$PAGE*/ +/* +********************************************************************************************************* +* ACCEPT SEMAPHORE +* +* Description: This function checks the semaphore to see if a resource is available or, if an event +* occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the +* resource is not available or the event did not occur. +* +* Arguments : pevent is a pointer to the event control block +* +* Returns : > 0 if the resource is available or the event did not occur the semaphore is +* decremented to obtain the resource. +* == 0 if the resource is not available or the event did not occur or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass a pointer to a semaphore +********************************************************************************************************* +*/ + +#if OS_SEM_ACCEPT_EN > 0 +INT16U OSSemAccept (OS_EVENT *pevent) +{ + INT16U cnt; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (0); + } + OS_ENTER_CRITICAL(); + cnt = pevent->OSEventCnt; + if (cnt > 0) { /* See if resource is available */ + pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */ + } + OS_EXIT_CRITICAL(); + return (cnt); /* Return semaphore count */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A SEMAPHORE +* +* Description: This function creates a semaphore. +* +* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is +* available (or no event has occurred). You initialize the semaphore to a +* non-zero value to specify how many resources are available (e.g. if you have +* 10 resources, you would initialize the semaphore to 10). +* +* Returns : != (void *)0 is a pointer to the event control block (OS_EVENT) associated with the +* created semaphore +* == (void *)0 if no event control blocks were available +********************************************************************************************************* +*/ + +OS_EVENT *OSSemCreate (INT16U cnt) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { /* Get an event control block */ + pevent->OSEventType = OS_EVENT_TYPE_SEM; + pevent->OSEventCnt = cnt; /* Set semaphore value */ + pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */ + } + return (pevent); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A SEMAPHORE +* +* Description: This function deletes a semaphore and readies all tasks pending on the semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the semaphore was deleted +* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the semaphore was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the semaphore MUST check the return code of OSSemPend(). +* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless +* they check 'pevent' to see that it's a NULL pointer. +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the semaphore. +* 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in +* applications where the semaphore is used for mutual exclusion because the resource(s) +* will no longer be guarded by the semaphore. +********************************************************************************************************* +*/ + +#if OS_SEM_DEL_EN > 0 +OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on semaphore */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the semaphore */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON SEMAPHORE +* +* Description: This function waits for a semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for the resource up to the amount of time specified by this argument. +* If you specify 0, however, your task will wait forever at the specified +* semaphore or, until the resource becomes available (or the event occurs). +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task owns the resource +* or, the event you are waiting for occurred. +* OS_ERR_TIMEOUT The semaphore was not received within the specified +* 'timeout'. +* OS_ERR_PEND_ABORT The wait on the semaphore was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : none +********************************************************************************************************* +*/ + +void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return; + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return; + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */ + pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return; + } + /* Otherwise, must wait until event occurs */ + OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed-out or aborted */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that didn't get event within TO */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return; + } + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A SEMAPHORE +* +* Description: This function aborts & readies any tasks currently waiting on a semaphore. This function +* should be used to fault-abort the wait on the semaphore, rather than to normally signal +* the semaphore via OSSemPost(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* semaphore +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* semaphore +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the semaphore. +* OS_ERR_PEND_ABORT At least one task waiting on the semaphore was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the semaphore +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the semaphore, or upon error. +* > 0 if one or more tasks waiting on the semaphore are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_SEM_PEND_ABORT_EN > 0 +INT8U OSSemPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on semaphore? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on semaphore */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on semaphore */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on semaphore */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST TO A SEMAPHORE +* +* Description: This function signals a semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* Returns : OS_ERR_NONE The call was successful and the semaphore was signaled. +* OS_ERR_SEM_OVF If the semaphore count exceeded its limit. In other words, you have +* signalled the semaphore more often than you waited on it with either +* OSSemAccept() or OSSemPend(). +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +********************************************************************************************************* +*/ + +INT8U OSSemPost (OS_EVENT *pevent) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore */ + /* Ready HPT waiting on event */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + return (OS_ERR_NONE); + } + if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */ + pevent->OSEventCnt++; /* Increment semaphore count to register event */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ + return (OS_ERR_SEM_OVF); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A SEMAPHORE +* +* Description: This function obtains information about a semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore +* +* p_sem_data is a pointer to a structure that will contain information about the +* semaphore. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_PDATA_NULL If 'p_sem_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_SEM_QUERY_EN > 0 +INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *p_sem_data) +{ +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif + INT8U i; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_sem_data == (OS_SEM_DATA *)0) { /* Validate 'p_sem_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_sem_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_sem_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + p_sem_data->OSCnt = pevent->OSEventCnt; /* Get semaphore count */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_SEM_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* SET SEMAPHORE +* +* Description: This function sets the semaphore count to the value specified as an argument. Typically, +* this value would be 0. +* +* You would typically use this function when a semaphore is used as a signaling mechanism +* and, you want to reset the count value. +* +* Arguments : pevent is a pointer to the event control block +* +* cnt is the new value for the semaphore count. You would pass 0 to reset the +* semaphore count. +* +* perr is a pointer to an error code returned by the function as follows: +* +* OS_ERR_NONE The call was successful and the semaphore value was set. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore. +********************************************************************************************************* +*/ + +#if OS_SEM_SET_EN > 0 +void OSSemSet (OS_EVENT *pevent, INT16U cnt, INT8U *perr) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + OS_ENTER_CRITICAL(); + *perr = OS_ERR_NONE; + if (pevent->OSEventCnt > 0) { /* See if semaphore already has a count */ + pevent->OSEventCnt = cnt; /* Yes, set it to the new value specified. */ + } else { /* No */ + if (pevent->OSEventGrp == 0) { /* See if task(s) waiting? */ + pevent->OSEventCnt = cnt; /* No, OK to set the value */ + } else { + *perr = OS_ERR_TASK_WAITING; + } + } + OS_EXIT_CRITICAL(); +} +#endif + +// +INT16U OSSemCheck (OS_EVENT *pevent) +{ + INT16U cnt; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (0); + } + OS_ENTER_CRITICAL(); + cnt = pevent->OSEventCnt; + OS_EXIT_CRITICAL(); + return (cnt); /* Return semaphore count */ +} + +#endif /* OS_SEM_EN */ diff --git a/.svn/pristine/f3/f314655b528b7eddc67fa3bb7a217de0588c4c1c.svn-base b/.svn/pristine/f3/f314655b528b7eddc67fa3bb7a217de0588c4c1c.svn-base new file mode 100644 index 0000000..8d8bd6e --- /dev/null +++ b/.svn/pristine/f3/f314655b528b7eddc67fa3bb7a217de0588c4c1c.svn-base @@ -0,0 +1,888 @@ + + + + 2 + + Flash + + ARM + + 1 + + C-SPY + 2 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + JLINK_ID + 2 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 0 + 1 + 1 + + + + + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/.svn/pristine/f3/f39a6f70a567ff88eda97034935e973cf37314aa.svn-base b/.svn/pristine/f3/f39a6f70a567ff88eda97034935e973cf37314aa.svn-base new file mode 100644 index 0000000..8a4d84c --- /dev/null +++ b/.svn/pristine/f3/f39a6f70a567ff88eda97034935e973cf37314aa.svn-base @@ -0,0 +1,220 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* DCC Communication +* +* File : OS_DCC.C +* Version : V1.82 +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.40a and higher +********************************************************************************************************* +*/ + +#include + /* This directive suppresses warnings for non-... */ +#pragma diag_suppress=Pe940 /* ...void functions with no return values. */ + +#if OS_CPU_ARM_DCC_EN > 0 + +/* +********************************************************************************************************* +* CONSTANTS +********************************************************************************************************* +*/ + +#define OS_DCC_OP_READ_U32 0x01000000 +#define OS_DCC_OP_READ_U16 0x02000000 +#define OS_DCC_OP_READ_U8 0x04000000 +#define OS_DCC_OP_GET_CAPS 0x08000000 +#define OS_DCC_OP_WRITE_U32 0x10000000 +#define OS_DCC_OP_WRITE_U16 0x20000000 +#define OS_DCC_OP_WRITE_U8 0x40000000 +#define OS_DCC_OP_ODD_ADDR 0x80000000 +#define OS_DCC_OP_COMMAND 0x00000001 + +#define OS_DCC_COMM_CTRL_RD 0x00000001 +#define OS_DCC_COMM_CTRL_WR 0x00000002 + +#define OS_DCC_SIGNATURE 0x91CA0000 +#define OS_DCC_CONFIG 0x00000077 + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +static INT32U OSDCC_Cmd; +static INT32U OSDCC_Addr; +static INT32U OSDCC_ItemCnt; +static INT32U OSDCC_Data; + +/* +********************************************************************************************************* +* OSDCC_ReadCtrl() +* +* Description: This function retrieves data from the comms control register. +* +* Arguments : none +* +* Returns : The contents of the comms control register +* +* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents +* of the comms control register in R0. Thus, the function does not contain an +* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the +* top of this file, is used to suppress the warning that normally results from non- +* void functions lacking return statements. +********************************************************************************************************* +*/ + +static __arm INT32U OSDCC_ReadCtrl (void) +{ + __asm("mrc P14,0,R0,C0,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Read() +* +* Description: This function retrieves data from the comms data read register. +* +* Arguments : none +* +* Returns : The contents of the comms data read register +* +* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents +* of the comms data read register in R0. Thus, the function does not contain an +* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the +* top of this file, is used to suppress the warning that normally results from non- +* void functions lacking return statements. +********************************************************************************************************* +*/ + +static __arm INT32U OSDCC_Read (void) +{ + __asm("mrc P14,0,R0,C1,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Write() +* +* Description: This function places data in the comms data write register. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static __arm void OSDCC_Write (INT32U data) +{ + __asm("mcr P14,0,R0,C1,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Handler() +* +* Description: This function reads commands from the DCC comms data read register. Data may be +* transferred to or from memory based on those commands. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function should be called periodically. If OS_CPU_ARM_DCC_EN is '1', this +* function will be called from both the idle task hook and the tick interrupt hook. +********************************************************************************************************* +*/ + +void OSDCC_Handler (void) +{ + INT32U reg_val; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + OS_ENTER_CRITICAL(); /* Disable interrupts */ + + /* Check for the presence of new data */ + if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_RD) != 0) { + reg_val = OSDCC_Read(); /* Read the new data */ + + if ((reg_val & OS_DCC_OP_COMMAND) != 0) { /* Determine whether a command has been received */ + OSDCC_Cmd = reg_val; + /* Check for an odd address in the next operation */ + if ((OSDCC_Cmd & OS_DCC_OP_ODD_ADDR) != 0) { + OSDCC_Addr |= 1; + } + /* If data will be read, adjust OSDCC_ItemCnt */ + if ((OSDCC_Cmd & (OS_DCC_OP_READ_U32 | OS_DCC_OP_READ_U16 | OS_DCC_OP_READ_U8 + | OS_DCC_OP_GET_CAPS)) != 0) { + OSDCC_ItemCnt = (OSDCC_Cmd >> 2) & 0xffff; + } else { /* Data will be written; initialize OSDCC_Data */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) { + OSDCC_Data |= (OSDCC_Cmd << 14) & 0xffff0000; + } else { + OSDCC_Data = (OSDCC_Cmd >> 2) & 0xffff; + } + /* Write a single byte */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U8) != 0) { + *(INT8U *)OSDCC_Addr = OSDCC_Data; + OSDCC_Addr += 1; + } + /* Write two bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U16) != 0) { + *(INT16U *)OSDCC_Addr = OSDCC_Data; + OSDCC_Addr += 2; + } + /* Write four bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) { + *(INT32U *)OSDCC_Addr =OSDCC_Data; + OSDCC_Addr += 4; + } + } + OS_EXIT_CRITICAL(); + return; + } + OSDCC_Addr = reg_val; /* An address was received; OSDCC_Addr is updated */ + } + /* Determine whether data must be read */ + if (OSDCC_ItemCnt != 0) { + /* Confirm that the comms data write register... */ + /* ...is free from the processor point of view */ + if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_WR) == 0) { + reg_val = (OS_DCC_CONFIG | OS_DCC_SIGNATURE); + /* Read a single byte */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U8) != 0) { + reg_val = *(INT8U *)OSDCC_Addr; + OSDCC_Addr += 1; + } + /* Read two bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U16) != 0) { + reg_val = *(INT16U *)OSDCC_Addr; + OSDCC_Addr += 2; + } + /* Read four bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U32) != 0) { + reg_val = *(INT32U *)OSDCC_Addr; + OSDCC_Addr += 4; + } + + OSDCC_Write(reg_val); /* Place data in the comms data write register */ + OSDCC_ItemCnt--; /* Decrement the number of items to be read */ + } + } + OS_EXIT_CRITICAL(); +} + +#endif diff --git a/.svn/pristine/f7/f79bb474f8c6613811c65114b7263919a56b15eb.svn-base b/.svn/pristine/f7/f79bb474f8c6613811c65114b7263919a56b15eb.svn-base new file mode 100644 index 0000000..a93419b --- /dev/null +++ b/.svn/pristine/f7/f79bb474f8c6613811c65114b7263919a56b15eb.svn-base @@ -0,0 +1,865 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MESSAGE QUEUE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_Q.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +/* +********************************************************************************************************* +* ACCEPT MESSAGE FROM QUEUE +* +* Description: This function checks the queue to see if a message is available. Unlike OSQPend(), +* OSQAccept() does not suspend the calling task if a message is not available. +* +* Arguments : pevent is a pointer to the event control block +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_Q_EMPTY The queue did not contain any messages +* +* Returns : != (void *)0 is the message in the queue if one is available. The message is removed +* from the so the next time OSQAccept() is called, the queue will contain +* one less entry. +* == (void *)0 if you received a NULL pointer message +* if the queue is empty or, +* if 'pevent' is a NULL pointer or, +* if you passed an invalid event type +* +* Note(s) : As of V2.60, you can now pass NULL pointers through queues. Because of this, the argument +* 'perr' has been added to the API to tell you about the outcome of the call. +********************************************************************************************************* +*/ + +#if OS_Q_ACCEPT_EN > 0 +void *OSQAccept (OS_EVENT *pevent, INT8U *perr) +{ + void *pmsg; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ + if (pq->OSQEntries > 0) { /* See if any messages in the queue */ + pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ + pq->OSQEntries--; /* Update the number of entries in the queue */ + if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ + pq->OSQOut = pq->OSQStart; + } + *perr = OS_ERR_NONE; + } else { + *perr = OS_ERR_Q_EMPTY; + pmsg = (void *)0; /* Queue is empty */ + } + OS_EXIT_CRITICAL(); + return (pmsg); /* Return message received (or NULL) */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MESSAGE QUEUE +* +* Description: This function creates a message queue if free event control blocks are available. +* +* Arguments : start is a pointer to the base address of the message queue storage area. The +* storage area MUST be declared as an array of pointers to 'void' as follows +* +* void *MessageStorage[size] +* +* size is the number of elements in the storage area +* +* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created queue +* == (OS_EVENT *)0 if no event control blocks were available or an error was detected +********************************************************************************************************* +*/ + +OS_EVENT *OSQCreate (void **start, INT16U size) +{ + OS_EVENT *pevent; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */ + OS_ENTER_CRITICAL(); + pq = OSQFreeList; /* Get a free queue control block */ + if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */ + OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/ + OS_EXIT_CRITICAL(); + pq->OSQStart = start; /* Initialize the queue */ + pq->OSQEnd = &start[size]; + pq->OSQIn = start; + pq->OSQOut = start; + pq->OSQSize = size; + pq->OSQEntries = 0; + pevent->OSEventType = OS_EVENT_TYPE_Q; + pevent->OSEventCnt = 0; + pevent->OSEventPtr = pq; +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); /* Initalize the wait list */ + } else { + pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */ + OSEventFreeList = pevent; + OS_EXIT_CRITICAL(); + pevent = (OS_EVENT *)0; + } + } + return (pevent); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MESSAGE QUEUE +* +* Description: This function deletes a message queue and readies all tasks pending on the queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* queue. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the queue was deleted +* OS_ERR_DEL_ISR If you tried to delete the queue from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the queue +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the queue was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the queue MUST check the return code of OSQPend(). +* 2) OSQAccept() callers will not know that the intended queue has been deleted unless +* they check 'pevent' to see that it's a NULL pointer. +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the queue. +* 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in +* applications where the queue is used for mutual exclusion because the resource(s) +* will no longer be guarded by the queue. +* 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc() +* type call) then your application MUST release the memory storage by call the counterpart +* call of the dynamic allocation scheme used. If the queue storage was created statically +* then, the storage can be reused. +********************************************************************************************************* +*/ + +#if OS_Q_DEL_EN > 0 +OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on queue */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ + pq->OSQPtr = OSQFreeList; + OSQFreeList = pq; + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the queue */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for queue */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ + pq->OSQPtr = OSQFreeList; + OSQFreeList = pq; + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FLUSH QUEUE +* +* Description : This function is used to flush the contents of the message queue. +* +* Arguments : none +* +* Returns : OS_ERR_NONE upon success +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* WARNING : You should use this function with great care because, when to flush the queue, you LOOSE +* the references to what the queue entries are pointing to and thus, you could cause +* 'memory leaks'. In other words, the data you are pointing to that's being referenced +* by the queue entries should, most likely, need to be de-allocated (i.e. freed). +********************************************************************************************************* +*/ + +#if OS_Q_FLUSH_EN > 0 +INT8U OSQFlush (OS_EVENT *pevent) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } +#endif + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */ + pq->OSQIn = pq->OSQStart; + pq->OSQOut = pq->OSQStart; + pq->OSQEntries = 0; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON A QUEUE FOR A MESSAGE +* +* Description: This function waits for a message to be sent to a queue +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for a message to arrive at the queue up to the amount of time +* specified by this argument. If you specify 0, however, your task will wait +* forever at the specified queue or, until a message arrives. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the queue was aborted. +* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked +* +* Returns : != (void *)0 is a pointer to the message received +* == (void *)0 if you received a NULL pointer message or, +* if no message was received or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass a pointer to a queue. +* +* Note(s) : As of V2.60, this function allows you to receive NULL pointer messages. +********************************************************************************************************* +*/ + +void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + void *pmsg; + OS_Q *pq; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } + if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((void *)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ + if (pq->OSQEntries > 0) { /* See if any messages in the queue */ + pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ + pq->OSQEntries--; /* Update the number of entries in the queue */ + if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ + pq->OSQOut = pq->OSQStart; + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return message received */ + } + OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* Was task readied because timed-out or aborted?*/ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate a timeout occured */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return ((void *)0); /* No message received */ + } + pmsg = OSTCBCur->OSTCBMsg;/* No, Extract message from TCB (Put there by QPost) */ + OSTCBCur->OSTCBMsg = (void *)0; + OSTCBCur->OSTCBStat = OS_STAT_RDY; + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return message received */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A MESSAGE QUEUE +* +* Description: This function aborts & readies any tasks currently waiting on a queue. This function +* should be used to fault-abort the wait on the queue, rather than to normally signal +* the queue via OSQPost(), OSQPostFront() or OSQPostOpt(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* queue +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* queue +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the queue. +* OS_ERR_PEND_ABORT At least one task waiting on the queue was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the queue +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the queue, or upon error. +* > 0 if one or more tasks waiting on the queue are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_Q_PEND_ABORT_EN > 0 +INT8U OSQPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on queue? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on queue */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on queue */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on queue */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A QUEUE +* +* Description: This function sends a message to a queue +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. +********************************************************************************************************* +*/ + +#if OS_Q_POST_EN > 0 +INT8U OSQPost (OS_EVENT *pevent, void *pmsg) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on queue */ + /* Ready highest priority task waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + *pq->OSQIn++ = pmsg; /* Insert message into queue */ + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ + pq->OSQIn = pq->OSQStart; + } + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO THE FRONT OF A QUEUE +* +* Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at +* the front instead of the end of the queue. Using OSQPostFront() allows you to send +* 'priority' messages. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. +********************************************************************************************************* +*/ + +#if OS_Q_POST_FRONT_EN > 0 +INT8U OSQPostFront (OS_EVENT *pevent, void *pmsg) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on queue */ + /* Ready highest priority task waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */ + pq->OSQOut = pq->OSQEnd; + } + pq->OSQOut--; + *pq->OSQOut = pmsg; /* Insert message into queue */ + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A QUEUE +* +* Description: This function sends a message to a queue. This call has been added to reduce code size +* since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the +* capability to broadcast a message to ALL tasks waiting on the message queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* opt determines the type of POST performed: +* OS_POST_OPT_NONE POST to a single waiting task +* (Identical to OSQPost()) +* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue +* OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront()) +* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the +* interrupt disable time is proportional to the number of tasks waiting on the queue. +********************************************************************************************************* +*/ + +#if OS_Q_POST_OPT_EN > 0 +INT8U OSQPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */ + if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ + while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on queue */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + } + } else { /* No, Post to HPT waiting on queue */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + } + OS_EXIT_CRITICAL(); + if ((opt & OS_POST_OPT_NO_SCHED) == 0) { /* See if scheduler needs to be invoked */ + OS_Sched(); /* Find highest priority task ready to run */ + } + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + if ((opt & OS_POST_OPT_FRONT) != 0x00) { /* Do we post to the FRONT of the queue? */ + if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */ + pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */ + } + pq->OSQOut--; + *pq->OSQOut = pmsg; /* Insert message into queue */ + } else { /* No, Post as FIFO */ + *pq->OSQIn++ = pmsg; /* Insert message into queue */ + if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ + pq->OSQIn = pq->OSQStart; + } + } + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MESSAGE QUEUE +* +* Description: This function obtains information about a message queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* p_q_data is a pointer to a structure that will contain information about the message +* queue. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_Q_QUERY_EN > 0 +INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *p_q_data) +{ + OS_Q *pq; + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_q_data == (OS_Q_DATA *)0) { /* Validate 'p_q_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_q_data->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_q_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + pq = (OS_Q *)pevent->OSEventPtr; + if (pq->OSQEntries > 0) { + p_q_data->OSMsg = *pq->OSQOut; /* Get next message to return if available */ + } else { + p_q_data->OSMsg = (void *)0; + } + p_q_data->OSNMsgs = pq->OSQEntries; + p_q_data->OSQSize = pq->OSQSize; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_Q_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUEUE MODULE INITIALIZATION +* +* Description : This function is called by uC/OS-II to initialize the message queue module. Your +* application MUST NOT call this function. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_QInit (void) +{ +#if OS_MAX_QS == 1 + OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */ + OSQFreeList->OSQPtr = (OS_Q *)0; +#endif + +#if OS_MAX_QS >= 2 + INT16U i; + OS_Q *pq1; + OS_Q *pq2; + + + + OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); /* Clear the queue table */ + pq1 = &OSQTbl[0]; + pq2 = &OSQTbl[1]; + for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE control blocks */ + pq1->OSQPtr = pq2; + pq1++; + pq2++; + } + pq1->OSQPtr = (OS_Q *)0; + OSQFreeList = &OSQTbl[0]; +#endif +} +#endif /* OS_Q_EN */ diff --git a/.svn/pristine/f8/f8307ce4398aedabecc6f32d9094d6610fe3aba0.svn-base b/.svn/pristine/f8/f8307ce4398aedabecc6f32d9094d6610fe3aba0.svn-base new file mode 100644 index 0000000..8aac14a --- /dev/null +++ b/.svn/pristine/f8/f8307ce4398aedabecc6f32d9094d6610fe3aba0.svn-base @@ -0,0 +1,141 @@ +#include +#include "keyboard.h" +#include "app_serv.h" + + +#define KBRD_QUERY_LEN 4 + +OS_STK KbrdTaskStk[KBRD_TASK_STK_SIZE]; +OS_EVENT *KbrdQuery = NULL; +void *KbrdTbl[KBRD_QUERY_LEN]; + + +void KbrdTask(void *p_arg); + +unsigned short kbrd_state; + +void InitKbrd() +{ + // +/* +P0.28 MK_P24 1 +P0.27 MK_P25 2 +P3.26 MK_P26 3 +P3.25 MK_P27 a +P1.18 MK_P32 b +P1.19 MK_P33 c +*/ + // + PINSEL1_bit.P0_28 = 0x0; + PINSEL1_bit.P0_27 = 0x0; + PINSEL7_bit.P3_26 = 0x0; + + PINMODE1_bit.P0_28 = 0; + PINMODE1_bit.P0_27 = 0; + PINMODE7_bit.P3_26 = 0; + + FIO0DIR_bit.P0_28 = 1; + FIO0DIR_bit.P0_27 = 1; + FIO3DIR_bit.P3_26 = 1; + + FIO0MASK_bit.P0_28 = 0; + FIO0MASK_bit.P0_27 = 0; + FIO3MASK_bit.P3_26 = 0; + + // + PINSEL3_bit.P1_18 = 0x0; + PINSEL3_bit.P1_19 = 0x0; + PINSEL7_bit.P3_25 = 0x0; + + PINMODE3_bit.P1_18 = 0; + PINMODE3_bit.P1_19 = 0; + PINMODE7_bit.P3_25 = 0; + + FIO1DIR_bit.P1_18 = 0; + FIO1DIR_bit.P1_19 = 0; + FIO3DIR_bit.P3_25 = 0; + + FIO1MASK_bit.P1_18 = 0; + FIO1MASK_bit.P1_19 = 0; + FIO3MASK_bit.P3_25 = 0; + + // + PINSEL3_bit.P1_20 = 0x0; + PINMODE3_bit.P1_20 = 0; + FIO1DIR_bit.P1_20= 0; + FIO1MASK_bit.P1_20 = 0; + + kbrd_state = 0; + + // + if (KbrdQuery == NULL) + { + KbrdQuery = OSQCreate(&KbrdTbl[0], KBRD_QUERY_LEN); + OSTaskCreate(KbrdTask, (void *)0, (OS_STK *)&KbrdTaskStk[KBRD_TASK_STK_SIZE-1], KBRD_TASK_PRIO); + } +} + +#define KBRD_SCAN_LINE1() {FIO0CLR_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE2() {FIO0SET_bit.P0_28 = 1; FIO0CLR_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE3() {FIO0SET_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3CLR_bit.P3_26 = 1;} + +void KbrdTask(void *p_arg) +{ + unsigned short prew_state = 0; + + while (1) + { + unsigned short state; + + OSTimeDly(17); + + state = 0; + KBRD_SCAN_LINE1(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1 << KEY_F1); + if (!FIO1PIN_bit.P1_18) state |= (1 << KEY_F2); + if (!FIO1PIN_bit.P1_19) state |= (1 << KEY_F3); + KBRD_SCAN_LINE2(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1 << KEY_LEFT); + if (!FIO1PIN_bit.P1_18) state |= (1 << KEY_UP); + if (!FIO1PIN_bit.P1_19) state |= (1 << KEY_RIGHT); + KBRD_SCAN_LINE3(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1 << KEY_STOP); + if (!FIO1PIN_bit.P1_18) state |= (1 << KEY_DOWN); + if (!FIO1PIN_bit.P1_19) state |= (1 << KEY_START); + + if (!FIO1PIN_bit.P1_20) state |= (1 << KEY_USER_START); + + if (prew_state == state) + { // + if (kbrd_state ^ state) + { // + for (char i = 0; i < KEY_USER_START+1; i++) + { + // + if (!(kbrd_state & (1 << i)) && (state & (1 << i))) + { + OSQPost(KbrdQuery, (void *)i); + PostUserEvent(EVENT_KEY_EMPTY+i); // + } + } + } + kbrd_state = state; + } + + prew_state = state; + } + +} + +int GetKbrdEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(KbrdQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + \ No newline at end of file diff --git a/.svn/wc.db b/.svn/wc.db new file mode 100644 index 0000000000000000000000000000000000000000..9afc60b73d2b2f233226d0d35cba0fafc7035966 GIT binary patch literal 204800 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 +#include "CCRSProtocol.h" +#include "VMCConst.h" +#include "validator.h" +#include "uart1.h" +#include +#include +#include + +int iCmdDelay=20; +int iLastError=0; + +// crc +unsigned short crc16_ccitt(unsigned char data, unsigned short crc) +{ register unsigned short a=0x8408, d = crc, i; + d^= data; + for (i=0; i<8; i++) + {if (d & 0x0001) + {d>>= 1; + d^=a;} + else d>>=1; + } + return d; +} + +// crc +unsigned short CalculateCRC(unsigned char *pBuffer) +{ + unsigned short wCRC=0; + int Len = (pBuffer[2]) ? pBuffer[2] : ((unsigned short)pBuffer[4]<<8)+pBuffer[5]; + for (int i=0;i0) + { + if(COMPort_Recieve(BufIn+iBytesToRecieve, iLen)) + { + iRecievingError=RE_NONE; + break; + } + else + { + iRecievingError=RE_DATA; + PurgeComm(); + } + } + else + { + iRecievingError=RE_NONE; + break; + } + } + } + } + return iRecievingError; +} + + +/** + + crc + + + The function is a simple wrapper for the CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function + and performs the following actions: + -# Complementing the output frame with the device address and CRC16 + -# Sending the frame and receiving a response using CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function + -# Checking received frame integrity (by CRC16 value) + -# Returning the response wrapped in the CCommand object + + \param Cmd a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC) + \param Addr a parameter of type BYTE containing the device address used for communication. + Refer to \link Addr Device address list \endlink for the valid values + + +*/ +unsigned char tmpBuffer[256]; + +int TransmitCMD(unsigned char *Cmd, unsigned char Addr, unsigned char **data) +{ + int i=(Cmd[2]) ? Cmd[2] + : ((unsigned short)Cmd[4]<<8)+Cmd[5]; + Cmd[1] = Addr; + unsigned short wCRC=CalculateCRC(Cmd); + Cmd[i-2] = (unsigned char)wCRC; + Cmd[i-1] = (unsigned char)(wCRC>>8); + + int iErrCode=SendCommand(Cmd, tmpBuffer); + if((!iErrCode)&&(Cmd[3])&&(0xFF!=Cmd[3])) + { + if (tmpBuffer[2]) + { + wCRC = (unsigned short)tmpBuffer[tmpBuffer[2]-2]; + wCRC += (unsigned short)((unsigned short)tmpBuffer[tmpBuffer[2]-1])<<8; + } + else + { + wCRC = 0; + //wCRC=tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]: + // (((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-2]+ + // (tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]:(((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-1]<<8); + } + if(CalculateCRC(tmpBuffer)!=wCRC) iErrCode=RE_CRC; + } + *data = tmpBuffer; + return iErrCode; +} + +/** \brief The CCCRSProtocol::Transmit function carries complete protocol exchange + + The function is a simple wrapper for the CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function + and performs the following actions: + -# Sending the frame and receiving a response using CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function + -# Checking the device response and determining whether ACK or NAK should be sent + -# Sending ACK or NAK message to the device or retransmitting the command up to 3 times untill communication is successfully completed + -# Returning the response wrapped in the CCommand object + + \param CMD a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC) + \param Addr a parameter of type BYTE containing the device address used for communication. + Refer to \link Addr Device address list \endlink for the valid values + + \return CCommand - an object containing response data and communication error code + + +*/ +// , ACK , +int Transmit(unsigned char *CMD, unsigned char Addr) +{ + unsigned char *cmdRes, cmdACK[16]; + int error; + + VPend(); + for (int i=0; i<3; i++) + { + error=TransmitCMD(CMD, Addr, &cmdRes); + cmdACK[0] = SYNC; + cmdACK[2] = 6; + cmdACK[3] = ACK; + + if (error == RE_NONE) + { + if((ACK==cmdRes[3]) && (cmdRes[2]==6)) + { // + VPost(); + return error; + } + if((NAK==cmdRes[3]) && (cmdRes[2]==6)) + { + if (iCmdDelay) Sleep(iCmdDelay);//5 + } + else + { + cmdACK[3] = ACK; + TransmitCMD(cmdACK, Addr, &cmdRes); + if (iCmdDelay) Sleep(iCmdDelay);//5 + break; + } + } + else + { + if(error != RE_TIMEOUT) + { + cmdACK[3] = NAK; + TransmitCMD(cmdACK, Addr, &cmdRes); + if (iCmdDelay) Sleep(iCmdDelay);//5 + } + } + } + + VPost(); + return error; +} + +////////////////////////////////////////////////////////////////////// +// CCNET Commands implementation +/** \defgroup CCNETCommands CCNET protocol commands and requests + + The group contains member functions providing interface to CCNET commands and requests. + All functions return a bool result showing whether operation was successfully completed. + In the case of error the error code (refer to \link ErrCode Possible error codes \endlink) + is stored in the CCCRSProtocol::iLastError member variable, which can be used in further analysis. + + @{ +*/ + +/** \brief The CCCRSProtocol::CmdReset function sends a RESET command to the device + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if command was acknowledged + + +*/ + +unsigned char cc_buf[256]; + +int CC_CmdReset(unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,6,RESET,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response = Transmit(cc_buf, Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack != ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD; + return 0; + } + else + { + return 1; + } + + } + else + { + return 0; + } +} + + +/** \brief The CCCRSProtocol::CmdPoll function sends POLL command to the device + + The function sends POLL command and fills bytes Z1 and Z2 of the response into the CCCRSProtocol::PollResults structure. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange was successfully completed + + +*/ +int CC_CmdPoll(unsigned char Addr, TPollResults *PollResults) +{ + const unsigned char Data[]={SYNC,0,6,POLL,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + if(!Response) + { + PollResults->Z1 = tmpBuffer[3]; + PollResults->Z2 = tmpBuffer[4]; + return 1; + } + else + { + PollResults->Z1=0; + PollResults->Z2=0; + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdStatus function sends STATUS REQUEST to the device + + The response status data is stored in the CCCRSProtocol::BillStatus member structure. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange was successfully completed + + +*/ +int CC_CmdStatus(unsigned char Addr, TBillStatus* BillStatus) +{ + const unsigned char Data[]={SYNC,0,6,GET_STATUS,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + BillStatus->Enabled=0; + BillStatus->Security=0; + BillStatus->Routing=0; + return 0; + } + BillStatus->Enabled=tmpBuffer[5]+((unsigned long)tmpBuffer[4]<<8)+((unsigned long)tmpBuffer[3]<<16); + BillStatus->Security=tmpBuffer[8]+((unsigned long)tmpBuffer[7]<<8)+((unsigned long)tmpBuffer[6]<<16); + BillStatus->Routing=tmpBuffer[11]+((unsigned long)tmpBuffer[10]<<8)+((unsigned long)tmpBuffer[9]<<16); + return 1; + } + else + { + return 0; + } + +} + +/** \brief The CCCRSProtocol::CmdIdentification function sends IDENTIFICATION request + + The function sends IDENTIFICATION request and stores device identification in the member CCCRSProtocol::Ident structure. + The function supports both new and old identification formats of Bill-To-Bill units. + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the exchange was successfully completed and data received + + +*/ +int CC_CmdIdentification(unsigned char Addr, TIdent* Ident) +{ + const unsigned char Data[]={SYNC,0,6,IDENTIFICATION,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if (!Response) + { + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + return 0; + } + strcpy(Ident->BCCPUBoot,"N/A"); + strcpy(Ident->BCCPUVersion,"N/A"); + strcpy(Ident->BCCS1Boot,"N/A"); + strcpy(Ident->BCCS2Boot,"N/A"); + strcpy(Ident->BCCS3Boot,"N/A"); + strcpy(Ident->BCCSVersion,"N/A"); + strcpy(Ident->BCDispenserBoot,"N/A"); + strcpy(Ident->BCDispenserVersion,"N/A"); + strcpy(Ident->BVBootVersion,"N/A"); + strcpy(Ident->BVVersion,"N/A"); + strcpy(Ident->PartNumber,"N/A"); + char sTemp[64]; + int iPos=3,iLen=15; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->PartNumber,sTemp); + iLen=12; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->SN,sTemp); + char *strTemp=(char*)tmpBuffer+iPos; + + + Ident->DS1=0;iPos+=8; + for(int i=0;i<7;i++) + { + Ident->DS1<<=8; + Ident->DS1+=strTemp[i]; + } + if(tmpBuffer[2]<109) return 1; + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BVBootVersion,sTemp); + + iLen=20; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BVVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCPUBoot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCPUVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCDispenserBoot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCDispenserVersion,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS1Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS2Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCS3Boot,sTemp); + + iLen=6; + strncpy(sTemp,(char*)tmpBuffer+iPos,iLen); + sTemp[iLen]=0;iPos+=iLen; + strcpy(Ident->BCCSVersion,sTemp); + return 1; + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdHold function sends HOLD command to the device + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange successfully completed + + +*/ +int CC_CmdHold(unsigned char Addr) +{ + const unsigned char Data[256]={SYNC,0,6,HOLD,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack!=ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdSetSecurity function sends SET SECURITY LEVELS command + + \param wS a parameter of type DWORD - a bitmap containing security levels to set + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if exchange successfully completed + + +*/ +int CC_CmdSetSecurity(unsigned long wS, unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,9,SET_SECURITY,0,0,0,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + cc_buf[4]=(unsigned char)(wS>>16); + cc_buf[5]=(unsigned char)(wS>>8); + cc_buf[6]=(unsigned char)(wS); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack != ACK) + { + iLastError = (ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdBillType function sends ENABLE BILL TYPE command + + \param enBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to the enabled bill types + \param escBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to bill type processed with escrow + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool- true if the command was acknowledged + + +*/ +int CC_CmdBillType(unsigned long enBill, unsigned long escBill, unsigned char Addr) +{ + unsigned char Data[]={SYNC,0,12,BILL_TYPE, + (unsigned char)(enBill>>16),(unsigned char)(enBill>>8),(unsigned char)enBill, + (unsigned char)(escBill>>16),(unsigned char)(escBill>>8),(unsigned char)escBill, + 0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf, Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdPack function sends PACK command + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the command was acknowledged + + +*/ +int CC_CmdPack(unsigned char Addr) +{ + const unsigned char Data[]={SYNC,0,6,PACK,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + unsigned char ack; + if (!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + +/** \brief The CCCRSProtocol::CmdReturn function sends RETURN command + + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the command was acknowledged + + +*/ +int CC_CmdReturn(unsigned char Addr) +{ + const unsigned char Data[256]={SYNC,0,6,RETURN,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + unsigned char ack; + if(!Response) + { + ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + + +/** \brief The CCCRSProtocol::CmdGetBillTable function sends BILL TABLE request + + \param BillTable a parameter of type _BillRecord * containing pointer to the _BillRecord array receiving the bill table. + Position in the array corresponds to the bill type and the structure at the position describes that bill type. + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the response was successfully received + + +*/ +int CC_CmdGetBillTable(unsigned char Addr, TBillRecord *BillTable) +{ + const unsigned char Data[]={SYNC,0,6,GET_BILL_TABLE,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + int i; + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + for(int i=0;i<24;i++) + { + BillTable[i].Denomination=0; + strcpy(BillTable[i].sCountryCode,""); + } + return 0; + } + for(i=0;i>24),(unsigned char)(dwOpt>>16),(unsigned char)(dwOpt>>8),(unsigned char)dwOpt, + 0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + unsigned char ack = tmpBuffer[3]; + if(ack!=ACK) + { + iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD; + return 0; + } + else return 1; + + } + else + { + return 0; + } +} + + + +/** \brief The CCCRSProtocol::CmdGetCRC32 function sends CRC32 request + + \param dwCRC a parameter of type DWORD & containing a reference to the variable receiving CRC32 of the firmware. + \param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values + + \return bool - true if the request was answered + + +*/ +int CC_CmdGetCRC32(unsigned long *dwCRC, unsigned char Addr) +{ + unsigned char Data[]={SYNC,0,6,CRC32,0,0}; + memcpy(cc_buf, Data, sizeof(Data)); + int Response=Transmit(cc_buf,Addr); + if(!Response) + { + + if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6)) + { + iLastError=ER_INVALID_CMD; + dwCRC=0; + return 0; + } + *dwCRC=tmpBuffer[6]+((unsigned long)tmpBuffer[5]<<8)+((unsigned long)tmpBuffer[4]<<16)+((unsigned long)tmpBuffer[3]<<24); + return 1; + } + else + { + dwCRC=0; + return 0; + } +} + + + + + + + +/** @} */ \ No newline at end of file diff --git a/DRIVERS/ccnet/CCRSProtocol.h b/DRIVERS/ccnet/CCRSProtocol.h new file mode 100644 index 0000000..097c3cc --- /dev/null +++ b/DRIVERS/ccnet/CCRSProtocol.h @@ -0,0 +1,364 @@ +#ifndef _CCRSPROTOCOL_H_ +#define _CCRSPROTOCOL_H_ + +#define CC_TIME_OUT 300 + +#define SYNC 0x02 //!< synchronization byte +#define ACK 0x00 //!< ACK code +#define NAK 0xFF //!< NAK code +#define ST_INV_CMD 0x30 //!< INVALID COMMAND response + +/** \defgroup Addr Device Addresses +* @{ +*/ +#define ADDR_BB 0x01 //!< Address for Bill-To-Bill units +#define ADDR_CHANGER 0x02 //!< Address for Coin Changer +#define ADDR_FL 0x03 //!< Address for Bill Validators +#define ADDR_CR 0x04 //!< Address for Smart Card Reader +/**@} */ + +/** \defgroup Cmds Interface commands +* @{ +*/ +#define RESET 0x30 //! +#include "uart1.h" + + +void Uart1_Send(unsigned char *buf, int len) +{ + while (len--) Uart1_WrByte(*buf++); +} + + +int Uart1_Receive(unsigned char *buf, int len, int timeout) +{ + while (len--) + { + if (!Uart1_RdByteWithTimeOut(buf++, timeout)) return 0; + } + return 1; +} + + +void Uart1_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(PCLK_UART1); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART1 = 1; /* Enable the power bit for UART0 */ + + U1LCR = 0x80; /* Enable acces to Divisor latches */ + + U1DLL = divlo; /* Load divisor */ + U1DLM = divhi; + + U1FDR = 0x10; + + U1LCR = 0; + + U1MCR = 0; + U1ACR = 0; + + U1FCR_bit.FCRFE = 1; // enable fifo + + U1LCR_bit.WLS = 0x03; // 8 bit + U1LCR_bit.SBS = 0; // 1 stop bit + + U1IER = 0; + + PINSEL4_bit.P2_0 = 0x2; + PINSEL4_bit.P2_1 = 0x2; + + PINMODE4_bit.P2_0 = 0; + PINMODE4_bit.P2_1 = 0; + + FIO2DIR_bit.P2_0 = 1; + FIO2DIR_bit.P2_1 = 0; + + FIO2MASK_bit.P2_0 = 1; + FIO2MASK_bit.P2_1 = 1; + + OS_EXIT_CRITICAL(); +} + +void Uart1_WrByte(CPU_INT08U tx_byte) +{ + while (!U1LSR_bit.THRE) { + OSTimeDly(1); + } + + U1THR = tx_byte; +} + +void Uart1_Purge(void) +{ + // + U1FCR_bit.RFR = 1; +} + +int Uart1_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout) +{ + CPU_INT32U ctr = 0; + + while (!U1LSR_bit.DR) { + OSTimeDly(1); + if (++ctr > timeout) return 0; + } + + //error = U1LSR; + *byte = (CPU_INT08U)(U1RBR & 0x00FF); /* Remove the data from the holding register */ + return 1; +} diff --git a/DRIVERS/ccnet/uart1.h b/DRIVERS/ccnet/uart1.h new file mode 100644 index 0000000..041e01e --- /dev/null +++ b/DRIVERS/ccnet/uart1.h @@ -0,0 +1,11 @@ +#ifndef _UART1_H_ +#define _UART1_H_ + +extern void Uart1_Purge(void); +extern void Uart1_Send(unsigned char *buf, int len); +extern int Uart1_Receive(unsigned char *buf, int len, int timeout); +extern void Uart1_WrByte(CPU_INT08U tx_byte); +extern int Uart1_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout); +extern void Uart1_Init(CPU_INT32U baud_rate); + +#endif //#ifndef _UART0_H_ diff --git a/DRIVERS/fiscal/fiscal.c b/DRIVERS/fiscal/fiscal.c new file mode 100644 index 0000000..252a936 --- /dev/null +++ b/DRIVERS/fiscal/fiscal.c @@ -0,0 +1,802 @@ +/* + - +*/ +#include +#include "uart0.h" +#include "fiscal.h" +#include "fr.h" + +CPU_INT08U fisc_buf[256]; + + +int FiscPollExt(void) +{ + CPU_INT08U ack; + int byte; + FiscUartSendByte(FISC_ENQ); + byte = FiscUartRecieveByte(&ack, FISC_TIMEOUT); + if (!byte) return FISC_UNDEF;; + if (ack == FISC_NACK) return FISC_READY; + else if (ack == FISC_ACK) return FISC_BUSY; + return FISC_UNDEF; +} + + +// +int FiscPoll(void) +{ + CPU_INT08U ack; + FiscUartSendByte(FISC_ENQ); + if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_UNDEF;; + if (ack == FISC_NACK) return FISC_READY; + else if (ack == FISC_ACK) return FISC_BUSY; + return FISC_UNDEF; +} + +// +int FiscSendCommand(CPU_INT08U cmd, CPU_INT08U *dat, CPU_INT08U len) +{ + CPU_INT08U lrc,ack; + + FiscPurgeRx(); + + FiscUartSendByte(FISC_STX); + FiscUartSendByte(len+1); + + lrc = len+1; + FiscUartSendByte(cmd); + lrc ^= cmd; + while(len--) + { + FiscUartSendByte(*dat); + lrc ^= *dat++; + } + FiscUartSendByte(lrc); + + if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_ERR; + + if (ack == FISC_NACK) + { // 5 , + for (int i=0; i<100; i++) + { + FiscSleep(FISC_TIMEOUT); + int poll = FiscPoll(); + if (poll == FISC_READY) return FISC_OK; + else if (poll == FISC_BUSY) continue; + return FISC_ERR; + } + } + else if (ack == FISC_ACK) return FISC_OK; + + return FISC_ERR; +} + + +// +// , +int FiscReceiveAnswer(CPU_INT08U **dat, CPU_INT08U *len, CPU_INT32U timeout) +{ + CPU_INT08U byte, lrc, num; + + *dat = NULL; + *len = 0; + + // + if (!FiscUartRecieveByte(&byte, timeout)) return FISC_ERR; + if (byte != FISC_STX) return FISC_ERR; + + // + if (!FiscUartRecieveByte(&byte, FISC_TIMEOUT)) return FISC_ERR; + if (!byte) return FISC_ERR; + num = byte; + + // = byte + if (!FiscUartRecieve(fisc_buf, num, FISC_BYTE_TIMEOUT)) return FISC_ERR; + + // + if (!FiscUartRecieveByte(&byte, FISC_BYTE_TIMEOUT)) return FISC_ERR; + + // + lrc = num; + for (CPU_INT08U i=0; i 20) len = 20; + memcpy(&fisc_buf[5], str, len); + + if (FiscSendCommand(FISC_PRINT_BOLD_STRING, fisc_buf, 25) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_BOLD_STRING) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscBeep(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_BEEP, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_BEEP) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// (. 40 ) +// flags: 0 - , 1 - +int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + memset(&fisc_buf[5], 0, 40); + len = strlen((char const*)str); + if (len > 40) len = 40; + memcpy(&fisc_buf[5], str, len); + + if (FiscSendCommand(FISC_PRINT_STRING, fisc_buf, 45) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_STRING) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memset(&fisc_buf[4], 0, 30); + len = strlen((char const*)str); + if (len > 30) len = 30; + memcpy(&fisc_buf[4], str, len); + memcpy(&fisc_buf[34], &number, 2); + + if (FiscSendCommand(FISC_PRINT_DOC_HEADER, fisc_buf, 36) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 5) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DOC_HEADER) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +// 6 - long long +int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = reg; + + if (FiscSendCommand(FISC_GET_MONEY_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (9 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_MONEY_REG) || (rxdat[1] != 0)) {return FISC_ERR;} + + *value = 0; + memcpy(value, &rxdat[3], 6); + + return FISC_OK; +} + + +// +// 2 +int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = reg; + + if (FiscSendCommand(FISC_GET_OPER_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_OPER_REG) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(value, &rxdat[3], 2); + + return FISC_OK; +} + +// +int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = type; + + if (FiscSendCommand(FISC_BILL_CUT, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_BILL_CUT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + fisc_buf[5] = strnum; + + if (FiscSendCommand(FISC_PULL_OUT_TAPE, fisc_buf, 6) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PULL_OUT_TAPE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +// +int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = dir; + + if (FiscSendCommand(FISC_EJECT_UNDERLAY_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_EJECT_UNDERLAY_DOC) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// (. 40 ) +// flags: 0 - , 1 - +int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = flags; + fisc_buf[5] = flags; + memset(&fisc_buf[6], 0, 40); + len = strlen((char const*)str); + if (len > 40) len = 40; + memcpy(&fisc_buf[6], str, len); + + if (FiscSendCommand(FISC_PRINT_STRING_BY_FONT, fisc_buf, 46) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (len != 3) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_STRING_BY_FONT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_NO_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_NO_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + + +// c +int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + +// c +int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_TO_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_TO_BUF) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(100); + + return FISC_OK; +} + +// c +int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_DAY_REPORT_FROM_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_DAY_REPORT_FROM_BUF) || (rxdat[1] != 0)) {return FISC_ERR;} + + OSTimeDly(5000); + + return FISC_OK; +} + + +// +int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_SECTION_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_SECTION_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_TAXES_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_TAXES_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +// - , doc - +int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4); + fisc_buf[8] = 0; + + if (FiscSendCommand(FISC_MAKE_DEPOSIT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_DEPOSIT) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(doc, (CPU_INT08U*)&rxdat[3], 2); + + return FISC_OK; +} + +// +int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4); + fisc_buf[8] = 0; + + if (FiscSendCommand(FISC_MAKE_PAYOUT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (5 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_PAYOUT) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(doc, (CPU_INT08U*)&rxdat[3], 2); + + return FISC_OK; +} + +// +// +int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_CLICHE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_CLICHE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = param; + + if (FiscSendCommand(FISC_END_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_END_DOC) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_PRINT_ADV_TEXT, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_ADV_TEXT) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// +int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + if (FiscSendCommand(FISC_GET_DEVICE_TYPE, NULL, 0) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if ((sizeof(TFiscDevType)+2) < len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_GET_DEVICE_TYPE) || (rxdat[1] != 0)) {return FISC_ERR;} + + memcpy(dev, &rxdat[2], sizeof(TFiscDevType)); + + return FISC_OK; +} + +// +int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + fisc_buf[4] = type; + + if (FiscSendCommand(FISC_OPEN_BILL, fisc_buf, 5) != FISC_OK) + { + return FISC_ERR; + } + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) + { + return FISC_ERR; + } + + *err = rxdat[1]; + + if (3 != len) + { + return FISC_ERR; + } + + if ((rxdat[0] != FISC_OPEN_BILL) || (rxdat[1] != 0)) + { + return FISC_ERR; + } + + return FISC_OK; +} + +// +int FiscMakeSell(CPU_INT32U pass, + CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department, + CPU_INT08U* tax, char* text, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], (CPU_INT08U*)count, 5); + memcpy(&fisc_buf[9], (CPU_INT08U*)price, 5); + fisc_buf[14] = department; + memcpy(&fisc_buf[15], (CPU_INT08U*)tax, 4); + memset(&fisc_buf[19], 0, 40); + strcpy((char*)&fisc_buf[19], text); + + if (FiscSendCommand(FISC_MAKE_SELL, fisc_buf, 59) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_MAKE_SELL) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + + +// +int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4); + memcpy(&fisc_buf[4], cash, 5); + memset(&fisc_buf[9], 0, 15+2); + memcpy(&fisc_buf[26], tax, 4); + memset(&fisc_buf[30], 0, 40); + strcpy((char*)&fisc_buf[70], text); + + if (FiscSendCommand(FISC_CLOSE_BILL, fisc_buf, 70) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (8 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_CLOSE_BILL) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + +// ( ) +int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err) +{ + CPU_INT08U* rxdat; + CPU_INT08U len; + + *err = 0; + + if (FiscSendCommand(FISC_PRINT_CONTINUE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;} + + if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;} + + *err = rxdat[1]; + + if (3 != len) {return FISC_ERR;} + + if ((rxdat[0] != FISC_PRINT_CONTINUE) || (rxdat[1] != 0)) {return FISC_ERR;} + + return FISC_OK; +} + diff --git a/DRIVERS/fiscal/fiscal.h b/DRIVERS/fiscal/fiscal.h new file mode 100644 index 0000000..15927de --- /dev/null +++ b/DRIVERS/fiscal/fiscal.h @@ -0,0 +1,395 @@ +#ifndef _FISCAL_H_ +#define _FISCAL_H_ + +extern CPU_INT08U FiscalState; +#define FISCAL_NOCONN 0 +#define FISCAL_CONN 1 + +// +#define FISC_ENQ 0x05 +#define FISC_STX 0x02 +#define FISC_ACK 0x06 +#define FISC_NACK 0x15 + +// +#define FISC_SPEED 115200 + +// +#define FISC_TIMEOUT 105 +#define FISC_BYTE_TIMEOUT 10 +#define FISC_ANSWER_TIMEOUT 5000 + +// +#define FISC_GET_FACTORY_NUMBER 0x0f +#define FISC_GET_SHORT_STATUS 0x10 +#define FISC_GET_FULL_STATUS 0x11 +#define FISC_PRINT_BOLD_STRING 0x12 + #define FISC_CONTROL_TAPE 0x01 + #define FISC_BILL_TAPE 0x02 + #define FISC_UNDERLAY_DOC 0x04 +#define FISC_BEEP 0x13 +#define FISC_PRINT_STRING 0x17 +#define FISC_PRINT_DOC_HEADER 0x18 +#define FISC_GET_MONEY_REG 0x1A +#define FISC_GET_OPER_REG 0x1B +#define FISC_BILL_CUT 0x25 + #define FISC_FULL_CUT 0 + #define FISC_HALF_CUT 1 +#define FISC_PULL_OUT_TAPE 0x29 +#define FISC_EJECT_UNDERLAY_DOC 0x2A + #define FISC_EJECT_DOWN 0 + #define FISC_EJECT_UP 1 +#define FISC_PRINT_STRING_BY_FONT 0x2F +#define FISC_PRINT_DAY_REPORT_NO_CLEAR 0x40 +#define FISC_PRINT_DAY_REPORT_CLEAR 0x41 +#define FISC_PRINT_SECTION_REPORT 0x42 +#define FISC_PRINT_TAXES_REPORT 0x43 +#define FISC_MAKE_DEPOSIT 0x50 +#define FISC_MAKE_PAYOUT 0x51 +#define FISC_PRINT_CLICHE 0x52 +#define FISC_END_DOC 0x53 + #define FISC_WITHOUT_ADV 0 // + #define FISC_WITH_ADV 1 // +#define FISC_PRINT_ADV_TEXT 0x54 +#define FISC_GET_DEVICE_TYPE 0xFC + +#define FISC_OPEN_BILL 0x8D + #define FISC_BILL_SELL 0 + #define FISC_BILL_BUY 1 + +#define FISC_MAKE_SELL 0x80 +#define FISC_CLOSE_BILL 0x85 + +#define FISC_PRINT_CONTINUE 0xB0 + +#define FISC_PRINT_DAY_REPORT_TO_BUF 0xC6 +#define FISC_PRINT_DAY_REPORT_FROM_BUF 0xC7 + +// +#define FiscPurgeRx Uart0_Flush +#define FiscUartSend Uart0_Send +#define FiscUartRecieve Uart0_Receive +#define FiscUartRecieveByte Uart0_RdByteWithTimeOut +#define FiscUartSendByte Uart0_WrByte +#define FiscSleep(x) OSTimeDly(x) + +// FiscPoll() +#define FISC_READY 0 +#define FISC_BUSY -1 +#define FISC_UNDEF -2 + +// +#define FISC_OK 0 +#define FISC_ERR -1 + +// +#define FR_ERROR_CODE_1 0x1 // 1, 2 +#define FR_ERROR_CODE_2 0x2 // 1 +#define FR_ERROR_CODE_3 0x3 // 2 +#define FR_ERROR_CODE_4 0x4 // +#define FR_ERROR_CODE_5 0x5 // +#define FR_ERROR_CODE_6 0x6 // +#define FR_ERROR_CODE_7 0x7 // +#define FR_ERROR_CODE_8 0x8 // +#define FR_ERROR_CODE_9 0x9 // +#define FR_ERROR_CODE_a 0x0A // BCD +#define FR_ERROR_CODE_b 0x0B // +#define FR_ERROR_CODE_11 0x11 // +#define FR_ERROR_CODE_12 0x12 // +#define FR_ERROR_CODE_13 0x13 // +#define FR_ERROR_CODE_14 0x14 // +#define FR_ERROR_CODE_15 0x15 // +#define FR_ERROR_CODE_16 0x16 // // +#define FR_ERROR_CODE_17 0x17 // // +#define FR_ERROR_CODE_18 0x18 // // +#define FR_ERROR_CODE_19 0x19 // // +#define FR_ERROR_CODE_1a 0x1A // // +#define FR_ERROR_CODE_1b 0x1B // // +#define FR_ERROR_CODE_1c 0x1C // // +#define FR_ERROR_CODE_1d 0x1D // // +#define FR_ERROR_CODE_1f 0x1F // // +#define FR_ERROR_CODE_20 0x20 // // +#define FR_ERROR_CODE_21 0x21 // // +#define FR_ERROR_CODE_22 0x22 // // +#define FR_ERROR_CODE_23 0x23 // // +#define FR_ERROR_CODE_24 0x24 // // +#define FR_ERROR_CODE_25 0x25 // // +#define FR_ERROR_CODE_28 0x28 // 2 // +#define FR_ERROR_CODE_33 0x33 // // +#define FR_ERROR_CODE_35 0x35 // // +#define FR_ERROR_CODE_36 0x36 // // +#define FR_ERROR_CODE_37 0x37 // // +#define FR_ERROR_CODE_38 0x38 // //+ +#define FR_ERROR_CODE_39 0x39 // // +#define FR_ERROR_CODE_3a 0x3A // // +#define FR_ERROR_CODE_3c 0x3C //: // +#define FR_ERROR_CODE_3e 0x3E // // +#define FR_ERROR_CODE_3f 0x3F // // +#define FR_ERROR_CODE_40 0x40 // // +#define FR_ERROR_CODE_41 0x41 // // +#define FR_ERROR_CODE_42 0x42 // 2 // +#define FR_ERROR_CODE_43 0x43 // 3 // +#define FR_ERROR_CODE_44 0x44 // 4 +#define FR_ERROR_CODE_45 0x45 //C // +#define FR_ERROR_CODE_46 0x46 // // +#define FR_ERROR_CODE_47 0x47 // // +#define FR_ERROR_CODE_48 0x48 // // +#define FR_ERROR_CODE_4a 0x4A // - // +#define FR_ERROR_CODE_4b 0x4B // // +#define FR_ERROR_CODE_4c 0x4C // // +#define FR_ERROR_CODE_4d 0x4D // // +#define FR_ERROR_CODE_4e 0x4E // 24 // +#define FR_ERROR_CODE_4f 0x4F // // +#define FR_ERROR_CODE_50 0x50 // // +#define FR_ERROR_CODE_51 0x51 // // +#define FR_ERROR_CODE_52 0x52 // 2 // +#define FR_ERROR_CODE_53 0x53 // 3 // +#define FR_ERROR_CODE_54 0x54 // 4 // +#define FR_ERROR_CODE_56 0x56 // // +#define FR_ERROR_CODE_57 0x57 //: // +#define FR_ERROR_CODE_58 0x58 // // +#define FR_ERROR_CODE_59 0x59 // // +#define FR_ERROR_CODE_5b 0x5B // // +#define FR_ERROR_CODE_5c 0x5C // 24 +#define FR_ERROR_CODE_5d 0x5D // // +#define FR_ERROR_CODE_5e 0x5E // // +#define FR_ERROR_CODE_5f 0x5F // // +#define FR_ERROR_CODE_60 0x60 // // +#define FR_ERROR_CODE_61 0x61 // // +#define FR_ERROR_CODE_62 0x62 // // +#define FR_ERROR_CODE_63 0x63 // // +#define FR_ERROR_CODE_64 0x64 // //+ +#define FR_ERROR_CODE_65 0x65 // // +#define FR_ERROR_CODE_66 0x66 // // +#define FR_ERROR_CODE_67 0x67 // //+ +#define FR_ERROR_CODE_68 0x68 // // +#define FR_ERROR_CODE_69 0x69 // // +#define FR_ERROR_CODE_6a 0x6A // I +#define FR_ERROR_CODE_6b 0x6B // // +#define FR_ERROR_CODE_6c 0x6C // // +#define FR_ERROR_CODE_6d 0x6D // // +#define FR_ERROR_CODE_6e 0x6E // // +#define FR_ERROR_CODE_6f 0x6F // // +#define FR_ERROR_CODE_70 0x70 // // +#define FR_ERROR_CODE_71 0x71 // //+ +#define FR_ERROR_CODE_72 0x72 // // +#define FR_ERROR_CODE_73 0x73 // // +#define FR_ERROR_CODE_74 0x74 // // +#define FR_ERROR_CODE_75 0x75 // //+ +#define FR_ERROR_CODE_76 0x76 // : //+ +#define FR_ERROR_CODE_77 0x77 // : //+ +#define FR_ERROR_CODE_78 0x78 // // +#define FR_ERROR_CODE_79 0x79 // // +#define FR_ERROR_CODE_7a 0x7A // +#define FR_ERROR_CODE_7b 0x7B // // +#define FR_ERROR_CODE_7c 0x7C // // +#define FR_ERROR_CODE_7d 0x7D // // +#define FR_ERROR_CODE_7e 0x7E // // +#define FR_ERROR_CODE_7f 0x7F // // +#define FR_ERROR_CODE_80 0x80 // //+ +#define FR_ERROR_CODE_81 0x81 // //+ +#define FR_ERROR_CODE_82 0x82 // //+ +#define FR_ERROR_CODE_83 0x83 // //+ +#define FR_ERROR_CODE_84 0x84 // // +#define FR_ERROR_CODE_85 0x85 // // +#define FR_ERROR_CODE_86 0x86 // // +#define FR_ERROR_CODE_87 0x87 // // +#define FR_ERROR_CODE_88 0x88 // // +#define FR_ERROR_CODE_89 0x89 // // +#define FR_ERROR_CODE_8a 0x8A // // +#define FR_ERROR_CODE_8b 0x8B // // +#define FR_ERROR_CODE_8c 0x8C // // +#define FR_ERROR_CODE_8d 0x8D // // +#define FR_ERROR_CODE_8e 0x8E // // +#define FR_ERROR_CODE_8f 0x8F // // // +#define FR_ERROR_CODE_90 0x90 // , +#define FR_ERROR_CODE_91 0x91 // +#define FR_ERROR_CODE_92 0x92 // +#define FR_ERROR_CODE_93 0x93 // +#define FR_ERROR_CODE_94 0x94 // +#define FR_ERROR_CODE_a0 0xA0 // +#define FR_ERROR_CODE_a1 0xA1 // +#define FR_ERROR_CODE_a2 0xA2 //: +#define FR_ERROR_CODE_a3 0xA3 // +#define FR_ERROR_CODE_a4 0xA4 // +#define FR_ERROR_CODE_a5 0xA5 // +#define FR_ERROR_CODE_a6 0xA6 // +#define FR_ERROR_CODE_a7 0xA7 // +#define FR_ERROR_CODE_a8 0xA8 //: +#define FR_ERROR_CODE_a9 0xA9 //: +#define FR_ERROR_CODE_aa 0xAA // ( ) +#define FR_ERROR_CODE_b0 0xB0 //: +#define FR_ERROR_CODE_b1 0xB1 //: +#define FR_ERROR_CODE_b2 0xB2 //: +#define FR_ERROR_CODE_c0 0xC0 // ( ) +#define FR_ERROR_CODE_c1 0xC1 //: ? +#define FR_ERROR_CODE_c2 0xC2 // +#define FR_ERROR_CODE_c3 0xC3 // +#define FR_ERROR_CODE_c4 0xC4 // +//#define FR_ERROR_CODE_c5 0xC5 // +//#define FR_ERROR_CODE_c6 0xC6 // // +//#define FR_ERROR_CODE_c7 0xC7 // +//#define FR_ERROR_CODE_c8 0xC8 // // + +#define FR_ERROR_NUMBER 143 + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U FactoryNumber[7]; + CPU_INT08U RNM[7]; +}TFiscFactoryNumber; + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U OperatorNumber; // 1..30 + CPU_INT16U Flags; // + /* + ( ): + 0 (0 , 1 ) + 1 (0 , 1 ) + 2 (0 , 1 ) + 3 (0 , 1 ) + 4 (0 0 , 1 2 ) + 5 (0 , 1 ) + 6 (0 , 1 ) + 7 (0 , 1 ) + 8 (0 , 1 ) + 9 (0 , 1 ) + 10 (0 , 1 ) + 11 (0 , 1 ) + 12 (0 , 1 ) + 12 (0 , 1 ) + 13 (0 , 1 ) + 13 (0 , 1 ) + 14 (0 , 1 ) + 15 (0 , 1 + ) [ ]. (1 , 0 + ) + 15 (0 , 1 ) + */ + CPU_INT08U Mode; // + CPU_INT08U SubMode; // + CPU_INT08U BillOperationNumber_L; // - , . + CPU_INT08U BatteryVoltage; // + CPU_INT08U PowerSupplyVoltage; // + CPU_INT08U ErrorCodeFP; // + CPU_INT08U ErrorCodeEKLZ; // + CPU_INT08U BillOperationNumber_H; // - , . + CPU_INT08U Reserve[3]; // +}TFiscShortStatus; + +// +#pragma pack(1) +typedef struct{ +/* + (1 ) 130 + (2 ) + (2 ) + (3 ) -- + (1 ) + (2 ) + (2 ) + (1 ) + (1 ) + (1 ) + (2 ) + (2 ) + (3 ) -- + (3 ) -- + (3 ) -- + (1 ) + ( ): +0 1 (0 , 1 ) +1 2 (0 , 1 ) +2 (0 , 1 ) +3 (0 , 1 ) +4 (0 >80%, 1 <80%) +5 (0 , 1 ) +6 (0 , 1 ) +7 24 (0 , 1 ) + (4 ) + (2 ) + (2 ) + () (1 ) + () (1 ) + (6 ) +*/ + CPU_INT08U OperatorNumber; // 1..30 + CPU_INT08U version[4]; + CPU_INT08U version_date[3]; + CPU_INT08U nomer_v_zale; + CPU_INT16U document_number; + CPU_INT16U Flags; // + CPU_INT08U Mode; // + CPU_INT08U SubMode; // + CPU_INT08U port; + CPU_INT08U ver_fp[4]; + CPU_INT08U date_fp[3]; + CPU_INT08U date[3]; + CPU_INT08U time[3]; + CPU_INT08U fp_flags; + CPU_INT32U FactoryNumber; + CPU_INT16U LastSmena; + CPU_INT16U FpFreePlace; + CPU_INT08U perereg; + CPU_INT08U perereg_free; + CPU_INT08U inn[6]; + +}TFiscFullStatus; + +// +#pragma pack(1) +typedef struct{ + CPU_INT08U Type; // (1 ) 0255 + CPU_INT08U Subtype; // (1 ) 0255 + CPU_INT08U ProtocolVersion; // (1 ) 0255 + CPU_INT08U ProtocolSubVersion; // (1 ) 0255 + CPU_INT08U Model; // (1 ) 0255 + CPU_INT08U Language; // (1 ) 0255 0; 1; + #define FISC_LANG_RUS 0 + #define FISC_LANG_ENG 1 + CPU_INT08U Name[32]; // WIN1251. + // , , + // (X ) +}TFiscDevType; +extern TFiscDevType FiscDevInfo; + +// +extern int FiscPoll(void); +extern int FiscGetFactoryNumber(CPU_INT32U pass, TFiscFactoryNumber* fnum, CPU_INT08U* err); +extern int FiscGetShortStatus(CPU_INT32U pass, TFiscShortStatus* stat, CPU_INT08U* err); +extern int FiscGetFullStatus(CPU_INT32U pass, TFiscFullStatus* stat, CPU_INT08U* err); +extern int FiscPrintBoldString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscBeep(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err); +extern int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err); +extern int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err); +extern int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err); +extern int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err); +extern int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err); +extern int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err); +extern int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err); +extern int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err); +extern int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err); +extern int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err); +extern int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err); +extern int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err); + +extern int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err); +extern int FiscMakeSell(CPU_INT32U pass, CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department, CPU_INT08U* tax, char* text, CPU_INT08U* err); +extern int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err); + +extern int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err); +extern int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err); + +extern int FiscPollExt(void); + +#endif //#ifndef _FISCAL_H_ diff --git a/DRIVERS/fiscal/uart0.c b/DRIVERS/fiscal/uart0.c new file mode 100644 index 0000000..2db1e44 --- /dev/null +++ b/DRIVERS/fiscal/uart0.c @@ -0,0 +1,270 @@ +#include +#include "uart0.h" + +#define UART0_RX_BUFSIZE 128 +#define UART0_TX_BUFSIZE 64 + +unsigned char UART0TXBuffer[UART0_TX_BUFSIZE]; +unsigned short UART0TXhead = 0; +unsigned short UART0TXtail = 0; +unsigned short UART0TXcount = 0; +unsigned char UART0RXBuffer[UART0_RX_BUFSIZE]; +unsigned short UART0RXhead = 0; +unsigned short UART0RXtail = 0; +unsigned short UART0RXcount = 0; + + +void Uart0_Flush(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + UART0TXcount = UART0TXhead = UART0TXtail = 0; + UART0RXcount = UART0RXhead = UART0RXtail = 0; + U0IER_bit.THREIE = 0; + U0FCR = 0x06; + OS_EXIT_CRITICAL(); +} + + +int Uart0_Getc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = -1; + + if (UART0RXcount > 0) + { + UART0RXcount--; + res = UART0RXBuffer[UART0RXhead++]; + UART0RXhead %= UART0_RX_BUFSIZE; + } + OS_EXIT_CRITICAL(); + + return res; +} + +int Uart0_Gotc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART0RXcount > 0) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + + +int Uart0_Ready() +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART0TXcount < UART0_TX_BUFSIZE) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart0_Putc(unsigned char ch) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + + if (UART0TXcount < UART0_TX_BUFSIZE) + { + if (UART0TXcount == 0) + { + if (U0LSR_bit.THRE) + { + U0THR = ch; + } + else + { + UART0TXcount++; + UART0TXBuffer[UART0TXtail++] = ch; + UART0TXtail %= UART0_TX_BUFSIZE; + U0IER = 3; + } + } + else + { + UART0TXcount++; + UART0TXBuffer[UART0TXtail++] = ch; + UART0TXtail %= UART0_TX_BUFSIZE; + U0IER = 3; + } + } + else + { + res = -1; + } + OS_EXIT_CRITICAL(); + return res; +} + + +void Uart0_Isr(void) +{ + CPU_INT08U IIRValue; + CPU_INT08U u1lsr; + volatile CPU_INT08U Dummy; + + IIRValue = U0IIR; + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + + if (IIRValue == 2) /* Receive Data Available */ + { + /* Receive Data Available */ + if (U0LSR_bit.DR) + { + if (UART0RXcount < UART0_RX_BUFSIZE) + { + UART0RXBuffer[UART0RXtail++] = U0RBR; + UART0RXtail %= UART0_RX_BUFSIZE; + UART0RXcount++; + } + else + { + Dummy = U0RBR; + } + } + } + else if (IIRValue == 1) /* THRE, transmit holding register empty */ + { + /* THRE interrupt */ + if (UART0TXcount > 0) + { + U0THR = UART0TXBuffer[UART0TXhead++]; + UART0TXhead %= UART0_TX_BUFSIZE; + UART0TXcount--; + } + else + { + U0IER = 1; + } + } + else + { + Dummy = U0RBR; + u1lsr = U0LSR; + u1lsr = u1lsr; + } + +} + +void Uart0_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(3); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */ + + U0IER = 0; + + U0FCR = 0x06; // enable and reset fifo + + U0ACR = 0; + + //U1FCR = 0x01; // enable and reset fifo + + U0LCR = 0x80; /* Enable acces to Divisor latches */ + + U0DLL = divlo; /* Load divisor */ + U0DLM = divhi; + U0FDR = 0x10; + + U0LCR = 0; + + U0LCR_bit.WLS = 0x03; // 8 bit + U0LCR_bit.SBS = 0; // 1 stop bit + + U0IER = 1; + + PINSEL0_bit.P0_2 = 0x1; + PINSEL0_bit.P0_3 = 0x1; + + PINMODE0_bit.P0_2 = 0; + PINMODE0_bit.P0_3 = 0; + + FIO0DIR_bit.P0_2 = 1; + FIO0DIR_bit.P0_3 = 0; + + FIO0MASK_bit.P0_2 = 1; + FIO0MASK_bit.P0_3 = 1; + + VICINTSELECT &= ~(1 << VIC_UART0); + VICVECTADDR6 = (CPU_INT32U)Uart0_Isr; + VICINTENABLE = (1 << VIC_UART0); + + Uart0_Flush(); + + OS_EXIT_CRITICAL(); +} + + +void Uart0_WrByte(CPU_INT08U tx_byte) +{ + while (Uart0_Putc(tx_byte) != 0) OSTimeDly(1); +} + + +void Uart0_Send(unsigned char *buf, int len) +{ + while (len--) Uart0_WrByte(*buf++); +} + + +int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout) +{ + CPU_INT32U ctr = 0; + int res = -1; + + while (res < 0) { + res = Uart0_Getc(); + if (res >= 0) break; + OSTimeDly(1); + if (ctr++ > timeout) return 0; + } + + *byte = res; + return 1; +} + + +int Uart0_Receive(unsigned char *buf, int len, int timeout) +{ + while (len--) + { + if (!Uart0_RdByteWithTimeOut(buf++, timeout)) return 0; + } + return 1; +} + diff --git a/DRIVERS/fiscal/uart0.h b/DRIVERS/fiscal/uart0.h new file mode 100644 index 0000000..7a2dda2 --- /dev/null +++ b/DRIVERS/fiscal/uart0.h @@ -0,0 +1,15 @@ +#ifndef _UART0_H_ +#define _UART0_H_ + +extern void Uart0_Send(unsigned char *buf, int len); +extern int Uart0_Receive(unsigned char *buf, int len, int timeout); +extern void Uart0_Init(CPU_INT32U baud_rate); +extern void Uart0_WrByte(CPU_INT08U tx_byte); +extern void Uart0_Flush(void); +extern int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout); +extern int Uart0_Ready(); +extern int Uart0_Gotc(void); +extern int Uart0_Getc(void); +extern int Uart0_Putc(unsigned char ch); + +#endif //#ifndef _UART0_H_ diff --git a/DRIVERS/fram/fram.c b/DRIVERS/fram/fram.c new file mode 100644 index 0000000..dce3f39 --- /dev/null +++ b/DRIVERS/fram/fram.c @@ -0,0 +1,161 @@ +#include +#include "spi.h" +#include "fram.h" + +void Write_ON(unsigned short address) +{ + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_ON); + spi_unselectChip(FM25_SPI); +} + +void Write_OFF(unsigned short address) +{ + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_OFF); + spi_unselectChip(FM25_SPI); +} + +void Write_Status_Register(unsigned char byte, unsigned short address) +{ + spi_getSem(); + + Write_ON(address); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE_STATUS); + SpiExchange(FM25_SPI, byte); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); +} + +void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array) +{ + unsigned short i; + + spi_getSem(); + + Write_ON(uAddress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_WRITE); + SpiExchange(FM25_SPI, (char)(uAddress >> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)adress); + SpiExchange(FM25_SPI, byte); + spi_unselectChip(FM25_SPI); + + Write_OFF(adress); + + spi_freeSem(); +} + +unsigned char Read_Status_Register(unsigned short adress) +{ + unsigned char temp = 0; + + spi_getSem(); + + Write_OFF(adress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_READ_STATUS); + temp = SpiExchange(FM25_SPI, 0x00); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); + + return temp; +} + +void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array) +{ + unsigned short i; + + spi_getSem(); + + Write_OFF(uAddress); + + spi_selectChip(FM25_SPI); + SpiExchange(FM25_SPI, FRAM_READ); + SpiExchange(FM25_SPI, (char)(uAddress >> 8)); + SpiExchange(FM25_SPI, (char)uAddress); + for(i=0;i> 8)); + SpiExchange(FM25_SPI, (char)adress); + temp = SpiExchange(FM25_SPI, 0xFF); + spi_unselectChip(FM25_SPI); + + spi_freeSem(); + + return temp; +} + +void WriteFullControl(void) +{ + +} + diff --git a/DRIVERS/fram/fram.h b/DRIVERS/fram/fram.h new file mode 100644 index 0000000..391057d --- /dev/null +++ b/DRIVERS/fram/fram.h @@ -0,0 +1,23 @@ +#ifndef _FRAM_H_ +#define _FRAM_H_ + +#define FRAM_WRITE 0x02 +#define FRAM_READ 0x03 + +#define FRAM_WRITE_ON 0x06 +#define FRAM_WRITE_OFF 0x04 + +#define FRAM_READ_STATUS 0x05 +#define FRAM_WRITE_STATUS 0x01 + +extern void WriteByteFram(unsigned short adress,unsigned char byte); +extern unsigned char ReadByteFram(unsigned short adress); + +extern unsigned char Read_Status_Register(unsigned short adress); +extern void Write_Status_Register(unsigned char byte, unsigned short address); + +extern void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array); +extern void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array); +extern void SetArrayFram(unsigned short uAddress, unsigned short uBytesNumber, unsigned char byte); + +#endif diff --git a/DRIVERS/fram/spi.c b/DRIVERS/fram/spi.c new file mode 100644 index 0000000..81a9f01 --- /dev/null +++ b/DRIVERS/fram/spi.c @@ -0,0 +1,94 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include +#include "cpu.h" +#include "spi.h" + +OS_EVENT *SpiLock = NULL; + +unsigned char SpiExchange(unsigned char spi, unsigned char ch) +{ + SSP0DR = ch; + while(SSP0SR_bit.BSY); + return SSP0DR; +} + +void SpiInit(void) +{ + // on spi power + PCONP_bit.PCSSP0 = 1; + + // clk = cclk + PCLKSEL1_bit.PCLK_SSP0 = 1; + + // pin select + PINSEL0_bit.P0_15 = 0x2; + PINSEL1_bit.P0_16 = 0x0; // FRAM CS + PINSEL1_bit.P0_17 = 0x2; + PINSEL1_bit.P0_18 = 0x2; + + PINMODE0_bit.P0_15 = 2; + PINMODE1_bit.P0_16 = 0; + PINMODE1_bit.P0_17 = 2; + PINMODE1_bit.P0_18 = 2; + + // Chip select + FIO0MASK_bit.P0_16 = 0; + FIO0DIR_bit.P0_16 = 1; + FIO0SET_bit.P0_16 = 1; + + FIO0MASK_bit.P0_15 = 1; + FIO0MASK_bit.P0_17 = 1; + FIO0MASK_bit.P0_18 = 1; + + SSP0CR0_bit.DSS = 7; // 8-bit + SSP0CR0_bit.FRF = 0; // spi + SSP0CR0_bit.SPO = 0; + SSP0CR0_bit.SPH = 0; + SSP0CR0_bit.SCR = 1; + + SSP0CR1_bit.LBM = 0; + SSP0CR1_bit.SSE = 1; + SSP0CR1_bit.MS = 0; // master + SSP0CR1_bit.SOD = 0; + + SSP0CPSR_bit.CPSDVSR = 2; + + SSP0IMSC = 0; + SSP0DMACR = 0; + + if (!SpiLock) SpiLock = OSSemCreate(1); +} + + +unsigned char spi_selectChip(unsigned char spi) +{ + if (spi == FM25_SPI){ + FIO0CLR_bit.P0_16 = 1; + } + return 0; +} + +unsigned char spi_unselectChip(unsigned char spi) +{ + if (spi == FM25_SPI){ + FIO0SET_bit.P0_16 = 1; + } + return 0; +} + +void spi_getSem() +{ + CPU_INT08U err; + do{ + OSSemPend(SpiLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +void spi_freeSem() +{ + OSSemPost(SpiLock); +} + diff --git a/DRIVERS/fram/spi.h b/DRIVERS/fram/spi.h new file mode 100644 index 0000000..12881ad --- /dev/null +++ b/DRIVERS/fram/spi.h @@ -0,0 +1,15 @@ +#ifndef __SPI_H__ +#define __SPI_H__ + +// spi fram +#define FM25_SPI 0 + +extern unsigned char spi_unselectChip(unsigned char spi); +extern unsigned char spi_selectChip(unsigned char spi); +extern void SpiInit(void); +extern unsigned char SpiExchange(unsigned char spi, unsigned char ch); +extern void spi_getSem(); +extern void spi_freeSem(); + + +#endif //#ifndef __SPI_H__ \ No newline at end of file diff --git a/DRIVERS/keyboard/keyboard.c b/DRIVERS/keyboard/keyboard.c new file mode 100644 index 0000000..6396b3e --- /dev/null +++ b/DRIVERS/keyboard/keyboard.c @@ -0,0 +1,225 @@ +#include +#include "keyboard.h" +#include "app_serv.h" + + +#define KBRD_QUERY_LEN 4 + +OS_STK KbrdTaskStk[KBRD_TASK_STK_SIZE]; +OS_EVENT *KbrdQuery = NULL; +void *KbrdTbl[KBRD_QUERY_LEN]; + + +void KbrdTask(void *p_arg); + +unsigned long kbrd_state; + +void InitKbrd() +{ + // +/* +P0.28 MK_P24 1 +P0.27 MK_P25 2 +P3.26 MK_P26 3 +P3.25 MK_P27 a +P1.18 MK_P32 b +P1.19 MK_P33 c +*/ + // + PINSEL1_bit.P0_28 = 0x0; + PINSEL1_bit.P0_27 = 0x0; + PINSEL7_bit.P3_26 = 0x0; + + PINMODE1_bit.P0_28 = 0; + PINMODE1_bit.P0_27 = 0; + PINMODE7_bit.P3_26 = 0; + + FIO0DIR_bit.P0_28 = 1; + FIO0DIR_bit.P0_27 = 1; + FIO3DIR_bit.P3_26 = 1; + + FIO0MASK_bit.P0_28 = 0; + FIO0MASK_bit.P0_27 = 0; + FIO3MASK_bit.P3_26 = 0; + + // + PINSEL3_bit.P1_18 = 0x0; + PINSEL3_bit.P1_19 = 0x0; + PINSEL7_bit.P3_25 = 0x0; + + PINMODE3_bit.P1_18 = 0; + PINMODE3_bit.P1_19 = 0; + PINMODE7_bit.P3_25 = 0; + + FIO1DIR_bit.P1_18 = 0; + FIO1DIR_bit.P1_19 = 0; + FIO3DIR_bit.P3_25 = 0; + + FIO1MASK_bit.P1_18 = 0; + FIO1MASK_bit.P1_19 = 0; + FIO3MASK_bit.P3_25 = 0; + + // + PINSEL3_bit.P1_20 = 0x0; + PINMODE3_bit.P1_20 = 0; + FIO1DIR_bit.P1_20= 0; + FIO1MASK_bit.P1_20 = 0; + + // +/* + P1.25 MK_P39 + P1.23 MK_P37 + P1.31 MK_P20 + P0.25 MK_P7 + P1.24 MK_P38 + P0.26 MK_P6 + P1.29 MK_P45 + P0.1 MK_P47 + P2.13 MK_P50 + P2.11 MK_P52 +*/ + // 1 + PINSEL3_bit.P1_25 = 0x0; + PINMODE3_bit.P1_25 = 0; + FIO1DIR_bit.P1_25 = 0; + FIO1MASK_bit.P1_25 = 0; + + // 2 + PINSEL3_bit.P1_23 = 0x0; + PINMODE3_bit.P1_23 = 0; + FIO1DIR_bit.P1_23 = 0; + FIO1MASK_bit.P1_23 = 0; + + // 3 + PINSEL3_bit.P1_31 = 0x0; + PINMODE3_bit.P1_31 = 0; + FIO1DIR_bit.P1_31 = 0; + FIO1MASK_bit.P1_31 = 0; + + // 4 + PINSEL1_bit.P0_25 = 0x0; + PINMODE1_bit.P0_25 = 0; + FIO0DIR_bit.P0_25 = 0; + FIO0MASK_bit.P0_25 = 0; + + // 5 + PINSEL3_bit.P1_24 = 0x0; + PINMODE3_bit.P1_24 = 0; + FIO1DIR_bit.P1_24 = 0; + FIO1MASK_bit.P1_24 = 0; + + // 6 + PINSEL1_bit.P0_26 = 0x0; + PINMODE1_bit.P0_26 = 0; + FIO0DIR_bit.P0_26 = 0; + FIO0MASK_bit.P0_26 = 0; + + // 7 + PINSEL3_bit.P1_29 = 0x0; + PINMODE3_bit.P1_29 = 0; + FIO1DIR_bit.P1_29 = 0; + FIO1MASK_bit.P1_29 = 0; + + // 8 + PINSEL0_bit.P0_1 = 0x0; + PINMODE0_bit.P0_1 = 0; + FIO0DIR_bit.P0_1 = 0; + FIO0MASK_bit.P0_1 = 0; + + // 9 + PINSEL4_bit.P2_13 = 0x0; + PINMODE4_bit.P2_13 = 0; + FIO2DIR_bit.P2_13 = 0; + FIO2MASK_bit.P2_13 = 0; + + // 10 + PINSEL4_bit.P2_11 = 0x0; + PINMODE4_bit.P2_11 = 0; + FIO2DIR_bit.P2_11 = 0; + FIO2MASK_bit.P2_11 = 0; + + kbrd_state = 0; + + // + if (KbrdQuery == NULL) + { + KbrdQuery = OSQCreate(&KbrdTbl[0], KBRD_QUERY_LEN); + OSTaskCreate(KbrdTask, (void *)0, (OS_STK *)&KbrdTaskStk[KBRD_TASK_STK_SIZE-1], KBRD_TASK_PRIO); + } +} + +#define KBRD_SCAN_LINE1() {FIO0CLR_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE2() {FIO0SET_bit.P0_28 = 1; FIO0CLR_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;} +#define KBRD_SCAN_LINE3() {FIO0SET_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3CLR_bit.P3_26 = 1;} + +void KbrdTask(void *p_arg) +{ + unsigned long prew_state = 0; + + while (1) + { + unsigned long state; + + OSTimeDly(17); + + state = 0; + KBRD_SCAN_LINE1(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_F1); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_F2); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_F3); + KBRD_SCAN_LINE2(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_LEFT); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_UP); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_RIGHT); + KBRD_SCAN_LINE3(); + OSTimeDly(1); + if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_STOP); + if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_DOWN); + if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_START); + + if (!FIO1PIN_bit.P1_20) state |= (1UL << KEY_USER_START); + + if (!FIO1PIN_bit.P1_25) state |= (1UL << KEY_DEFERRED_CH1); + if (!FIO1PIN_bit.P1_23) state |= (1UL << KEY_DEFERRED_CH2); + if (!FIO1PIN_bit.P1_31) state |= (1UL << KEY_DEFERRED_CH3); + if (!FIO0PIN_bit.P0_25) state |= (1UL << KEY_DEFERRED_CH4); + if (!FIO1PIN_bit.P1_24) state |= (1UL << KEY_DEFERRED_CH5); + if (!FIO0PIN_bit.P0_26) state |= (1UL << KEY_DEFERRED_CH6); + if (!FIO1PIN_bit.P1_29) state |= (1UL << KEY_DEFERRED_CH7); + if (!FIO0PIN_bit.P0_1) state |= (1UL << KEY_DEFERRED_CH8); + if (!FIO2PIN_bit.P2_13) state |= (1UL << KEY_DEFERRED_CH9); + if (!FIO2PIN_bit.P2_11) state |= (1UL << KEY_DEFERRED_CH10); + + if (prew_state == state) + { // + if (kbrd_state ^ state) + { // + for (unsigned long i = 0; i < KEY_COUNT; i++) + { + // + if (!(kbrd_state & (1UL << i)) && (state & (1UL << i))) + { + OSQPost(KbrdQuery, (void *)i); + PostUserEvent(EVENT_KEY_EMPTY+i); // + } + } + } + kbrd_state = state; + } + + prew_state = state; + } + +} + +int GetKbrdEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(KbrdQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + \ No newline at end of file diff --git a/DRIVERS/keyboard/keyboard.h b/DRIVERS/keyboard/keyboard.h new file mode 100644 index 0000000..caa006c --- /dev/null +++ b/DRIVERS/keyboard/keyboard.h @@ -0,0 +1,37 @@ +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + + +// +#define KEY_EMPTY 0 +// +#define KEY_F1 1 +#define KEY_F2 2 +#define KEY_F3 3 +#define KEY_LEFT 4 +#define KEY_UP 5 +#define KEY_RIGHT 6 +#define KEY_STOP 7 +#define KEY_DOWN 8 +#define KEY_START 9 +// +#define KEY_USER_START 10 + +// +#define KEY_DEFERRED_CH1 11 +#define KEY_DEFERRED_CH2 12 +#define KEY_DEFERRED_CH3 13 +#define KEY_DEFERRED_CH4 14 +#define KEY_DEFERRED_CH5 15 +#define KEY_DEFERRED_CH6 16 +#define KEY_DEFERRED_CH7 17 +#define KEY_DEFERRED_CH8 18 +#define KEY_DEFERRED_CH9 19 +#define KEY_DEFERRED_CH10 20 + +#define KEY_COUNT 21 + +extern void InitKbrd(); +extern int GetKbrdEvent(int* event); + +#endif //#ifndef _KEYBOARD_H_ diff --git a/DRIVERS/lcd/lcd.c b/DRIVERS/lcd/lcd.c new file mode 100644 index 0000000..5803042 --- /dev/null +++ b/DRIVERS/lcd/lcd.c @@ -0,0 +1,333 @@ +#include +#include +#include "lcd.h" + +const unsigned char rus_sym_table[64]= + { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, + 0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, + 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, + 0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1, + 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, + 0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0, + 0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 }; + + +void us_delay(unsigned long x) +{ + while (x--) + { + for (int i=0; i<5; i++) __no_operation(); + } +} + + +void LCD_putch(unsigned char data) +{ + if (data >= 0xC0) data = rus_sym_table[data-0xC0]; + + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(100); +// OSTimeDly(1); // Wait for busy flag (BF) +} + +void LCD_putch_table(unsigned char data) +{ + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + + // E=0; write data + LCD_CLR_E_PIN(); + us_delay(100); +// OSTimeDly(1); // Wait for busy flag (BF) +} + +unsigned char LCD_getch() +{ + unsigned char data_h, data_l; + LCD_SET_DATA_IN(); + // LCD Upper 4 bits data + LCD_SET_RS_PIN(); // RS = 1, E = 1 + LCD_SET_E_PIN(); + LCD_SET_RW_PIN(); + + us_delay(1); + data_h = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 1, E = 1 + us_delay(1); + data_l = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(100); + + return (data_h << 4) | data_l; +} + + +unsigned char LCD_get_status() +{ + unsigned char data_h, data_l; + LCD_SET_DATA_IN(); + // LCD Upper 4 bits data + LCD_CLR_RS_PIN(); // RS = 0, E = 1 + LCD_SET_E_PIN(); + LCD_SET_RW_PIN(); + + us_delay(1); + data_h = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(1); + + // LCD Lower 4 bits data + LCD_SET_E_PIN(); // RS = 0, E = 1 + us_delay(1); + data_l = LCD_IN_DATA(); + LCD_CLR_E_PIN(); + us_delay(100); + + return (data_h << 4) | data_l; +} + +void LCD_putcmd(unsigned char data,unsigned char cmdtype) +{ + LCD_SET_DATA_OUT(); + // LCD Upper 4 bits data + LCD_CLR_RS_PIN(); // RS = 0, E = 1 + LCD_SET_E_PIN(); + LCD_CLR_RW_PIN(); + us_delay(1); + LCD_OUT_DATA(data >> 4); + us_delay(1); + // E=0; write data + LCD_CLR_E_PIN(); + + // cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes + if (cmdtype == LCD_2CYCLE) { + // LCD Lower 4 bits data + us_delay(1); + LCD_SET_E_PIN(); // RS = 0, E = 1 + us_delay(1); + LCD_OUT_DATA(data); + us_delay(1); + // E=0; write data + LCD_CLR_E_PIN(); + + us_delay(1); + + //while(LCD_get_status() & 0x80); + OSTimeDly(2); // Wait for busy flag (BF) + + //LCD_get_status(); + } +} + + +void InitLcdPins() +{ + /* +P2.8 MK_P65 A0 +P2.7 MK_P66 E +P2.6 MK_P67 R_W +P0.19 MK_P59 DB4 +P0.20 MK_P58 DB5 +P0.21 MK_P57 DB6 +P0.22 MK_P56 DB7 + */ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + + PINSEL4_bit.P2_8 = 0x0; + PINSEL4_bit.P2_7 = 0x0; + PINSEL4_bit.P2_6 = 0x0; + + PINMODE4_bit.P2_8 = 0; + PINMODE4_bit.P2_7 = 0; + PINMODE4_bit.P2_6 = 0; + + FIO2DIR_bit.P2_8 = 1; + FIO2DIR_bit.P2_7 = 1; + FIO2DIR_bit.P2_6 = 1; + + FIO2MASK_bit.P2_8 = 0; + FIO2MASK_bit.P2_7 = 0; + FIO2MASK_bit.P2_6 = 0; + + PINSEL1_bit.P0_19 = 0x0; + PINSEL1_bit.P0_20 = 0x0; + PINSEL1_bit.P0_21 = 0x0; + PINSEL1_bit.P0_22 = 0x0; + + PINMODE1_bit.P0_19 = 0; + PINMODE1_bit.P0_20 = 0; + PINMODE1_bit.P0_21 = 0; + PINMODE1_bit.P0_22 = 0; + + FIO0DIR_bit.P0_19 = 1; + FIO0DIR_bit.P0_20 = 1; + FIO0DIR_bit.P0_21 = 1; + FIO0DIR_bit.P0_22 = 1; + + FIO0MASK_bit.P0_19 = 0; + FIO0MASK_bit.P0_20 = 0; + FIO0MASK_bit.P0_21 = 0; + FIO0MASK_bit.P0_22 = 0; + + LCD_CLR_E_PIN(); + LCD_CLR_RW_PIN(); + LCD_CLR_RS_PIN(); + + OS_EXIT_CRITICAL(); +} + +unsigned char test = 0; + +void InitLcd() +{ + InitLcdPins(); + + // Wait for more than 15 ms after VCC rises to 4.5 V + OSTimeDly(30); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Send Command 0x30 + LCD_putcmd(0x30,LCD_1CYCLE); + us_delay(40); + // Function set: Set interface to be 4 bits long (only 1 cycle write). + LCD_putcmd(0x20,LCD_1CYCLE); + us_delay(40); + // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font) + LCD_putcmd(0x28,LCD_2CYCLE); + // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off + LCD_putcmd(0x08,LCD_2CYCLE); + // Display Clear + LCD_putcmd(0x01,LCD_2CYCLE); + // Entry Mode Set: I/D=1; Increment, S=0; No shift + LCD_putcmd(0x06,LCD_2CYCLE); + // Display On, Cursor Off + LCD_putcmd(0x0C,LCD_2CYCLE); + + +} + +void LCD_gotoline(unsigned char n) +{ + switch (n){ + case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); break; + case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); break; + case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); break; + case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); break; + default: return; + } +} + +// n +void LCD_puts(unsigned char *s, unsigned char n) +{ + unsigned char i; + LCD_gotoline(n); + + i=0; + while((*s != 0) && (*s != '\n') && (i<20)) + { + LCD_putch(*s); + s++; + i++; + } + + while(i<20) + { + LCD_putch(' '); + i++; + } +} + + +void LCD_goto(unsigned char m, unsigned char n) +{ + switch (n){ + case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); break; + case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); break; + case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); break; + case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); break; + default: return; + } +} + +// n m +void LCD_putc(unsigned char c, unsigned char m, unsigned char n) +{ + LCD_goto(m, n); + LCD_putch(c); +} + +// n m +void LCD_putc_embed(unsigned char c, unsigned char m, unsigned char n) +{ + LCD_goto(m, n); + LCD_putch_table(c); +} + + +void LCD_clear(void) +{ + // Display Clear + LCD_putcmd(0x01,LCD_2CYCLE); +} + +void LCD_cursor_on(void) +{ + LCD_putcmd(0x0F,LCD_2CYCLE); +} + +void LCD_cursor_off(void) +{ + LCD_putcmd(0x0C,LCD_2CYCLE); +} + diff --git a/DRIVERS/lcd/lcd.h b/DRIVERS/lcd/lcd.h new file mode 100644 index 0000000..15dbfb3 --- /dev/null +++ b/DRIVERS/lcd/lcd.h @@ -0,0 +1,50 @@ +#ifndef __LCD_H__ +#define __LCD_H__ + +/*! + + ks066, 4 + +*/ + +#define LCD_HOME 0x02 +#define LCD_CLEAR 0x01 +#define LCD_GOTO_LINE_0 0x80 +#define LCD_GOTO_LINE_1 0xC0 +#define LCD_GOTO_LINE_2 0x94 +#define LCD_GOTO_LINE_3 0xD4 +#define LCD_1CYCLE 0 +#define LCD_2CYCLE 1 + + +#define LCD_PORT PORTB + #define D4_pin PB4 + #define D5_pin PB5 + #define D6_pin PB6 + #define D7_pin PB7 + +#define LCD_SET_E_PIN() {FIO2SET_bit.P2_7 = 1;} +#define LCD_CLR_E_PIN() {FIO2CLR_bit.P2_7 = 1;} + +#define LCD_SET_RW_PIN() {FIO2SET_bit.P2_6 = 1;} +#define LCD_CLR_RW_PIN() {FIO2CLR_bit.P2_6 = 1;} + +#define LCD_SET_RS_PIN() {FIO2SET_bit.P2_8 = 1;} +#define LCD_CLR_RS_PIN() {FIO2CLR_bit.P2_8 = 1;} + +#define LCD_OUT_DATA(x) {FIO0PIN &= ~(0x0fL << 19); FIO0PIN |= (((x) & 0xf) << 19);} +#define LCD_IN_DATA() ((FIO0PIN >> 19) & 0x0f) +#define LCD_SET_DATA_IN() {FIO0DIR &= ~(0x0fL << 19);} +#define LCD_SET_DATA_OUT() {FIO0PIN |= (0x0fL << 19);} + + +extern void InitLcd(); +extern void LCD_puts(unsigned char *s, unsigned char n); +extern void LCD_putc(unsigned char c, unsigned char n, unsigned char m); +extern void LCD_clear(void); +extern void LCD_putc_embed(unsigned char c, unsigned char n, unsigned char m); +extern void LCD_cursor_on(void); +extern void LCD_cursor_off(void); +extern void LCD_goto(unsigned char n, unsigned char m); + +#endif //#ifndef __LCD_H__ diff --git a/DRIVERS/modem/modem.c b/DRIVERS/modem/modem.c new file mode 100644 index 0000000..49ad8af --- /dev/null +++ b/DRIVERS/modem/modem.c @@ -0,0 +1,935 @@ +#include +#include "modem.h" +#include "modem_task.h" +#include "app_serv.h" +#include "data.h" +#include "datadesc.h" +#include "uart2.h" + +static char additional_buf[256]; + +#define ModemUart_Ready Uart2_Ready +#define ModemComPortFlush Uart2_Flush +#define ModemUart_Getc Uart2_Getc +#define ModemUart_Gotc Uart2_Gotc +#define ModemUart_Putc Uart2_Putc +#define ModemUart_Init Uart2_Init + + +static OS_EVENT *ModemLock = NULL; +static char modem_buf[512]; +static int modem_connected; + +// +static void GetModem(void) +{ + CPU_INT08U err; + while (1) + { + OSSemPend(ModemLock, 1, &err); + if (!err) break; + OSTimeDly(1); + } +} + +// +static void FreeModem(void) +{ + OSSemPost(ModemLock); +} + +// +static void ModemWriteStr(char const *str) +{ + while (*str != 0) + { + while (!ModemUart_Ready()) OSTimeDly(1); + ModemUart_Putc(*str++); + } +} + +// +static int ModemReadStr(char *str, unsigned long timeout) +{ + int byte_ctr = 0; + while (byte_ctr < 256) + { + CPU_INT08U byte; + unsigned long to = timeout; + + while (!ModemUart_Gotc()) + { + if (to == 0) + { + *str = 0x00; + return 0; + } + OSTimeDly(1); + to--; + } + + int ch = ModemUart_Getc(); + if (ch < 0) + { + *str = 0x00; + return 0; + } + + byte = (char)ch; + *str++ = byte; + byte_ctr++; + if (byte == 0x0a) break; + } + + *str = 0x00; + return 1; +} + +static int ModemReadByte(CPU_INT08U *byte, unsigned long timeout) +{ + unsigned long ctr = 0; + + while (!ModemUart_Gotc()) + { + OSTimeDly(1); + ctr++; + if (ctr > timeout) return 0; + } + + *byte = (CPU_INT08U)ModemUart_Getc(); + return 1; +} + +// +static int ModemReadStrAndComp(char *str, char const *format, unsigned long timeout) +{ + int result; + + if (ModemReadStr(str, timeout)) + { + result = strcmp ((char *)str, (char const *)format); + } + else + { + return -1; + } + + return result; +} + +// / +int InitModem(void) +{ + int result; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT32U val; + + OS_ENTER_CRITICAL(); + email_options.valid = 0; + modem_connected = 0; + OS_EXIT_CRITICAL(); + + GetData(&EnableModemDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + if (val) + { + PINSEL1_bit.P0_24 = 0x0; + PINMODE1_bit.P0_24 = 0; + FIO0DIR_bit.P0_24 = 1; + FIO0MASK_bit.P0_24 = 0; + FIO0CLR_bit.P0_24 = 1; + OSTimeDly(1000); + FIO0SET_bit.P0_24 = 1; + + OSTimeDly(60000); + + ModemUart_Init(115200); + + if (!ModemLock) ModemLock = OSSemCreate(1); + + GetModem(); + + // + sprintf(modem_buf, "AT\r\n"); + result = ModemSendOKCommand(modem_buf, 1000); + if (result != 0) + { + FreeModem(); + goto EXIT_INIT; + } + + // , + sprintf(modem_buf, "AT+CPIN?\r\n"); + result = ModemSendOKCommand(modem_buf, 1000); + if (result != 0) + { + FreeModem(); + goto EXIT_INIT; + } + + FreeModem(); + + OS_ENTER_CRITICAL(); + modem_connected = 1; + OS_EXIT_CRITICAL(); + + OSTimeDly(1000); + + result = InitModemEmailParams(); + } + else + { + result = 0; + } +EXIT_INIT: + // + if (ModemQuery == NULL) + { + ModemQuery = OSQCreate(&ModemTbl[0], MODEM_QUERY_LEN); + OSTaskCreate(ModemTask, (void *)0, (OS_STK *)&ModemTaskStk[MODEM_TASK_STK_SIZE-1], MODEM_TASK_PRIO); + } + return result; +} + + + +// - - +int ModemSendSMSMessage(char const* number, char const* text) +{ + char i; + + GetModem(); + + if (ModemWriteSMS(text, (unsigned char*)&i)) {FreeModem(); return -1;} + ModemComPortFlush(); + OSTimeDly(200); + if (ModemSendSMS(number, i)) {FreeModem(); return -1;} + ModemComPortFlush(); + OSTimeDly(200); + if (ModemDeleteSMS(i)) {FreeModem(); return -1;} + OSTimeDly(200); + ModemComPortFlush(); + + FreeModem(); + return 0; +} + + +// +int ModemReadSMS(char *text, int index) +{ + unsigned char count; + char *ptr; + + GetModem(); + ModemComPortFlush(); + sprintf((char*)modem_buf, "AT+CMGR=%d\r\n", index); + ModemWriteStr(modem_buf); + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + + // + count = 0; + while (count < 160) + { + modem_buf[0] = 0; + if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;} + if (strcmp(modem_buf, "OK\r\n") == 0) + { + break; + } + else if (strlen(modem_buf) != 0) + { + // + ptr = (char*)modem_buf; + if (strlen((char const*)modem_buf) < 1) {FreeModem(); return -1;} + while (*ptr) {*text++ = *ptr++; count++;} + } + else + { + break; + } + } + + FreeModem(); + return 0; +} + + +// index +int ModemSendSMS(char const* number, unsigned char index) +{ + GetModem(); + + sprintf((char*)modem_buf, "AT+CMSS=%d,%s\r\n", index, number); + ModemWriteStr(modem_buf); + if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;} + if (!ModemReadStr(modem_buf, 10000)) {FreeModem(); return -1;} + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMSS:")) {FreeModem(); return -1;} + if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;} + if (ModemReadStrAndComp(modem_buf, "OK\r\n", 10000)) {FreeModem(); return -1;} + + FreeModem(); + return 0; +} + + +// index +int ModemDeleteSMS(unsigned char index) +{ + int result; + GetModem(); + sprintf((char*)modem_buf, "AT+CMGD=%d\r\n",index); + result = ModemSendOKCommand(modem_buf, 1000); + FreeModem(); + return result; +} + +// , index , +int ModemWriteSMS(char const* text, unsigned char *index) +{ + CPU_INT08U byte; + unsigned long word; + int result; + + GetModem(); + + // + ModemWriteStr("AT+CMGW\r\n"); + if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;} + + if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;} + if (byte != '>') {FreeModem(); return -1;} + + if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;} + if (byte != ' ') {FreeModem(); return -1;} + + // + ModemWriteStr(text); + // + ModemUart_Putc(0x1a); + // + if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;} + // , + if (!ModemReadStr(modem_buf, 5000)) {FreeModem(); return -1;} + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMGW:")) {FreeModem(); return -1;} + { + int len = strlen((char const*)&modem_buf[7]); + if (len == 3) word = modem_buf[7]-0x30; + else if (len == 4) {word = (modem_buf[7]-0x30)*10 + (modem_buf[8]-0x30);} + } + + *index = (unsigned char)word; + + result = ModemReadStrAndComp(modem_buf, "\r\n", 1000) + ModemReadStrAndComp(modem_buf, "OK\r\n", 1000); + FreeModem(); + // + return result; +} + +// , "OK" +// 0 +int ModemSendOKCommand(char *str, unsigned long timeout) +{ + int i; + + ModemComPortFlush(); + + ModemWriteStr(str); + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "OK\r\n") == 0) + { + return 0; + } + else if (strcmp(str, "ERROR\r\n") == 0) + { + return -2; + } + + continue; + } + else + { + return -1; + } + } + + return -3; +} + +int ModemSendOKData(char *str, int len, unsigned long timeout) +{ + int i; + + ModemComPortFlush(); + + for (i = 0; i < len; i++) + { + while (!ModemUart_Ready()) OSTimeDly(1); + ModemUart_Putc(str[i]); + } + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "OK\r\n") == 0) + { + return 0; + } + else if (strcmp(str, "ERROR\r\n") == 0) + { + return -2; + } + + continue; + } + else + { + return -1; + } + } + + return -3; +} + + +// , , "\r\n" +// 0 +int ModemSendCommand(char *str, unsigned long timeout) +{ + CPU_INT08U i; + + ModemComPortFlush(); + + ModemWriteStr(str); + + i = MODEM_REPEAT_RX; + while (i--) + { + if (ModemReadStr(str, timeout)) + { + if (strcmp(str, "\r\n") == 0) + { + continue; + } + else + { + return 0; + } + } + else + { + return -1; + } + } + + return -3; +} + + +// , num , +int ModemRxNewSMS(unsigned long *num) +{ + int len; + + GetModem(); + + if (!ModemReadStr(modem_buf, 10)) {FreeModem(); return 0;} + + if (!strcmp((char const*)modem_buf, "\r\n")) + { + // + if (!ModemReadStr(modem_buf, 100)) {FreeModem(); return 0;} + } + + if (strlen((char const*)modem_buf) < 13) {FreeModem(); return 0;} + + modem_buf[6] = 0; + if (strcmp((char const*)modem_buf, "+CMTI:")) {FreeModem(); return 0;} + + len = strlen((char*)&modem_buf[12]); + if (len == 3) *num = modem_buf[12]-0x30; + else if (len == 4) {*num = (modem_buf[12]-0x30)*10 + (modem_buf[13]-0x30);} + + OSTimeDly(200); + FreeModem(); + return 1; +} + +typedef struct +{ + char const *name; // + char *dest; // +} CfgElem; + +static const CfgElem email_cfg_list[EMAIL_CFG_ELEM_COUNT] = +{ + {"[receiver]=", email_options.receiver}, + {"[ap_dns]=", email_options.ap_dns}, + {"[ap_password]=", email_options.ap_password}, + {"[ap_ip]=", email_options.ap_ip}, + {"[ap_user]=", email_options.ap_user}, + {"[ap_apn]=", email_options.ap_apn}, + {"[smtp_user]=", email_options.smtp_user}, + {"[smtp_password]=", email_options.smtp_password}, + {"[smtp_mail]=", email_options.smtp_mail}, + {"[smtp_server]=", email_options.smtp_server}, + {"[smtp_port]=", email_options.smtp_port} +}; + + +// +int InitModemEmailParams(void) +{ + CPU_INT08U i, j; + char *text; + CPU_INT32U status = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + text = additional_buf; + + OS_ENTER_CRITICAL(); + email_options.valid = 0; + OS_EXIT_CRITICAL(); + + for (i = 1; i < 24; i++) + { + if (ModemReadSMS(text, i)) + { + // + continue; + } + + for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++) + { + int str_len = strlen(email_cfg_list[j].name); + char flag = 0; + while (str_len--) + { + if (email_cfg_list[j].name[str_len] != text[str_len]) + { + flag = 1; + break; + } + } + if (!flag) + { + strcpy(email_cfg_list[j].dest, &text[strlen(email_cfg_list[j].name)]); + for (str_len = 0; str_len < 64; str_len++) + { + if (email_cfg_list[j].dest[str_len] == 0) break; + if (email_cfg_list[j].dest[str_len] == '\r') {email_cfg_list[j].dest[str_len] = 0; break;} + if (email_cfg_list[j].dest[str_len] == '\n') {email_cfg_list[j].dest[str_len] = 0; break;} + } + + // + status |= 1L << j; + break; + } + } + + OSTimeDly(200); + } + + i = 1; + for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++) + { + if ((status & (1 << j)) == 0) + { + i = 0; + break; + } + } + + OS_ENTER_CRITICAL(); + email_options.valid = i; + OS_EXIT_CRITICAL(); + + return 0; +} + +void ResetModemValid(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + email_options.valid = 0; + modem_connected = 0; + OS_EXIT_CRITICAL(); +} + + +// , ( ) +CPU_INT08U IsModemValid(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (email_options.valid && modem_connected) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + +CPU_INT08U IsModemConn(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (modem_connected) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + +CPU_INT08U IsModemConf(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT08U result = 0; + + OS_ENTER_CRITICAL(); + if (email_options.valid) + { + result = 1; + } + OS_EXIT_CRITICAL(); + + return result; +} + + +// .. , , +int ModemConfigGprs() +{ + int repeat = 0; + if (!email_options.valid) return -1; + + GetModem(); + +REP_1: + sprintf(modem_buf, "AT^SICS=0,conType,GPRS0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + sprintf(modem_buf, "AT^SISC=0\r\n"); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + OSTimeDly(500); + if (repeat++ == 0) goto REP_1; + FreeModem(); + return -5; + } + + sprintf(modem_buf, "AT^SICS=0,inactTO,\"20\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -6; + } + + sprintf(modem_buf, "AT^SICS=0,dns1,\"%s\"\r\n", email_options.ap_dns); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -7; + } + + sprintf(modem_buf, "AT^SICS=0,passwd,\"%s\"\r\n", email_options.ap_password); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -8; + } + + sprintf(modem_buf, "AT^SICS=0,apn,\"%s\"\r\n", email_options.ap_apn); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -9; + } + + sprintf(modem_buf, "AT^SICS=0,user,\"%s\"\r\n", email_options.ap_user); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -10; + } + + FreeModem(); + return 0; +} + +int ModemConfigSmtp() +{ + int repeat = 0; + if (!email_options.valid) return -1; + + GetModem(); +REP_2: + // Select service type SMTP. + sprintf(modem_buf, "AT^SISS=0,srvType,\"Smtp\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + sprintf(modem_buf, "AT^SISC=0\r\n"); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + OSTimeDly(10000); + if (repeat++ == 0) goto REP_2; + FreeModem(); + return -25; + } + + // Choose ASCII alphabet. + sprintf(modem_buf, "AT^SISS=0,alphabet,\"1\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -26; + } + + // Select connection profile 0. + sprintf(modem_buf, "AT^SISS=0,conId,\"0\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -27; + } + + // Specify SMTP server address. + sprintf(modem_buf, "AT^SISS=0,address,\"%s\"\r\n", email_options.smtp_server); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -28; + } + + // Specify sender's user name required for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,user,\"%s\"\r\n", email_options.smtp_user); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -29; + } + + // Specify password used by the sender for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,passwd,\"%s\"\r\n", email_options.smtp_password); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -30; + } + + // Sender name and password can be used for SMTP authentication. + sprintf(modem_buf, "AT^SISS=0,smAuth,\"1\"\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -31; + } + + // Port for SMTP connection. + sprintf(modem_buf, "AT^SISS=0,tcpPort,\"%s\"\r\n", email_options.smtp_port); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -32; + } + + FreeModem(); + return 0; +} + +// : , +// callback , +int ModemSendEmail(char *subj, TextCallbackFunc text_callback) +{ + char *text; + int result = -1; + + if (!email_options.valid) return -50; + + result = ModemConfigGprs(); + if (result) + { + return result; + } + + result = ModemConfigSmtp(); + if (result) + { + return result; + } + + GetModem(); + + // Sender's email address. + sprintf(modem_buf, "AT^SISS=0,smFrom,\"%s\"\r\n", email_options.smtp_mail); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -51; + } + + // Recipient's email address. + sprintf(modem_buf, "AT^SISS=0,smRcpt,\"%s\"\r\n", email_options.receiver); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -52; + } + + // Enter text for subject field. + sprintf(modem_buf, "AT^SISS=0,smSubj,\"%s\"\r\n", subj); + if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0) + { + FreeModem(); + return -53; + } + + sprintf(modem_buf, "AT^SISC=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + FreeModem(); + return -54; + } + + OSTimeDly(5000); + // Open the service, i.e. start to send the email. + sprintf(modem_buf, "AT^SISO=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + FreeModem(); + return -55; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + FreeModem(); + return -56; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + FreeModem(); + return -57; + } + + if (strcmp(modem_buf, "^SISW: 0, 1\r\n") != 0) + { + return -58; + } + + text = additional_buf; + + OSTimeDly(1000); + + // + while (text_callback(text) == 0) + { + int lenght = strlen(text); + int wr_len, reg, eof; + int wr_ctr = 0; + + while (wr_ctr < lenght) + { + sprintf(modem_buf, "AT^SISW=0,%d\r\n", lenght-wr_ctr); + if (ModemSendCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + result = -59; + goto EMAIL_EXIT_FAIL; + } + + sscanf(modem_buf, "^SISW: %d, %d, %d", ®, &wr_len, &eof); + + if ((reg != 0) || (eof != 0) || (wr_len > lenght-wr_ctr) || (wr_len == 0)) + { + result = -60; + goto EMAIL_EXIT_FAIL; + } + + if (ModemSendOKData(text, wr_len, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -61; + goto EMAIL_EXIT_FAIL; + } + + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) + { + result = -62; + goto EMAIL_EXIT_FAIL; + } + + wr_ctr += wr_len; + OSTimeDly(50); + } + } + + // Set the to mark the end of the email body. + // The is accepted by the service. + sprintf(modem_buf, "AT^SISW=0,0,1\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -63; + goto EMAIL_EXIT_FAIL; + } + + // The "^SISW" URC confirms that all data is sent suc-cessfully. + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // odoa + { + result = -64; + goto EMAIL_EXIT_FAIL; + } + if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // ^sisw + { + result = -65; + goto EMAIL_EXIT_FAIL; + } + if (strcmp(modem_buf, "^SISW: 0, 2\r\n") != 0) + { + result = -66; + goto EMAIL_EXIT_FAIL; + } + + // Close the service. + sprintf(modem_buf, "AT^SISC=0\r\n"); + if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0) + { + result = -67; + goto EMAIL_EXIT_FAIL; + } + + FreeModem(); + return 0; + +EMAIL_EXIT_FAIL: + sprintf(modem_buf, "AT^SISC=0\r\n"); + OSTimeDly(10000); + ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT); + FreeModem(); + return result; +} + diff --git a/DRIVERS/modem/modem.h b/DRIVERS/modem/modem.h new file mode 100644 index 0000000..ea6294e --- /dev/null +++ b/DRIVERS/modem/modem.h @@ -0,0 +1,63 @@ +#ifndef __MODEM_H__ +#define __MODEM_H__ + +#define MODEM_REPEAT_RX 5 +#define MODEM_RX_TIMEOUT 5000 +#define MODEM_OPEN_SERVICE_TIMEOUT 30000 + +/* + strings.append("[receiver]=" + config.get('Receiver', 'email')) + strings.append("[ap_dns]=" + config.get('AccessPoint', 'dns', '')) + strings.append("[ap_password]=" + config.get('AccessPoint', 'password', '')) + strings.append("[ap_ip]=" + config.get('AccessPoint', 'ip', '')) + strings.append("[ap_user]=" + config.get('AccessPoint', 'user', '')) + strings.append("[ap_apn]=" + config.get('AccessPoint', 'apn', '')) + strings.append("[smtp_user]=" + config.get('Smtp', 'user', '')) + strings.append("[smtp_password]=" + config.get('Smtp', 'password', '')) + strings.append("[smtp_mail]=" + config.get('Smtp', 'mail', '')) + strings.append("[smtp_server]=" + config.get('Smtp', 'smtp_server', '')) + strings.append("[smtp_port]=" + config.get('Smtp', 'port', '25')) +*/ +typedef struct +{ + char receiver[64]; + char ap_dns[64]; + char ap_password[64]; + char ap_ip[64]; + char ap_user[64]; + char ap_apn[64]; + char smtp_user[64]; + char smtp_password[64]; + char smtp_mail[64]; + char smtp_server[64]; + char smtp_port[64]; + + CPU_INT08U valid; +} EmailOptions; +static EmailOptions email_options; + +#define EMAIL_CFG_ELEM_COUNT 11 + + +typedef int (*TextCallbackFunc)(char *str); + + +extern int InitModem(void); +extern void ModemWriteStr(char const *str); +extern int ModemSendOKCommand(char *str, unsigned long timeout); +extern int ModemDeleteSMS(unsigned char index); +extern int ModemWriteSMS(char const* text, unsigned char *index); +extern int ModemSendSMS(char const* number, unsigned char index); +extern int ModemReadSMS(char *text, int index); +extern int ModemSendSMSMessage(char const* number, char const* text); +extern int ModemRxNewSMS(unsigned long *num); +extern int ModemSendCommand(char *str, unsigned long timeout); +extern CPU_INT08U IsModemConn(void); +extern CPU_INT08U IsModemConf(void); + +extern int InitModemEmailParams(void); +extern int ModemSendEmail(char *subj, TextCallbackFunc text_callback); +extern CPU_INT08U IsModemValid(void); +extern void ResetModemValid(void); + +#endif //#ifndef __MODEM_H__ diff --git a/DRIVERS/modem/uart2.c b/DRIVERS/modem/uart2.c new file mode 100644 index 0000000..0284545 --- /dev/null +++ b/DRIVERS/modem/uart2.c @@ -0,0 +1,228 @@ +#include +#include "uart2.h" + + +static unsigned char UART2TXBuffer[UART2_TX_BUFSIZE]; +static unsigned short UART2TXhead = 0; +static unsigned short UART2TXtail = 0; +static unsigned short UART2TXcount = 0; +static unsigned char UART2RXBuffer[UART2_RX_BUFSIZE]; +static unsigned short UART2RXhead = 0; +static unsigned short UART2RXtail = 0; +static unsigned short UART2RXcount = 0; + + +void Uart2_Flush(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + UART2TXcount = UART2TXhead = UART2TXtail = 0; + UART2RXcount = UART2RXhead = UART2RXtail = 0; + U2IER_bit.THREIE = 0; + U2FCR = 0x06; + OS_EXIT_CRITICAL(); +} + +int Uart2_Getc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = -1; + + if (UART2RXcount > 0) + { + UART2RXcount--; + res = UART2RXBuffer[UART2RXhead++]; + UART2RXhead %= UART2_RX_BUFSIZE; + } + OS_EXIT_CRITICAL(); + + return res; +} + +int Uart2_Gotc(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART2RXcount > 0) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart2_Ready(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + if (UART2TXcount < UART2_TX_BUFSIZE) res = 1; + OS_EXIT_CRITICAL(); + return res; +} + +int Uart2_Putc(unsigned char ch) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int res = 0; + + if (UART2TXcount < UART2_TX_BUFSIZE) + { + if (UART2TXcount == 0) + { + if (U2LSR_bit.THRE) + { + U2THR = ch; + } + else + { + UART2TXcount++; + UART2TXBuffer[UART2TXtail++] = ch; + UART2TXtail %= UART2_TX_BUFSIZE; + U2IER = 3; + } + } + else + { + UART2TXcount++; + UART2TXBuffer[UART2TXtail++] = ch; + UART2TXtail %= UART2_TX_BUFSIZE; + U2IER = 3; + } + } + else + { + res = -1; + } + OS_EXIT_CRITICAL(); + return res; +} + +static void Uart2_Isr(void) +{ + CPU_INT08U IIRValue; + CPU_INT08U u1lsr; + volatile CPU_INT08U Dummy; + + IIRValue = U2IIR; + IIRValue >>= 1; /* skip pending bit in IIR */ + IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ + + if (IIRValue == 2) /* Receive Data Available */ + { + /* Receive Data Available */ + if (U2LSR_bit.DR) + { + if (UART2RXcount < UART2_RX_BUFSIZE) + { + UART2RXBuffer[UART2RXtail++] = U2RBR; + UART2RXtail %= UART2_RX_BUFSIZE; + UART2RXcount++; + } + else + { + Dummy = U2RBR; + } + } + } + else if (IIRValue == 1) /* THRE, transmit holding register empty */ + { + /* THRE interrupt */ + if (UART2TXcount > 0) + { + U2THR = UART2TXBuffer[UART2TXhead++]; + UART2TXhead %= UART2_TX_BUFSIZE; + UART2TXcount--; + } + else + { + U2IER = 1; + } + } + else + { + Dummy = U2RBR; + u1lsr = U2LSR; + u1lsr = u1lsr; + } + +} + +void Uart2_Init(CPU_INT32U baud_rate) +{ + float div_fp; /* Baud rate divisor floating point precision */ + CPU_INT16U div_int; /* Baud rate divisor floating point precision */ + CPU_INT08U divlo; + CPU_INT08U divhi; + CPU_INT32U pclk_freq; + + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + pclk_freq = BSP_CPU_PclkFreq(PCLK_UART2); /* Get peripheral clock frequency */ + + div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */ + div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */ + + divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */ + divhi = (div_int >> 8) & 0x00FF; + + PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */ + + U2IER = 0; + + U2FCR = 0x06; // enable and reset fifo + + U2ACR = 0; + + //U1FCR = 0x01; // enable and reset fifo + + U2LCR = 0x80; /* Enable acces to Divisor latches */ + + U2DLL = divlo; /* Load divisor */ + U2DLM = divhi; + U2FDR = 0x10; + + U2LCR = 0; + + U2LCR_bit.WLS = 0x03; // 8 bit + U2LCR_bit.SBS = 0; // 1 stop bit + + U2IER = 1; + + PINSEL0_bit.P0_10 = 0x1; + PINSEL0_bit.P0_11 = 0x1; + + PINMODE0_bit.P0_10 = 0; + PINMODE0_bit.P0_11 = 0; + + FIO0DIR_bit.P0_10 = 1; + FIO0DIR_bit.P0_11 = 0; + + FIO0MASK_bit.P0_10 = 1; + FIO0MASK_bit.P0_11 = 1; + + VICINTSELECT &= ~(1 << VIC_UART2); + VICVECTADDR28 = (CPU_INT32U)Uart2_Isr; + VICINTENABLE = (1 << VIC_UART2); + + Uart2_Flush(); + + OS_EXIT_CRITICAL(); +} + + + diff --git a/DRIVERS/modem/uart2.h b/DRIVERS/modem/uart2.h new file mode 100644 index 0000000..bd65706 --- /dev/null +++ b/DRIVERS/modem/uart2.h @@ -0,0 +1,18 @@ +#ifndef _UART_H_ +#define _UART_H_ + + +#define UART2_RX_BUFSIZE 128 +#define UART2_TX_BUFSIZE 64 + + +extern void Uart2_Init(CPU_INT32U uart_speed); +extern void Uart2_Flush(void); +extern int Uart2_Gotc(void); +extern int Uart2_Getc(void); +extern int Uart2_Ready(void); +extern int Uart2_Putc(CPU_INT08U ch); + + +#endif //#ifndef _UART_H_ + diff --git a/Flash/Exe/solarium.hex b/Flash/Exe/solarium.hex new file mode 100644 index 0000000..6369c0f --- /dev/null +++ b/Flash/Exe/solarium.hex @@ -0,0 +1,5894 @@ +:1000000018F09FE518F09FE518F09FE518F09FE5C0 +:1000100018F09FE5586FA0B818F09FE518F09FE51D +:100020008008010000870000108700002087000082 +:1000300034870000000000005C870000708700002B +:1000440008B4024B9C4608BC6047C0468832000096 +:1000540070B598B00600002014900023002214A963 +:10006400B74801F07DFC149800281ED0C748002131 +:10007400017000242406240E0A2C13D200201390AD +:1000840001232406240E220013A9C14801F068FCB0 +:100094001398002804D0BD480078401CBB49087060 +:1000A400641CE7E7BB4801210170CA4800210170C4 +:1000B400C948002101700023002216A9C74801F095 +:1000C4004FFC1698C649884202D1042002F05CFD18 +:1000D40001A800F084FD002801D100F0E8FC01989B +:1000E400401E32D0801E00D18EE1401E00D1D9E1E5 +:1000F400401E00D124E2401E00D179E1801E00D1CF +:1001040045E2401E00D143E2401E00D141E2401EC0 +:1001140000D13FE2401E00D1ACE2401E00D176E2A5 +:10012400401E00D1A7E2401E00D1A2E2401E0128D9 +:1001340000D82CE3801E092800D8D5E20A3800D163 +:10014400E5E0401E00D14DE1C2E702F08BFD02F074 +:10015400FDFFD049086001F0CBF8CF480078401C7F +:10016400CD4908700006000E0A2103F081F8002929 +:100174000DD1CA480078002803D003F098FD002868 +:1001840005D003F022FB002801D103F05DF904F04F +:10019400DFFA02F056FD00289AD103F055FE00283C +:1001A40025D000F08BFE04F00AFDBD4800688021D4 +:1001B40089030143BA48016076480078012812D1C6 +:1001C40085480078002811D105F0FFFB002804D0F1 +:1001D40003220021002005F07DFE06F021F87E4870 +:1001E4000121017002E07C480021017070E7D148D0 +:1001F400007804214843D049085800280DD0CD4840 +:10020400007800F037FD04F0DAFCA548006880218E +:1002140089030143A248016078E05E480078012820 +:100224003ED100F093FD04F0CAFC03F00DF96A48D6 +:10023400007800286AD005F0C8FB002804D0032207 +:10024400BE49BE4805F046FE0120129000201190E0 +:100254000020C043109001F01DFB040011AA12A954 +:10026400B448007800F0CEFE0123B248027810A909 +:10027400CD4801F075FB119860433C214843129925 +:10028400FFF7DEFE10993C225143814202D205F071 +:10029400C7FF01E005F0C5FF4F480021017035E0BC +:1002A4003C48007802281ED17D48006880218903DB +:1002B40001437B48016005F0B3FFBC480078002887 +:1002C40007D001F0F5F8B9480078401EB749087026 +:1002D4001CE03048002101709648007801F018F9BC +:1002E40004F06DFC12E02B48007800280ED16C4815 +:1002F40000688021890301436948016005F090FF8B +:100304008C48007801F004F904F059FCE0E6002080 +:1003140002900024182C15D200200F9001232200F3 +:100324000FA9A34801F01CFB02980F990422624311 +:10033400A04B9A58514340180290641CEAE7C04607 +:100344002C170100234801210170029ACE499A48D2 +:1003540006F068F8CD4804F0A2FC029A0C210020B3 +:1003640003F01AFE00230022C949CA4801F0F8FA32 +:100374000024182C10D20123220004206043C64913 +:1003840009188B4801F0ECFA641CF2E7605600404F +:100394007C0C0100625600400023002202A9CD48D3 +:1003A40001F02EFB02F0D2FE03900023002203A9E9 +:1003B400C94801F025FB0A4803900023002203A941 +:1003C400064801F01DFB042002F0DEFB04F0A0F956 +:1003D4007EE6C0466556004066560040CC190100D2 +:1003E40021436587BD480021017004F09EFC6FE63F +:1003F40005F0E8F802F025FC0006000E02000B21CF +:10040400002003F0C9FD63E601200E9000230022C2 +:100414000EA9B34801F0A4FA05F012FF0E99414366 +:100424000D0001F037FA04006419200001F016FAF7 +:10043400AC480078012803D100F088FC04F0BFFB2D +:100444002A0002213B48007803F0A6FD01200D900C +:1004540000200C900020C0430B900CAA0DA9354835 +:10046400007800F0CFFD0123324802780BA94E48F2 +:1004740001F076FA0C9860433C2148430D99FFF74C +:10048400DFFD0B993C225143814201D205F0C8FEA5 +:100494001EE6C0466455004067560040685600405A +:1004A4003CC0FF3F17A805F012FB040001200A908E +:1004B400002009900020C043089009AA0AA91D48F9 +:1004C400007800F09FFD01231A48027808A93648F5 +:1004D40001F046FA01F0DEF90500099829194843AC +:1004E4003C2148430A99FFF7ABFD08993C2251434C +:1004F40081420FD2BF480321017005F066FA00283B +:1005040017D0032005F062FD002812D1012003F06A +:100514001BFC0EE0B7480021017005F056FA0028D4 +:1005240007D0032005F020FD002802D1012003F0AC +:100534000BFCCDE561560040C4530040FFFFFF00B3 +:1005440015A805F0C4FA050001F0A4F90400641923 +:10055400200001F083F963480078012803D100F0FA +:10056400F5FB04F02CFB05F030FA002805D003223B +:100574000021C943C54805F0ADFC2A000121C44847 +:10058400007803F009FD159804F091F8A0E59FE5C3 +:100594009EE59DE502F055FB002803D14F48007805 +:1005A40000280BD094E5C046AC0F01006356004010 +:1005B4003C190100A85100407454004003F044FC6D +:1005C400002804D000F07AFC04F0F9FA80E54548EC +:1005D400007800281AD1C6480078022816D300F003 +:1005E40031FEAB48007804214843C249085800282A +:1005F40006D0A748007800F03DFB04F0E0FA05E0DF +:10060400A348007800F084FF04F0D9FA60E502F012 +:1006140018FB002803D131480078002800D057E5A2 +:1006240003F012FC002804D000F048FC04F0C7FAE0 +:100634004EE52C48007800281AD1AD4800780228ED +:1006440016D300F0BFFD9248007804214843A9491D +:100654000858002806D08E48007800F00BFB04F000 +:10066400AEFA05E08A48007800F052FF04F0A7FAD9 +:100674002EE52DE52CE502F0E4FA002803D1174815 +:10068400007800280AD023E5103E01006C570100D1 +:10069400685500406C190100E850004003F0D4FB99 +:1006A400002804D000F00AFC04F089FA10E50D4893 +:1006B400002101707648007800F02AFF04F07FFAE8 +:1006C40005F083F9002804D003220021002005F05E +:1006D40001FCFDE4FC1901002C1A010065560040E0 +:1006E4008C0E010062560040019804214843814960 +:1006F400081848380068002848D001980421484365 +:100704007C49081848380021016001981238000615 +:10071400000E05F0A3FE01980421484383490818FC +:100724004838019904225143D14A5118483909687B +:10073400016001987E49081812380221017001985D +:1007440004214843CA49081848380268032101981B +:1007540012380006000E03F01FFC03F0BBF800285B +:1007640007D000F0A5FE04F02AFAD3480221017054 +:1007740002E0D14800210170D04803210170D04823 +:100784000068802189030143CD480160A0E4CD487D +:100794000078002800D09BE402F053FA002879D0B6 +:1007A400C9480078002800D192E404F09BF8C749B6 +:1007B400884221D103F08EF8002866D003F09FF818 +:1007C40000A9891C1E2006F0E3F903F0ACF8684682 +:1007D4008078002803D06846807803F0C1F802F0DE +:1007E400B5FC02000921002003F0D6FB04F09DFAB9 +:1007F4004BE0C0466456004004F074F8B4498842A3 +:1008040021D103F067F800283FD003F078F800A95D +:10081400491C1E2006F0F1F903F085F8684640787B +:10082400002803D06846407803F09AF802F08EFC62 +:1008340002000821002003F0AFFB04F076FA4E20FA +:1008440003F0AEF821E004F04DF8A24988421CD12F +:1008540003F040F8002818D003F051F869461E2030 +:1008640006F033FA03F05FF868460078002803D0F6 +:100874006846007803F074F802F068FC02000A216C +:10088400002003F089FB04F050FA21E4FFFFFF008D +:100894006156004003F0D8FA002804D000F00EFBA3 +:1008A40004F08DF914E412480078002801D1FFF710 +:1008B4000FFC8148007800283CD18748007800F07C +:1008C40087FF002801D0FFF703FC03F018F802F0BB +:1008D400BBFD002810D503F0B7FA00280CD003F0B4 +:1008E40022F800F0EBFA04F06AF9FFF7F1FBC046D6 +:1008F40060560040C453004003F015F86E480121CF +:10090400017000F023FA04F05AF905F05EF80028AB +:1009140005D003220021C943704805F0DBFA05F035 +:1009240080FC6F4800210170FFF7D2FB7453004034 +:100934005455004060480078012800D0B5E00120FB +:100944000790002006900020059006AA07A9624897 +:10095400007800F057FB00F09DFF04000698604308 +:100964003C2148430799FFF76BFB5B490978042254 +:1009740051433F4A505001235748027805A9A448DF +:1009840000F0EEFF544800780421484338490858E1 +:1009940005993C225143884200D284E005F015F8C1 +:1009A400002804D003220021002005F093FA02F06D +:1009B40091FF002812D048480078042148432C496C +:1009C4000958200003F00EF8002807D102F0BEFBFE +:1009D400020007214048007803F0DEFA22003E4876 +:1009E400007804214843224909583B48007803F021 +:1009F40053FD002000F032FF00200490012336480C +:100A0400027804A9964800F0ABFF049800281DD092 +:100A14003148007804214843924900220A502E4864 +:100A24000078914901220A542B4800780421484354 +:100A3400B64901220A5022480068802189030143F3 +:100A44001F4801601C48002101702CE022480078F6 +:100A540004214843AD4900220A5001231E4802786C +:100A64001D480078042148437E4909187F4801E065 +:100A74009C53004000F074FF174800787A49012223 +:100A84000A5402F027FF002807D000F011FD04F0FB +:100A940096F809480221017002E00748002101701C +:100AA400064805210170FFF713FBFFF711FB012036 +:100AB40006F060FAFFF70CFB6256004063560040F4 +:100AC4003CC0FF3F6556004072560040D45E0100B2 +:100AD400105F0100405F010061560040FFFFFF000E +:100AE4006456004080B502F075F801F018FA03F07E +:100AF400A7FD00F081FE00F0DDFE05F08DFD8448C9 +:100B04000068844901408248016083480068814943 +:100B140001408148016081480068802189030143C4 +:100B24007E4801607E4800687E4901407C4801603F +:100B34004F4800688021890301434D48016004F057 +:100B44001FFDFA20800006F015FA04F053FF7648E2 +:100B540006F010FA02F0ACFE02F007F902F0F6FA21 +:100B640002000621002003F017FA00230022694640 +:100B74006E4800F0F5FE0023002269466C4800F040 +:100B84003FFF06F0A5FA002803D0192003F0DCF893 +:100B940002E0192003F006F905F063FB65480068DC +:100BA40000280BD14021644807F016F86149086019 +:100BB4000723624A0021624807F054F902F0C6FA9A +:100BC4006049086002F03DF8002803D15E4804F053 +:100BD40096F802E0B14804F092F809BC184710B541 +:100BE40082B004006846002101706A460121514820 +:100BF400006807F043F8010068460078002801D037 +:100C0400002001E02160012016BC08BC1847000048 +:100C1400DC0F010010B5040021004648006807F00D +:100C2400C1F810BC08BC184780B59D48002101706C +:100C34009B4800780A2811D200200090012398488C +:100C440002786946974800F08BFE0098002805D189 +:100C540093480078401C92490870E9E709BC18479A +:100C64003C10010074530040545500404C0F0100E7 +:100C74003CC0FF3F10B588B0040004206043234902 +:100C8400085800283DD088480078022810D3012352 +:100C940022006946854800F088FF684607F090FA0C +:100CA4002200521C82A16B46181805F0BBFB03E01E +:100CB400C4A1684605F0B6FB0021684607F0D4FAE3 +:100CC4007C49684605F0AEFB0121684607F0CCFA82 +:100CD4007949684605F0A6FB0221684607F0C4FA84 +:100CE40071480078022804D3B749684605F09AFB96 +:100CF40003E0B4A1684605F095FB0321684607F0BC +:100D0400B3FA08B010BC08BC18470000C453004034 +:100D14000CC002E0FFF3FFFF4CC002E020C0FF3F25 +:100D240030C0FF3FFFFFDFFF102700003C0D010034 +:100D34005C0E01006C550040644B0040742400407C +:100D44005500000064550040545D010070B58CB03E +:100D54009E4904A805F066FB002104A807F084FA64 +:100D640000F098FD05002A00994904A805F05AFBF3 +:100D7400012104A807F078FA0120039000200290D2 +:100D8400002402AA03A94648007800F03BF902981F +:100D940068433C2148430399FFF752F904002000BB +:100DA4003C21FFF74DF90B001E0020003C21FFF70A +:100DB40047F902003300874904A805F033FB0221F8 +:100DC40004A807F051FA84480078002809D0824822 +:100DD4000078401E80490870804904A805F022FB71 +:100DE40053E0002001900020009001232C48027859 +:100DF40001A97B4800F0B4FD012329480278694623 +:100E0400784800F0ADFD28480078022807D324482C +:100E14000278521C744904A805F004FB03E073A192 +:100E240004A805F0FFFA01983C21484384421DD3ED +:100E34006F4800688021890301436D480160009870 +:100E44003C214843844208D304A807F0B9F969490E +:100E540004AA101805F0E6FA17E004A807F0B0F9A0 +:100E6400654904AA101805F0DDFA0EE0634800682D +:100E74008021890301436148016004A807F0A0F9B7 +:100E8400CC4904AA101805F0CDFA032104A807F0F0 +:100E9400EBF90CB070BC08BC1847000008580100FE +:100EA400615600407C0C010060560040AC0C01000F +:100EB400202564008C5201009852010000B589B0CD +:100EC400012002F09DFF002803D102F0E7FF002873 +:100ED40025D0B94901A805F0A5FA002101A807F019 +:100EE400C3F9474901A805F09DFA012101A807F0BB +:100EF400BBF9012002F084FF002860D0AF4901A8AB +:100F040005F090FA022101A807F0AEF937A101A873 +:100F140005F088FA032101A807F0A6F94FE01A208A +:100F240002F06EFF00281CD0A34901A805F07AFA4C +:100F3400002101A807F098F9A14901A805F072FA67 +:100F4400012101A807F090F928A101A805F06AFA87 +:100F5400022101A807F088F9032101A807F084F908 +:100F64002DE002F0A4FE002829D0934901A805F041 +:100F740059FA002101A807F077F9684600210170A9 +:100F8400AD4901A805F04EFA012101A807F06CF95A +:100F9400684602F0A5FE6846027801A9A74800F059 +:100FA400CAFE022101A807F05FF96846027801A988 +:100FB400A34800F0C0FE032101A807F055F909B0C9 +:100FC40008BC1847200000004C250100203E010009 +:100FD400303E010060250100645600407425010084 +:100FE400DC0F0100AC0F010064610100000000008F +:100FF40038C0FF3FA4520100B05201003CC0FF3F83 +:10100400503E0100F1B586B00F001600AE480078DE +:10101400002802D10020C043C8E0684601F05FFE0A +:101024000020049000250123A848027804A9A848B8 +:1010340000F096FC0498012806D031D3032819D077 +:101044000DD3042821D02BE06846C078002803D0B3 +:101054006846C078052801D30120050022E06846CF +:10106400C078002803D06846C078062801D1012042 +:10107400050017E06846C078052803D06846C078A4 +:10108400062801D1012005000CE06846C078052837 +:1010940003D26846C078022801D20120050001E08D +:1010A40000200500002004002406240E042C40D255 +:1010B4002D062D0E002D18D001238448007804211C +:1010C40048432406240E021903A9824800F048FC70 +:1010D40001237E480078042148432406240E021983 +:1010E40002A97D4800F03CFC17E001237748007812 +:1010F400042148432406240E021903A9774800F06A +:101104002FFC012371480078042148432406240E4F +:10111400021902A9724800F023FC684680780399FA +:10112400884204D3684680780299884201D3641CBB +:10113400BAE72406240E042C02D30120C04335E070 +:101144002D062D0E002D18D00123604800780421AF +:1011540048432406240E02193100624800F000FCC2 +:1011640001235A480078042148432406240E021916 +:1011740039005D4800F0F4FB17E001235348007880 +:10118400042148432406240E02193100574800F074 +:10119400E7FB01234D480078042148432406240E2C +:1011A40002193900C04800F0DBFB002007B0F0BC96 +:1011B40008BC1847403E01006C610100BC520100AC +:1011C400603E01001CB541480078401C0400240620 +:1011D400240E0A2C0ED20020019001232406240E92 +:1011E400220001A9B14800F0BBFB0198002801D1FD +:1011F400641CECE72406240E0A2C02D23348047043 +:1012040016E0002004002406240E0A2C0ED200202E +:10121400009001232406240E22006946A34800F00E +:101224009FFB0098002801D1641CECE72748047058 +:1012340013BC08BC18470000C8520100DC120100AE +:101244000C1301001CB521480078401E040024063C +:101254002416002C0ED40020019001232406241609 +:10126400220001A9914800F07BFB0198002801D1DC +:10127400641EECE724062416002C02D413480470E0 +:101284001EE009200400114800782100090609160F +:101294000004001409040914884211DA00200090A3 +:1012A40001232406241622006946804800F058FBD6 +:1012B4000098002802D00548047001E0641EE2E7AB +:1012C40013BC08BC1847000060560040615600403B +:1012D4000C100100EC1101001C1201008C11010022 +:1012E400BC1101002C110100CC1001005C110100A3 +:1012F40010B500242406240E0A2C00D3D1E02406C1 +:10130400240E7E48005D002806D0022852D009D35E +:10131400032800D19AE0C2E020000006000E05F088 +:1013240004F9BCE02406240E0420604374490858E0 +:1013340000280CD02406240E042060437049085869 +:10134400401E2406240E042161436D4A5050240695 +:10135400240E042060436B490858002829D1240630 +:10136400240E0420604366490858002821D1200037 +:101374000006000E05F072F82406240E04206043D3 +:101384005F492406240E042262435F4B9A580A5094 +:101394002406240E5948022101552406240E042053 +:1013A400604359490A58032120000006000E02F048 +:1013B400F3FD74E02406240E0420604350490858C9 +:1013C40000280CD02406240E042060434C490858FD +:1013D400401E2406240E04216143494A5050240629 +:1013E400240E042060434649085800282DD12000CB +:1013F4000006000E05F099F801232406240E2200AD +:101404002406240E042060433D4909183F4800F097 +:10141400A7FA2406240E04206043394908583C21C5 +:1014240048432406240E04216143354A50502406BF +:10143400240E32480321015501F088FE02000421E4 +:1014440020000006000E02F0A7FD28E02406240E6A +:10145400042060432A49085800280CD02406240E8E +:101464000420604326490858401E2406240E042103 +:101474006143234A50502406240E0420604320492B +:10148400085800280BD12406240E1C4800210155BD +:101494002406240E042060431B4900220A50641CC5 +:1014A40028E710BC08BC1847FC1001007C0C0100A4 +:1014B40000B589B09B49684604F0B4FF0021684632 +:1014C40006F0D2FE9849684604F0ACFF0121684654 +:1014D40006F0CAFE9549684604F0A4FF0221684656 +:1014E40006F0C2FEDA49684604F09CFF0321684610 +:1014F40006F0BAFE09B008BC184700005455004075 +:1015040074530040C45300409C5300407C0F0100BE +:1015140030B58DB00500AD480021017000242406CB +:10152400240E0A2C13D200200C9001232406240E2E +:1015340022000CA9AD4800F013FA0C98002804D03E +:10154400A2480078401CA1490870641CE7E79F4842 +:101554000078002820D1A649684604F063FF0021E2 +:10156400684606F081FEA349684604F05BFF01214A +:10157400684606F079FEB749684604F053FF022135 +:10158400684606F071FEB449684604F04BFF032137 +:10159400684606F069FEC1E08C480078012854D101 +:1015A40001200B9000200A900AAA0BA9280000062B +:1015B400000EFFF727FD0A9B0B9AB449684604F016 +:1015C40031FF0021684606F04FFE28000006000E99 +:1015D40000F0FEF800281DD0AD49684604F022FF53 +:1015E4000121684606F040FEAF49684604F01AFF40 +:1015F4000221684606F038FE28000006000E00F0BE +:1016040097F80100684601F0D7FC0321684606F00C +:101614002BFE19E0A549684604F004FF0121684641 +:1016240006F022FEA249684604F0FCFE0221684648 +:1016340006F01AFE002300226946B44800F0B5FA09 +:101644000321684606F010FE68E001232D062D0EE6 +:101654002A006946AE4800F0A8FA684606F0B0FDD4 +:101664002D062D0E2A00521CAAA16B46181804F050 +:10167400D9FE0021684606F0F7FD012009900020FC +:10168400089008AA09A928000006000EFFF7BAFC72 +:10169400089B099A7D49684604F0C4FE0121684606 +:1016A40006F0E2FD28000006000E00F091F8002884 +:1016B4001AD09949684604F0B5FE0221684606F03E +:1016C400D3FD9649684604F0ADFE28000006000EDE +:1016D40000F02EF80400684606F072FD21006A4608 +:1016E400101801F069FC15E08D49684604F09AFE73 +:1016F4000221684606F0B8FD8A49684604F092FE65 +:10170400684606F05DFD00230022694609187F48FB +:1017140000F04BFA0321684606F0A6FD0DB030BC7C +:1017240008BC1847D452010088250100E05201008A +:101734007CB504002406240E042060437A490E5824 +:101744000020019000200090002501232406240E8F +:10175400220001A9754800F003F901232406240E90 +:1017640022006946724800F0FBF800983C21484387 +:1017740000902406240E6F48005D002805D002283E +:101784000FD003D3032816D01CE01BE000983018B8 +:101794002406240E04216143674A51584018050069 +:1017A40010E000982406240E04216143624A515833 +:1017B4004018050006E02406240E042060435E4918 +:1017C40008580500280076BC08BC1847605600403D +:1017D40000B501000906090E5648405C002801D0F6 +:1017E400012000E0002008BC184700007C0C010028 +:1017F400803E0100EC5201001CB500230022694622 +:101804004E4800F0ADF80023002201A94C4800F036 +:10181400A7F80421684606F0C3FE04000198844238 +:1018240012D0002000900421684606F0B9FE019011 +:10183400002300226946414800F0E2F80023002218 +:1018440001A93F4800F0DCF813BC08BC18470000AD +:10185400703E01009C250100B02501001CB5040068 +:1018640000940421684606F09BFE019000230022A8 +:101874006946324800F0C4F80023002201A9304828 +:1018840000F0BEF813BC08BC18470000C4250100D2 +:10189400D825010080B5002300226946274800F0BE +:1018A4005FF800980ABC1847903E0100EC2501003F +:1018B400746101001CB5002300226946214800F030 +:1018C4004FF80023002201A91F4800F049F8042121 +:1018D400684606F065FE04000198844212D01B4855 +:1018E40000900421684606F05BFE0190002300226C +:1018F4006946144800F084F80023002201A9124824 +:1019040000F07EF813BC08BC18470000DC0C010092 +:10191400AC0C0100202564004C250100F8520100A4 +:10192400A03E0100045301009C5300404C0F0100F1 +:101934007C0F010054550040745300402C170100E3 +:101944005C1701008C170100BC170100570400004C +:1019540008B4024B9C4608BC6047C046148600008D +:10196400F2B582B0040016001F0000200090E07859 +:1019740000281AD03F063F0E012F0CD16068864222 +:1019840005D3A0696168491E484300900DE0A06931 +:101994007043009009E0002300226946A068FFF725 +:1019A400DFFF0098A16948430090A07800280ED179 +:1019B400002506F023FE050004220098E1680918BA +:1019C40001A806F059FF2800FFF7C2FF0FE0A07836 +:1019D400012809D101AA0421E068009BC018000471 +:1019E400000C06F0F0FF02E00020C04305E00422F2 +:1019F40001A9029806F040FF0020FEBC08BC18476D +:101A0400F8B584B004000F0016000020019020787F +:101A1400012802D10020C0439CE0206900284DD059 +:101A240025690422290003A806F026FF04222900C0 +:101A3400091D02A806F020FF04223900684606F0BA +:101A44001BFF607802280AD102980099884203D3C8 +:101A540000980399884236D20020C0437AE0607827 +:101A640003280AD102980099884203DB009803995D +:101A7400884228DA0020C0436CE0607804280CD146 +:101A84000298009906F0F0FF04D30098039906F039 +:101A9400EBFF18D20020C0435CE06078052812D028 +:101AA4006078072807D10098B421C90088420AD376 +:101AB4000020C0434EE00020C0434BE00422390024 +:101AC400684606F0D9FEE07800281AD06846007C03 +:101AD40001280CD16068864205D3A0696168491E5B +:101AE400484301900DE0A0697043019009E0002390 +:101AF400002201A9A068FFF733FF0198A1694843B8 +:101B04000190A07800280ED1002506F077FD05008D +:101B1400042269460198E368181806F0ADFE28000F +:101B2400FFF716FF0FE0A078012809D16A460421C7 +:101B3400E068019BC0180004000C06F0C8FE02E037 +:101B44000020C04306E06069002802D0606906F006 +:101B5400A3FF002005B0F0BC08BC184770B5050011 +:101B64000C002869002807D02E6904223100091DC1 +:101B7400200006F081FE01E000200400002070BC7B +:101B840008BC184770B505000C002869002806D069 +:101B94002E6904223100200006F06EFE01E00020D0 +:101BA4000400002070BC08BC1847FEB504000E00F9 +:101BB4006846037A019A69462000FFF7D1FE6078EF +:101BC400022836D12020205C00282CD0206900284F +:101BD40018D025690098296888420CD36868009950 +:101BE400884208D3009804214843616A09583000A8 +:101BF40006F058FF5AE069A1300006F053FF0020B8 +:101C0400C04354E02078012808D1009804214843B7 +:101C1400616A0958300006F045FF47E05FA13000D3 +:101C240006F040FF42E0009A5DA1300004F0FAFBA8 +:101C34003CE06078032805D1009A59A1300004F0F3 +:101C4400F1FB33E06078042809D1009806F062FFC4 +:101C540002000B00BC49300004F0E4FB26E060788D +:101C6400052804D10099300001F08EF91EE0607857 +:101C7400062804D10099300001F0C8F916E0607814 +:101C8400072810D100983C21FEF7DAF90F000098DC +:101C94003C21FEF7D5F905003B002A00AB49300092 +:101CA40004F0C0FB02E00020C04300E00020FEBCC2 +:101CB40008BC1847F8B505000C0017001E002100E9 +:101CC400280000F025F8E869002812D02020285CBC +:101CD400002807D0200006F073FA9DA1201806F012 +:101CE4004DFF06E0200006F06BFA9AA1201806F0DA +:101CF40045FF200006F064FA33001B061B0E3A0071 +:101D040021182800FFF751FF0020F2BC08BC184737 +:101D140038B504000D00E069002804D0E16928000A +:101D240006F0C0FE03E01DA1280006F0BBFE002063 +:101D340032BC08BC1847F8B504000D001700202079 +:101D4400205C002804D1002028700020C04321E03A +:101D54006078022804D0002028700020C04319E0D5 +:101D64002069002811D02669306887420AD3706838 +:101D7400B84207D304207843616A0958280006F062 +:101D840091FE06E00020C04304E004A1280006F010 +:101D940089FE0020F2BC08BC1847000000000000C7 +:101DA4002564000038B504000D0001232A00210039 +:101DB4002C312000FFF724FE002032BC08BC184759 +:101DC40070B584B005002E692869002801D100206F +:101DD4008AE00422310002A806F04EFD04223100FC +:101DE400091D01A806F048FDE878002840D0002429 +:101DF4006868844277D20123220069462800FFF7ED +:101E0400AFFD687802280CD101980099884203D369 +:101E140000980299884229D221002800FFF7C2FFC6 +:101E240024E0687803280CD101980099884203DBE8 +:101E340000980299884219DA21002800FFF7B2FFBE +:101E440014E0687804280ED10198009906F00CFE7D +:101E540004D30098029906F007FE07D22100280057 +:101E6400FFF7A0FF02E00020C0433DE0641CBFE791 +:101E74000123002269462800FFF772FD68780228D2 +:101E84000CD101980099884203D3009802998842A2 +:101E940029D200212800FFF785FF24E06878032871 +:101EA4000CD101980099884203DB0098029988427A +:101EB40019DA00212800FFF775FF14E06878042878 +:101EC4000ED10198009906F0CFFD04D30098029931 +:101ED40006F0CAFD07D200212800FFF763FF02E0E5 +:101EE4000020C04300E0002004B070BC08BC1847C8 +:101EF40038B50500E878002809D0002468688442D1 +:101F040009D221002800FFF74DFF641CF6E70021E9 +:101F14002800FFF747FF002032BC08BC184710B563 +:101F24000024042060430C490858002807D00420EA +:101F3400604309490858FFF743FF641CF1E7002098 +:101F440010BC08BC184700007C610100105301005C +:101F5400200000003D0000009005010038B5050098 +:101F64000C000123220069463448FFF7F9FC2800DD +:101F740006F026F9009B2200521C3149281804F06F +:101F840051FA0123220069462E48FFF7E9FC280094 +:101F940006F016F9009A2C49281804F043FA012394 +:101FA400220069462948FFF7DBFC280006F008F9FF +:101FB4000099281801F000F8280006F001F924A17E +:101FC400281804F02FFA31BC08BC184738B50500AE +:101FD4000C000123220069461E48FFF7C1FC2800BB +:101FE40006F0EEF8009B2200521C1549281804F054 +:101FF40019FA0123220069461748FFF7B1FC2800AB +:1020040006F0DEF8009A1049281804F00BFA0123B0 +:10201400220069461148FFF7A3FC280006F0D0F817 +:102024000099281800F0C8FF280006F0C9F808A194 +:10203400281804F0F7F931BC08BC1847AC150100A6 +:10204400C03D01007C15010020610100DC15010088 +:102054000D0A00003C1601000C1601006C1601006C +:1020640030B58FB00400AB480068112800DBF8E1FC +:1020740000202070A7480068002815D10AA800F0A5 +:102084002EFEA549200004F0CDF9200006F098F8B2 +:102094000AA9201800F05DFF200006F091F89F497E +:1020A400201804F0BFF9D5E19A480068012834D11A +:1020B4009B49200004F0B6F90023002201A99948A5 +:1020C400FFF74EFC200006F07BF8019A9649201891 +:1020D40004F0A8F90023002201A99448FFF740FC6A +:1020E400200006F06DF8019A9149201804F09AF93D +:1020F4000023002201A98F48FFF732FC200006F0DC +:102104005FF80199201800F057FF200006F058F8F6 +:10211400CEA1201804F086F99CE17E4800680228CC +:1021240007D1200006F04CF8C949201804F07AF9C8 +:1021340090E178480068032834D17949200004F0FC +:1021440071F9002300226946CC48FFF709FC2000FE +:1021540006F036F8009A7449201804F063F9002355 +:1021640000226946C648FFF7FBFB200006F028F86A +:10217400009A6F49201804F055F90023002269469B +:10218400C048FFF7EDFB200006F01AF8009920186C +:1021940000F012FF200006F013F8ACA1201804F0A0 +:1021A40041F957E15B48006804280BD1CB49200072 +:1021B40004F038F9200006F003F8C949201804F0A7 +:1021C40031F947E15348006805280DD10020050086 +:1021D400032D00DB3EE1200005F0F2FF290020186A +:1021E400FFF7BCFE6D1CF3E74A48006806280DD1D2 +:1021F40003200500062D00DB2CE1200005F0E0FFA4 +:1022040029002018FFF7AAFE6D1CF3E74148006877 +:1022140007280DD1062005000A2D00DB1AE1200055 +:1022240005F0CEFF29002018FFF798FE6D1CF3E798 +:102234003848006808280BD1AA49200004F0F2F8B5 +:10224400200005F0BDFFA649201804F0EBF801E1D9 +:102254003048006809280DD100200500032D00DB5B +:10226400F8E0200005F0ACFF29002018FFF7AEFECF +:102274006D1CF3E7274800680A280DD103200500E8 +:10228400062D00DBE6E0200005F09AFF2900201867 +:10229400FFF79CFE6D1CF3E71E4800680B280DD168 +:1022A400062005000A2D00DBD4E0200005F088FF9D +:1022B40029002018FFF78AFE6D1CF3E71548006813 +:1022C4000C2839D1BC49200004F0ACF800230022CA +:1022D40007A9BA48FFF744FB0798002811D120004A +:1022E40005F06EFFB649201804F09CF80948006810 +:1022F400401C0849086007480068401C05490860FC +:10230400A8E0200005F05CFFAE49201804F08AF82C +:10231400A0E0C046D8550040D43D0100D4020100DD +:10232400D40A01008C1401002C6101005C1401002A +:1023340038610100BC140100CC4800680D2821D18B +:102344000020207000200500062D00DB82E0012320 +:102354002A0003A9AB48FFF703FB039800280BD01E +:10236400200005F02DFF039B04216943B24A525813 +:10237400B249201804F056F8200005F021FF03901C +:102384006D1CE1E7B94800680E281CD100202070BC +:10239400062005000C2D5DDA01232A0006A99948C0 +:1023A400FFF7DEFA069800280BD0200005F008FF9E +:1023B400069B04216943A04A5258A049201804F0FE +:1023C40031F86D1CE6E7A94800680F281CD10020ED +:1023D40020700C200500122D3CDA01232A0005A9E7 +:1023E4008848FFF7BDFA059800280BD0200005F0B7 +:1023F400E7FE059B042169438F4A52588F492018F0 +:1024040004F010F86D1CE6E798480068102821D104 +:102414000020207012200500182D1BDA01232A0049 +:1024240004A97848FFF79CFA049800280BD02000F0 +:1024340005F0C6FE049B042169437F4A52587F4934 +:10244400201803F0EFFF6D1CE6E7C0460D0A0000FC +:10245400E404010085480068401C844908600020A9 +:10246400A6E082480068FF21123188423CDA8C4899 +:102474000068002808D10020C04399E01C15010021 +:10248400EC1401004C1501007848016811390CA8BE +:1024940001F06CFD00202070744800681138002899 +:1024A40003D18049200003F0BDFF0C98002806D119 +:1024B4006E480068401C6D490860002078E02000E8 +:1024C40005F07EFE0CA9201801F0C8FE67480068DC +:1024D400401C6649086000206AE0C046840301008D +:1024E400540B010034040100604800686E498842BE +:1024F4005CDA00200290002020705C4800686B4980 +:102504004018002803D16A49200003F08BFF0123FF +:10251400564800686549421802A96648FFF720FA40 +:102524000298002806D151480068401C4F490860B1 +:1025340000203DE0200005F043FE5FA1201803F0D9 +:1025440071FF0123494800685849421802A95948B3 +:10255400FFF706FA029908A800F003FE200005F030 +:102564002FFE08A9201800F0F4FC200005F028FE36 +:102574005249201803F056FF200005F021FE0123E4 +:102584003A490968494A8A1821184D48FFF70DFB52 +:10259400200005F015FE4BA1201803F043FF33483B +:1025A4000068401C31490860002001E00020C0435D +:1025B4000FB030BC08BC1847340601006C19010088 +:1025C4003C2001008C1A010000B58DB02748002181 +:1025D4000160002300223249A148FFF7C1F900231A +:1025E400002269469F48FFF7BBF9009AAB4901A84E +:1025F40003F018FFAA4901A805F09AF90DB008BC28 +:10260400184700003C19010010B582B00400684668 +:10261400002101706A460121A248006805F02EFBE2 +:10262400010068460078002801D0002001E0216004 +:10263400012016BC08BC1847A8510040F01B01003B +:1026440010B504000948006800280AD1074800684A +:10265400401C064908609449200003F0E3FE002072 +:1026640001E00020C04310BC08BC1847D855004006 +:1026740000B58DB00023002269467A48FFF770F94F +:10268400009A8A4901A803F0CDFE77480021016031 +:10269400874901A805F04CF90DB008BC18470000A3 +:1026A400DC550040C806010011020000EFFEFFFFE8 +:1026B4005C0701006C1301007C202000C46401004D +:1026C4003C1301000D0A00007CB505007948006840 +:1026D400002819D178480168684600F042FD77491E +:1026E400280003F09FFE280005F06AFD69462818BB +:1026F40000F02FFC280005F063FD71490A68714958 +:10270400281803F08FFEA2E06A48006801281BD154 +:102714006D4800680400002C0AD1280005F050FD23 +:102724006A49281803F07EFE6248642101608EE045 +:102734006749280003F076FE280005F041FD65494D +:10274400281803F06FFE82E05A48006802281ED160 +:102754000020287000200400062C78DA042060434E +:102764005D4908580600002E0BD0280005F028FD0E +:10277400330004216143594A52585949281803F037 +:1027840051FE280005F01CFD0600641CE4E74948DE +:10279400006803281AD100202870062004000C2C9D +:1027A40055DA042060434C4908580600002E0BD02B +:1027B400280005F005FD330004216143474A5258BF +:1027C4004749281803F02EFE641CE8E739480068DE +:1027D40004281AD1002028700C200400122C36DAA8 +:1027E400042060433C4908580600002E0BD0280002 +:1027F40005F0E6FC330004216143384A5258384955 +:10280400281803F00FFE641CE8E72A48006805282E +:102814001AD10020287012200400182C17DA042082 +:1028240060432D4908580600002E0BD0280005F0FF +:10283400C7FC330004216143284A52582849281808 +:1028440003F0F0FD641CE8E70020C04305E01948EC +:102854000068401C17490860002076BC08BC184773 +:10286400CC0D01009C190100D855004000B58DB075 +:102874000023002269461B48FFF772F8009A1A49A0 +:1028840001A803F0CFFD0B4800210160174901A8FE +:1028940005F04EF80DB008BC18470000141C0100E8 +:1028A40065200000D4550040582001007420010028 +:1028B40045260000D8550040E4550040E83D01009D +:1028C400E0550040FC3D010068550040A81E010091 +:1028D400340601008C1A0100E8500040A851004061 +:1028E400F01B01009C19010090200100CD2600007E +:1028F400F1B58CB000200190642004F03BFB04F09F +:1029040073FE002827D10023002201A9A348FFF762 +:1029140027F8019800281AD004F07FFE002803D17C +:102924009F480221016006E004F08CFE002802D1D9 +:102934009B480121016004F0CBFB002803D019203F +:1029440001F002FA06E0192001F02CFA02E09448A2 +:1029540000210160CEE7924800210160002300229B +:1029640001A98E48FEF7FCFF0198002802D104F06B +:102974002AFEBFE708A8FFF747FE002800D1B7E00A +:10298400089801285BD0B5D3032800D1ADE000D26C +:1029940084E00428AED10023002269468148FEF772 +:1029A400DFFF009880498842A4D1002300227F4998 +:1029B4007F48FEF7D5FF002300227E497E48FEF7BC +:1029C400CFFF00200500032D14DA00200400032C9F +:1029D4000ADAFFF74BFF0600002E05D0FA2080002C +:1029E40004F0C8FA641CF2E7032C03DB04F070FB68 +:1029F4006D1CE8E7032D08DB00220F21002001F005 +:102A0400CBFA042000F0C0F818E000200090002366 +:102A1400002269466348FEF7F3FF0023002269465B +:102A24006348FEF7EDFF0023002269466248FEF783 +:102A3400E7FF00220E21002001F0AEFA5AE7002041 +:102A44000500032D14DA00200400032C0ADAFFF732 +:102A5400BBFD0600002E05D0FA20800004F08AFA9F +:102A6400641CF2E7032C03DB04F032FB6D1CE8E783 +:102A7400032D05DB00220F21002001F08DFA0CE06C +:102A840000220E21002001F087FA01F007FE002346 +:102A940000224A494A48FEF7B3FF2BE7002005000D +:102AA400032D14DA00200400032C0ADAFFF7E0FDFA +:102AB4000600002E05D0FA20800004F05BFA641CA6 +:102AC400F2E7032C03DB04F003FB6D1CE8E7032DA2 +:102AD40005DB00220F21002001F05EFA04E0002251 +:102AE4000E21002001F058FA04E704F0F1FA01E79E +:102AF400344804F03FFA0023002202A93248FEF7CA +:102B04002FFF0023002203A93048FEF729FF039872 +:102B14003C21FDF795FA079003983C21FDF790FAC4 +:102B24000F000023002206A92548FEF719FF029989 +:102B340004A800F016FB069909A800F012FB04A8EB +:102B440080780799884200D2D4E604A84078B84235 +:102B540000D2CFE609A8007904A9097988420CD1EA +:102B640009A8807904A98979884206D109A84079FD +:102B740004A94979884200D1BCE6012000F004F898 +:102B84000E4802990160B5E610B504002100104812 +:102B9400006805F007F910BC08BC18473C0D01009B +:102BA400E8550040CC19010021436587E0550040F9 +:102BB400FC190100E45500402C1A0100EC550040BA +:102BC4004C0C010010270000FC1301002C0E010026 +:102BD400D455004010B5002405F010FD04002F4822 +:102BE40000682F4901402D4801602E4800682C4997 +:102BF40001402C4801602C4800682C4901402A48B7 +:102C040001602B48006829490140294801602000DF +:102C1400FEF79EFE012004F0ADF905F0EFFC040080 +:102C240024480068400203D523480021017002E0D3 +:102C34002148012101702000FEF78AFE10BC08BC67 +:102C4400184738B5002505F0D9FC05001A48007866 +:102C540004002800FEF77CFE20000006000E32BCB3 +:102C640008BC184710B513480068400202D500207C +:102C7400040001E0012004000F4800782406240E1B +:102C8400844206D00C4804700620FDF7C3FF0120DF +:102C940000E0002010BC08BC184700000CC002E093 +:102CA400FFCFFFFF4CC002E020C0FF3FFFFFBFFF8C +:102CB40030C0FF3F34C0FF3F7456004010B5B048E9 +:102CC40000684007400F04002000C00702D501201F +:102CD400FDF7A0FFAA48046010BC08BC184738B52B +:102CE4000400002505F08AFC050071480068207086 +:102CF40070480068607070480068A0706F48006891 +:102D0400E0706F48006820716E4800686071A648E2 +:102D140000683030A0712800FEF71AFE31BC08BCF0 +:102D2400184738B50400002505F068FC0500207834 +:102D34005F49086060785F490860A0785E49086070 +:102D4400E0785E49086020795D49086060795D49F2 +:102D54000860A079FA21C9004018A7490860280032 +:102D6400FEF7F6FD31BC08BC184710B500248548B1 +:102D74000068802189000143824801608B48006813 +:102D84008B4901408948016005F038FC04009B48E8 +:102D940011210160092005F062FFC00B401E854926 +:102DA4000860092005F05BFF82490968491C8022FC +:102DB40012025143401A924908607B4800689149C5 +:102DC400884208D33C480068182804D27648006832 +:102DD4008D49884214D38948002101607248894989 +:102DE40001603848082101603548082101603248F3 +:102DF400072101602F4800210160804811210160F2 +:102E0400924893490160934800689349014091486E +:102E14000160924807210160914880218901016085 +:102E24009048002101609048FF2101608F480121F2 +:102E340001602000FEF78CFD10BC08BC184730B5BB +:102E440085B005000C00A079039060790290207988 +:102E54000190207800906378A278B949280003F0A3 +:102E6400E1FA05B030BC08BC184730B58BB005009A +:102E74000C0004A8039005A8029006A8019007A8D6 +:102E8400009008AB09AAAE49280006F075FB049827 +:102E9400A07105986071069820710998A07008982F +:102EA4006070079820700BB030BC08BC1847000055 +:102EB400204002E0244002E0284002E0304002E0EA +:102EC4002C4002E0384002E010B50400A078182835 +:102ED40002D30020C04339E060783C2802D30120AB +:102EE400C04333E020783C2802D30220C0432DE0C5 +:102EF40060790D2802D26079012802D20420C043EF +:102F040024E0A079642802D30520C0431EE0A07900 +:102F1400042100F0ADF900290BD16079022808D111 +:102F24002079002802D020791E280ED30320C04324 +:102F34000CE02079002805D060798249085C217969 +:102F4400884202D20320C04300E0002010BC08BC29 +:102F5400184730B585B005000C00207803906078E0 +:102F64000290A0780190207900906379A279764943 +:102F7400280003F057FA05B030BC08BC184700001D +:102F8400004002E0C4C01FE030B583B004000D006F +:102F94002900684600F0E5F869462000FFF74FFF76 +:102FA40037BC08BC184700003C4002E0A8C11FE041 +:102FB400FFFFF3FF804002E0F1B582B00E00300065 +:102FC4003C2100F055F93C2100F052F90D0030008D +:102FD4003C2100F04DF90F003000E121090100F01F +:102FE40047F9040000972B0022009849029803F047 +:102FF40019FAF7BC08BC18473C4002E0084002E05C +:10300400844002E0DA07000035080000F1B582B020 +:103014000E0030003C2100F02BF93C2100F028F98F +:103024000D0030003C2100F023F90F003000E121B5 +:10303400090100F01DF9040000972B0022008449C7 +:10304400029803F0EFF9F7BC08BC184734F1FFFF0E +:10305400C12C00000CF0FFFFFFDFFFFF34F2FFFF85 +:1030640010F0FFFF404002E0104002E00C4002E09C +:10307400F8B504000D00A079462801D3754801E095 +:10308400FA20C000A1790E183604360C0C207043C7 +:10309400617947180D3F2D062D0E052D3BD03604C2 +:1030A400360C711EFF206E30414300913604360CFD +:1030B400701E042100F0DCF80099081861790222DE +:1030C4005143654A515A4018217940180700360483 +:1030D400360C3000042100F0CBF8002903D16079CC +:1030E400032800D37F1C2D062D0E042D13D0182089 +:1030F4004743A0783F182D062D0E032D0BD03C20FE +:10310400474360783F182D062D0E022D03D03C2036 +:10311400474320783F183800F2BC08BC1847000029 +:1031240010B5040002212000FFF7A2FF4B4940180C +:103134003C2148432178401810BC08BC18470000C3 +:10314400C81E010070520100E81E010000B583B0E2 +:103154006846FFF7C4FD6846FFF7E2FF03B008BC0A +:10316400184770B504000D00002628003C49FCF700 +:1031740067FF06003000001D0721FCF761FFE170C6 +:103184003848854204D338482D180020A07101E046 +:103194004620A071FF206E300600A079042100F0C3 +:1031A40067F8002901D0002000E00120FF216E31E2 +:1031B40046182B484643B54204D3AD1BA079401CA6 +:1031C400A071EAE7012060716079022809D1A07931 +:1031D400042100F04DF8002901D0002002E0012074 +:1031E40000E000206179214A515C0E181C484643D6 +:1031F400B54204D3AD1B6079401C6071E4E728003C +:103204001749FCF71DFF401C207128001449FCF7E6 +:1032140017FF0D002800E1210901FCF711FFA07040 +:103224002800E1210901FCF70BFF0D0028003C21D7 +:10323400FCF706FF607028003C21FCF701FF0D003D +:103244002800207070BC08BC1847000050520100D0 +:10325400605201006C070000AC200100C0BF45C2F1 +:103264008051010080436D3880BC92C770520100C8 +:103274007847C046802411E200106142402032E0C9 +:103284006800001A010050E1020051231800003ABE +:103294000030A0E3200851E10118A091103083927E +:1032A400200451E10114A09108308392200251E1DD +:1032B4000112A09104308392200151E10111A091E7 +:1032C40002308392A00051E18110A09101308392D9 +:1032D400010050E0A110A0E1001061E20130D3E24E +:1032E4004A0000DA010090E00100403020C063E2AF +:1032F4008CF18FE0010011E1A718000A010050E1F0 +:103304000010A0310000A0330010A0231EFF2FE105 +:103314008000B1E0010040308000B1E001004030A5 +:103324008000B1E0010040308000B1E00100403095 +:103334008000B1E0010040308000B1E00100403085 +:103344008000B1E0010040308000B1E00100403075 +:103354008000B1E0010040308000B1E00100403065 +:103364008000B1E0010040308000B1E00100403055 +:103374008000B1E0010040308000B1E00100403045 +:103384008000B1E0010040308000B1E00100403035 +:103394008000B1E0010040308000B1E00100403025 +:1033A4008000B1E0010040308000B1E00100403015 +:1033B4008000B1E0010040308000B1E00100403005 +:1033C4008000B1E0010040308000B1E001004030F5 +:1033D4008000B1E0010040308000B1E001004030E5 +:1033E4008000B1E0010040308000B1E001004030D5 +:1033F4008000B1E0010040303013A0E1110320E06F +:103404000000A0E002C0A0E31C0380E11EFF2FE146 +:10341400013093E201009030010040300010A0E13F +:103424000300A3E01EFF2FE104402DE90000602209 +:1034340093FFFFEB8220B0E10010614200006022A4 +:103444000440BDE81EFF2FE170B588B000230022C0 +:1034540004A9A048FEF784FA0498002801D10020AA +:1034640033E103F0C1FD04000600A01B06F098F848 +:103474009949884200DB1EE1642003F07BFD03F0E0 +:10348400B3FD040003F04AFA05000120C04385425D +:1034940008D19248002101701A2000F055FC002048 +:1034A400C04312E10020C0438542DED001AA8C490A +:1034B400012003F030FB00281DD068460079002865 +:1034C4000ED068460079002803D06846007900F0E1 +:1034D40047FA8248012101701A2000F063FC07E0DA +:1034E40000F02EFA7D48002101701A2000F02CFC17 +:1034F4000120C043E9E07948012101701A2000F05D +:1035040051FC022276490B3101A8801C05F0B4F964 +:103514006846C088800605D4A12000F021FA022064 +:10352400C043D2E0A12000F03BFA6B2000F038FA4F +:103534006B48807B401E07D0401E0BD0401E0FD02E +:10354400401E012816D916E06B2000F009FA03206A +:10355400C043BAE06B2000F003FA0420C043B4E097 +:103564006B2000F0FDF901A9012003F0CCFC05203B +:10357400C043AAE079E75A48407B002811D0401E96 +:1035840012D0401E13D0401E14D0401E6BD0401EDB +:103594006CD0401E6ED0801E70D0001F00D189E018 +:1035A40089E000F0CDF986E000F0CAF983E000F08C +:1035B400C7F980E00023002202A9BC48FEF7D0F935 +:1035C400029802282CD101A91E2003F04AFB684668 +:1035D40000794B2819D16846007900F0C1F9FFF74A +:1035E400B5FD02000A21002000F0D6FC01A91E202E +:1035F40003F06BFB68460079002833D068460079F5 +:1036040000F0AEF90720C0435FE068460079002867 +:1036140028D06846007900F0A3F90820C04354E09C +:103624000298012815D101A91E2003F0E6FAFFF73C +:103634008DFD02000821002000F0AEFC68460079F0 +:1036440000280FD06846007900F08AF90920C043A9 +:103654003BE00298002805D14E2000F081F90A20B1 +:10366400C04332E027E000F06BF924E04F2000F083 +:1036740077F920E0C02000F073F91CE006AA0020CE +:10368400002103C2083A03A80021016001A80090A8 +:10369400AA4B03AA06A9012003F0E0FB68460079BF +:1036A400002806D06846007900F05AF90A20C04381 +:1036B4000BE000E0D9E6A01B05F072FF0649884242 +:1036C40001DA002001E00020C04308B070BC08BC4F +:1036D40018470000BC0E0100102700006856004087 +:1036E400445300407CB50023002201A9AB48FEF7F7 +:1036F40037F900F004F90198002857D00620050096 +:10370400002D1BD404206843B249085806F064F81D +:103714000A200400642003F02DFC03F0FFF80600E7 +:10372400002E03D00020C043864200D102E0641E74 +:10373400002CEFD1002C01D16D1EE1E7002D0AD53C +:103744001A2000F001FBA4480021017000F0EBF8FE +:103754000020C04336E06A46A049012003F0DBF9AB +:10376400002819D068460078002808D068460078F8 +:10377400002811D06846007800F0F2F80CE000F060 +:10378400DFF89548002101701A2000F0DDFA00F0FE +:10379400CAF80120C04315E08F48012101701A20A6 +:1037A40000F000FB00F0BFF800200BE08A48002185 +:1037B400017000F0C5F81A2000F0F4FA00F0B3F834 +:1037C4000220C04376BC08BC18477CB50023002205 +:1037D40001A97248FEF7C4F800F091F80198002896 +:1037E40054D006200500002D18D4042068437949DC +:1037F400085805F0F1FF0220040003F08FF80600DA +:10380400002E03D00020C043864200D102E0641E93 +:10381400002CF2D1002C01D16D1EE4E7002D0AD555 +:103824001A2000F091FA6C480021017000F07BF836 +:103834000020C04336E06A466849012003F06BF972 +:10384400002819D068460078002808D06846007817 +:10385400002811D06846007800F082F80CE000F0EF +:103864006FF85D48002101701A2000F06DFA00F035 +:103874005AF80120C04315E05748012101701A206D +:1038840000F090FA00F04FF800200BE052480021BD +:10389400017000F055F81A2000F084FA00F043F8A3 +:1038A4000220C04376BC08BC184700009C160100E7 +:1038B40080B54B480068002804D1012006F09EF82A +:1038C40047490860FFF70EFF002801D1FFF7BCFD50 +:1038D40009BC184738B5002404F090FE04003E48A3 +:1038E4000078012802D10120050001E00020050034 +:1038F4002000FEF72DF8280032BC08BC184780B51C +:103904006A4601213648006806F0A1F86846007846 +:10391400002806D0012003F02DFB6846007800281B +:10392400EED109BC184780B5C82003F023FB2C480E +:10393400006806F0F9F809BC184700003C230100B0 +:1039440010B51B242406240EAA2C06D2200000063F +:10395400000E00F027FA641CF4E710BC08BC1847FA +:1039640010B504002406240E002C14D000200006F8 +:10397400000E8F280FD20006000EC049095C2406F1 +:10398400240EA14205D11B300006000E00F0DCF924 +:1039940001E0401CEBE710BC08BC1847BC0E01005A +:1039A40010B5040000200006000E8F280FD2000678 +:1039B400000EB249095C2406240EA14205D11B3035 +:1039C4000006000E00F0EEF901E0401CEBE710BC2D +:1039D40008BC18475C1F010068560040445300406F +:1039E400AC550040F2B58CB005000C98FA21890062 +:1039F40048433C21FCF724FB002108AA03C2083AEF +:103A04006420684300210AAA03C2083A280006F089 +:103A1400C5F80022B04B06F0CBF80022AF4B06F0FD +:103A2400C7F806000F000C9806F0B8F802000B0067 +:103A34003000390006F0BAF906F056FB06AA03C2B4 +:103A4400083A05A80021016000200490FFF757FF01 +:103A5400FFF7FAFC002804D5FFF765FF6320C04395 +:103A6400ECE00020040003AA0021012003F064F923 +:103A740000281AD06846007B002804D06846007BE2 +:103A8400FFF76EFF07E0FFF75BFFA6480021017018 +:103A94001A2000F059F92406240E002C04D0FFF754 +:103AA40042FF0020C043C9E0641C2406240E002CFD +:103AB40008D0FFF7C9FC0028D5D0FFF734FFC72092 +:103AC400C043BBE00023002204A99748FDF748FF48 +:103AD4000498002836D10020040003A802909348DB +:103AE400019005A80090002306AA08A9012003F06C +:103AF4005BF900281AD06846007B002804D0684689 +:103B0400007BFFF72DFF07E0FFF71AFF8548002130 +:103B140001701A2000F018F92406240E002C04D099 +:103B2400FFF701FF0120C04388E0641C2406240E33 +:103B3400002C4DD0FFF788FC0028CED0FFF7F3FE11 +:103B44007B487BE00498012842D10020040008AAA5 +:103B5400FA208000002103C2083A6420684300214F +:103B640006AA03C2083A03A802907248019005A865 +:103B74000090002306AA08A9012003F015F90028E3 +:103B84001AD06846007B002804D06846007BFFF703 +:103B9400E7FE07E0FFF7D4FE6248002101701A2017 +:103BA40000F0D2F82406240E002C04D0FFF7BBFE4C +:103BB4000220C04342E0641C2406240E002C07D0DB +:103BC400FFF742FC0028C2D0FFF7ADFE5A4835E0AB +:103BD4000020040003A80090584B05AA0AA901205C +:103BE40003F03CF900281AD06846007B002804D072 +:103BF4006846007BFFF7B4FE07E0FFF7A1FE4948E3 +:103C0400002101701A2000F09FF82406240E002CD5 +:103C140004D0FFF788FE0320C0430FE0641C240691 +:103C2400240E002C07D0FFF70FFC0028D2D0FFF79A +:103C34007AFE414802E0FFF776FE00200DB0F0BCAA +:103C440008BC184710B5040000200006000E8F2899 +:103C54000FD20006000E0949095C2406240EA14275 +:103C640005D11B300006000E00F0CAF802E0401C2B +:103C7400EBE7002010BC08BC18470000F007010067 +:103C840000B5010000200006000E8F280CD20006AB +:103C9400000E2B4A125C0906090E8A4202D1000664 +:103CA400000E02E0401CEEE7002008BC184738B5BF +:103CB400002400252D062D0E462D09D22D062D0E8D +:103CC4002048405DFFF7BEFF204304006D1CF1E770 +:103CD400200032BC08BC18470000594000004E4088 +:103CE40070B5040000250020207000263606360E2C +:103CF400462E13D23606360E1248805DFFF7A2FF19 +:103D04000500002D08D03606360E0E48805DFFF7FC +:103D1400B7FF1B30207001E0761CE7E7280070BC79 +:103D240008BC184768560040CC1601005423010013 +:103D3400D4FEFFFFB04E010070FEFFFF3C230100E4 +:103D4400F0070100080A0100F0B583B00400002563 +:103D540004F054FC05002406240E20002021FFF763 +:103D640087FA04214843BA49009001912406240E9D +:103D740020002021FFF77CFA04214843B4490E585F +:103D840001272406240E20002021FFF771FA8F401A +:103D94003743019900980F502800FDF7D9FDF7BC6F +:103DA40008BC1847F0B583B00400002504F026FCD5 +:103DB40005002406240E20002021FFF759FA0421CF +:103DC4004843A349009001912406240E2000202199 +:103DD400FFF74EFA042148439D490E580127240653 +:103DE400240E20002021FFF743FA8F40BE4301999F +:103DF40000980E502800FDF7ABFDF7BC08BC18472F +:103E0400F8B506000024002504F0F8FB050036068A +:103E1400360E30002021FFF72BFA042148438C4949 +:103E24000858009001273606360E30002021FFF78F +:103E34001FFA8F40009807403C002800FDF788FDDA +:103E44002000F2BC08BC184738B500240025002027 +:103E54000090002300226946B648FDF781FD04F076 +:103E6400CDFB05000098002808D1FFF720FF204370 +:103E740004001A20FFF7C4FF204304000120FFF7C9 +:103E8400BFFF204304002800FDF762FD002C01D091 +:103E9400012000E0002032BC08BC18470020704715 +:103EA40010B502242406240E192C06D22000000684 +:103EB400000EFFF777FF641CF4E710BC08BC18473A +:103EC400F1B582B000270026002500200400FF2C55 +:103ED4001BD86A46082108206043974BC018000489 +:103EE400000C04F070FD0098002804D00098002114 +:103EF400C943884201D1270007E00098A84202D3B1 +:103F0400009805002600641CE1E7FF2C06D9300068 +:103F1400401C80214900FCF793F80F00FFF716F9C5 +:103F24000090029801906A46082108207843824B49 +:103F3400C0180004000C04F0CAFCF7BC08BC184705 +:103F440038B505000C00FF2C02D90020C0430AE05C +:103F54002A00082108206043774BC0180004000C95 +:103F640004F031FD002032BC08BC184738B5050008 +:103F74000C00FF2C02D90020C0430AE02A000A21C9 +:103F84000A2060436D4BC0180004000C04F01BFDB4 +:103F9400002032BC08BC1847F7B584B000270026BF +:103FA400002500200400FF2C1BD86A460A210A20A1 +:103FB4006043624BC0180004000C04F004FD009838 +:103FC400002804D000980021C943884201D1270069 +:103FD40007E00098A84202D3009805002600641C5C +:103FE400E1E7FF2C06D93000401C80214900FCF792 +:103FF40027F80F00FFF7AAF8009068466946097C85 +:10400400417268466946097D0172069801906A46C4 +:104014000A210A207843494BC0180004000C04F01C +:1040240056FC07B0F0BC08BC184780B500228021BC +:104034000901414804F089FC09BC184780B50022F5 +:10404400A02109013D4804F080FC09BC1847000088 +:104054001454004038B504000D002D062D0E280020 +:10406400401E1AD0401E1DD0401E20D0401E23D01A +:10407400801E26D0401E29D0401E2CD0401E2FD09A +:10408400401E32D0401E35D0401E38D0401E3BD09A +:10409400401E43D0401E3CD045E06149200002F060 +:1040A400C1F944E05F49200002F0BCF93FE05E49F9 +:1040B400200002F0B7F93AE05C49200002F0B2F9BE +:1040C40035E05B49200002F0ADF930E059492000A9 +:1040D40002F0A8F92BE05849200002F0A3F926E0E9 +:1040E4005649200002F09EF921E05549200002F0D3 +:1040F40099F91CE05349200002F094F917E0524961 +:10410400200002F08FF912E05049200002F08AF9F1 +:104114000DE04F49200002F085F908E04D492000E8 +:1041240002F080F903E04CA1200002F07BF931BCDD +:1041340008BC1847EC0E0100CE070000CE0F0000AB +:1041440038B504000D002D062D0E2800401E1AD08F +:10415400401E1DD0401E20D0401E23D0801E26D0DD +:10416400401E29D0401E2CD0401E2FD0401E32D0DD +:10417400401E35D0401E38D0401E3BD0401E43D098 +:10418400401E3CD045E0B249200002F04BF944E027 +:10419400B049200002F046F93FE0AF49200002F0A8 +:1041A40041F93AE0AD49200002F03CF935E0AC4970 +:1041B400200002F037F930E0AA49200002F032F979 +:1041C4002BE0A949200002F02DF926E0A7492000A0 +:1041D40002F028F921E0A649200002F023F91CE0AE +:1041E400A449200002F01EF917E0A349200002F0C0 +:1041F40019F912E0A149200002F014F90DE0A049D8 +:10420400200002F00FF908E09E49200002F00AF9AC +:1042140003E09D49200002F005F931BC08BC1847B1 +:1042240064560100705601007C5601008856010056 +:1042340094560100A0560100C04E0100D04E01006A +:1042440048380100E04E0100AC560100F04E010078 +:104254005C38010070380100EDE5F2007CB5040023 +:104264000D00287A002800D1EBE0280005F07AFF41 +:1042740001006846FEF775FF84A1200002F0D2F821 +:10428400200003F09DFF69462018FEF762FE20001F +:1042940003F096FF297A2018FFF752FF287A0128A5 +:1042A40002D0287A022816D1200003F089FF6A7A06 +:1042B400521C7749201802F0B5F8200003F080FF63 +:1042C40006002800001D05F04DFF02007149A019E9 +:1042D40002F0A8F8ADE0287A032815D1200003F0F5 +:1042E4006FFF6A7A521C6A49201802F09BF820007A +:1042F40003F066FF06002800001D05F033FF0100EF +:10430400A019FEF759FE94E0287A042810D1200061 +:1043140003F056FF6A7A521C5D49201802F082F8B5 +:10432400200003F04DFFC5A1201802F07BF880E0C7 +:10433400287A062807D1200003F042FFBFA12018E5 +:1043440002F070F875E0287A072809D1200003F0FC +:1043540037FF6A7A521C4E49201802F063F868E06D +:10436400287A082807D1200003F02AFFB3A12018D7 +:1043740002F058F85DE0287A092807D1200003F0FC +:104384001FFFAEA1201802F04DF852E0287A0A2847 +:1043940007D1200003F014FFA8A1201802F042F86E +:1043A40047E0287A0B2815D12800001D05F0DAFE15 +:1043B400002807D1200003F003FFD349201802F09E +:1043C40031F836E0200003F0FBFED049201802F05B +:1043D40029F82EE0287A0C280DD1200003F0F0FEF5 +:1043E40006002800001D05F0BDFE0200D649A019F4 +:1043F40002F018F81DE0287A0D280DD1200003F0F2 +:10440400DFFE06002800001D05F0ACFE0200CFA16F +:10441400A01902F007F80CE0287A0E2802D0287AB6 +:104424000F2806D1200003F0CBFE84A1201801F050 +:10443400F9FF200003F0C4FEDAA1201801F0F2FF16 +:1044440003E0D949200001F0EDFF73BC08BC184714 +:104454008438010098380100AC380100C0380100EC +:10446400004F0100D43801006C23010084230100B3 +:10447400081E0100E8380100FC3801009C230100FB +:10448400281E0100481E0100103901007C20200074 +:10449400B85601003464010070B5A6B004000E00E3 +:1044A400150002AA04212406240E04206043CB2311 +:1044B400DB00C0180004000C04F085FA01AA0421F2 +:1044C4002406240E04206043D023DB00C01800041B +:1044D400000C04F078FA6A4604212406240E042011 +:1044E4006043D523DB00C0180004000C04F06BFA11 +:1044F4000298401C0290019880190190009840197C +:10450400009002AA04212406240E04206043CB2335 +:10451400DB00C0180004000C04F0D9F901AA04213E +:104524002406240E04206043D023DB00C0180004BA +:10453400000C04F0CCF96A4604212406240E04205D +:104544006043D523DB00C0180004000C04F0BFF95D +:1045540002AA0421DA20C00004F035FA01AA0421D9 +:10456400924804F030FA6A460421DB20C00004F0CB +:104574002AFA0298401C0290019880190190009830 +:104584004019009002AA0421DA20C00004F09FF927 +:1045940001AA0421854804F09AF96A460421DB2023 +:1045A400C00004F094F903AA8621E820C00004F0B6 +:1045B4000AFA2406240E0420604303A90858401C68 +:1045C4002406240E0421614303AA50502406240E19 +:1045D4000420604303A90818806A80192406240E65 +:1045E4000421614303AA511888622406240E04207E +:1045F400604303A90818006D40192406240E042101 +:10460400614303AA511808652198401C21902298FF +:1046140080192290239840192390842103A803F041 +:10462400BFFF03A98431088003AA8621E820C000C3 +:1046340004F04DF926B070BC08BC18470000000017 +:1046440010B5A2B06A468621E820C00004F0BBF988 +:104654008421684603F0A4FF04006846843000887F +:104664002404240C844215D086220021684605F0D7 +:104674008BFD8421684603F093FF694684310880EA +:104684006A468621E820C00004F021F900F006F80B +:1046940000F03EF822B010BC08BC184780B50022D8 +:1046A4008421CB20C00004F050F909BC184710B590 +:1046B40082B00400182C23D26A46042104206043EB +:1046C4003B4BC0180004000C04F07DF90098401C1A +:1046D40000906A46042104206043354BC01800044E +:1046E400000C04F0F4F86A460421324804F06BF933 +:1046F4000098401C00906A4604212E4804F0E7F814 +:1047040013BC08BC184700003C640100C4560100F7 +:1047140010B582B00020009000200400182C0BD2A9 +:104724006A46042104206043214BC0180004000C95 +:1047340004F0CDF8641CF1E76A4604211D4804F036 +:10474400C6F813BC08BC1847446401002575000072 +:1047540070B50024AA2C1CDA20002021FEF788FD65 +:104764000421484314490D58012620002021FEF756 +:104774007FFD8E402E40002E09D120000006000E41 +:10478400FFF73EFB002802D02000FFF799FB641CD2 +:10479400E0E720220949084804F06EF870BC08BC20 +:1047A400184700000D0A0000104F0100D406000055 +:1047B400DC0600003C070000345400401454004060 +:1047C40030B589B005000C00287800280BD16A6840 +:1047D40046A1684601F026FE21000906090E684636 +:1047E40005F08EFF66E02878022855D1684620211E +:1047F40001703F480078002840D03E4800782406E5 +:10480400240E84423AD13C480068203000780028C5 +:1048140018D06946491C38480068FDF779FA37A171 +:10482400684604F0ABF93649684604F0A7F935A1A7 +:10483400684604F0A3F921000906090E684605F04C +:104844005FFF37E06946491C2B480068FDF760FAB2 +:10485400294800681C3005F085FC002803D02AA1F3 +:10486400684604F08BF92649684604F087F921006C +:104874000906090E684605F043FF1BE000230022E9 +:104884006946491C6868FDF715FA21000906090EF6 +:10489400684605F035FF0DE0287801280AD16A68DA +:1048A40012A1684601F0BEFD21000906090E684602 +:1048B40005F026FF09B030BC08BC184710B582B01B +:1048C400040068460021017021000906090E6846AB +:1048D40005F016FF13BC08BC184780B505F07BFF34 +:1048E40009BC1847B84800687047000020257300C9 +:1048F4006C56004070560040C85500403C00000013 +:10490400545400403E0000003D000000F8B5AE489D +:104914000068407A01283BD10020040005F069FFBB +:10492400002005002D062D0E042D14D22D062D0E6B +:1049340004206843A449096809680858009000984D +:10494400002808D021000906090E0098FFF738FF57 +:10495400641C6D1CE6E72406240E042C06D22000F9 +:104964000006000EFFF7AAFF641CF4E796480068EF +:10497400006800684078800709D50022122185204C +:1049840005F015FF00221321842005F010FF13E128 +:104994008D4800680068006800900098002802D1E3 +:1049A400FFF79BFF08E100210098FFF709FF874804 +:1049B4000078002803D18648002101701DE0824858 +:1049C4000068007A042805D280480078401E804997 +:1049D400087012E07D4800787B490968097A891ECD +:1049E400884205DA79480078401E7949087004E065 +:1049F40076480078801E7649087075480078401C17 +:104A04000500012004002406240E042C1FD26E4845 +:104A14000068007A2D062D0E854218D22D062D0E23 +:104A2400042068436849096809680E58002E05D1B6 +:104A340020000006000EFFF741FF05E021000906F3 +:104A4400090E3000FFF7BCFE6D1C641CDBE7240676 +:104A5400240E042C06D220000006000EFFF72EFFC1 +:104A6400641CF4E75948007804214843564909680E +:104A740009680818406806783606360E002E0CD1F0 +:104A84005248007852490978421A521C1206120EF2 +:104A94000021DF2005F08BFE3AE03606360E012EAB +:104AA4000CD14A4800784A490978421A521C120625 +:104AB400120E0021132005F07AFE29E03606360E88 +:104AC400022E25D141480078042148433E49096813 +:104AD4000968081847687868007800280CD13B48B2 +:104AE40000783B490978421A521C1206120E002122 +:104AF400842005F05CFE0BE03448007834490978E2 +:104B0400421A521C1206120E0021DF2005F04FFE3D +:104B14002D480068006800684778B80709D5002266 +:104B24001221852005F043FE00221321842005F084 +:104B34003EFEA048007800283CD09F480068203002 +:104B44000078002836D19C4800684078022811D1AA +:104B54001E4800781E490978411A491C0906090EA5 +:104B640096480078964A127880180006000E05F0E0 +:104B7400EDFD1CE0904800684078052804D08E487C +:104B840000684078072812D1104800781049097845 +:104B9400411A491C0906090E88480078884A127887 +:104BA400A94B9A5C80180006000E05F0CFFD05F0B5 +:104BB40019FE01E005F01DFEF1BC08BC1847A3482E +:104BC4000121017070470000B85500406A5600404A +:104BD4006B56004010B501000020002213001A009B +:104BE400521C0C7A1B061B0EA3420CD21206120E88 +:104BF400042353430C68E3581C78012C02D01C781E +:104C0400022CEBD11000401E0006000E10BC08BCA4 +:104C1400184730B502000800401C0B005B1C1C0048 +:104C240023005B1C157A2406240EAC420CD21B060E +:104C34001B0E04245C4315682C592578012D02D0E1 +:104C44002578022DEBD11800401E0006000E30BC62 +:104C540008BC184730B503000C00641C0A00521C41 +:104C64000906090E002901D1002015E01000421E9A +:104C74000006000E00280CD01206120E0420504329 +:104C84001D6828580578012D02D00578022DEDD134 +:104C94001400601E0006000E30BC08BC184710B596 +:104CA40004006B480078082826D269480078082157 +:104CB40048436849684A12680A50654800780821E0 +:104CC40048436449081865490978017160480078C7 +:104CD400401C5F490870604804605F480068FFF743 +:104CE40079FF5E4908706068002802D0606803F0AC +:104CF400D3FE56480121017010BC08BC184710B5FA +:104D040004005548046054480068FFF763FF5349A2 +:104D140008706068002802D0606803F0BDFE4B484C +:104D24000121017010BC08BC184780B548480078C0 +:104D3400002822D046480078401E4549087044485F +:104D440000780821484343490858434908604048CB +:104D54000078082148433F49081800793F49087002 +:104D64003D4800684068002804D03B48006840681B +:104D740003F092FE35480121017009BC184780B543 +:104D84003648007804214843A54909680968081889 +:104D94004068806800280BD03048007804214843DC +:104DA4009F4909680968081840688068FFF777FF19 +:104DB40009BC18476C560040C85500406E56004068 +:104DC4006D5600407CB505000C001600954800683F +:104DD4004078022823D16846252101706846302195 +:104DE40041702406240E20000A21FEF741FA3030D7 +:104DF400694688702406240E20000A21FEF738FA3A +:104E040030316846C17068467521017168460021D9 +:104E1400417132006946280001F004FB10E081482A +:104E240000684078052804D07E4800684078072848 +:104E340006D10023002229007A480068FCF7B5FE59 +:104E440073BC08BC18470000DC56010071560040D2 +:104E54006956004008520040B85500406A56004068 +:104E640010B571480021017070480078042148434E +:104E74006B4909680968081840684068694908600E +:104E84006A480078401C6A490978401A69490870E0 +:104E940000230022684963480068FCF761FD61480B +:104EA4000068103005F05EF9040004222100634814 +:104EB40003F0E2FC04222100091D614803F0DCFC3C +:104EC4005848006820300078002807D000230022CA +:104ED4005C4954480068FCF768FE45E0594951486C +:104EE4000068FCF715FF4F4800681C3005F03AF9DC +:104EF400002803D054A1534803F040FE514803F066 +:104F04005FF9401C514908704648006840780228FF +:104F14000ED12000001D05F025F902004CA14948DE +:104F240001F080FA474803F04BF94A49087014E04D +:104F34003C4800684078052803D146480C2101709C +:104F44000BE0384800684078072803D14148042121 +:104F5400017002E03F4800210170374802683D4873 +:104F640001783848FFF72EFF3B480121017010BC3F +:104F740008BC1847384800210170704700B587B055 +:104F8400284800684078022812D12648006820305A +:104F94000078002804D1284A30A12A4804F0ECFA09 +:104FA4000023002224491F480068FCF729FD31E052 +:104FB4001C4800684078052814D104A92148FDF74D +:104FC40054FF04A8FDF780FF002823D104A8FEF7AE +:104FD400A7F803900023002203A912480068FCF7F5 +:104FE4000FFD17E00F4800684078072812D101AB85 +:104FF40002AA1B49134804F0BFFA02983C21484313 +:105004000199401800900023002269460548006871 +:10501400FCF7F6FC10480021017007B008BC1847E3 +:10502400B8550040C85500406D5600406A560040CF +:105034006B56004070560040BC550040C4550040BB +:10504400C0550040545400403D0000006E560040DE +:10505400257500006F5600406C5600402564000022 +:10506400D0560100F0B58FB0070000246848FFF760 +:1050740046FE0020029002A805F0D4FE002810D1BC +:10508400641CFA20800084420BDAFA204000844237 +:1050940003DB60480078002803D15F4800780028CB +:1050A400E7D05D480078002804D05B4800210170F7 +:1050B400FFF72CFC57480078002800D0B7E0002008 +:1050C40004000298002800D1AEE0029804281FD002 +:1050D400CFD306284BD005D308280ED076D3092881 +:1050E40077D0C6E7C3480178C3480068FFF7B2FD2C +:1050F400C0490870FFF70AFCBBE7BE480178BE4808 +:105104000068FFF786FDBB490870FFF7FFFBB0E7B7 +:10511400B9480068006806687078800726D5756805 +:105124006878022820D10023002201A92800FCF776 +:1051340017FC0EA92800FCF725FD08A92800FCF798 +:105144000DFD0198401E019001980E99884203D3E9 +:1051540008980199884201D20898019000230022FE +:1051640001A92800FCF74CFCFFF7D0FB81E7A2481B +:105174000068006806687078800726D575686878C6 +:10518400022820D10023002269462800FCF7E8FB0E +:1051940007A92800FCF7F6FC0DA92800FCF7DEFCA3 +:1051A4000098401C009000980799884203D30D98FA +:1051B4000099884201D20798009000230022694692 +:1051C4002800FCF71DFCFFF7A1FB52E7FFF7ADFD3C +:1051D4004FE789480068407A012802D1FFF796FB1F +:1051E40047E78448007804214843834909680968EB +:1051F400081845682878022810D16E68307800288D +:1052040011D1FFF72DFEFA20800004000BE0C04608 +:10521400305701006C560040715600402878012830 +:1052240001D1FFF7ACFD24E7FFF770FB21E70298FB +:10523400002800D199E10298042800D122E100D28B +:1052440090E1062800D151E108D3082800D18DE06F +:1052540000D282E1092800D182E183E1C5480068D7 +:1052640020300078002823D006A9C2480068FCF743 +:1052740089FC0CA9BF480068FCF770FCBE480068B4 +:10528400401CBD490860BC4800680699884204D3A4 +:105294000C98B9490968884202D2B7480699016056 +:1052A400B5480268B549B3480068FCF744FD5CE0C2 +:1052B400B04800684078022814D1C0480078AF494B +:1052C400085C401CBD490978AC4A5054BB4800787E +:1052D400AA49085C3A2848D3B8480078A74930223C +:1052E4000A5442E0A3480068407805281CD1B3481A +:1052F4000078B349085CA149085C401CAF490978AF +:10530400AF4A515C9D4A5054AC480078AC49085CA3 +:105314009A49085C3A2828D3A8480078A849085C28 +:10532400964930220A5420E09248006840780728C1 +:105334001BD1A2480078A249085C9049085C401C33 +:105344009E4909789E4A515C8C4A50549B48007887 +:105354009B49085C8949085C3A2806D39748007839 +:105364009749085C854930220A54FBE0814800686B +:1053740020300078002823D00BA97E480068FCF771 +:1053840001FC05A97B480068FCF7E8FB7A48006843 +:10539400401E79490860784800680B99884204D314 +:1053A400059875490968884202D2734805990160D5 +:1053B4007148026871496F480068FCF7BCFC60E002 +:1053C4006C4800684078022818D17C4800786B4902 +:1053D400085C401E79490978684A50547748007837 +:1053E4006649085C30284CD27448007863493922F5 +:1053F4000A5446E06A560040B85500405D480068CB +:10540400407805281CD16D4800786D49085C5B49DB +:10541400085C401E69490978694A515C574A5054EE +:10542400664800786649085C5449085C302828D2EC +:10543400624800786249085C504939220A5420E0E5 +:105444004C480068407807281BD15C4800785C49C8 +:10545400085C4A49085C401E58490978584A515C1E +:10546400464A5054554800785549085C4349085CFD +:10547400302806D2514800785149085C3F49392206 +:105484000A546FE03B48006820300078002823D09D +:105494000AA938480068FCF775FB04A93548006878 +:1054A400FCF75CFB34480068401E3349086032480E +:1054B40000680A99884204D304982F4909688842ED +:1054C40002D22D48049901602B4802682B492948CF +:1054D4000068FCF730FC08E038480078002804D065 +:1054E40036480078401E354908703BE02148006882 +:1054F40020300078002823D003A91E480068FCF758 +:1055040041FB09A91B480068FCF728FB1A480068FE +:10551400401C19490860184800680399884204D35C +:10552400099815490968884202D213480399016011 +:105534001148026811490F480068FCF7FCFB0BE0B6 +:105544001E4800782D490978491E884204DA1B4810 +:105554000078401C1949087004E0FFF70BFD01E0D6 +:10556400FFF70CFDFFF7D2F983E500200400FFF7F5 +:10557400CDF97EE5C8550040BC5500405454004068 +:1055840080B51F48002101701E48002101701E488B +:10559400002101701D48002101701D480021016097 +:1055A400402200211B4804F0EFFD0B231A4A00217E +:1055B4001A4802F057FC09BC184700006D56004019 +:1055C400DC56010080B50B2002F016FDFFF785F9CB +:1055D400642001F0CFFCFFF7D3FF642001F0CAFC84 +:1055E400FDF72FFB002803D10D48FFF788FB02E0ED +:1055F4000C48FFF784FB09BC184700006F560040B5 +:10560400695600406A5600406B5600406C56004094 +:10561400B855004008520040741E00406950000014 +:10562400545D01000858010030B583B00500002422 +:10563400B74800210160B748012101700120FEF73D +:10564400B1FB0220FEF7AEFB962001F093FC002391 +:10565400002201A9BA48FCF783F9AE480078012872 +:105664001ED10198002809D1AA4801210170012006 +:10567400FEF798FB0220FEF795FBE5E700F062F9E0 +:10568400002803D00120FEF75FFBDDE70120FEF7D1 +:1056940089FB0220FEF786FB9E48002101700CE086 +:1056A4000198002809D19B48012101700120FEF7CF +:1056B40079FB0220FEF776FBC6E76946032000F07B +:1056C400D5FB002800D133E12406240E002C08D099 +:1056D40068460078422804D0002004001D20FBF70F +:1056E40099FA684600781038052822D9C01F042882 +:1056F4001FD9401F20D025385DD0401E5FD0401EEA +:1057040069D0401E6BD0401E6DD0801E6FD009380A +:10571400042800D8A4E01538022800D8A0E01B38DB +:1057240000D1D0E0401E00D19EE0401E00D1F3E045 +:10573400F5E0FEF7B5FBF4E00220FEF733FB684624 +:105744004078603812D0401E14D0401E0ED0801E07 +:1057540014D0401E16D0401E18D0401E1AD0401E31 +:105764001CD0401E1ED0C01E20D023E00320FEF714 +:10577400EBFA1FE00420FEF7E7FA1BE00520FEF732 +:10578400E3FA17E00620FEF7DFFA13E00720FEF73E +:10579400DBFA0FE00820FEF7D7FA0BE00920FEF74A +:1057A400D3FA07E00A20FEF7CFFA03E00B20FEF756 +:1057B400CBFAFFE7B5E00C20FEF7C6FAB1E0240609 +:1057C400240E002C06D11C20FBF724FAFEF768FBFC +:1057D40001200400A5E00E20FEF7B6FAA1E00F2098 +:1057E400FEF7B2FA9DE01020FEF7AEFA99E06846A3 +:1057F400407850380ED0401E10D0401E12D0401EAB +:1058040014D0401E16D0113818D0401E1AD0401E95 +:105814001CD01EE01120FEF797FA1AE01220FEF7C2 +:1058240093FA16E01320FEF78FFA12E01420FEF725 +:105834008BFA0EE01520FEF787FA0AE01620FEF731 +:1058440083FA06E01720FEF77FFA02E01820FEF73D +:105854007BFA0120FEF778FA2E480121017060E0FE +:105864000220FEF771FA5CE003220021002000F020 +:1058740031FB002802D10120FEF766FA6846407821 +:10588400182814D22248006805F0FAFA69464978C3 +:105894000C225143984A515805F0FCFA05F04EFB8E +:1058A4001B490860684640789449086005E0184838 +:1058B400002101609148182101600520FBF7AAF935 +:1058C400FEF7EEFA2DE068464078182814D2104806 +:1058D400006805F0D5FA694649780C225143864A96 +:1058E400515805F0D7FA05F029FB094908606846C4 +:1058F40040788249086005E00548002101607F483E +:10590400182101600420FBF785F9FEF7C9FA08E0C5 +:1059140038560040740A0040FEF7C2FA01E0FEF770 +:10592400BFFA0120FEF73EFA7548002101708BE6AC +:105934000120FEF709FA72480121017084E6000093 +:105944000C0D010010B5C82001F014FB0020040068 +:10595400182C06DA042060436A4900220A50641CA9 +:10596400F6E700F083F8032000F04EFA002802D195 +:105974000020C04326E06049032000F065FB0028B6 +:1059840002D10120C0431DE000200400182C0BDAD2 +:105994000C2060435849085805F0D0FA04216143AB +:1059A400584A5050641CF1E703220021002000F003 +:1059B40091FA002802D10220C04303E0504800219C +:1059C4000170002010BC08BC184738B5002402F050 +:1059D40015FE04004A480078002802D10120050081 +:1059E40001E0002005002000FBF7B2FF280032BCD4 +:1059F40008BC184710B59620800105F0DFFA002492 +:105A040002F0FCFD040040480068404901403E4863 +:105A140001603F4800683D4901403D4801603D4800 +:105A24000068102101433B4801603B480068102195 +:105A340088433949086039480068102101433748D0 +:105A440001602000FBF784FF3548006800280AD174 +:105A5400012003F0D3FF324908600623314A0021B4 +:105A6400314802F0FFF910BC08BC184780B500F0BB +:105A740013F82A4800681021014328480160642073 +:105A840001F078FA29480068102101432748016091 +:105A940000F016F809BC184780B56A460121204871 +:105AA400006803F0D4FF68460078002806D001207F +:105AB40001F060FA684600780028EED109BC184766 +:105AC40080B51748006804F02FF809BC184770B572 +:105AD4000400002502F092FD0500154806681448EC +:105AE400002101600548006820602800FBF730FFB2 +:105AF400300070BC08BC184744480040700A00409D +:105B0400740A0040A851004010C002E0FFFCFFFFEF +:105B140050C002E040C0FF3F50C0FF3F5CC0FF3FA9 +:105B240034560040743000402D56000058C0FF3FEA +:105B34003856004008B4024B9C4608BC6047C04637 +:105B4400C0B1000030B50200AE4B08001206120EC0 +:105B5400504000252C002404240C082C0BD2C5072B +:105B640004D50004000C4008584002E00004000C76 +:105B74004008641CEFE70004000C30BC08BC184764 +:105B8400F8B507000026B878002801D0BC7803E0F7 +:105B940038790002797944180025A01E854208DA74 +:105BA40031000904090C785DFFF7CCFF06006D1C79 +:105BB400F3E730000004000CF2BC08BC1847F0B551 +:105BC40083B005000E000020C04307000024012C10 +:105BD40050DA0620009005F0A1FAA878002807D131 +:105BE4002879000269794118280005F0C3F903E017 +:105BF400A978280005F0BEF9E878002802D0E878F2 +:105C0400FF2802D10020070035E0962252000099B7 +:105C1400300005F0BEF900282AD03078022803D0DD +:105C24000120C043070023E0B078002801D0B078F9 +:105C340003E070793179090240180099401A019003 +:105C44000198012811DB962252000199009830181E +:105C540005F09FF9002802D0002007000AE0022086 +:105C6400C043070005F05AFA02E00020070001E0F3 +:105C7400641CACE73800FEBC08BC1847F7B5040048 +:105C8400A078002801D0A77803E020790002617988 +:105C940047186846007960702000FFF771FF05001F +:105CA400E019801E29000170E019401E2900090432 +:105CB400090C090A017081492000FFF780FF0600E2 +:105CC400002E27D1E078002824D0E078FF2821D0C6 +:105CD4007A488078002811D0784880787749081865 +:105CE400801E007805002D042D0C744880787349BB +:105CF4000818401E007800022D1801E0002005005D +:105D04006E48FFF73DFF2D042D0CA84202D003205E +:105D1400C04306000298694901603000FEBC08BC1B +:105D24001847F0B585B007000E00FFF7B5FE002454 +:105D3400032C60DA6A4631000906090E3800FFF7C1 +:105D44009DFF050068460221017101A806218170AA +:105D540001A80021C170002D33D10098C07800281B +:105D640007D100988078062803D1FFF7A9FE280000 +:105D740044E00098C078FF280ED100988078062867 +:105D84000AD14F480068002833D04D480068000409 +:105D9400000C01F0EFF82CE001A80021C1706A4664 +:105DA40031000906090E01A8FFF768FF444800689E +:105DB400002805D0424800680004000C01F0DAF81D +:105DC40019E00020C043854213D001A8FF21C1700F +:105DD4006A4631000906090E01A8FFF74FFF38484B +:105DE4000068002805D0364800680004000C01F063 +:105DF400C1F8641C9CE7FFF763FE280005B0F0BC03 +:105E040008BC1847088400001CB5040068462D49E6 +:105E14000CC90CC008390838062269462A4802F021 +:105E24002BFD21000906090E2748FFF77AFF010020 +:105E3400002917D12148C07802001206120E002A48 +:105E44000ED01206120E302A04D020480423DB435D +:105E5400036003E01D480523DB430360002002E0E8 +:105E6400012000E0002016BC08BC184730B583B000 +:105E740005000C00684616490CC90CC008390838DE +:105E840006226946104802F0F7FC29000906090EAB +:105E94000D48FFF746FF0100002907D10748C078E5 +:105EA4002070064800796070012004E00020207012 +:105EB4000020607000203EBC08BC184764490040C4 +:105EC400680A004044610100644A00406055004093 +:105ED4004C610100FEB505000C00160068465849E7 +:105EE4008CC98CC00C390C382800000C6946087128 +:105EF4002800000A6946487168462900817120001B +:105F0400000C6946C8712000000A69460872684698 +:105F1400210041720C226946484802F0ADFC310070 +:105F24000906090E4548FFF7FCFE0100002917D1B8 +:105F34004448C07802001206120E002A0ED012063F +:105F4400120E302A04D03C480423DB43036003E0F0 +:105F540039480523DB430360002002E0012000E010 +:105F64000020FEBC08BC18471CB5040068469649CE +:105F74000CC90CC008390838062269462F4802F0BB +:105F84007BFC21000906090E2C48FFF7CAFE01001C +:105F9400002917D12B48C07802001206120E002ADD +:105FA4000ED01206120E302A04D089480423DB4393 +:105FB400036003E086480523DB430360002002E01E +:105FC400012000E0002016BC08BC184710B5C0B082 +:105FD400040068467D4980225200FFF7ABFD802211 +:105FE40052006946154802F047FC21000906090ED3 +:105FF4001248FFF796FE0100002917D11148C07816 +:1060040002001206120E002A0ED01206120E302AB8 +:1060140004D06F480423DB43036003E06C4805238A +:10602400DB430360002002E0012000E0002040B0D8 +:1060340010BC08BC1847000060550040644A00408A +:106044008052010064490040F1B586B00E0003A8F7 +:1060540060490CC90CC008390838062203A95E48F7 +:1060640002F00AFC6846017E5B48FFF75AFE009086 +:106074000098002800D0A2E05848C078302819D1F0 +:1060840056488078062815D151480521C943016036 +:106094000025182D0CDA0C2068430021315050A142 +:1060A4000C2068433018001D02F0FCFC6D1CF0E766 +:1060B400002085E00020040048488078401F844286 +:1060C40062DA20000521FDF7D3F805000C204543D2 +:1060D40042480019C07804F0D3FE705103223F48AF +:1060E4000119091D01A805F0C1F801A80021C1701A +:1060F40001A90D0020000521FDF7BAF80C21484341 +:106104003018001D290002F0CDFC34480019C07974 +:1061140000061BD5002531480019C0794006400E01 +:1061240085422FDA20000521FDF7A2F807000C2094 +:10613400474320000521FDF79BF80C2148433058C4 +:10614400284905F0E3F8F0516D1CE4E700252348E5 +:106154000019C0794006400E854213DA200005215B +:10616400FDF786F807000C20474320000521FDF7C2 +:106174007FF80C21484331581A4805F0ADF9F05125 +:106184006D1CE4E7641D97E7782C16DA20000521DE +:10619400FDF76EF80C2148430021315010A10D0089 +:1061A40020000521FDF764F80C2148433018001D38 +:1061B400290002F077FC641DE6E7012000E00020DE +:1061C40007B0F0BC08BC1847546101000800010086 +:1061D400605500405C610100644A0040644900402D +:1061E400000000000000204110B582B004006420CB +:1061F40000F0C0FE0023002269466B48FBF7B0FBA9 +:106204000098002807D000F00DF80028EFD00320F4 +:10621400FAF700FDEBE700F003F800F011F8E6E709 +:106224007047704738B5002402F0E8F904005F486D +:1062340005682000FBF78CFB280032BC08BC18471B +:1062440038B5002402F0DAF90400584805685748C4 +:10625400002101602000FBF77BFB280032BC08BC56 +:10626400184780B551480021016000F02EF808233A +:106274004F4A00214F4801F0F5FD09BC184700B50D +:106284004D4800684C49FF220A60C1061BD54B49A2 +:106294000968090213D54A4909684A4A12688A1AE0 +:1062A400494B9A420FD3474A12688A1A474B9A427B +:1062B40009D23E4A1268521C3C4B1A6003E0414921 +:1062C4003F4A12680A6008BC184770B5002402F0FF +:1062D40095F904003E4800688021090401433C48C4 +:1062E40001603C4800683C490140802000020843AA +:1062F4003849086039480068C02109020143374819 +:106304000160374800683449014035480160354828 +:106314000068354901403348016034480068324917 +:10632400014032480160172002F099FC0600300059 +:106334002F49F9F785FE05002E480068032188439C +:106344002C4908602B4800680C21884329490860BF +:10635400681E29490860294800210160284807214E +:106364000160284800210160274803210160264874 +:106374000121016025480068254901402348016046 +:1063840024482549016025480A21016024488021C8 +:10639400090501600848FF2101602000FBF7D8FAD5 +:1063A40070BC08BC184700005C0E01007455004026 +:1063B400742A0040ED610000004007E014C0FF3F74 +:1063C4002C4007E07855004099080000282300007D +:1063D400C4C01FE0ACC11FE0FF3FFFFF04C002E0E8 +:1063E40044C002E000C0FF3FFFFF7FFF10C0FF3F3B +:1063F400A0860100704007E00C4007E0144007E06D +:10640400284007E03C4007E0044007E00CF0FFFFB1 +:10641400FFFFFFF76CF1FFFF836200006CF2FFFFE8 +:1064240010F0FFFF0CB41CB5040004A801900A008E +:10643400009401AB6946084878441C3005F0FCF828 +:10644400009900220A70002801D40098001B02B0B1 +:10645400019910BC03B008474326000000B5664903 +:106464000988012282400A4363490A800006000E1B +:1064740000280ED002281BD012D3042827D01FD303 +:10648400062832D02AD308283ED035D3092843D051 +:1064940049E05A49096804220A4358490A6042E01B +:1064A40057490968802292000A4355490A603AE034 +:1064B40053490968802252000A4351490A6032E074 +:1064C4004F49096880220A434D490A602BE04C4930 +:1064D400096840220A434A490A6024E04849096895 +:1064E40020220A4346490A601DE0454909681022F2 +:1064F4000A4343490A6016E042490968802252056A +:106504000A4340490A600EE03F49096880221205A7 +:106514000A433D490A6006E03B4909688022520566 +:106524000A4339490A6008BC184700B5324909884A +:10653400012282409143304A11800006000E002857 +:106544000ED002281BD012D3042827D01FD306282C +:1065540032D02AD308283ED035D3092843D049E085 +:106564002A49096804220A4328490A6042E0284962 +:106574000968802292000A4325490A603AE02449C6 +:106584000968802252000A4321490A6032E0204906 +:10659400096880220A431E490A602BE01C490968E5 +:1065A40040220A431A490A6024E019490968202252 +:1065B4000A4317490A601DE01549096810220A4375 +:1065C40013490A6016E013490968802252050A43F8 +:1065D40010490A600EE0B1490968802212050A4395 +:1065E400AE490A6006E0AD490968802252050A43B3 +:1065F400AA490A6008BC18474056004058C0FF3FEB +:1066040018C0FF3F98C0FF3F38C0FF3F5CC0FF3F4A +:106614001CC0FF3F9CC0FF3F10B5002401F0EEFFFB +:1066240004009F480068302188439D4908609D48C4 +:106634000068302188439B4908609B480068042116 +:1066440001439948016099480068042188439749A7 +:106654000860974800680421014395480160954803 +:106664000068954901409348016094480068924944 +:1066740001409248016092480068802189000143EA +:106684008F4801608F4800688F4901408D48016040 +:106694008E4800688021890001438C480160854848 +:1066A40000688B4901408348016084480068884938 +:1066B400014082480160824800688021490001430A +:1066C4007F4801607F480068824901407D4801603D +:1066D4007E4800688021490001437C480160754878 +:1066E40000687D49014073480160744800687A4934 +:1066F400014072480160724800688021014370487B +:10670400016070480068802188436E4908606F48C2 +:106714000068802101436D480160664800686F4944 +:10672400014064480160654800686C490140634861 +:106734000160634800684021014361480160614889 +:106744000068402188435F49086060480068402130 +:1067540001435E480160574800686149014055485B +:106764000160564800685E4901405448016054483D +:1067740000682021014352480160524800682021EA +:1067840088435049086051480068202101434F481C +:106794000160484800685349014046480160474841 +:1067A400006850490140454801604548006810218F +:1067B400014343480160434800681021884341492C +:1067C400086042480068102101434048016046487F +:1067D400006846490140444801604548006843490F +:1067E4000140434801604348006880214905014352 +:1067F4004048016040480068404901403E4801600B +:106804003F4800688021490501433D4801603D48F7 +:1068140000683D4901403B4801603C4800683A49F2 +:1068240001403A4801603A48006880210905014363 +:1068340037480160374800683749014035480160EE +:1068440016480068802109050143144801602D4859 +:106854000068264901402B4801602C480068234900 +:1068640001402A4801602A48006880214905014303 +:1068740027480160274800682049014025480160F5 +:10688400064800688021490501430448016020004E +:10689400FBF75EF810BC08BC184700003CC0FF3F83 +:1068A40010C002E050C002E040C0FF3F50C0FF3FB4 +:1068B4005CC0FF3F00C002E0FFFFF3FF40C002E006 +:1068C40000C0FF3F10C0FF3FFFFDFFFF1CC0FF3FA4 +:1068D400FFFFFCFFFFFEFFFFFF3FFFFFFFCFFFFFB8 +:1068E400FFF3FFFFFFFCFFFF24C002E0FFFFFFFCFC +:1068F40064C002E080C0FF3F90C0FF3FFFFFFFEF96 +:106904009CC0FF3F0CC002E0FFFF3FFF4CC002E011 +:1069140020C0FF3F30C0FF3FFFFFFFF710B582B03C +:10692400052003F029F86921684603F035F80400CE +:10693400002C02D10120C0430EE0684600781528DF +:1069440001D1002008E068460078062802D1002022 +:10695400C04301E00120C04316BC08BC184780B501 +:10696400052003F009F86921684603F015F80028AA +:1069740002D10120C0430EE068460078152801D1F9 +:10698400002008E068460078062802D10020C043B1 +:1069940001E00120C0430ABC1847F1B582B00F00E2 +:1069A400140002F005FE022002F0E6FF2000401C65 +:1069B4000006000E02F0E0FF2000401C05006846BF +:1069C400007A02F0D9FF29006846057A4D4020007C +:1069D400441E0006000E002807D0387802F0CCFFD1 +:1069E40028003D7845407F1CF1E728000006000E92 +:1069F40002F0C2FF6921684602F0CEFF002802D1EE +:106A04000020C04321E068460078152815D10026EF +:106A1400642E18DA692000F0ADFAFFF7A0FF010038 +:106A2400002901D1002010E00020C043814201D19F +:106A3400761CEDE70020C04307E06846007806288E +:106A440001D1002001E00020C043FEBC08BC18476F +:106A5400F4B582B007000E000020386000203070CA +:106A64000299684602F098FF002802D10020C04332 +:106A74004EE068460078022802D00020C04347E078 +:106A84006921684602F088FF002802D10020C04333 +:106A94003EE068460078002802D10020C04337E079 +:106AA4006846007805000A222D062D0E2900364876 +:106AB40002F08FFF002802D10020C04328E00A2101 +:106AC400684602F069FF002802D10020C0431FE09D +:106AD4002C0000200006000E2D062D0EA84207D221 +:106AE40022000006000E28490C5C5440401CF1E7CB +:106AF400684600782406240E844202D00020C04355 +:106B040006E0062002F038FF1F4838603570002088 +:106B1400FEBC08BC184731B582B00D00140000203B +:106B24002070042202A91120FFF737FF002802D0A9 +:106B34000020C04325E0154A01A96846FFF788FFF5 +:106B4400002802D00020C0431BE000984078207049 +:106B540068460079302802D00020C04311E0009834 +:106B64000078112803D100984078002802D0002032 +:106B7400C04306E02E220099891C280001F07CFE07 +:106B840000203EBC08BC1847644C00408813000039 +:106B940011B583B00C00042203A94020FFF7FDFEC9 +:106BA400002802D00020C04322E0624A01A96846BE +:106BB400FFF74EFF002802D00020C04318E00098E1 +:106BC4004078207068460079032802D00020C04332 +:106BD4000EE000980078402803D1009840780028FF +:106BE40002D00020C04303E0524800F0C3F9002063 +:106BF40004B010BC08BC1847000011B583B00C00E9 +:106C0400042203A94120FFF7C8FE002802D0002077 +:106C1400C04322E0474A01A96846FFF719FF00284C +:106C240002D00020C04318E00098407820706846E5 +:106C34000079032802D00020C0430EE000980078B9 +:106C4400412803D100984078002802D00020C04396 +:106C540003E0384800F08EF9002004B010BC08BCF2 +:106C6400184711B583B00C00042203A9C620FFF70E +:106C740094FE002802D00020C04322E02D4A01A93E +:106C84006846FFF7E5FE002802D00020C04318E064 +:106C940000984078207068460079032802D00020CC +:106CA400C0430EE000980078C62803D100984078CD +:106CB400002802D00020C04303E0642000F05AF909 +:106CC400002004B010BC08BC184711B583B00C00F8 +:106CD400042203A9C720FFF760FE002802D0002089 +:106CE400C04322E0134A01A96846FFF7B1FE002819 +:106CF40002D00020C04318E0009840782070684615 +:106D04000079032802D00020C0430EE000980078E8 +:106D1400C72803D100984078002802D00020C0433F +:106D240003E0044800F026F9002004B010BC08BCBD +:106D3400184700008813000031B582B00D0014001C +:106D4400042202A9894801F097FD884805710522AB +:106D540086498D20FFF721FE002802D00020C04381 +:106D64001FE0834A01A96846FFF772FE002802D09B +:106D74000020C04315E000984078207068460079F0 +:106D8400032802D00020C0430BE0009800788D282F +:106D940003D100984078002802D00020C04300E0CE +:106DA40000203EBC08BC1847FBB582B017000A9E01 +:106DB4000B9D0C9C042202A96C4801F05DFD052288 +:106DC40003996A48001D01F057FD05223900674800 +:106DD400093001F051FD65486946097C817304223C +:106DE400310062480F3001F047FD282200215F483E +:106DF400133003F0C9F929005C48133001F052FE46 +:106E04003B225A498020FFF7C8FD002802D0002009 +:106E1400C0431FE0564A01A96846FFF719FE00283F +:106E240002D00020C04315E00098407820706846E6 +:106E34000079032802D00020C0430BE000980078BA +:106E4400802803D100984078002802D00020C04355 +:106E540000E0002005B0F0BC08BC1847F1B582B0D2 +:106E64000E0015001F00089C042202A93F4801F0EF +:106E740003FD052231003D48001D01F0FDFC1122F7 +:106E840000213A48093003F07FF9042229003748E9 +:106E94001A3001F0F1FC2822002134481E3003F09E +:106EA40073F939003148463001F0FCFD46222F4980 +:106EB4008520FFF772FD002802D00020C0431FE0A8 +:106EC4002B4A01A96846FFF7C3FD002802D0002021 +:106ED400C04315E00098407820706846007908287F +:106EE40002D00020C0430BE000980078852803D12D +:106EF40000984078002802D00020C04300E0002021 +:106F0400FEBC08BC184711B583B00C0000202070EB +:106F1400042203A9B020FFF740FD002802D000207E +:106F2400C0431FE0124A01A96846FFF791FD0028FB +:106F340002D00020C04315E00098407820706846D5 +:106F44000079032802D00020C0430BE000980078A9 +:106F5400B02803D100984078002802D00020C04314 +:106F640000E0002004B010BC08BC1847644C00408A +:106F74008813000070B50400002623480078012817 +:106F84002FD22404240C012C2BD301F037FB060050 +:106F94001E4800683030007805002D062D0E1C4870 +:106FA400405D1A4909683131097888432D062D0E50 +:106FB400174948552D062D0E1548405D002808D167 +:106FC4001448007811490968323109788843114915 +:106FD40008700E48006844853000FAF7B9FC05F0E3 +:106FE400E9FC70BC08BC184738B5002501F006FB65 +:106FF40005000948006804002800FAF7A9FC2000ED +:1070040032BC08BC184700007556004004560040C6 +:10701400FC550040795600401C56004080B56A4635 +:1070240001217948006802F012FD684600780028C2 +:1070340003D00120FFF79EFFF1E709BC184780B594 +:107044007148006802F070FD09BC184710B50400CF +:10705400207800280CD005F022FE002803D101205E +:10706400FFF788FFF7E7207805F02CFE641CEFE7B4 +:1070740010BC08BC1847F2B504000025FF2D21DC24 +:10708400009E05F0F9FD00280AD1002E03D100204E +:107094002070002019E00120FFF76CFF761EF0E756 +:1070A40005F0C2FD0100002903D500202070002056 +:1070B4000BE0080007002770641C6D1C3F063F0EA0 +:1070C4000A2FDBD1002020700120F2BC08BC184735 +:1070D40038B5002501F092FA05007C4800210170C2 +:1070E4007B48002101602800FAF732FC00230022CB +:1070F40069467848FAF734FC009800286DD0764841 +:107104000068764901407448016075480068734915 +:1071140001407348016073480068802149040143B9 +:107124007048016070480068704901406E48016011 +:107134006F4800688021490401436D480160FA20CA +:107144008000FFF717FF6B48006880214904014362 +:10715400684801606848FFF70DFFE120400205F030 +:107164007BFE29480068002804D1012002F046FC77 +:1071740025490860FFF752FF60496148FFF752F95B +:10718400FA2189005E4800F0CDF80400002C02D0FA +:10719400FFF755FF23E05B495948FFF743F9FA210C +:1071A4008900574800F0BEF80400002C02D0FFF715 +:1071B40046FF14E0FFF743FF01F020FA05004448BE +:1071C400012101602800FAF7C3FBFA208000FFF7D1 +:1071D400D1FE00F03DF9040001E0002004004A481B +:1071E400006800280BD10821484800F0F5FC464906 +:1071F40008601C23464A0021464800F033FE200064 +:1072040032BC08BC18470000CC550040F8B5060055 +:107214000F00FFF703FF05F0E5FC3A003E4938484C +:10722400FFF700F93648FFF711FF3C493448FFF7F0 +:1072340022FF002804D1FFF702FF0020C04341E0F1 +:1072440036492F48FFF717FF002804D1FFF7F7FE50 +:107254000020C04336E0002004002406240EA02CA5 +:107264002DD22748002101702C492548FFF703FF40 +:10727400002804D1FFF7E3FE0020C04322E02849A0 +:107284001F4805F0C7FE002819D01D4800F098FFDC +:10729400002814D01A480500194800F091FF00286E +:1072A40004D1FFF7CCFE0020C0430BE0287800286F +:1072B400D3D0287830706D1C761C641CF6E7FFF779 +:1072C400BEFE0020F2BC08BC18470000004000408D +:1072D400D05500403C0D010004C002E0FFFFFCFF5C +:1072E40044C002E000C0FF3F10C0FF3FFFFFFFFEAD +:1072F4001CC0FF3F18C0FF3F60EA0000AC640100FF +:1073040044420040FC600100D455004094540040C5 +:1073140074160040F5280000005201008813000094 +:10732400B464010070B504000E0005F05BFC20009D +:10733400FFF78CFE052005002800451E00281AD002 +:1073440031002000FFF797FE002811D03E492000AD +:1073540005F060FE002801D100200EE03B4920002A +:1073640005F058FE002802D10120C04305E0E3E700 +:107374000020C04301E00220C04370BC08BC184791 +:10738400F8B504000E00170005F02CFC00200500E1 +:10739400B5420CDA05F083FC002803D10120FFF785 +:1073A400E9FDF7E7605D05F08DFC6D1CF0E7052055 +:1073B40005002800451E00281AD039002000FFF7D8 +:1073C4005AFE002811D02049200005F023FE002891 +:1073D40001D100200EE01D49200005F01BFE00280D +:1073E40002D10120C04305E0E3E70020C04301E0EF +:1073F4000220C043F2BC08BC1847000070B504006A +:107404000E0005F0EFFB2000FFF720FE052005002D +:107414002800451E0006000E002810D03100200070 +:10742400FFF729FE002807D091A1200005F0F2FD06 +:107434000028EDD0002004E00020C04301E0022039 +:10744400C04370BC08BC1847B4640100BC640100AC +:10745400FEB50027002000908648019001F0CEF888 +:107464000090C748002101700098FAF771FA0120D2 +:1074740006003606360E182E00D386E03606360E83 +:1074840031000198FFF7C2FE00287CD100200400DF +:107494002406240E0B2C73D22406240E08206043E9 +:1074A4007549085800F08CFE0500684600210172F9 +:1074B4002800451E00280DD02406240E0820604311 +:1074C4006D490858405D0199495D8842F0D068468D +:1074D400012101726846007A00284FD12406240E47 +:1074E400082060436449085800F06AFE01990918AD +:1074F4002406240E082060435F4A1018406801F0F7 +:10750400D1FA00200500402D33DA2406240E082089 +:107514006043594908184068405D002829D0240672 +:10752400240E08206043544908184068405D0D2823 +:1075340009D12406240E082060434F4908184068E6 +:107544000021415515E02406240E082060434A49D1 +:1075540008184068405D0A2809D12406240E082032 +:1075640060434549081840680021415501E06D1CFD +:10757400C9E738000127A740074301E0641C87E7F7 +:10758400C820FFF7F7FC761C73E7012006000020F3 +:1075940004002406240E0B2C09D20120A0403840FC +:1075A400002802D10020060001E0641CF1E701F08C +:1075B40025F80090724806700098FAF7C9F900207F +:1075C400FEBC08BC184710B5002401F017F80400ED +:1075D4006B48002101706B48002101602000FAF71C +:1075E400B7F910BC08BC184738B50024002501F0D1 +:1075F40005F8040062480078002805D06148006856 +:10760400002801D0012005002000FAF7A1F9280084 +:107614000006000E32BC08BC184738B5002400250B +:1076240000F0ECFF040057480068002801D0012056 +:1076340005002000FAF78CF928000006000E32BC81 +:1076440008BC184738B50024002500F0D7FF040013 +:107654009C480078002801D0012005002000FAF79A +:1076640077F928000006000E32BC08BC1847000059 +:107674000D0A0000644D00400809010010B5002403 +:107684003F480078002802D10020C04375E0FFF78E +:10769400C5FC8D498D48FEF7C5FE8D498B48FFF723 +:1076A40041FE002815D08B498848FEF7BBFE8A4965 +:1076B4008648FFF737FEFA204000FFF75BFC200006 +:1076C4000400641C0028E4D0FFF7B9FC0420C04384 +:1076D40053E082497D48FEF7A5FE7D497B48FFF7CC +:1076E40021FE002804D0FFF7AAFC0520C04344E093 +:1076F4007B4A40327B497548FEF794FE74497348CF +:10770400FFF710FE002804D0FFF799FC0620C043C1 +:1077140033E0734A803274496C48FEF783FE6C4947 +:107724006A48FFF7FFFD002804D0FFF788FC072014 +:10773400C04322E06D4A6E496448FEF773FE644913 +:107744006248FFF7EFFD002804D0FFF778FC08201B +:10775400C04312E0674A68495C48FEF763FE5C492F +:107764005A48FFF7DFFD002804D0FFF768FC092022 +:10777400C04302E0FFF763FC002010BC08BC1847BC +:1077840000400040D055004010B500244D4800781A +:10779400002802D10020C04390E0FFF73FFC574986 +:1077A4004A48FEF73FFE4A494848FFF7BBFD002818 +:1077B40014D048494548FEF735FE47494348FFF78A +:1077C400B1FD4F48FFF7D6FB20000400641C0028DD +:1077D400E5D0FFF734FC1820C0436FE049493B482B +:1077E400FEF720FE3A493948FFF79CFD002804D0F3 +:1077F400FFF725FC1920C04360E043493348FEF7F6 +:1078040011FE33493148FFF78DFD002804D0FFF7FE +:1078140016FC1A20C04351E03C4A3D492B48FEF770 +:1078240001FE2B492948FFF77DFD002804D0FFF70E +:1078340006FC1B20C04341E0364A37492348FEF783 +:10784400F1FD23492148FFF76DFD002804D0FFF71F +:10785400F6FB1C20C04331E0304A31491B48FEF797 +:10786400E1FD1B491948FFF75DFD002804D0FFF72F +:10787400E6FB1D20C04321E02A491448FEF7D2FD4F +:1078840013491248FFF74EFD002804D0FFF7D7FB39 +:107894001E20C04312E0244A24490C48FEF7C2FDCE +:1078A4000B490A48FFF73EFD002804D0FFF7C7FB49 +:1078B4001F20C04302E0FFF7C2FB002010BC08BC3D +:1078C4001847000000400040941F0100444200405B +:1078D400881300000861010030750000B01F01002A +:1078E400403D00402C24010044240100803E00401F +:1078F4005C240100403E004074240100CC1F0100C0 +:1079040010270000E81F01008C240100803F004084 +:1079140004200100C03E0040A4240100003F0040B8 +:10792400BC240100D4240100C03F004020200100F9 +:10793400F3B585B00026F64395480078002802D1B7 +:107944003120C04320E1FFF799FE0600002E01D04C +:10795400300019E1FFF718FF0600002E01D03000B7 +:1079640012E1FFF75BFB8B4A8B498C48FEF75AFD0B +:107974008B498A48FFF7D6FC002804D0FFF75FFB49 +:107984003220C04300E1874A87498448FEF74AFD14 +:1079940083498248FFF7C6FC002804D0FFF74FFB59 +:1079A4003320C043F0E0059A80497C48FEF73AFD55 +:1079B4007B497A48FFF7B6FC002804D0FFF73FFB69 +:1079C4003420C043E0E07A497448FEF72BFD79493E +:1079D4007248FFF7A7FC002804D0FFF730FB3520DE +:1079E400C043D1E06E48FFF7C5FA73496B48FEF710 +:1079F40019FD70496948FFF795FC002804D0FFF78A +:107A04001EFB3620C043BFE06A496448FFF733FBDE +:107A1400002804D1FFF713FB3720C043B4E06549C5 +:107A24005E48FFF728FB002804D1FFF708FB382045 +:107A3400C043A9E06149594805F0ECFA002802D096 +:107A44003920C043A0E05E480700FA208000FFF719 +:107A540091FA3800069905F019FB002848D138003E +:107A640000F0AEFB05000024AC42F2DA2A1B5549B3 +:107A74004A48FEF7D7FC4F494848FFF7BFFC0028A7 +:107A840003D03A20C043060070E002A8009001AB86 +:107A940003AA4D49414801F06FFD0398029901433F +:107AA400002906D1281B0199884202DB019800288D +:107AB40003D13B20C043060058E03E4A01993800F8 +:107AC400FFF75EFC002803D03C20C04306004DE0D5 +:107AD40038493248FFF7CFFA002803D13D20C0438C +:107AE400060043E0019824183220FFF743FABBE76D +:107AF40036492A48FEF796FC2E492848FFF712FC1F +:107B0400002803D03E20C04306002FE02949234823 +:107B1400FFF7B1FA002803D13F20C043060025E057 +:107B240024491E48FFF7A7FA002803D14020C04388 +:107B340006001BE02649194805F06CFA002803D01A +:107B44004120C043060011E019491448FEF76AFCBD +:107B540018491248FFF7E6FB002803D04220C0432F +:107B6400060003E0FFF76BFA00200DE010490B4814 +:107B7400FEF758FC1748FFF7FDF90E490748FFF7D1 +:107B8400D1FBFFF75CFA300007B0F0BC08BC184723 +:107B940000400040403F0040EC24010044420040CB +:107BA40088130000403D0040042501001C2501000D +:107BB40008610100307500001461010010520100D9 +:107BC400644D004020520100AC3D010030520100E0 +:107BD4004052010010270000F2B5070000266C484F +:107BE4000078012801D3002045E000F007FD0600DD +:107BF40068480068040067480068002804D06548A5 +:107C040000684068634908603000F9F7A1FE002C61 +:107C140030D000F0F3FC06005F4800680500002D3A +:107C24001ED05D485C490968096801603000F9F7B5 +:107C34008FFE6F6068460088042148433818A860A6 +:107C4400EF602F6168460088A8820020E882022045 +:107C54002070002020816560200004F0EDFD09E023 +:107C64004C48006860604B4804603000F9F770FECF +:107C7400002004002000F2BC08BC1847F3B581B012 +:107C84001400002642480078012803D30220207003 +:107C9400002079E041480078012803D30D202070AA +:107CA400002071E000F0AAFC06000198406805007D +:107CB400E88A012815D328690100091D2961006893 +:107CC4000700E88A401EE8822869A968884201D131 +:107CD400686828613000F9F73BFE00202070380006 +:107CE40052E02F4800682C300078042101432C48CE +:107CF40000682C3001702A4800682D300021017082 +:107D040027480068694609894185019804F01EFDE9 +:107D14003000F9F71DFE04F04DFE00F06FFC060084 +:107D24001F4800682D300078002816D068461C498A +:107D340009682D3109780170019804F049FD30007B +:107D4400F9F706FE68460078022802D00A2020705F +:107D540001E00E202070002016E011480068006A3F +:107D640007000F480068002101620D4800682C30AC +:107D7400002101700A4800680021C1613000F9F750 +:107D8400E7FD002020703800FEBC08BC1847000046 +:107D940075560040F4550040185600407656004091 +:107DA40004560040F2B5070000253878022801D0B7 +:107DB400012031E000F022FC0500B87A00280DD043 +:107DC400002304220099380004F061FC0600280016 +:107DD400F9F7BEFD04F0EEFD00201DE07868040014 +:107DE400E08AA18A884204D32800F9F7B1FD1E2055 +:107DF40012E0E0680100091DE16000990160E08A79 +:107E0400401CE082E068A168884201D16068E060BB +:107E14002800F9F79DFD0020F2BC08BC184770B596 +:107E240060210E4804F0BAFD0C4805000B481830D8 +:107E34000600002004002404240C032C04D22E6029 +:107E440018351836641CF6E70020286004480349F6 +:107E5400016070BC08BC1847000000004851004095 +:107E640018560040F3B585B017001D00002400F03B +:107E7400C5FB04005F480078012804D32000F9F70B +:107E840067FD3C2047E02D062D0E04206843584929 +:107E9400085800283BD12D062D0E04206843544970 +:107EA40001220A502000F9F753FD00233A000699F5 +:107EB400059805F0F5F80390002002900020019049 +:107EC4000020009000230022039928000006000EE1 +:107ED40004F0E2FD06003606360E002E06D1A74851 +:107EE400007801280FD104F065FD0CE000F086FB5A +:107EF40004002D062D0E042068433D4900220A503B +:107F04002000F9F725FD30000006000E03E02000F4 +:107F1400F9F71EFD282007B0F0BC08BC1847F7B5D8 +:107F240084B01E00109D002400F068FB040031485A +:107F34000078012804D32000F9F70AFD3C2052E020 +:107F44003606360E0420704329490858002846D1C5 +:107F54003606360E04207043254901220A502000BB +:107F6400F9F7F6FC2A001204120C0E990D9800F091 +:107F740019F92B001B041B0C069A0599049805F0AB +:107F84008FF803902D042D0C02950F9801900E98F4 +:107F940000906846038E0D9A039930000006000E87 +:107FA40004F07AFD07003F063F0E002F06D1734808 +:107FB400007801280FD104F0FDFC0CE000F01EFB5A +:107FC40004003606360E04207043094900220A5084 +:107FD4002000F9F7BDFC38000006000E03E0200085 +:107FE400F9F7B6FC282007B0F0BC08BC184700001D +:107FF400044F004075560040F1B582B00026604839 +:108004000078012801D34020B4E06846007A1F2894 +:1080140001D13E20AEE000F0F1FA06006846007A95 +:10802400FF2805D16846574909682E31097801723D +:108034006846007A04214843534908580400002C38 +:1080440004D13000F9F784FC432093E0012C04D1DF +:108054003000F9F77DFC3D208CE03020205C0500E9 +:108064002D062D0E4948405D3121615C88432D0663 +:108074002D0E464948552D062D0E4448405D0028D6 +:1080840006D1434800783221615C88434049087036 +:10809400E0690700002F15D02D062D0E7819C07A3F +:1080A4003121615C88432D062D0E7919C8722D0685 +:1080B4002D0E7819C07A002804D1B87A3221615C77 +:1080C4008843B872606A00900098002802D0009833 +:1080D40005F078F8002060852C20002121542D2003 +:1080E400002121542B480078FF2804D02948007827 +:1080F400401C284908703000F9F72AFC04F0C6FA3D +:1081040000F07CFA060023480078012804D32148B3 +:108114000078401E1F490870200004F0BFFF1E486D +:108124000078401E1C4908706846007A04214843C0 +:10813400154900220A50A069002806D1606900216F +:10814400816160691549086005E0A0696169416160 +:108154006069A16981611248006860611048046027 +:108164003000F9F7F5FB05480078012801D104F047 +:1081740021FC0020FEBC08BC184700007A560040D1 +:108184007556004004560040044F0040FC55004022 +:1081940079560040765600407B5600401056004009 +:1081A4000856004000B5D30708D5930706D5002923 +:1081B40004D0491E00230360001DF8E708BC1847DB +:1081C4007847C046013080E2001FB0E10300000A96 +:1081D4000110D0E4000051E3FAFFFF1A0A0000EA9C +:1081E400002090E528C09FE50C1052E00210D1E178 +:1081F4008C0311E10420B005FAFFFF0A0110D0E45A +:10820400000051E30110D014FCFFFF1A030050E0FA +:108214001EFF2FE101010101574800210160704751 +:10822400B54800210160704700B5B44800780028C3 +:1082340003D152480021016002E0B04800210170DE +:1082440008BC18474D480068042148434C4908605D +:10825400AA48012101707047474800210160704716 +:108264004548002101607047F1B582B00F003F0618 +:108274003F0E002F05D0022F09D005D3032F09D0BC +:108284000BE09F48060009E09E48060006E09E4871 +:10829400060003E0B048060000E02CE00298040069 +:1082A4002078202801D1641CFAE714222021300010 +:1082B40001F06AFF2000FFF783FF0500142D09DA9F +:1082C4000921009128000221FAF7D2FF0099081A27 +:1082D400002804D52100300000F0E4FB0BE021006D +:1082E4000C0028000221FAF7C3FF4142701809303C +:1082F400210000F0D7FBF7BC08BC184780B5002369 +:10830400002269469548F9F72BFB0098002804D110 +:10831400FCF70BFD9248FCF7C2FC92480021017067 +:1083240009BC184780B51420FEF724FE8D480121AE +:10833400017009BC184730B583B08B480021016037 +:10834400002500200400FF2C0CD821006846FBF710 +:10835400F7FD0098A84203D3009805008248046002 +:10836400641CF0E7002D03D18048FCF7C8FCFFE74C +:1083740037BC08BC18470000A05500407C5500409D +:108384008055004010B50400207A002800D1A7E0F1 +:10839400217A7748FBF75EFE207A012802D0207A02 +:1083A400022813D17248FFF70BFF627A521C7149FD +:1083B4006F4B1818FEF736F82000001D01F0D2FEAE +:1083C40002006D496D48FEF72DF891E0207A0328EC +:1083D40012D16748FFF7F4FE627A521C6549644B78 +:1083E4001818FEF71FF82000001D01F0BBFE010065 +:1083F4006248FAF7E1FD7BE0207A04280ED15C485C +:10840400FFF7DEFE627A521C5A49594B1818FEF7E0 +:1084140009F85BA15948FEF705F869E0207A0628B7 +:1084240004D157A15548FDF7FDFF61E0207A0728E4 +:1084340006D1627A521C53495048FDF7F3FF57E0C6 +:10844400207A082804D14EA14C48FDF7EBFF4FE0F9 +:10845400207A092804D14AA14848FDF7E3FF47E000 +:10846400207A0A2804D146A14448FDF7DBFF3FE007 +:10847400207A0B280FD12000001D01F073FE002884 +:1084840004D141493D48FDF7CDFF31E03F493B4828 +:10849400FDF7C8FF2CE0207A0C2809D12000001D2C +:1084A40001F060FE02003A493448FDF7BBFF1FE0CB +:1084B400207A0D2809D12000001D01F053FE02008E +:1084C40034A12E48FDF7AEFF12E0207A0E2802D028 +:1084D400207A0F280CD12AA12848FDF7A3FF07E032 +:1084E4002D492348FDF79EFF2B492448FDF79AFFA9 +:1084F40010BC08BC18470000A85500407356004043 +:10850400B4540040CC540040E45400403EB52348E9 +:108514000021016000250024FF2C0CD821006846AE +:10852400FBF724FD0098A84203D3009805001B48DC +:108534000460641CF0E7002D03D10C48FCF7DFFB5A +:1085440007E0164801686846FBF710FD6846FFF728 +:1085540019FF37BC08BC1847FC540040BC0E01008E +:10856400705F01007256004090550040A85701000A +:10857400145500404C640100546401002C55004023 +:1085840000000000E85601005C640100F45601009C +:1085940064640100257500006C640100945500407A +:1085A40070B50200FF24FF200D00691E2D062D0E5C +:1085B400002D16D0157865402B00521C1B061B0E8F +:1085C40002255D430C4E755B2D042D0C2D0A454090 +:1085D4002C001B061B0E02255D43074E755B28000D +:1085E400E2E72406240E24020006000E20430004C1 +:1085F400000C70BC08BC184708FE00007847C04651 +:1086040000000FE1C01080E301F021E11EFF2FE123 +:1086140000F021E11EFF2FE1D3F021E348029FE5A2 +:108624000FE0A0E110FF2FE124029FE50110A0E379 +:108634000010C0E528029FE5000090E500D090E519 +:1086440004009DE400F06FE1FFDFFDE800402DE948 +:1086540000402DE9FF1F2DE900000FE101001EE39A +:108664002000801301002DE9F0019FE5001090E542 +:1086740000D081E5F0019FE50FE0A0E110FF2FE1BC +:10868400D0019FE5D0119FE50020D1E50020C0E591 +:10869400C8019FE5C8119FE5002091E5002080E511 +:1086A40000D092E50100BDE800F06FE1FFDFFDE8D6 +:1086B400B4019FE50FE0A0E110FF2FE194019FE5D5 +:1086C40094119FE50020D1E50020C0E58C019FE5D1 +:1086D4008C119FE5002091E5002080E500D092E513 +:1086E4000100BDE800F06FE1FFDFFDE8FF5F2DE969 +:1086F4000E30A0E10000A0E3200000EAFF5F2DE9B6 +:108704000E30A0E10100A0E31C0000EAFF5F2DE9A8 +:108714000E30A0E10200A0E3180000EA04E04EE2FB +:10872400FF5F2DE90E30A0E10300A0E3130000EA8F +:1087340008E04EE2FF5F2DE90E30A0E10400A0E363 +:108744000E0000EA08E04EE2FF5F2DE90E30A0E1E2 +:108754000500A0E3090000EA04E04EE2FF5F2DE912 +:108764000E30A0E10600A0E3040000EA04E04EE2BB +:10877400FF5F2DE90E30A0E10700A0E3FFFFFFEA51 +:1087840000104FE11F2001E2130052E31F00001A02 +:1087940000200FE10D40A0E1D3F021E308002DE912 +:1087A40000402DE9E01F2DE9E003B4E8E0032DE9E2 +:1087B40002002DE998109FE50010D1E5010051E376 +:1087C4000600001A9C309FE50040D3E5014084E296 +:1087D4000040C3E584309FE5004093E500D084E584 +:1087E40002F02FE188109FE50FE0A0E111FF2FE1D7 +:1087F40038D08DE2D3F021E370009FE50FE0A0E1D3 +:1088040010FF2FE10100BDE800F06FE1FFDFFDE89C +:1088140000200FE1D3F021E348309FE50040D3E589 +:10882400014084E20040C3E502F02FE140309FE5BF +:108834000FE0A0E113FF2FE1D3F021E324309FE503 +:108844000040D3E5014044E20040C3E502F02FE1DB +:10885400FF9FFDE87A560040775600407856004066 +:10886400045600400C560040755600401FD10000CD +:10887400DBC40000FB8C000070B504000D00160082 +:1088840032002900200002F085FC200070BC08BCE6 +:10889400184710B50400002004F08AFD06210020CA +:1088A40004F0AAFC002004F093FD10BC08BC184797 +:1088B40010B50400002004F07BFD0421002004F026 +:1088C4009BFC002004F084FD10BC08BC1847F8B5DC +:1088D40004000E00170004F08BFD20000004000CBF +:1088E400FFF7D7FF002004F063FD0221002004F00D +:1088F40083FC21000904090C090A0906090E002059 +:1089040004F07AFC21000906090E002004F074FC2E +:10891400002005002D042D0C3604360CB54207D278 +:108924002D042D0C795D002004F066FC6D1CF1E72C +:10893400002004F04DFD20000004000CFFF7B8FFF8 +:1089440004F06AFDF1BC08BC1847F8B504000E0039 +:10895400170004F04DFD20000004000CFFF799FF00 +:10896400002004F025FD0221002004F045FC210034 +:108974000904090C090A0906090E002004F03CFC4C +:1089840021000906090E002004F036FC0020050031 +:108994002D042D0C3604360CB54207D239000906D5 +:1089A400090E002004F028FC6D1CF1E7002004F0FF +:1089B4000FFD20000004000CFFF77AFF04F02CFDEB +:1089C400F1BC08BC1847F8B504000E00170004F009 +:1089D4000FFD20000004000CFFF76AFF002004F0E4 +:1089E400E7FC0321002004F007FC21000904090C22 +:1089F400090A0906090E002004F0FEFB21000906FD +:108A0400090E002004F0F8FB002005002D042D0CB5 +:108A14003604360CB54208D2FF21002004F0ECFBEA +:108A24002D042D0C78556D1CF0E7002004F0D0FCCB +:108A340004F0F2FCF1BC08BC184710B40168001D36 +:108A440000290FD00268436882180830DC0702D579 +:108A54004C46641E1B191468121D1C601B1D091F43 +:108A6400F9D1EBE710BC70477847C04640C7A0E394 +:108A740080007CE181007C911EFF2F8101C080E198 +:108A84008CC0B0E10100002A010050E11EFF2FE17B +:108A9400000051111EFF2FE100470268531C0360C0 +:108AA400117070477847C04601402DE9013020E03D +:108AB400030013E30E00001A030010E30400000A8D +:108AC4000130D1E40130C0E4000033E3F9FFFF1AC0 +:108AD4000C0000EA34C09FE5002091E50C3052E020 +:108AE4000230D3E18C0313E1042080040420B10597 +:108AF400F9FFFF0A0130D1E40130C0E4000033E3A0 +:108B04000130D114FBFFFF1A0140BDE81EFF2FE125 +:108B1400010101017847C0460010A0E1810EA0E1E7 +:108B240040C7A0E381007CE10200003A7018810391 +:108B34000010E0131EFF2FE181005CE10A00009A9F +:108B440081C0B0E11EFF2F01801401E2E01581E233 +:108B54008CC3A0E18CC0B0E1401941E2FCFFFF5A94 +:108B64008C0AA0E1AC1581E01EFF2FE1C111A0E148 +:108B74007014C1E3E01581E21EFF2FE102001378B7 +:108B8400002B03D0521C1378002BFBD10B781370ED +:108B9400002B02D0521C491CF8E7704708B4024B62 +:108BA4009C4608BC6047C0468832000008B4024BAB +:108BB4009C4608BC6047C046C8D4000080B500F09D +:108BC40067F900F00BFA00F049FA00F0DBFA00F064 +:108BD40017F909BC1847FEB5854800688007800F5F +:108BE400002803D0022807D003D309E081480400F9 +:108BF40008E08148040005E080200002040001E050 +:108C04007C4804007D480068800118D57B480068D2 +:108C14008004800C401C029078480068000C000717 +:108C2400000F401C01900299009120000199FFF768 +:108C3400B5FF00994143022041430D0000E02500A7 +:108C44008C4800680006000E401C06002800310015 +:108C5400FFF7A4FF07003800FEBC08BC184770B536 +:108C64000600FFF7B8FF04003606360E3000002871 +:108C74000F2808D9103803281ED9401F06281BD9ED +:108C8400083819D033E07C48006802217143C84099 +:108C94008007800F0500002D02D12000800827E006 +:108CA400012D01D1200023E0022D02D12000400833 +:108CB4001EE02000C0081BE0C048006831001039E5 +:108CC40002225143C8408007800F0500002D02D1C5 +:108CD400200080080CE0012D01D1200008E0022DC5 +:108CE40002D12000400803E02000C00800E000207A +:108CF40070BC08BC1847F1B582B00298062802D0AF +:108D0400029807280ED1FF20C04300680190019803 +:108D1400002806D00198FFF7BFFEFF20C0430121C1 +:108D240001605DE0554800680068040002995448F9 +:108D340004F0A4FB00906168524804F09FFB00908B +:108D4400A168514804F09AFB0090E1684F4804F090 +:108D540095FB009021699A4804F090FB00906169AA +:108D6400984804F08BFB0090A169974804F086FBB7 +:108D74000090E169954804F081FB0090216A9448D1 +:108D840004F07CFB0090616A924804F077FB009049 +:108D9400A16A914804F072FB0090E16A9F4804F0D4 +:108DA4006DFB0090216B9E4804F068FB0090616BA2 +:108DB4009C4804F063FB009021009B4804F05EFB98 +:108DC4000700A16B994804F059FB0600E16B984831 +:108DD40004F054FB05002168964804F04FFBFEE7BD +:108DE400F7BC08BC1847C0480021C943016070475C +:108DF4000CC11FE000093D00001BB70088C01FE044 +:108E040038B58D480068102188438B4908608B4829 +:108E14008B4901608B48102101600120FFF71FFF7F +:108E240005002800FA218900FFF7B8FE0400AF48C6 +:108E340002210160AD4800210160834800210160E6 +:108E4400601E824908608248032101608148002134 +:108E54000160814800210160A4480121016031BC06 +:108E640008BC184780B5A248FF21016003F08CFBC1 +:108E740009BC184704C11FE0A8C11FE00456004004 +:108E8400841B0100B03E0100C03E0100D03E010041 +:108E9400F8B500240B2000900020070003200500F3 +:108EA4000520060093480068800111D504F0F8FA03 +:108EB400040091480068022188438F4908608F4864 +:108EC400AA2101608D48552101602000FFF76EFE44 +:108ED40004F0E6FA040088480068012188438649C2 +:108EE40008608648AA210160844855210160200059 +:108EF400FFF75CFE824800681021884380490860BF +:108F04007F480068202101437D4801607C48006857 +:108F1400012101437A480160794800684006FBD585 +:108F240078480121016004F0BBFA04000098390478 +:108F34000143754801607148AA2101606F485521B9 +:108F440001602000FFF732FE04F0AAFA04006A4828 +:108F5400006801210143684801606848AA21016052 +:108F64006648552101602000FFF720FE6748056030 +:108F7400674806605F4800684001FBD5654866495C +:108F840001600E486549016004F08AFA04005A48F9 +:108F9400006802210143584801605848AA21016031 +:108FA4005648552101602000FFF700FE5148006833 +:108FB4008001FBD5F1BC08BC18470000ACC11FE020 +:108FC400E03E0100F03E0100003F0100103F0100BF +:108FD400203F0100303F0100403F010010B5FFF782 +:108FE400FAFD0400D348002101604D48844202D2B6 +:108FF4004C48012101604C48844202D24948022174 +:1090040001604948844202D3464803210160C948AB +:109014000221016010BC08BC18470000503F010049 +:10902400603F0100703F0100803F0100903F01005C +:10903400A03F0100B03F01000CF0FFFF10F1FFFF63 +:10904400698E000010F0FFFF104000E0184000E0BF +:10905400144000E0284000E03C4000E03348002198 +:109064000160334800210160324800210160324828 +:109074000021016031480021016031480021016074 +:109084003048002101603048002101602F48002150 +:1090940001602F48002101602E48002101602E4804 +:1090A400002101602D48002101602D48002101604C +:1090B4002C48002101602C48002101602B4800212C +:1090C40001602B48002101602A48002101602A48E0 +:1090D4000021016029480021016029480021016024 +:1090E400CA4800210160704714F0FFFF044000E00B +:1090F400004000E088C01FE080C01FE08CC01FE07B +:10910400A0C11FE00CC11FE084C01FE004C11FE028 +:1091140008C11FE0A8C11FE0AAAAAAAAAAA8AA2255 +:10912400002D310104C01FE0005A6202088002E0F1 +:10913400188002E000C0FF3F20C0FF3F40C0FF3F57 +:1091440060C0FF3F80C0FF3F10C0FF3F30C0FF3F03 +:1091540050C0FF3F70C0FF3F90C0FF3F00C002E01F +:1091640004C002E008C002E00CC002E010C002E04B +:1091740014C002E018C002E01CC002E020C002E0FB +:1091840024C002E046480021C9430160FF20C043D7 +:10919400002101604748002101604B484B490160B0 +:1091A4004B4850490160504854490160544855495E +:1091B400016059485949016059485F4901605F4855 +:1091C4006349016063486449016068486849016013 +:1091D40068486D4901606D48714901607148724980 +:1091E400016076487649016076487B4901607B4896 +:1091F4007F4901607F488049016085488549016055 +:1092040085488A4901608A488E4901608E488F49A1 +:1092140001609348934901609348984901609848D4 +:109224009C4901609C489D490160A148A149016095 +:10923400A148A6490160A648AA490160AA48AB49C9 +:109244000160AF48AF490160AF48B4490160B44818 +:10925400B8490160B848B9490160704700B5FEE7F4 +:1092640080B5BB4800210160FFF7F8FF09BC18472F +:1092740080B5B74801210160FFF7F0FF09BC18472A +:1092840080B5B34802210160FFF7E8FF09BC184725 +:1092940080B5AF4803210160FFF7E0FF09BC184720 +:1092A40014F0FFFF80B5AA4804210160FFF7D6FF40 +:1092B40009BC184720F0FFFF80B5A54805210160CF +:1092C400FFF7CCFF09BC184700F1FFFF65920000CF +:1092D40004F1FFFF80B59E4806210160FFF7BEFF41 +:1092E40009BC18477592000008F1FFFF80B5984843 +:1092F40007210160FFF7B2FF09BC184785920000FF +:109304000CF1FFFF9592000080B59148082101609F +:10931400FFF7A4FF09BC184710F1FFFFA992000052 +:1093240014F1FFFF80B58A4809210160FFF796FF19 +:1093340009BC184700C01FE0BD92000018F1FFFFF0 +:1093440080B583480A210160FFF788FF09BC1847EC +:10935400D99200001CF1FFFFF192000080B57C4817 +:109364000B210160FFF77AFF09BC184720F1FFFFCA +:109374000D93000024F1FFFF80B575480C210160B6 +:10938400FFF76CFF09BC18472993000028F1FFFF81 +:1093940080B56F480D210160FFF760FF09BC1847D5 +:1093A400459300002CF1FFFF6193000080B56848ED +:1093B4000E210160FFF752FF09BC184730F1FFFF8F +:1093C4007D93000034F1FFFF80B561480F210160F7 +:1093D400FFF744FF09BC18479593000038F1FFFFDD +:1093E40080B55B4810210160FFF738FF09BC1847BE +:1093F400B19300003CF1FFFFCD93000080B55448C9 +:1094040011210160FFF72AFF09BC184728C002E0B8 +:1094140040F1FFFFE593000044F1FFFF80B54C48A5 +:1094240012210160FFF71AFF09BC184701940000DC +:1094340048F1FFFF80B5464813210160FFF70EFF96 +:1094440009BC1847219400004CF1FFFF3994000037 +:1094540080B53F4814210160FFF700FF09BC18479D +:1094640050F1FFFF5594000054F1FFFF80B53848D8 +:1094740015210160FFF7F2FE09BC18477194000042 +:1094840058F1FFFF80B5324816210160FFF7E6FE70 +:1094940009BC1847899400005CF1FFFFA594000003 +:1094A40080B52B4817210160FFF7D8FE09BC184787 +:1094B40060F1FFFFC194000064F1FFFF80B5244810 +:1094C40018210160FFF7CAFE09BC1847D9940000AF +:1094D40068F1FFFF80B51E4819210160FFF7BEFE49 +:1094E40009BC1847F59400006CF1FFFF11950000CA +:1094F40080B517481A210160FFF7B0FE09BC184770 +:1095040070F1FFFF2995000074F1FFFF80B510484A +:109514001B210160FFF7A2FE09BC18474595000016 +:1095240078F1FFFF80B50A481C210160FFF796FE21 +:1095340009BC1847599500007CF1FFFF69950000AC +:1095440080B503481D210160FFF788FE09BC184758 +:109554007055004080B507481E210160FFF77EFE6C +:1095640009BC184780B503481F210160FFF776FE48 +:1095740009BC1847705500400DB400B582B004A86A +:1095840000900A006B4603A9034878440A3003F0AC +:10959400B3FF029906B00847258700001EFF2FE19C +:1095A40000B5002802D541420800FFE708BC18476F +:1095B40010B50024FFF722F8040000207A4908803F +:1095C4007A4908807A49088000207A4908807A49D3 +:1095D40008807A4908807A480068022188437849DB +:1095E40008607848062101602000F8F7B1F910BC42 +:1095F40008BC184738B50025FFF700F8050000241B +:10960400E4436E480088012815D36C480088401E46 +:109614006A490880684800886B49085C0400664809 +:109624000088401C64490880634800888021F9F759 +:109634001FFE614801802800F8F78AF9200032BC37 +:1096440008BC184770B505000026FEF7D7FF0600D2 +:1096540000245748008840283CD2554800880028F8 +:109664001FD15A480078800602D55948057034E065 +:109674004F480088401C4E4908804B480088554993 +:109684000D5449480088401C4749088046480088D2 +:109694004021F9F7EDFD44480180A648032101600B +:1096A4001BE043480088401C414908803E4800882C +:1096B40048490D543C480088401C3B4908803A48BE +:1096C40000884021F9F7D4FD3748018099480321E7 +:1096D400016002E00020C04304003000F8F738F9CC +:1096E400200070BC08BC184738B53648006805002F +:1096F4002D062D0E6D086D076D0F2D062D0E022DF6 +:1097040024D132480078C0074BD52C4800888028E3 +:1097140017D2284800882C492D4A12780A54254823 +:109724000088401C23490880224800888021F9F7DA +:109734009FFD2048018021480088401C1F49088063 +:109744002FE068462249097801702AE02D062D0E83 +:10975400012D1FD116480088012817D3134800880B +:109764001C49085C1A49087010480088401C0F49BD +:1097740008800E4800884021F9F77AFD0B480180E3 +:109784000B480088401E0A4908800AE00C48012161 +:10979400016006E068460E49097801700B480078BC +:1097A400040031BC08BC18474A56004048560040E3 +:1097B4004C560040505600404E5600405256004011 +:1097C40004C000E008C000E0844F004014C000E082 +:1097D40000C000E088520040F1B584B00026FEF7D6 +:1097E4000DFF06000320FFF73AFA0190019800F0FC +:1097F400D5F90022504B00F0D9FA04000D0004986A +:1098040000F0CCF902000B002000290000F0CEFA91 +:1098140004F0F4FB02900298FFF77CF902000B00BD +:109824000020464904F042FC04F0E2FC07006846CC +:1098340039004170684639000904090C090A0170AD +:109844003F4800688021490401433D48016039488C +:10985400002101603B48062101603B480021016072 +:109864003A48802101703A48694649780170314884 +:1098740069460978016037481021016033480021A6 +:1098840001703248007803210143304801702F48A9 +:109894000078FB2101402D48017026480121016018 +:1098A4002D48006830218843102101432A48016073 +:1098B40029480068C02188434021014326480160AB +:1098C40026480068302188432449086023480068FA +:1098D400C0218843214908602148006804210143CC +:1098E4001F4801601E480068082188431C4908601D +:1098F4001C480068042101431A48016019480068A3 +:109904000821014317480160174800684021884333 +:109914001549086015481649016016484021016040 +:10992400FFF746FE3000F8F713F805B0F0BC08BCAA +:109934001847000004C000E0000030400000E03F91 +:10994400C4C01FE008C000E020C000E00CC000E07C +:1099540000C000E028C000E000C002E040C002E017 +:1099640000C0FF3F10C0FF3F0CF0FFFF18F1FFFFE6 +:10997400ED96000010F0FFFF10B504002000000673 +:10998400000EFFF75FFE002803D00120FDF7F2FA76 +:10999400F4E710BC08BC1847F8B507000C00002514 +:1099A4000026F643002E0ED5FFF724FE0600002EF7 +:1099B40009D50120FDF7DEFA280005006D1C84425C +:1099C400F0D2002002E0300038700120F2BC08BC64 +:1099D400184770B504000D0016002800451E002825 +:1099E40008D031002000FFF7D7FF641C0028F4D111 +:1099F400002000E0012070BC08BC184770B50400CA +:109A0400002661480078012801D300201CE0FEF7FD +:109A1400F5FD06005D48006805005C480068002804 +:109A240004D05A4800684068584908603000F7F785 +:109A34008FFF002D07D0032028702C810020686040 +:109A4400280002F0F9FE280070BC08BC1847F2B5E3 +:109A54000500140000262878032802D00120207075 +:109A64005FE049480078012802D30220207058E0C2 +:109A740047480078012802D30D20207051E0FEF7FA +:109A8400BDFD06002889012808D32889401E2881A5 +:109A94003000F7F75DFF0020207042E03D48006889 +:109AA4002C300078012101433A4800682C300170C1 +:109AB400384800682D300021017036480068694636 +:109AC40009884185280002F041FE3000F7F740FF85 +:109AD40002F070FFFEF792FD06002E4800682D305C +:109AE4000078002814D02B4800682D300078070037 +:109AF400280002F06DFE3000F7F72AFF3F063F0E04 +:109B0400022F02D00A20207001E00E20207008E00D +:109B1400204800680021C1613000F7F719FF0020D8 +:109B24002070F1BC08BC184770B5040000252078EB +:109B3400032801D0012023E0FEF760FD0500A07A90 +:109B440000280DD0002301220021200002F09FFDF7 +:109B540006002800F7F7FCFE02F02CFF00200FE0BF +:109B640020890D49884207D02089401C2081280083 +:109B7400F7F7EEFE002003E02800F7F7E9FE3220B5 +:109B840070BC08BC1847000075560040F4550040EE +:109B94007656004004560040FFFF00007847C04658 +:109BA4000010B0E14214A013AF11001A1EFF2FE100 +:109BB4007847C046B0402DE9037021E0807407E285 +:109BC400FF40A0E3704E84E321CA14E0235A14102A +:109BD40004003C11040035112500000A05C08CE086 +:109BE400843AC3E1403983E38115A0E1801481E321 +:109BF400A05A81E180E5A0E10210A0E19E0282E08A +:109C0400000050E30000A0E39521A0E00010A0E3D1 +:109C1400932EA1E001208213010090E00010A0E344 +:109C24000110A1E09305A1E040CE4CE20156B0E161 +:109C34000200002A8220B0E10000B0E00110B1E08F +:109C440001C0BCE23E0000DAA050B0E18024D2E2C0 +:109C54000000B0E20C1AB1E0401941E2071081E1C2 +:109C64000C00005A041A87410000A043B040BDE82C +:109C74001EFF2FE1235A04E004003CE104003511E7 +:109C84002300000A81E090E183E092110300001AAE +:109C94000710A0E10000A0E3B040BDE81EFF2FE1E3 +:109CA4000C001CE105C08CE01200001A050015E14F +:109CB400F6FFFF0A0116B0E10010A0010000A003A6 +:109CC40014504502201A91E10006A0E105C0A0E16C +:109CD4000300004A01C04CE28000B0E10110B1E091 +:109CE400FBFFFF5A00E0A0E10150A0E1843AC3E188 +:109CF400403983E3BFFFFFEA01C04CE28220B0E1B8 +:109D04000330A3E0400913E3FAFFFF0A01C08CE229 +:109D1400B4FFFFEA81E090E183E092110010E003D8 +:109D24008059A0E3830075E10310A081810075913F +:109D3400D8FFFF8A041A87E10000A0E3B040BDE821 +:109D44001EFF2FE101C07CE220505CE2080000AA63 +:109D540020506CE2020012E1A220A0E10120821353 +:109D6400102592E1300CA0E1110580E1311CA0E145 +:109D7400080000EA35005CE3C4FFFFCA20C065E2C6 +:109D8400802092E13025A0E1012082133105A0E179 +:109D9400112C92E10010A0E38024D2E20000B0E292 +:109DA4000710B1E0B040BDE81EFF2FE17847C04680 +:109DB400F0002DE9037021E0807407E2FF40A0E386 +:109DC400704E84E321CA14E0235A141004003C1199 +:109DD40004003511A700000A05C04CE001C04CE2A4 +:109DE400C064E0E3014506E0204B84E10005A0E106 +:109DF400033506E0223B83E10225B0E10210A0E333 +:109E04001F00000A026050E00340D4E0403483E3C2 +:109E14000400002A01C04CE28660B0E10440A4E0E2 +:109E2400026096E00340B4E08660B0E10440A4E040 +:109E3400020056E10350D4E0026046200540A02110 +:109E44000110B1E0F7FFFF3A800EA0E38660B0E1B5 +:109E54000440A4E0020056E10350D4E0026046202E +:109E64000540A0210000B0E0F7FFFF3A8660B0E1B2 +:109E74000440A4E0026056E00350D4E0060016015A +:109E8400300000EA034054E0403483E30200002A37 +:109E940001C04CE28000B0E18440A3E0003063E202 +:109EA400000010E11100000A401E81E3000090E070 +:109EB4008440B3E0034044300110A1E0000090E08E +:109EC4008440B3E0034044300110A1E0000090E07E +:109ED4008440B3E0034044300110A1E0000090E06E +:109EE4008440B3E0034044300110B1E0F2FFFF3A94 +:109EF400844093E0034044300110A1E0844093E0A7 +:109F0400034044300110A1E0844093E00340443016 +:109F14000110B1E0F8FFFF3A800EA0E3844093E023 +:109F2400034044300000A0E0844093E00340443008 +:109F34000000A0E0844093E0034044300000B0E01F +:109F4400F5FFFF3A844093E08044A0230040A0330F +:109F540040448413810A80E1A115A0E140CE9CE233 +:109F64000D0000DAA020B0E18024D4E20000B0E2C9 +:109F74000C1AB1E0400971E3071081E10100004AC5 +:109F8400F000BDE81EFF2FE1FF1687E3701481E3A4 +:109F94000000A0E3F000BDE81EFF2FE1401981E3BB +:109FA40001C07CE220505CE2080000AA20506CE270 +:109FB400040014E1A440A0E101408413104594E19D +:109FC400300CA0E1110580E1311CA0E1080000EA99 +:109FD40034005CE30B0000CA20C065E2804094E1D9 +:109FE4003045A0E1014084133105A0E1114C94E116 +:109FF4000010A0E38044D4E20000B0E20710B1E016 +:10A00400F000BDE81EFF2FE10000A0E30710A0E16F +:10A01400F000BDE81EFF2FE10C001CE10700001A50 +:10A02400050015E10C00001A01C04CE28000B0E10B +:10A034000110A1E0400911E3FAFFFF0A01C08CE21C +:10A0440001C08CE28220B0E10330A3E0400913E3B5 +:10A05400FAFFFF0A02C04CE260FFFFEA015085E20A +:10A064008000B0E10110A1E0400911E3FAFFFF0A0A +:10A0740000C065E259FFFFEA235A04E004003CE112 +:10A08400040035110B00000A816090E18360921195 +:10A09400E0FFFF1A816090E10000A0E30710A0E157 +:10A0A400041A8111F000BDE81EFF2F1183C092E154 +:10A0B4000010E0031EFF2FE18069A0E30000A0E38D +:10A0C400810076E183007691810076010010E0231F +:10A0D4000200002A830076E10710A001041A871108 +:10A0E400F000BDE81EFF2FE17847C04681C0B0E113 +:10A0F4001800002AACCAA0E140CE4CE201C09CE2A8 +:10A104001400004A20005CE3060000AA1FC06CE2B1 +:10A114008115A0E1801481E3A00A81E1300CA0E163 +:10A124000010A0E31EFF2FE13FC07CE28115A0E1F7 +:10A13400801481E3A01A81E18005A0E1300CA051D4 +:10A14400710C2050311CA051010020500000E0434C +:10A154000010E0431EFF2FE10000A0E30010A0E385 +:10A164001EFF2FE17847C0460330D0E50220D0E53A +:10A174000110D0E50000D0E5032482E1010480E170 +:10A18400020880E11EFF2FE170B504000D001600E7 +:10A194002A003100200004F08FF8200070BC08BCB5 +:10A1A4001847310000B50100481E002905D00021E0 +:10A1B4000529F8DAC046491CFAE708BC184710B567 +:10A1C40004002406240EC02C05D32406240E66485D +:10A1D4000019C038047865480068F021C9030143B8 +:10A1E4006248016062480068802149000143604878 +:10A1F40001605F480068802101435D480160954823 +:10A20400006840210143934801600120FFF7CAFF21 +:10A214005648006857490140544801605348006853 +:10A2240021000906090E09090906090EC90401439A +:10A234004E4801600120FFF7B5FF86480068802181 +:10A244000143844801600120FFF7ACFF48480068DF +:10A2540080210143464801600120FFF7A3FF4348E2 +:10A2640000684449014041480160404800682406B0 +:10A27400240E2107090FC90401433C480160012051 +:10A28400FFF790FF73480068802101437148016023 +:10A294006420FFF787FF10BC08BC184710B5040002 +:10A2A40032480068F021C903014330480160304856 +:10A2B40000688021490001432D4801602C48006852 +:10A2C400802101432A48016062480068402101431B +:10A2D400604801600120FFF765FF244800682549B4 +:10A2E4000140224801602148006821000906090E46 +:10A2F40009090906090EC90401431C48016001202B +:10A30400FFF750FF53480068802101435148016022 +:10A314000120FFF747FF16480068802101431448D5 +:10A3240001600120FFF73EFF104800681149014019 +:10A334000E4801600D4800682406240E2107090F09 +:10A34400C9040143094801600120FFF72BFF41487C +:10A354000068802101433F4801606420FFF722FF29 +:10A3640010BC08BC18470000940A010014C0FF3F49 +:10A3740058C0FF3FFFFF87FF38B505000C009C481D +:10A384000068F021C903014399480160314800681D +:10A394008021490001432F480160964800688021CC +:10A3A4000143944801602B48006840210143294837 +:10A3B40001600120FFF7F6FE8D4800688E490140D8 +:10A3C4008B4801608A48006829000906090E0909BA +:10A3D4000906090EC9040143854801600120FFF7FD +:10A3E400E1FE1C480068802101431A4801602406EC +:10A3F400240E012C2AD10120FFF7D4FE7D480068E9 +:10A40400802101437B4801600120FFF7CBFE78489F +:10A4140000687949014076480160754800682D0656 +:10A424002D0E2907090FC904014371480160012059 +:10A43400FFF7B8FE07480068802101430548016022 +:10A444000120FFF7AFFE0220FCF794FD31BC08BCED +:10A45400184700005CC0FF3F10B50024FEF7CEF89B +:10A464000400664800686649014064480160634826 +:10A4740000686449014061480160604800686249BD +:10A4840001405E480160614800685D4901405F48E1 +:10A4940001605E4800685B4901405C4801605B48BC +:10A4A40000685949014059480160594800688021B1 +:10A4B4004900014356480160554800688021014322 +:10A4C40053480160524800684021014350480160EC +:10A4D40050480068504901404E4801604D480068AA +:10A4E400802188434B4908604A48006840218843DA +:10A4F4004849086049480068C021884347490860C2 +:10A5040046480068464901404448016043480068A1 +:10A514004449014041480160404800683A490140CB +:10A524003E48016040480068C02188433E490860B5 +:10A534003D4800683A4901403B4801603A48006898 +:10A544003849014038480160374800682E490140C5 +:10A5540035480160354800688021090301433348C8 +:10A564000160324800688021490301432F4801609B +:10A574002E4800688021890301432C4801602B4840 +:10A5840000688021C9030143284801602848006805 +:10A5940028490140264801602548006826490140B1 +:10A5A4002348016022480068244901402048016092 +:10A5B4001F480068224901401D4801602148006885 +:10A5C400802101431F4801601E4800684021014367 +:10A5D4001C4801601B480068802149000143194858 +:10A5E40001602000F7F7B4F910BC08BC184700005C +:10A5F40014C0FF3F58C0FF3FFFFF87FF10C002E0B9 +:10A60400FFFFFCFFFF3FFFFFFFCFFFFF50C002E053 +:10A6140040C0FF3F50C0FF3FFFFEFFFF04C002E009 +:10A62400FFFCFFFFFFF3FFFF44C002E000C0FF3F59 +:10A6340010C0FF3FFFFFF7FFFFFFEFFFFFFFDFFF4C +:10A64400FFFFBFFF5CC0FF3F80B5FFF705FF1E2083 +:10A65400FCF790FC00213020FFF78EFE2820FFF746 +:10A66400A1FD00213020FFF787FE2820FFF79AFD87 +:10A6740000213020FFF780FE2820FFF793FD002102 +:10A684002020FFF779FE2820FFF78CFD01212820E8 +:10A69400FFF772FE01210820FFF76EFE0121012061 +:10A6A400FFF76AFE01210620FFF766FE01210C2058 +:10A6B400FFF762FE09BC184710B504002406240EF7 +:10A6C400002C05D0022C0DD007D3032C0FD013E09F +:10A6D40001218020FFF750FE0FE00121C020FFF789 +:10A6E4004BFE0AE001219420FFF746FE05E001211C +:10A6F400D420FFF741FE00E0FFE710BC08BC184778 +:10A7040070B505000C0020000006000EFFF7D4FF12 +:10A7140000200600287800280CD028780A2809D0C0 +:10A724003606360E142E05D22878FFF748FD6D1C28 +:10A73400761CEFE73606360E142E04D22020FFF7DF +:10A744003EFD761CF6E770BC08BC184738B504001B +:10A754000D002D062D0E002D05D0022D13D00AD389 +:10A76400032D18D01FE00121200080380006000EC0 +:10A77400FFF702FE18E00121200040380006000E19 +:10A78400FFF7FAFD10E0012120006C380006000EEE +:10A79400FFF7F2FD08E0012120002C380006000E2E +:10A7A400FFF7EAFD00E0FFE731BC08BC184770B5CD +:10A7B40005000C00160031000906090E20000006F1 +:10A7C400000EFFF7C3FF28000006000EFFF766FD2A +:10A7D40070BC08BC184780B501210120FFF7CCFDEF +:10A7E40009BC184780B501210F20FFF7C5FD09BC3E +:10A7F400184780B501210C20FFF7BEFD09BC18479E +:10A8040080B5D8480068D8490140D6480160D54889 +:10A814000068D6490140D3480160D5480068D5494D +:10A824000140D3480160D4480068CF490140D24870 +:10A834000160D1480068CD490140CF480160CF484C +:10A844000068CC490140CD480160CD4800688021B2 +:10A8540049050143CA480160C948006880210905C7 +:10A864000143C7480160C74800688021C904014307 +:10A87400C4480160C4480068C4490140C24801603A +:10A88400C1480068C2490140BF480160C14800682E +:10A89400C1490140BF480160C04800683021884375 +:10A8A400BE490860BD480068C0218843BB490860B0 +:10A8B400AF480068BA490140AD480160B948006832 +:10A8C40030218843B7490860B6480068C0218843EE +:10A8D400B4490860A9480068B1490140A74801602B +:10A8E400B1480068B1490140AF480160AE48006812 +:10A8F400AF490140AC480160A2480068AD4901403D +:10A90400A0480160AC480068A8490140AA48016019 +:10A91400A9480068A6490140A74801609D4800680D +:10A92400A44901409B4801609C480068A349014038 +:10A934009A4801609B480068A04901409948016019 +:10A94400994800689E490140974801609A48006808 +:10A954009B49014098480160904800689049014033 +:10A964008E4801608F4800688D4901408D48016020 +:10A974008D4800688F4901408B4801608E4800680B +:10A984008C4901408C480160844800688D4901402D +:10A9940082480160834800688A4901408148016017 +:10A9A40081480068884901407F4801608248006806 +:10A9B400854901408048016078480068800080082B +:10A9C4007649086077480068800080087549086007 +:10A9D400754800684000400873490860764800687C +:10A9E40040004008744908605E4800686C490140B2 +:10A9F4005C48016060480068694901405E48016044 +:10AA04005F4800686B4901405D4801605E4800682A +:10AA1400684901405C480160604800686B49014036 +:10AA24005E4801605F480068684901405D48016014 +:10AA34005D480068664901405B4801605E48006803 +:10AA4400634901405C480160464800684949014047 +:10AA5400444801604848006846490140464801604E +:10AA6400474800684C490140454801604648006831 +:10AA7400494901404448016048480068554901403B +:10AA84004648016047480068524901404548016012 +:10AA94004548006850490140434801604648006801 +:10AAA4004D490140444801604C4800680C218843EA +:10AAB4004A4908604A4800680C21884348490860AC +:10AAC4002F480068022188432D4908602E480068F9 +:10AAD400022188432C490860424800683D490140EE +:10AAE40040480160404800683A4901403E480160DE +:10AAF4003E4800683E4901403C4801603D480068CA +:10AB04003B4901403B480160364800681749014011 +:10AB140034480160344800681449014032480160F7 +:10AB240032480068344901403048016031480068C7 +:10AB3400314901402F480160B74800210160B748FE +:10AB4400006800280BD10421B548FDF745F8B34946 +:10AB540008600923BF4A0021BF48FDF783F909BCF7 +:10AB64001847C04604C002E0FFFFFFFCFFFF3FFFA1 +:10AB74001CC002E0FFFFCFFF44C002E05CC002E063 +:10AB840000C0FF3F60C0FF3F10C0FF3FFFFFFFEF6B +:10AB9400FFFFFFF770C0FF3FFFFFFFFB0CC002E0A9 +:10ABA400FFFFF3FF4CC002E020C0FF3FFFFFFBFFAD +:10ABB400FFFFF7FFFFFFFFFD30C0FF3FFFFCFFFF7C +:10ABC400FFFFEFFFFF3FFFFFFFFF7FFFFFFFFCFFE4 +:10ABD400FFFFFFFEFFFFFFF3FFFFFFDF00C002E008 +:10ABE40040C002E010C002E050C002E040C0FF3F9D +:10ABF400FFDFFFFF50C0FF3FFFF7FFFFF8B507007F +:10AC040000241120FCF7B6F90020050093480068E1 +:10AC140080214905014391480160914800688021E1 +:10AC2400090501438E4801608E4800688021C904EB +:10AC340001438C4801600120FCF79CF98A480068B4 +:10AC4400800102D428000225054388480068400397 +:10AC540002D428000425054384480068000302D474 +:10AC64002800082505437E480068802149050143E2 +:10AC74007B480160794800688021090501437748D1 +:10AC84000160784800688021C90401437548016067 +:10AC94000120FCF76FF974480068800102D4280091 +:10ACA4001025054371480068400302D4280020257C +:10ACB40005436E480068000302D42800402505437C +:10ACC400674800688021490501436548016064487C +:10ACD40000688021090501436148016064480068F7 +:10ACE4008021C9040143624801600120FCF742F954 +:10ACF4005D480068800102D42800802505435B4834 +:10AD04000068400303D4280080256D00054357489C +:10AD14000068000303D428008025AD000543534890 +:10AD24000068C00203D428008025ED0005434F4885 +:10AD34000068800103D4280080252D0105434B4879 +:10AD44000068000203D4280080256D0105434748AC +:10AD54000068002803D428008025AD010543454838 +:10AD64000068800103D428008025ED0105433F4895 +:10AD74000068C00103D4280080252D0205433D4806 +:10AD84000068400103D4280080256D02054337483C +:10AD94000068800003D428008025AD0205433548AF +:10ADA4000068800703D428008025ED02054332485B +:10ADB4000068800403D4280080252D0305432E4811 +:10ADC4000068000503D4280080256D030543AC42C8 +:10ADD40020D1114800686840002819D00026152E9B +:10ADE40016D20D4800680121B140014000290DD15F +:10ADF4000120B0402840002808D0310007480068EE +:10AE0400FCF7D0FF3000C01DF5F704FF761CE6E721 +:10AE1400014805602C00F4E6B4550040B0550040EC +:10AE24004455004010B582B004006846002101700A +:10AE34006A46012111480068FCF720FF01006846BA +:10AE44000078002801D0002001E02160012016BC18 +:10AE540008BC18473C3D004001AC00001CC0FF3F4B +:10AE640018C0FF3F78C0FF3F74C0FF3F34C0FF3FAE +:10AE74007CC0FF3F14C0FF3F54C0FF3FB0550040AB +:10AE84007847C0469D10A0E3000050E32E0D001A41 +:10AE94001EFF2FE17847C046010030E180142142B3 +:10AEA400400D004A01C050E00C0040300C108130CD +:10AEB400FF20A0E3A0CB02E0A13B12E002003C1182 +:10AEC4008024A0E31300000A03C04CE018005CE3F4 +:10AED4001EFF2FC1011482E1A03BA0E1000482E126 +:10AEE400310C90E00200C031A000822119C06CE254 +:10AEF400521CC1E1001C91E12004A0E102C0D1E098 +:10AF0400830BA0E04037A0E3800073E11EFF2F31E4 +:10AF1400420400E01EFF2FE1FF005CE31EFF2F014F +:10AF24008114B0E10C001C11A10480001EFF2F014C +:10AF3400170053E3E7FFFFDA1EFF2FE17847C0460F +:10AF440080C0B0E10800002A2CCCA0E17FC05CE204 +:10AF54000500004A1FC07CE20004A0E1800480E3F5 +:10AF6400300CA0510000E0431EFF2FE10000A0E3DD +:10AF74001EFF2FE138B505000C002000441E0028F8 +:10AF840004D0287800F0BBF86D1CF6E731BC08BC8F +:10AF9400184770B504000D0016002800451E00284F +:10AFA40008D03100200000F0C0F8641C0028F4D15F +:10AFB400002000E0012070BC08BC1847F1B584B043 +:10AFC4000026FDF71BFB06000420FDF748FE019058 +:10AFD4000198FEF7E3FD00225F4BFEF7E7FE040055 +:10AFE4000D000498FEF7DAFD02000B002000290092 +:10AFF400FEF7DCFE03F002F802900298FDF78AFDEA +:10B0040002000B000020554903F050F803F0F0F85B +:10B014000700684639004170684639000904090C84 +:10B02400090A01704E480068102101434C48016030 +:10B034004C48802101704C486946497801704B485E +:10B044006946097801604A48102101604548002199 +:10B0540001704848002101704748002101604748B9 +:10B06400006801210143454801603E4800780321FE +:10B0740001433C4801703B480078FB2101403948BA +:10B0840001703A48002101603D480068032188436B +:10B09400022101433A480160394800680C21884381 +:10B0A400082101433648016036480068032188437B +:10B0B40034490860334800680C21884331490860EA +:10B0C40031480068012101432F4801602E4800687F +:10B0D400022188432C4908602C480068012101435F +:10B0E4002A48016029480068022101432748016079 +:10B0F4003000F6F72DFC05B0F0BC08BC184710B5BD +:10B10400040023480078800603D40120FBF732FFB3 +:10B11400F7E71548047010BC08BC184717480068C6 +:10B124000221014315480160704770B505000C0009 +:10B13400002617480078C00707D40120FBF71AFF40 +:10B14400761CB442F5D2002003E00748007828704A +:10B15400012070BC08BC1847000030400000E03FEC +:10B16400C4C01FE00C0001E0000001E0040001E0A5 +:10B17400280001E0100001E0200001E0080001E0E7 +:10B1840010C002E050C002E040C0FF3F50C0FF3F8B +:10B19400140001E07847C046030011E30400000AEC +:10B1A400012052E20130D1240130C024F9FFFF8A8A +:10B1B4001EFF2FE1030010E31200001A102052E2D8 +:10B1C4000500003A30002DE93810B1E8102052E2B1 +:10B1D4003810A0E8FBFFFF2A3000BDE8823EB0E152 +:10B1E4000810B1280810A028043091440430804489 +:10B1F400822FB0E1B220D1200130D144B220C0204E +:10B204000130C0441EFF2FE1042052E21000003A36 +:10B21400010010E30600001A043091E4042052E215 +:10B22400B230C0E06338A0E1B230C0E0F9FFFF2AD9 +:10B23400070000EA043091E4042052E20130C0E443 +:10B244006334A0E1B230C0E06338A0E10130C0E46F +:10B25400F7FFFF2A04208232012052E20130D12478 +:10B264000130C024FBFFFF8A1EFF2FE17847C04650 +:10B2740001402DE9040052E30D00003A030011E3FC +:10B284001800001A7CE09FE5003091E503C010E24D +:10B294000700001A042052E2AEC3432003C0CC21AD +:10B2A4000C001E21043080040430B105F8FFFF0AAD +:10B2B400042092E2020012E10800000A0130D1E405 +:10B2C400012052E20130C0E4030013110130D11413 +:10B2D400FAFFFF1A0210B0E10020A0E3F90B001BF3 +:10B2E4000140BDE81EFF2FE10130D1E4012052E20C +:10B2F4000130C0E4010053E3030011E3F9FFFF8AC6 +:10B30400DFFFFF2AF2FFFFEA808080807847C04693 +:10B31400FF30A0E3A0CB13E0A12B131003003C11DA +:10B32400030032112F00000A02C04CE08024A0E385 +:10B33400013020E0023003E0011482E1000482E1E4 +:10B344002021A0E12111A0E1400FA0E3012052E05F +:10B3540001C04C3282208130822071E00220813091 +:10B364000000A0E0822071E0022081300000A0E013 +:10B37400822071E0022081300000A0E0822071E090 +:10B38400022081300000B0E0F2FFFF3A7FC09CE26F +:10B39400090000DA802F92E1A000A0E18014D2E23B +:10B3A4008C0BB0E080087053030080E11EFF2F5126 +:10B3B400FF00A043800B83411EFF2FE102C07CE20B +:10B3C400400780E319005CE3040000CA20106CE22B +:10B3D400102192E18014D2E2300CA3E01EFF2FE191 +:10B3E4000300A0E11EFF2FE14027A0E3800072E1EB +:10B3F400810072310B00003A800072E10400003ACF +:10B40400810072E10000E023800411E38004204203 +:10B414001EFF2FE1810072E10000E0130100200013 +:10B42400800400021EFF2FE180C0B0E181C0B01192 +:10B434000700001A80C0B0E1010020E0800400E2AF +:10B44400830B80111EFF2F1181C0B0E10000E003C7 +:10B454001EFF2FE1A0CB13E01500001AA1CB13E0CF +:10B46400013020E0803403E20900001A0004A0E166 +:10B4740000C0A0E38000B0E101C04C52FCFFFF5AC1 +:10B484000114A0E18110B0E101C08C52FCFFFF5A0D +:10B49400AAFFFFEA00C06CE20004A0E18000B0E172 +:10B4A40001C04C52FCFFFF5A0114A0E1801481E357 +:10B4B400A2FFFFEA013020E0803403E20114A0E19E +:10B4C4008110B0E101C08C52FCFFFF5A0004A0E1DE +:10B4D400800480E399FFFFEA7847C046FF20A0E399 +:10B4E400A0CB12E0A13B121002003C110200331168 +:10B4F4001500000A012020E003C08CE08034A0E3A2 +:10B50400011483E1000483E1913080E0802402E2AD +:10B514008010B0E18000A0317FC0DCE2360000BAC8 +:10B52400A330A0E1003C93E12004A0E18014D3E225 +:10B534008C0BB0E080087053000082E11EFF2F5195 +:10B54400FF00A043800B82411EFF2FE1A13B02E0DC +:10B5540002003CE1020033111A00000A8020B0E12D +:10B564008120B0110200001A010020E0800400E2F2 +:10B574001EFF2FE1012020E0802402E20C001CE1E8 +:10B584000900001A030013E12400000A03C0A0E12B +:10B594000004B0E18000B0E101C04C52FCFFFF5A4E +:10B5A4000114A0E1801481E3D6FFFFEA0114B0E1A5 +:10B5B4008110B0E101C04C52FCFFFF5A0004A0E12D +:10B5C400800480E3CFFFFFEA8030B0E18130B01126 +:10B5D4000000E0034037A0E3810073E10100A08193 +:10B5E400800073911EFF2F81010020E0800400E29F +:10B5F400820B80E11EFF2FE10020A0E308C07CE263 +:10B6040020005CE3050000CA20106CE2A330B0E126 +:10B61400103193E18014D3E2300CA2E01EFF2FE13D +:10B624000200A0E11EFF2FE108B4024B9C4608BCB7 +:10B634006047C046A4E50000F0B5A3B002ACA0602A +:10B64400002016001D00E16002E0206B761C401C07 +:10B6540020633178002904D1206B23B0F0BC08BCEE +:10B664001847252908D10020A061E06120626062AA +:10B67400A062E06200210CE0E068A26802F024FF0E +:10B68400E0600028E1D10020C043E6E70120084340 +:10B694000100761C30780200203AF7D0D21E0AD07E +:10B6A400083A04D0921E04D0D21E06D007E002202D +:10B6B400EDE70420EBE70820E9E71020E7E72A2874 +:10B6C4000DD12868021D2A600068A063002804D5F3 +:10B6D400424208000421A2630143761C14E00020C6 +:10B6E400A0630AE0A26B274B9A4205D093009A18F4 +:10B6F400520080183038A063761C30780200303A4B +:10B704001206120E0A2AEDD330782E2803D0002018 +:10B71400C04360631EE0761C30782A2805D128686F +:10B72400761C021D2A600068F3E7002060630AE0CB +:10B73400626B144B9A4205D093009A1852008018F9 +:10B7440030386063761C30780200303A1206120EEC +:10B754000A2AEDD3A187317809487844223002F0CF +:10B76400B5FE002801D03078761C3E216054605C20 +:10B77400682809D1307868280FD13E2062210AE078 +:10B78400B06D0000FFFFFF7F6C2806D130786C2875 +:10B7940003D13E2071212154761C12A860613378B4 +:10B7A4001800253827D01C3800D185E0001F022856 +:10B7B40000D881E0133800D1A8E009387CD0801E7D +:10B7C40000D14DE1401E00D1F1E0401E022873D9A2 +:10B7D400001F00D1EBE0401F3BD0401E00D195E09C +:10B7E400401E25D0C01E0DD0801E00D18EE0C01E8C +:10B7F40000D18BE03EE1A1692522481CA06112A87A +:10B80400425444E12868011D29600068626B20618C +:10B81400002A02D5FCF7D4FC08E0002102F068FEFF +:10B82400002802D02169401A00E0606BE0612EE13B +:10B834002868011D296002680020C04310400021CF +:10B8440002AA03C212A82061782102A800F0A6F976 +:10B854001DE13E20205C623827D0801F0FD0801E5F +:10B864001BD0801E04D0401F17D0C01E0ED0801FD6 +:10B874002868011D2960216B0068016007E12868C0 +:10B88400011D2960216B0068018000E12868011D09 +:10B894002960216B00680160F9E02A68101D2860A6 +:10B8A400206B1268C11703C2F1E02868011D2960EA +:10B8B400216B00680170EAE03E20205C4C28286877 +:10B8C400C01D07218843010028600831296003C88E +:10B8D40002AA03C2002902D5A1692D2209E0A08F82 +:10B8E400810702D5A1692B2203E0C00705D5A16910 +:10B8F4002022481CA06112A84254A06912A9081869 +:10B904002061190002A800F0E3F9C0E03E20225CA7 +:10B914006C2A01D1286811E0712A09D1286807210D +:10B92400C01D8843010028600831296003C809E06C +:10B9340028686A2A02D1C01D0721F2E7011D296087 +:10B944000068002102AF682A03C706D102A803C811 +:10B9540002AA00210004000C10E0622A06D102A809 +:10B9640003C802AA00210006000E07E0742A01D0D1 +:10B974007A2A04D102A803C802AA002103C23C20E7 +:10B98400205C000766D502A803C8002901D100285D +:10B9940060D02020184378285CD1A16912A83022F5 +:10B9A4004254491C481CA06112A8435452E03E2052 +:10B9B400205C62380CD0801F11D0801E21D0801EE4 +:10B9C40029D0401F1DD0C01E16D0801F0ED027E0E6 +:10B9D4002868011D296000680006001624E0286814 +:10B9E400011D29600068000400141DE02868011D81 +:10B9F40029600068002118E02868011D296000689A +:10BA040012E028680721C01D88430100286008311E +:10BA1400296003C809E02868011D2960006803E063 +:10BA24002868011D29600068C11702AA03C2002901 +:10BA340002DAA1692D2209E0A08F810702D5A1694C +:10BA44002B2203E0C00705D5A1692022481CA06170 +:10BA540012A84254A06912A9081820611900F4E63A +:10BA6400A169481CA0612868021D2A60006812AA06 +:10BA740050540CE0A1692522481CA06112A842542C +:10BA8400002B04D0A169481CA06112A84354A06BE8 +:10BA9400A169761C401A616A401AE169401AA16AD8 +:10BAA400401A216A401AE16A401A01903C20205C45 +:10BAB400400710D4684620210170019801280ADB50 +:10BAC400019F0122694602A800F0ACFC002800D0C6 +:10BAD400D9E57F1EF5D1A26912A902A800F0A2FC43 +:10BAE400002800D0CFE5676A684630210170012F35 +:10BAF40009DB0122694602A800F094FC002800D06A +:10BB0400C1E57F1EF5D1E269216902A800F08AFC33 +:10BB1400002800D0B7E5A76A684630210170012FDC +:10BB240009DB0122694602A800F07CFC002800D051 +:10BB3400A9E57F1EF5D1E0692169226A091802A8E6 +:10BB440000F070FC002800D09DE5E76A68463021CB +:10BB54000170012F09DB0122694602A800F062FC92 +:10BB6400002800D08FE57F1EF5D13C20205C4007E3 +:10BB740000D46EE56846202101700198012800DA9E +:10BB840067E5019F0122694602A800F04BFC0028EA +:10BB940000D078E57F1E00D15BE5F3E7F2B506003F +:10BBA400706984B002906846007C6F2801D1082730 +:10BBB40008E06846007C20210143782901D00A2747 +:10BBC40000E0102703CE6A463C24083E03C26A46BE +:10BBD400127C642A03D06A46127C692A09D100299E +:10BBE40007DA684603C800220023121A6D468B4107 +:10BBF4000CC5684603C800290FD100280DD1706B0D +:10BC040000280AD1082F3BD1305D000738D50298AF +:10BC140030213B303B24017032E0684603C83A00CF +:10BC2400FB17641EFFF700FD30321206120E3A2A8B +:10BC340003D36846007C513812180298FB1702554A +:10BC4400684603C83A00FFF7EFFC6A4603C2684639 +:10BC540003C8002901D1002804D0029930690919C8 +:10BC64008842DAD3082F0BD13C20305C000707D57B +:10BC74000298005D302803D00298641E30210155DB +:10BC84003C20001BF061029909193161716B8842F3 +:10BC940006DA081A0D497062B08F0140B18710E0CE +:10BCA40000290ED53C21715C14220A40102A08D1C7 +:10BCB400B16BB269891A726A891A0C1A012C00DBF9 +:10BCC400746205B0F0BC08BC18470000EFFF000028 +:10BCD400F3B503C891B002AA07AD03C212A8007855 +:10BCE400202101436846017061290CD01198406BF2 +:10BCF400002802D51198062104E004D1672902D155 +:10BD04001198012141631198AD4A4168080D104012 +:10BD140090422BD1080318D111980068002814D13F +:10BD240011980321C16112A8007861380006000E41 +:10BD34001A2847D3254878449230009011980099E6 +:10BD440000690322FFF726FA17E211980321C16163 +:10BD540012A8007861380006000E1A282ED31C4958 +:10BD640079446C31119803220069EBE7010018D182 +:10BD7400119802F09DFC012813DB0027002069467E +:10BD84000978612931D11199302209690A70119A0F +:10BD9400491C4B1C136112AA1278612A1ED1782205 +:10BDA4001DE01199874A49680A4087491143119A4D +:10BDB40051608649471A0020C043E0E705497944A9 +:10BDC4001231CFE7044878440E30B6E778670000B4 +:10BDD4006C670000646700006867000058220A70FE +:10BDE4001199119A8969891C9161002803D1002451 +:10BDF40068468480B5E168460078612800D0A2E0F6 +:10BE04001198446B002C01D5212400E0641C03C864 +:10BE14006A462404241403C202A803C8661C002230 +:10BE2400002302F069FC684603C802AA02D28023F8 +:10BE34001B06594003C2381F6946888007AF68460D +:10BE440000217F1C0177012E31DB02A803C80022E8 +:10BE5400002302F06FFC2AD21C2102A802F088FC05 +:10BE640002A803C802F0C4F9F61F0500012E09DB7D +:10BE740002F0F0F902000B0002A803C802F00AFD68 +:10BE840002AA03C2FF1D072004E029077F1E090F31 +:10BE940039702D11012D01DB401EF6D5401E03D44F +:10BEA4007F1E00213970F9E7FF1D012ECDDA07A8A6 +:10BEB400401C07AD391A6D1CA14200DA0C002404A1 +:10BEC400241437D42000884206DA07A909184978CF +:10BED400082901D30F2100E0002107AA121801E06C +:10BEE400641E521E1378401E8B42F9D00F2904D1D0 +:10BEF40007A909184A78521C4A70002806D56846D2 +:10BF04008088694607AD001D641C888024042414BD +:10BF1400601E0FD429180A7830321206120E3A2AFB +:10BF240003D312AB1B783A3BD2180A70401E491E49 +:10BF34000028F0D51198406B002800D411E1119825 +:10BF4400611E41630DE102A803C80022002302F030 +:10BF5400D3FB06D202A803C880231B0602AA5940B9 +:10BF640003C2884888493F043F1447433800F7F721 +:10BF74007FF96946888004200D5E84490720421BAE +:10BF84000020012A24DB140002AAC0CA02AA03C2A8 +:10BF9400E00707D502A803C832003B00FDF708FEFE +:10BFA40006000F0002A80CC8641002A803C8FDF71D +:10BFB400FFFD02AA002C03C2EAD102A8C0C02BE0F4 +:10BFC400FF070000FFFF0F800000E03FFE030000BA +:10BFD4006F4F544204AA002603C2002C14D0E00779 +:10BFE40007D504A803C832003B00FDF7E1FD0600B5 +:10BFF4000F0004A80CC8641004A803C8FDF7D8FDFA +:10C0040004AA002C03C2EAD102A803C832003B00F0 +:10C01400FDF7CCFE02AA03C268460078662801D167 +:10C024000A3500E006251198406B40190490142845 +:10C0340001DB132004906846302107AC0177641CAF +:10C044000498012841DB02A803C802F01DFD08344E +:10C0540005940500042428000A21FCF79FFD0E0026 +:10C0640028000A21FCF79AFD050005983036401E89 +:10C074000690067028000A21FCF790FD0E002800A7 +:10C084000A21FCF78BFD050006983036401E05900A +:10C094000670641EDFD1059C0498083408380490A7 +:10C0A4000128CDDB02A803C802F0EEFCFDF776FD03 +:10C0B40002000B0002A803C802F0ECFB354B00227F +:10C0C400FDF776FD02AA03C2BDE707A9497807A8D0 +:10C0D400401C07AD201A6D1C30296A4608D16946F8 +:10C0E40089886D1C401E491E918029783029F6D01C +:10C0F40069460978662903D10421515E491C06E08A +:10C1040069460978652901D1012100E00021119ACD +:10C11400526B541824042414A04200DA04002404AA +:10C1240024141ED42100814204DA685C352801D32A +:10C13400392000E030206A1800E0641E521E137893 +:10C14400491E8342F9D0392802D1685C401C6854E6 +:10C15400002906D56846808869466D1E401C641C0B +:10C16400888069460420085E23041B14009012A8EA +:10C17400017811982A0000F00FF813B0F0BC08BC45 +:10C184001847000097750000A086010000002440B5 +:10C194000000F03F84D79741F6B587B004000E9FA6 +:10C1A400666B1D00012D02DAACA001250890202049 +:10C1B400084366280CD0672800D085E003213F049B +:10C1C400C9433F148F4200DA83E0B74200DB80E0CA +:10C1D4007F1C66280BD03C20205C000702D4B542AB +:10C1E40000DA2E003F043F14F61B00D50026236915 +:10C1F400E1693F0458183F14012F24DA491C302206 +:10C204000270012E03DA3C20205C000702D52E20A8 +:10C214005854491C7842E161864200DA77423F046F +:10C224003F147842F619A062AE4200DA35002D04BC +:10C234002D142562E06908992A001818FEF7AAFF50 +:10C24400701BE062D6E0BD4216DA08992A00FEF7B8 +:10C25400A1FFE069791B4019E061A162012E03DAB4 +:10C264003C21615C090705D521692E220A54206A04 +:10C27400401C2062E662BDE008993A00FEF78AFF9E +:10C28400E069ED1BC119E161012E03DA3C20205C59 +:10C29400000704D5481CE06120692E2242542D0475 +:10C2A4002D14AE4200DA350008982369C119E069FB +:10C2B4002D042D142A001818FEF76CFFE0694019AC +:10C2C400E061701BA06295E06129684614D1702179 +:10C2D40015E0B54204DA3C20205C000700D42E00AF +:10C2E400761E00D500266846007F6728684601D17F +:10C2F400652104E0452102E0412901D15021017763 +:10C30400089AE16912782369481C5A540899491C0F +:10C314000091012E03DA3C21615C090702D52E212C +:10C324001954401CE061012E11DB6D1E2D042D14E7 +:10C33400AE4200DA350000992D042D142A00181895 +:10C34400FEF728FFE0694019E061701BA062E06914 +:10C3540021693F0408186946097F0170401C3F1495 +:10C3640004D42B210170401C089005E02D2101709C +:10C37400401C0890380047423F0400253F1403AE98 +:10C38400012F0FDB0A22390001A802F09DFB02985D +:10C394006D1C3070019F761C3F043F14012FF1DAAD +:10C3A400022D0BDA6846007F20210143652905D15F +:10C3B4000898302101700898401C0890002D06D17F +:10C3C4000898302101700898401C08900CE0012D59 +:10C3D4000ADB6D1E089903A8405D30300870089888 +:10C3E400401C0890012DF4DAE1692269089851187B +:10C3F400401A20623C20205C1421014010290DD1F8 +:10C40400A069E1694018A16A4018216A4018E16AEC +:10C414004018A16B884201DA081A606209B0F0BCC6 +:10C4240008BC184770B506000C0015000020002D4C +:10C4340011D02178F068B26802F046F8F060002864 +:10C4440007D0306B641C401C306300206D1EF0D19B +:10C4540001E00020C04370BC08BC18473000320023 +:10C4640008B4024B9C4608BC6047C04614860000D2 +:10C4740008B4024B9C4608BC6047C046B486000022 +:10C4840008B4024B9C4608BC6047C0461C860000AA +:10C4940008B4024B9C4608BC6047C0465086000066 +:10C4A40080B500F0F5FD00F0FDF900F013FA00F09E +:10C4B4004BFA00F0D4F900F05FFE02F017FBFBF733 +:10C4C400AEFC00F029FA02F043FB00F0E5FD02F0B7 +:10C4D40077FC09BC184710B500246548007801288A +:10C4E40034D1FCF78BF8040062480078012804D3A7 +:10C4F40060480078401E5F4908705E480078002854 +:10C5040021D15D48007800281DD100F084FA5B48F1 +:10C5140000785B490978884215D05848007804218E +:10C524004843584908585849086057480068406BC0 +:10C53400401C554909684863A4480068401CA34945 +:10C544000860FFF795FF2000FFF78AFF10BC08BCC6 +:10C55400184780B546480078002813D100F05BFAEC +:10C564004748464909780170444800780421484303 +:10C574004449085844490860AD4843490968016082 +:10C58400FFF77EFF09BC184770B5002600F0C7FD11 +:10C59400FCF734F80600A7480068401CA549086069 +:10C5A4003000FFF75DFF3248007801285DD1BC48B8 +:10C5B4000078002803D0022807D003D30BE0012021 +:10C5C40005000DE0002005000AE001200500B44844 +:10C5D4000121017004E001200500B148002101702F +:10C5E4002D062D0E002D40D0B948006804002E20E1 +:10C5F400205C1F2839D0FCF701F80600608D002864 +:10C604002ED0608D401E60850004000C002827D1C8 +:10C614002C20205C3721084209D02C20205CC82122 +:10C6240001402C2021542D200121215402E02D20F1 +:10C63400002121542C20205C000711D4B548007837 +:10C644003221615C0143B34801703020205CD14940 +:10C65400085C3121615C01433020205CCD4A1154D7 +:10C6640064693000FFF7FCFEC1E770BC08BC1847E2 +:10C674007A56004075560040765600407856004081 +:10C6840077560040044F00400C5600407047FFB5F9 +:10C6940001008E7AAB4FBE5D330001269E4035000B +:10C6A4001B061B0ECE18F67AA64FBE5D6F463E7073 +:10C6B40001266F463F78BE4034001B061B0EDE0089 +:10C6C4006F463F78F61930001B061B0ECE18F67A1B +:10C6D400A6431B061B0ECF18FE721B061B0ECE189C +:10C6E400F67A002E02D18E7AAE438E720006000EC8 +:10C6F40004264643A84FBE5932000026568500261C +:10C70400D661019E16622D266F463F7B97552C26D7 +:10C71400965D6F463F7ABE432C27D6552C26965DF0 +:10C72400002E0DD17B4E36782E437A4F3E701B0679 +:10C734001B0E984EF65C26431B061B0E954FFE54AB +:10C744000006000E04B0F0BC08BC184700B5384A17 +:10C754001268D061364A1268303212781100090624 +:10C76400090E8C4A525C324B1B6831331B789A4356 +:10C774000906090E874B5A540906090E854A525C6C +:10C78400002A08D1634A1278294B1B6832331B787C +:10C794009A43604B1A70264A126830321278821813 +:10C7A400D27A234B1B6831331B781343204A126817 +:10C7B400303212788218D372827A1D4B1B6832335E +:10C7C4001B781343837208BC18470000F0550040DF +:10C7D40000B5174A12683032127811000906090EA2 +:10C7E4004218D27A124B1B6831331B789A430906DC +:10C7F400090E4318DA720906090E4218D27A002A81 +:10C8040006D1827A0A4B1B6832331B789A438272B0 +:10C81400074A12682D3200231370054A12682C321D +:10C8240000231370024A12680023D36108BC18471E +:10C83400045600401C56004000B5002383720300D8 +:10C844000B33190000231A001206120E042A04D214 +:10C8540000230B70491C521CF6E708BC184770B53E +:10C86400A0217E4800F09AF87C4805007B481030EF +:10C874000600002004002404240C092C06D2002005 +:10C8840028706E6010351036641CF4E700202870A0 +:10C894000020686072487149016070BC08BC184788 +:10C8A4007C5600406F48002101606F4800210170F0 +:10C8B4006E48002101706E48002101706D4800210E +:10C8C40001706D48002101606C48002101607047CF +:10C8D4001056004000B50F4A002313702D4A100073 +:10C8E400002211000906090E042904D20022027054 +:10C8F400401C491CF6E7624A00231370614A002376 +:10C904001370614A00231360AC4A0023136008BC0F +:10C91400184700007956004000B585B00320049004 +:10C9240000200390802002905848019058480090BD +:10C934001F23584A0021A248FBF7F1FA05B008BCAE +:10C94400184700000801010070B59921C9009D48ED +:10C9540000F024F88021104800F020F899480500E0 +:10C96400984848300600002004002406240E102CA9 +:10C9740004D26E6148354836641CF6E700206861CD +:10C9840091480021016091488E49016070BC08BC47 +:10C9940018470000FC550040044F004000B509044E +:10C9A400090C012904D300220270401C491EF6E739 +:10C9B40008BC184710B50024FBF720FE04002A48E1 +:10C9C4000078002821D12948007800281DD100F0E2 +:10C9D40022F82C4800782A490978884215D0294839 +:10C9E4000078042148437A490858274908602648B2 +:10C9F4000068406B401C2449096848631E4800686D +:10CA0400401C1D490860FFF743FD2000FFF728FD87 +:10CA140010BC08BC18476F4909786F4A515C08007C +:10CA24000006000EC1000006000E6C4A125C6A4B40 +:10CA34009A5C8918134A1170704738B504000025B0 +:10CA4400FBF7DCFD05000D480068401C0B4908603D +:10CA54002800FFF705FD00F022FBF1E7644E0040DB +:10CA6400F45500401C560040755600407656004070 +:10CA74007B5600407A560040F05500400056004076 +:10CA840077560040785600400C560040444400401D +:10CA9400FFFF000040460040FEB504000A9F002648 +:10CAA400FBF7ACFD0600494800680500002D7DD069 +:10CAB4006869464908603000FFF7D2FC0098286096 +:10CAC4002E202C542C20002129542D2000212954BF +:10CAD40000206885099868600898E8600198A86053 +:10CAE4002F8268460089688233200021295430202F +:10CAF40021000906090EC908295401203021695C66 +:10CB04008840322168542F206107490F295401209D +:10CB14002F21695C8840312168540020E86100209D +:10CB2400686200202862002068630020E863002017 +:10CB3400A8630020286400206864280000F0EEFA4E +:10CB4400280000F0AAFAFBF759FD06002406240E7B +:10CB5400042060431E490D501B4800686861002092 +:10CB6400A86119480068002802D017480068856148 +:10CB740015480560174800783221695C014315485F +:10CB840001703020285C1549095C3120285C084379 +:10CB94003021695C114A505411480078401C1049F6 +:10CBA40008703000FFF75CFC002003E03000FFF762 +:10CBB40057FC4220FEBC08BC184700000456004045 +:10CBC4003FCA00007830004010560040085600402C +:10CBD400044F00407956004008010100FC55004014 +:10CBE4007B56004010B50024FBF708FD040000202C +:10CBF4008D4908808D4908808D49088000208D4921 +:10CC040008808D4908808D4908808D48006802217C +:10CC140088438B4908608B48062101602000FFF798 +:10CC24001FFC10BC08BC184738B50025FBF7E6FC10 +:10CC340005000024E44381480088012815D37F4877 +:10CC44000088401E7D4908807B4800887E49085C36 +:10CC5400040079480088401C774908807648008899 +:10CC64008021F6F705FB744801802800FFF7F8FBE4 +:10CC7400200032BC08BC184738B50024FBF7BEFCC2 +:10CC8400040000256D480088012801D30120050017 +:10CC94002000FFF7E5FB280032BC08BC184738B574 +:10CCA4000024FBF7ABFC0400002561480088402801 +:10CCB40001D2012005002000FFF7D2FB280032BC7E +:10CCC40008BC184770B505000026FBF797FC060062 +:10CCD40000245748008840283CD255480088002842 +:10CCE4001FD15A480078800602D55948057034E0AF +:10CCF4004F480088401C4E4908804B4800885549DD +:10CD04000D5449480088401C47490880464800881B +:10CD14004021F6F7ADFA44480180A9480321016097 +:10CD24001BE043480088401C414908803E48008875 +:10CD340048490D543C480088401C3B4908803A4807 +:10CD440000884021F6F794FA374801809C48032173 +:10CD5400016002E00020C04304003000FFF780FBC4 +:10CD6400200070BC08BC184738B536480068050078 +:10CD74002D062D0E6D086D076D0F2D062D0E022D3F +:10CD840024D132480078C0074BD52C48008880282D +:10CD940017D2284800882C492D4A12780A5425486D +:10CDA4000088401C23490880224800888021F6F727 +:10CDB4005FFA2048018021480088401C1F490880F0 +:10CDC4002FE068462249097801702AE02D062D0ECD +:10CDD400012D1FD116480088012817D31348008855 +:10CDE4001C49085C1A49087010480088401C0F4907 +:10CDF40008800E4800884021F6F73AFA0B48018073 +:10CE04000B480088401E0A4908800AE00C480121AA +:10CE1400016006E068460E49097801700B48007805 +:10CE2400040031BC08BC1847565600405456004014 +:10CE3400585600405C5600405A5600405E5600402A +:10CE4400048007E0088007E004500040148007E0F5 +:10CE5400008007E0C8520040F1B584B00026FBF71B +:10CE6400CDFB06001820FBF7FAFE01900198FCF7B1 +:10CE740095FE0022534BFCF799FF04000D00049823 +:10CE8400FCF78CFE02000B0020002900FCF78EFF4B +:10CE940001F0B4F802900298FBF73CFE02000B008C +:10CEA4000020494901F002F901F0A2F9070068469F +:10CEB40039004170684639000904090C090A0170F7 +:10CEC40042480068802149040143404801603C48CD +:10CED400002101603E48062101603E4800210160B6 +:10CEE4003D48802101703D486946497801703448C5 +:10CEF4006946097801603A481021016036480021EA +:10CF040001703548007803210143334801703248E9 +:10CF14000078FB210140304801702948012101605B +:10CF240030480068304901408020400308432D49BF +:10CF340008602C4800682D4901408020C003084344 +:10CF4400284908602A4800682749014028480160A8 +:10CF540027480068254901402548016025480068A4 +:10CF64008021C90001432348016022480068224906 +:10CF7400014020480160214800688021C900014324 +:10CF84001E4801601D4800688021090101431B48B7 +:10CF940001601B4800681B490140194801601A4898 +:10CFA4001A4901601A48802149050160FFF71AFEF9 +:10CFB4003000FFF755FA05B0F0BC08BC1847000074 +:10CFC400048007E0000030400000E03FC4C01FE0E0 +:10CFD400088007E0208007E00C8007E0008007E07D +:10CFE400288007E000C002E0FFFFCFFFFFFF3FFF04 +:10CFF40040C002E000C0FF3FFFF7FFFF10C0FF3F4B +:10D004000CF0FFFFFFFFFFEF70F1FFFF6DCD00009D +:10D0140010F0FFFF7847C046003021E0030013E31F +:10D024001100001A002FB0E10500000A0120D0E42D +:10D034000130D1E4010052E303005221F8FFFF0A5A +:10D044000E0000EA3CC09FE5002090E5003091E529 +:10D05400030052E10C3042000230C3018C0313017F +:10D064000420B0050430B105F8FFFF0A0120D0E424 +:10D074000130D1E4010052E303005221FAFFFF0A18 +:10D08400030052E01EFF2FE10101010108473300B4 +:10D094002B480021018070477047704770477047E4 +:10D0A40070B5040010006608760035000560001FA6 +:10D0B400244E0660001F244E0660001F234E0660A7 +:10D0C400001F234E0660001F224E0660001F224EE2 +:10D0D4000660001F214E0660001F214E0660001FDF +:10D0E400204E0660001F204E0660001F1F4E066083 +:10D0F400001F1F4E0660001F1E4E0660001F0160C9 +:10D104002600F60703D5001F3326066002E0001F41 +:10D114001326066070BC08BC18477047704780B57A +:10D1240007480088401C0649088005480088642890 +:10D1340004D303480021018001F0FEFC09BC184718 +:10D144004656004014141414121212121111111123 +:10D15400101010100909090908080808070707072B +:10D164000606060605050505040404040303030373 +:10D17400020202020101010170B53C210F48FFF7D0 +:10D184000DFC0E4805000D480C300600002004007C +:10D194002404240C042C06D2002028706E600C3564 +:10D1A4000C36641CF4E700202870002068600448F2 +:10D1B4000249016070BC08BC1847000008530040D5 +:10D1C400F855004030B545682B0005682C00002B4D +:10D1D40007D1C5682A005460002C06D0002565607C +:10D1E40003E01C60002C00D06360856829000025E2 +:10D1F4004D6230BC08BC184700B502008A480906D5 +:10D20400090E016089480068C006FBD4864800689E +:10D214000006000E08BC184780B5854800688021C8 +:10D2240089030143824801608248006882490140C1 +:10D234008020C00008437F4908608048006880005F +:10D2440080088021090601437C4801607C4800680D +:10D25400032188437A490860794800680C2188438F +:10D2640008210143764801607548006830218843ED +:10D2740020210143724801607248006880008008E0 +:10D284008021090601436F4801606F48006803214B +:10D2940088436D4908606C4800680C218843082164 +:10D2A40001436948016068480068302188432021AF +:10D2B4000143654801606548006865490140634869 +:10D2C40001606448006880214902014361480160AB +:10D2D400614800688021490201435F4801605B485E +:10D2E40000688021090201435848016057480068DA +:10D2F4008021890201435548016054480068802117 +:10D30400C902014351480160544800680F21884311 +:10D314000721014351480160504800683021884387 +:10D324004E4908604D480068402188434B490860D5 +:10D334004A48006880218843484908604748006893 +:10D34400474901408020400008434449086045485B +:10D35400006801218843434908604248006802216B +:10D364000143404801603F480068042188433D4927 +:10D3740008603C480068082188433A4908603A48F4 +:10D384000068FF2188430221014337480160374880 +:10D3940000210160364800210160364800680028F9 +:10D3A40004D10120FCF72AFB3249086009BC184764 +:10D3B40000B501000906090E002906D12E480068AF +:10D3C4008022520202432C480260002008BC184705 +:10D3D40000B501000906090E002906D11E4800689F +:10D3E4008022520202431C480260002008BC1847F5 +:10D3F40080B56A4601211F480068FCF728FB68468F +:10D404000078002806D00120F9F7B4FD68460078BA +:10D414000028EED109BC184780B516480068FCF70F +:10D4240083FB09BC18470000088006E00C8006E076 +:10D43400C4C01FE0ACC11FE0FFF3FFFF00C002E067 +:10D4440004C002E040C002E044C002E010C0FF3F5C +:10D45400FFFFFEFF00C0FF3F18C0FF3F008006E053 +:10D46400FF00FFFF048006E0108006E0148006E061 +:10D47400248006E0305600401CC0FF3F0EB400B5C7 +:10D4840082B003A9009102006B460121034878444D +:10D494000A30FEF7D1F8029906B00847294C00007B +:10D4A4007847C04600000FE1C01080E301F021E19D +:10D4B40000100FE1C01001E2C00051E3F9FFFF1AB0 +:10D4C4001EFF2FE100F021E11EFF2FE180B50300D4 +:10D4D4005869401E58611969491C0028196106D40D +:10D4E40058681B680122002101F020FD01E00020A2 +:10D4F400C0430ABC18470000F0B58BB001900291FC +:10D5040018680027FF43002601AC3D000390266104 +:10D51400E2601CE02069019B401C2061029801220A +:10D52400002101F003FD010009390529F2D3202867 +:10D53400F0D02169491EB842216105D0019B010048 +:10D544000298002201F0F2FCE068401CE060E06810 +:10D5540001780B00093B052BDCD32029DAD0002904 +:10D5640007D1002D00DA002528000BB0F0BC08BC60 +:10D574001847252907D1401CE06001782A291CD1CD +:10D58400401CE0601AE0019B009020690122401CCD +:10D5940020610298002101F0C9FC009909788842B1 +:10D5A400D2D02169491EB8422161DAD0019B010021 +:10D5B4000298002201F0BAFCD3E700212020215474 +:10D5C400A6610BE0A1697B08994205D08B0059182C +:10D5D400490051183039A161401CE060E0680278CC +:10D5E400110030390A29EDD3E76101786FA000F00A +:10D5F4006DFF002804D0E0680178401CE06000E082 +:10D60400002121202154205C682806D1E06801789B +:10D6140068290DD12121622207E06C2808D1E06835 +:10D6240001786C2904D121217122401C6254E060EC +:10D63400E06801785FA000F049FF002819D1206953 +:10D64400019B401C206102980122002101F06EFC24 +:10D65400010009390529F2D32028F0D02169491E97 +:10D66400B842216105D0019B01000298002201F01B +:10D674005DFC01A800F010F8012803DA002D00D5A4 +:10D6840073E771E7002D00D500252220205C0028D7 +:10D6940000D159E76D1C57E710B504002220002182 +:10D6A4002154E068007825385FD01C3825D0001F4D +:10D6B400022822D913381CD0C01E70D0801F1CD061 +:10D6C400801E12D0401E14D0401E022815D9001FFF +:10D6D4000FD0401F15D0401E01280AD9001F42D088 +:10D6E400801E06D0C01E04D05BE0200000F066F867 +:10D6F40058E0200000F050F954E0200000F05AFAFD +:10D7040050E02020205C00282BD12120205C6238AE +:10D714000BD0801F18D0801E0ED0801E1BD0401F3F +:10D724000AD0C01E17D0801F15E0A068011DA1609B +:10D7340021690068017014E0A268101DA0602069CE +:10D744001268C11703C20CE0A068011DA160216921 +:10D754000068018005E0A068011DA16021690068DE +:10D76400016001201EE00121BFE720690122401C65 +:10D7740020616068236801F0D9FB2528F1D0226973 +:10D784000021521EC9438842226106D02368010049 +:10D794006068002201F0CAFB0021080002E0C943CE +:10D7A400A3E7002010BC08BC18470000686A6C742A +:10D7B4007A4C000063436E5B00000000F2B5040085 +:10D7C40084B0002003900498002600282CD5E0683B +:10D7D400401CE06001785E2904D1411CE1600078BE +:10D7E400029000E00296E06801785D2900D1401CB7 +:10D7F4005D2100F06BFE002804D1002005B0F0BCD0 +:10D8040008BC1847E168421A00920191E060009850 +:10D81400032809DB821E01982D21401C00F068FEBC +:10D82400002801D001200390A069012805DA04989A +:10D83400002801D0574800E0012060612020205CCE +:10D8440000280CD1A068011DA160076807E03D70A5 +:10D8540022202654E0697F1C401EE061022620003D +:10D86400FFF734FE00210500C943884278D00498AC +:10D87400012817DB28000938052801D3202D65D19C +:10D8840020690022401E206160682368290001F09D +:10D894004DFB0498002801D0022E6FD0022E63D1D4 +:10D8A4000120ABE7002851D50398002810D1029835 +:10D8B400009A002806D10198290000F019FE0028DA +:10D8C400DED005E00198290000F012FE0028D7D12F +:10D8D400039800283AD00299019A2806000E0029DC +:10D8E400009921D106E0984202DB937883422DDA35 +:10D8F400D21CC91E032908D353782D2B1378F2D0D8 +:10D90400834223D0521C491EF4E70029B8D013786F +:10D9140083421BD0521C491EF7E7984202DB9378DE +:10D924008342ADDAD21CC91E03290DD353782D2BA3 +:10D934001378F2D08342A3D0521C491EF4E7137823 +:10D9440083429DD0521C491E0029F8D12020205C1E +:10D95400002883D1E0690126002800D077E78FE70B +:10D964002069401E206194E7F00704D40020C043DE +:10D97400854200D041E70020C0433FE72020205CDF +:10D9840000288DD1E069002800D136E700203870E6 +:10D9940086E70000FFFFFF7FF0B50400A06989B0AF +:10D9A400012800DA8248606101AE2000FFF78EFD95 +:10D9B40005002B2D01D02D2D06D168460571761C4E +:10D9C4002000FFF783FD0500684600210170E06830 +:10D9D4000078642801D0752801D10A270EE069284F +:10D9E40001D100270AE06F2801D1082706E070283A +:10D9F40003D020210143782900D11027302D28D1CC +:10DA04006846012101702000FFF760FD20210143D9 +:10DA140009060500090E782917D1002F01D0102F0F +:10DA240007D110272000FFF751FD050068460021AB +:10DA34000170302D11D12000FFF748FD0500684624 +:10DA440001210170302D0CD1F5E7002FF1D1082709 +:10DA5400EFE7002F16D10A2714E068460078002863 +:10DA640010D030203070761C0CE001A81F308642A4 +:10DA740001D23570761C2000FFF728FD05006846AA +:10DA8400012101700020C04385421FD02906090EE0 +:10DA9400612901D3573909E0412901D3373905E018 +:10DAA40030390906090E0A2900D3FF210906380670 +:10DAB400090E000E8142D8D320690022401E206145 +:10DAC40060682368290001F031FA02E02069401EF1 +:10DAD400206168460078002808D101A8864203D155 +:10DAE4000020C04385425FD000205DE000203070FC +:10DAF4002020205C002856D1E0680178642901D0F8 +:10DB0400692929D13A00002101A801F06DFA2222E5 +:10DB14000123A3542122A25C623A0BD0921F15D098 +:10DB2400921E0DD0921E39D0521F09D0D21E35D06C +:10DB3400921F33E0A268131DA3601268107032E0D4 +:10DB4400A268131DA360126803C22CE0A268131D0F +:10DB5400A3601268108026E03A00002101A801F0B9 +:10DB64000BFB22220123A354E2681278702A15D0F9 +:10DB74002122A25C623ADDD0921FE7D0921E07D028 +:10DB8400921E0BD0521FDBD0D21E07D0921F05E08D +:10DB9400A268131DA360126803C204E0A268131DE7 +:10DBA400A36012681060012009B0F0BC08BC1847DB +:10DBB400FFFFFF7FF0B50700B86995B0012800DAD0 +:10DBC4001A48786104AC3800FFF780FC0500002097 +:10DBD40001902B2D01D02D2D06D168460574641CAF +:10DBE4003800FFF773FC050068460A2141700021E4 +:10DBF4000170302D29D13800FFF768FC2021014342 +:10DC040009060500090E782912D068460121017021 +:10DC1400302D00D0F4E03800FFF758FC05006846CA +:10DC240001210170302D00D0EDE0F4E7FFFFFF7F0C +:10DC34003020207078206070A41C3800FFF746FC68 +:10DC44000500684610214170E2E7202028430006C1 +:10DC5400000E6E286ED1684641706E262670641CD4 +:10DC64003800FFF733FC2021014309060500090EA3 +:10DC7400612915D038690021401EC9438D4238619D +:10DC840000D087E16846007800283FD104A8844288 +:10DC940000D086E10020C043854200D081E1A9E1A3 +:10DCA40061202070641C3800FFF710FC2021014320 +:10DCB40009060500090E6E29DCD13800FFF706FCC1 +:10DCC400050028280DD038690021401EC9438D4223 +:10DCD400386119D078683B680022290001F026F9E0 +:10DCE40012E03800FFF7F2FB0100050061391A2940 +:10DCF400F7D3010041391A29F3D330380A28F0D375 +:10DD04005F2DEED0292DB5D12670641C0020207023 +:10DD14002020385C002800D06BE1684640780B284E +:10DD240000D340E1019A002104A801F0F9FA02AA03 +:10DD340003C244E1692869D16846417069202070B2 +:10DD4400641C3800FFF7C2FB2021014309060500CB +:10DD5400090E6E298ED16E202070641C3800FFF7E6 +:10DD6400B5FB2021014309060500090E662900D0F0 +:10DD740080E73800FFF7AAFB2021014309060500CC +:10DD8400090E69290DD038690021401EC9438D420E +:10DD9400386132D078683B680022290001F0C6F867 +:10DDA4002BE03800FFF792FB202101430906050010 +:10DDB400090E6E2900D05DE73800FFF787FB2021AC +:10DDC400014309060500090E692900D052E738000D +:10DDD400FFF77CFB2021014309060500090E742985 +:10DDE40000D047E73800FFF771FB20210143090603 +:10DDF4000500090E792900D03CE76620207084E7ED +:10DE04000078002802D030202070641C002609E02D +:10DE14000198401C01903800FFF758FB0500684644 +:10DE2400012101700020C043854224D02806000E41 +:10DE3400612801D3573809E0412801D3373805E078 +:10DE440030380006000E0A2800D3FF2069464978BE +:10DE54000006000E884205D2242ED9DA2570641CEF +:10DE6400761CD8E72E2D06D12E202070641C380095 +:10DE7400FFF72CFB0500002E23D1302D0BD1019888 +:10DE8400401E01903800FFF721FB05006846012180 +:10DE94000170302DF3D00198002812D53020207065 +:10DEA4000198641C401C01900BE0242E02DA2570BA +:10DEB400641C761C3800FFF709FB05006846012145 +:10DEC40001700020C043854215D02806000E612849 +:10DED40001D3573809E0412801D3373805E03038F9 +:10DEE4000006000E0A2800D3FF2069464978000680 +:10DEF400000E8842D9D368460078002800D1B9E6DC +:10DF040069464978202028430A2905D10006000ED5 +:10DF1400652800D0AEE604E00006000E702800D0AC +:10DF2400A8E62570641C3800FFF7D0FA05002B2DF5 +:10DF340001D02D2D05D12570641C3800FFF7C6FAD9 +:10DF44000500684600210170302D0BD13800FFF721 +:10DF5400BDFA0500684601210170302DF6D030204D +:10DF64002070641C2800002630380A2802D381E679 +:10DF7400082E02DA2570641C761C3800FFF7A6FA16 +:10DF84000500684601210170280030380A2800D3B2 +:10DF940070E6EDE778683B680022290000F0C6FFD0 +:10DFA40070E6002026E00022002104A801F0B8F960 +:10DFB40002AA03C20198810002A800F0D9FB222022 +:10DFC400012139542120385C6C2807D1B868011D1F +:10DFD400B960026802A803C803C20AE04C28F5D05D +:10DFE400BC68201DB86002A803C800F007F82168C7 +:10DFF4000860012015B0F0BC08BC18477847C0463B +:10E0040080C9A0E381007CE12500008AE1CFA0E182 +:10E0140070C45CE280095C230900003A8CC0B0E162 +:10E02400FF055C331A00002A2CC1B0E10CC2A0E148 +:10E034006CC0A0E18011B0E18014D1E2A00EACE08C +:10E044001EFF2FE18115A0E1A01A81E18005B0E156 +:10E0540001108113801481E3CC0AA0E1090060E27D +:10E06400210050E30800002A8CCF80E120C06CE23C +:10E07400110CB0E18004D0E220C06CE2310CA0E1CC +:10E0840080C40CE20C00A0E01EFF2FE18C0FA0E185 +:10E094001EFF2FE17F04A0E3800880E30C0F80E1E2 +:10E0A4001EFF2FE10000E0E31EFF2FE17847C0468A +:10E0B40050002DE903C031E080342342F901004AC5 +:10E0C400024050E00360D1E00300002A040050E065 +:10E0D4000610D1E0042092E00630B3E080C9A0E34A +:10E0E40081007CE18340DC308044A0E32B00002AE3 +:10E0F40021CAA0E1236A4CE0350056E3370000CA88 +:10E10400833584E1A335A0E1811584E1C115A0E143 +:10E11400200056E3080000BA206056E20220B01145 +:10E124007346A0E1334624E001408413330690E0B3 +:10E134000010B1E20800002A0B0000EA7246A0E1D8 +:10E144003226A0E1024024E0732622E0332622E0B6 +:10E15400020090E03316B1E00300003AA110B0E1F0 +:10E164006000B0E16440B0E101408423401981E2E1 +:10E17400A020B0E18024D4E20000B0E20C1AA1E0B7 +:10E184005000BDE880C9A0E381007CE11EFF2F316F +:10E194000000A0E3211AA0E1011AA0E11EFF2FE173 +:10E1A40081007CE10F00002A836092E10B00000AE9 +:10E1B40081005CE10600008A21CAA0E10430C3E1C9 +:10E1C40001604CE2340056E3CEFFFFDA5000BDE8B4 +:10E1D4001EFF2FE18034C3E3020090E00310B1E09E +:10E1E4005000BDE81EFF2FE15000BDE81EFF2FE1E7 +:10E1F4007847C04681C0A0E1ACCAA0E140CE4CE261 +:10E2040001C09CE20C00004A1FC07CE20C00004AE2 +:10E214008110B0E10115A0E1801481E3A00A81E13D +:10E22400300CA0E1000010E18004A0430000602253 +:10E234001EFF2F21010040421EFF2FE10000A0E33A +:10E244001EFF2FE1800411E38004E0538004A04307 +:10E254001EFF2FE17847C0460010B0E11EFF2F01DA +:10E2640000006042C214A0434214A053400B50E388 +:10E274000008A03140174132400750E30004A031A8 +:10E2840080184132400550E30002A0314018413269 +:10E29400400450E30001A03180194132800450E36E +:10E2A4008000A03140194132C01941E2A01581E03B +:10E2B400800AA0E11EFF2FE17847C046022CB0E19E +:10E2C400222482E1222882E1010080E0033010E26E +:10E2D4000400000A031051E01100003A833FB0E14A +:10E2E40001206045B22060210230A0E110402DE9F8 +:10E2F40002C0A0E102E0A0E1101051E20C5020297C +:10E30400FCFFFF8A811EB0E10C0020290420204577 +:10E314000111B0E1B2206021012060451040BDE848 +:10E324001EFF2FE1031091E001206015020011E3AC +:10E33400012060151EFF2FE1000050E39D10A0E3B3 +:10E34400401F8143000070421EFF2F01400B50E329 +:10E354000008A03110104132400750E30004A031FE +:10E3640008104132400550E30002A031041041324C +:10E37400400450E30001A03102104132800450E314 +:10E384008000A0310110413200CCB0E12004A0E1B2 +:10E3940080C4DCE2810BA0E01EFF2FE1010030E12C +:10E3A40080142142BEF2FF4A000051E180C4208261 +:10E3B400800421820C10A0814037A0E3800073E127 +:10E3C400810053312B00002AA0CBA0E1A13BDCE06B +:10E3D4000800003A8024A0E3011482E11800008AB6 +:10E3E400800471E00600003AA004B0E1A010B0215E +:10E3F4008C0BA0E01EFF2FE1010050E01EFF2F0157 +:10E404008004B0E10120A0E3012082528000B051D9 +:10E41400FCFFFF5A8000A0E1A004A0E16C34A0E15D +:10E42400023C53E0E30080801EFF2F81800880E3DC +:10E4340043CCA0E1833FA0E101C06CE2300C83E156 +:10E444001EFF2FE1180053E31EFF2FC13123A0E16B +:10E45400121371E001208233800472E08000A03145 +:10E4640000C0CCE2802BB0E1A004A0E18014D2E291 +:10E474008C0BA0E01EFF2FE1800073E10E00002A48 +:10E484008120B0E10900000AA0CBA0E1A13B4CE04F +:10E49400020053E3040000BA8114A0E18024A0E345 +:10E4A400170053E3E8FFFFDA1EFF2FE1A20040E06C +:10E4B4008030B0E10000A0031EFF2FE1810073E172 +:10E4C4000000E0231EFF2FE1104734007847C046C8 +:10E4D4000020D0E5FF1001E2010052E3020031E127 +:10E4E4000120F085FBFFFF8A0000A0131EFF2FE12F +:10E4F4007847C046FF1001E2030010E30500000A5C +:10E50400012052E21C00003A0130D0E4030031E162 +:10E51400F8FFFF1A160000EA082052E20E00003A43 +:10E52400042082E230002DE9011481E1011881E127 +:10E534004CC09FE5043090E4042052E201302320D3 +:10E54400AC4343200340C4210C001421F8FFFF0A0C +:10E554003000BDE8FF1001E2040050E2082092E21E +:10E564000130D0E4012052E203003121FBFFFF8A95 +:10E574000100A013010050E21EFF2FE10000B0E3F0 +:10E584001EFF2FE18080808080C413E20100005AC6 +:10E59400002072E20030E3E241C03CE00E00001AC9 +:10E5A40001C093E11B00001A00502DE90210A0E104 +:10E5B40033D3FFEB0120A0E10010A0E30030A0E37F +:10E5C4000050BDE81EFF2FE10130A0E10020A0E1D2 +:10E5D4000010A0E30000A0E31EFF2FE100502DE98E +:10E5E4000100003A000070E20010E1E2EBFFFFEBF3 +:10E5F4000050BDE88CC0B0E10200003A000070E2B7 +:10E604000010E1E20C001CE11EFF2F51002072E219 +:10E614000030E3E21EFF2FE1020050E103C0D1E02D +:10E62400E8FFFF3A03C092E13F03000A30002DE9FE +:10E6340000C0A0E3022092E00330B3E00300002A0C +:10E64400030051E10200500101C08C22F8FFFF2AAF +:10E654006330B0E16220A0E18054A0E320405CE29A +:10E664003544A0210050A023355CA0310040A033E4 +:10E67400010000EAA330B0E16220A0E1020050E111 +:10E6840003C0D1E0020040200C10A0210440B4E0FB +:10E694000550B5E0F6FFFF3A0020A0E10130A0E10B +:10E6A4000400A0E10510A0E13000BDE81EFF2FE149 +:10E6B400104B70B401004A684C6880200006024088 +:10E6C40001201C404C6002D10C68002C0DD04D6818 +:10E6D4000C686E00E50F35434D6064000C60401E0D +:10E6E400EC02F4D54C6823404B604B681A434A60F3 +:10E6F40070BC7047FFFF0F007847C04680C9A0E395 +:10E7040081007CE183007C911EFF2F8101C083E1A5 +:10E714008CC090E10CC092E10200002A030051E198 +:10E72400020050011EFF2FE10100531100005201AD +:10E734001EFF2FE17847C04680C9A0E381007CE139 +:10E7440083007C911EFF2F8103C081E18CC090E186 +:10E754000CC092E10200002A010053E100005201C2 +:10E764001EFF2FE103005111020050011EFF2FE193 +:10E77400F8B5444E040060680D00000D3040B0420E +:10E7840009D16068000302D12068002801D002206A +:10E7940074E0012072E0010006D12000FFF788FF39 +:10E7A400012801DB002069E0012D0CDB311A8D42C8 +:10E7B40009D36068002802D53349002001E0002015 +:10E7C400310503C4E5E74142A94207DA61682F4AEB +:10E7D40028180A400005104360604DE063686268D1 +:10E7E400802109061B03401E1B0BCE0A2D181E4355 +:10E7F40028000A40002335306660352802D3626061 +:10E804002360CFE728001E260025F643B04204DA31 +:10E8140066682568266020306360434211D026680C +:10E8240067686D1EAD412020ED43C01AED0F864090 +:10E83400354326688740DE40374327606068D84008 +:10E8440060606068104360601148854204D28D4264 +:10E854000CD12078C00709D52068401C20602068AE +:10E86400002803D16068401C606005E06068904245 +:10E8740002D12068002895D00020C043F2BC08BC17 +:10E884001847C046FF0700000000F0FFFFFF0F809D +:10E89400010000807847C04650002DE903C031E0F4 +:10E8A4008034234205FEFF4A024050E00360D1E079 +:10E8B4000400002A806426E2040050E00610D1E03F +:10E8C400042092E00630B3E080C9A0E381007CE13B +:10E8D4008340DC308044A0E35500002A21CAA0E133 +:10E8E400236A4CE0360056E34F0000CA010056E3A9 +:10E8F400280000CA0CCAA0E1833584E1A23A83E16E +:10E904008225A0110225A001A330A001811584E174 +:10E91400A01A81E1800572E00310D1E01600004ADC +:10E924000010A0010000A0030060A0132060A00359 +:10E93400010011013C00000A0300004A016086E264 +:10E94400000090E00110B1E0FBFFFF5AECCFA0E122 +:10E9540086CA5CE00160DCE3ECC0A0E10600008A4A +:10E96400806976E2A66AA0E180C40CE23006A0E1E8 +:10E97400710620E03116A0E1010020E0A005B0E11D +:10E98400810A80E18014C1E3A040B0210000B0E21C +:10E99400A115ACE0240000EA833584E1A335A0E1AD +:10E9A400811584E1A115A0E1200056E3080000DAF6 +:10E9B400206056E20220B0117346A0E1334624E001 +:10E9C40001408413004074E23306D0E00010C1E239 +:10E9D400080000EA7246A0E13226A0E1024024E0E9 +:10E9E400732622E03336A0E1032022E0004074E2E3 +:10E9F4000200D0E00310C1E0400911E30500001A51 +:10EA040001C04CE28C2AB0E10200000A8440B0E16B +:10EA14000000B0E00110A1E04019C1E3A030B0E172 +:10EA24008034D4E20000B0E20C1AA1E05000BDE84A +:10EA34001EFF2FE181007CE10F00002A8034C3E334 +:10EA4400836092E10900000A8CC0A0E181005CE1CE +:10EA54000400008A21CAA0E101604CE2340056E3BC +:10EA6400CEFFFFDAF0FFFFEA020050E00310D1E02E +:10EA7400816090E10010A003EBFFFFEA83007C01BA +:10EA84000010E023E8FFFFEA7847C04681C0B0E108 +:10EA94000A00002AACCAA0E140CE4CE201C09CE2CC +:10EAA4000600004A1FC07CE28115A0E1801481E3C6 +:10EAB400A00A81E1300CA0510000E0431EFF2FE1C9 +:10EAC4000000A0E31EFF2FE17CB504000E0015003A +:10EAD40030002900F4F7CCFB45430090701B0190F3 +:10EAE400684603C803C476BC08BC184738B564211B +:10EAF4001048FDF753FF0F480400002005002D04C3 +:10EB04002D0C042D0AD22D042D0C14206843094920 +:10EB140008181430606014346D1CF0E70020606045 +:10EB240003480449016031BC08BC184700000000D8 +:10EB3400145600408450004010B596480068FAF717 +:10EB4400F3FF040020000006000E10BC08BC1847A8 +:10EB540070B5902189009248FDF720FF402191482B +:10EB6400FDF71CFF8E4805008D4824300600002068 +:10EB740004002404240C0F2C09D2642028702120C2 +:10EB840000212954EE6024352436641CF1E7642006 +:10EB940028702120002129540020E86082480021A7 +:10EBA40001607D48002101807C4810210180554886 +:10EBB4007B4901600120FAF721FF7C4908600020AD +:10EBC400FAF71CFF7349086000F003F870BC08BC36 +:10EBD400184700B585B003200490002003908020DE +:10EBE400029073480190734800901D23724A0021DB +:10EBF4007248F9F794F905B008BC1847FCB504004D +:10EC04000D002120032121542D062D0E012D05D1A7 +:10EC1400E06965490968401860610DE0A069002851 +:10EC240005D1E069604909684018606104E0A069A1 +:10EC34005D49096840186061684600906069082170 +:10EC4400F9F7ACFF00988180684680880821484322 +:10EC54005449081807003868002805D13C60002092 +:10EC6400E0600120B88007E0386806003C60E66098 +:10EC74003461B888401CB88000202061F3BC08BC13 +:10EC84001847FCB504006846009060690821F9F74C +:10EC940085FF00988180684680880821484341495F +:10ECA400081807003868A04207D1E06805003D60F5 +:10ECB400002D0AD00020286107E020690500E068E3 +:10ECC4000600EE60002E00D0356121200121215480 +:10ECD4000020E06000202061B888401EB880F3BCAA +:10ECE40008BC184780B56A46002130480068FAF726 +:10ECF400AEFE09BC184780B52C480068FAF714FF2B +:10ED040009BC18472C560040F1B582B001AA002175 +:10ED140020480068FAF79BFEFFF7E4FF22480068EA +:10ED2400401C21490860204800680821F9F736FF93 +:10ED34000F003F043F0C082078431A49081800903C +:10ED4400009800680400002C20D0E06806001648F3 +:10ED540000686169884217D16068050028000028AE +:10ED640003D0A168200000F0E3FA2000FFF789FF38 +:10ED74002020205C022804D101212000FFF73EFF5F +:10ED840002E02120022121543400DCE7FFF7B3FF25 +:10ED9400BCE700002856004044560040425600405C +:10EDA4000440004048520040205600402456004091 +:10EDB40044460040FDFF0000404800400DED0000C7 +:10EDC4002D4908002D4908002D4908002D49080047 +:10EDD4002D4908002D4908002D4908002D49080037 +:10EDE4002D4908002D4908002D4908002D49080027 +:10EDF4002D4908002D4908002D4908002D49080017 +:10EE04002D4908002D4908002D4908002D49080006 +:10EE14002D4908002D4908002D4908002D490800F6 +:10EE24002D4908002D4908002D4908002D490800E6 +:10EE34002D4908002D4908002D4908002D490800D6 +:10EE44002D4908002D4908002D4908002D490800C6 +:10EE54002D4908002D4908002D4908002D490800B6 +:10EE64002D4908002D4908002D4908002D490800A6 +:10EE74002D4908007047C0463C6501003465010017 +:10EE84003E650100406501004265010044650100E2 +:10EE940046650100486501004A6501004C650100B2 +:10EEA4004E65010050650100526501005465010082 +:10EEB40056650100586501005A6501005C65010052 +:10EEC4005E65010060650100626501006465010022 +:10EED40066650100686501006A6501006C650100F2 +:10EEE4006E650100706501007265010074650100C2 +:10EEF40076650100786501007A6501007C65010092 +:10EF04007E65010080650100826501008465010061 +:10EF140086650100886501008A6501008C65010031 +:10EF24008E65010090650100A46501001847F2B5E3 +:10EF340006001F0082B0002901D168460290340007 +:10EF440000E0641C2078010009390529F9D3202840 +:10EF5400F7D005002D2D01D02B2D01D1641C00E02C +:10EF64002B250299200000F045F8029A1268944279 +:10EF740001D1029A1660029A1268964203D10029BE +:10EF840011D100280FD12B2D03D180231B069942C8 +:10EF940009D22D2D19D1802301221B06994214D3A5 +:10EFA40001D8904211D300F0C5F922210160002F4D +:10EFB40001D0012038602D2D03D1802100200906C5 +:10EFC4000EE00020C04341080AE02D2D04D10022A8 +:10EFD4000023121A8B4101E002000B0010001900FB +:10EFE40003B0F0BC08BC184780B50023FFF79FFFAF +:10EFF4000CBC1847FDB50D0086B0002B01D00021D4 +:10F004001960069C00E0641C207801000939052978 +:10F01400F9D32028F7D02D2801D02B2803D1694615 +:10F024000870641C02E068462B21017007980028D0 +:10F0340003D4012801D0252806DB002D01D0069831 +:10F044002860002000218FE001280BDB102818D154 +:10F054002078302815D1607820210143782910D1F7 +:10F06400A41C0EE02078302801D00A2008E0607843 +:10F0740020210143782902D110200790F0E70820CD +:10F08400079003942078302803D1641C207830281A +:10F09400FBD000260027029404A8C0C06846C046DE +:10F0A40038A10196417014E004A9C0C1079A6946C9 +:10F0B4004978D317401A0006000E01903000019ED3 +:10F0C4003900360600F03EF9360E002736184F4157 +:10F0D400641C2178080041381A2800D22031079A8C +:10F0E40028A0FFF705FA0028DED10398A042A4D097 +:10F0F400079902982DA2515C201A401A25D40128A0 +:10F1040017DA019A00231206120E3900B01A994137 +:10F114008F420ED301D886420BD3079AD317FCF73C +:10F1240083FA02000B0004A803C88B4201D1824277 +:10F134000BD000F0FFF8222101600898002801D0CC +:10F14400012101600AA6C0CE09E0684600782D2896 +:10F1540005D100200021801BB94106000F00002DBD +:10F1640000D02C603000390009B0F0BC08BC18474E +:10F17400FFFFFFFFFFFFFFFF80B50023FFF73AFF0C +:10F184000CBC184730313233343536373839616284 +:10F19400636465666768696A6B6C6D6E6F707172C3 +:10F1A400737475767778797A00000000000041293D +:10F1B400211C191716151413121211111110101005 +:10F1C4000F0F0F0F0E0E0E0E0E0E0E0D0D0D0D0D5C +:10F1D4000D000000FDB588B004000D0008A800F083 +:10F1E400BDF80821014001910A99002901D00022AB +:10F1F4000A6008218843012836D10899022000902A +:10F2040004AB2A00200000F03DF9040004D102AA56 +:10F214000020002103C21DE00598FFF71BF802AA95 +:10F2240003C2022C16DB04AD0835641E394B02A858 +:10F2340003C80022FAF7BCFC060028680F00FFF799 +:10F2440009F832003B00FEF731FF02AA03C22D1D6C +:10F25400641EEBD1099804990A9B421802A803C8BA +:10F2640000F01CFA02AA48E0022837D1089900905D +:10F2740004AB2A00200000F0E9FA040004D102AA39 +:10F284000020002103C21DE00598FEF7E3FF02AA57 +:10F2940003C2022C16DB04AD0835641E1E4B02A803 +:10F2A40003C80022FAF784FC060028680F00FEF762 +:10F2B400D1FF32003B00FEF7F9FE02AA03C22D1D66 +:10F2C400641EEBD1049902A8FFF752FA0A9B099A2B +:10F2D40002A803C800F0E2F902AA0EE0032803D151 +:10F2E4000E4902AA002008E0042802AA03D1002043 +:10F2F400C043410801E00020002103C20198000638 +:10F3040002A803C802D08022120651400BB0F0BC00 +:10F3140008BC184765CDCD410000B0410000F07F26 +:10F3240080B50023FFF756FF0CBC18471EFF2FE1E2 +:10F3340028473500024880B500F092FB0ABC184704 +:10F344003C5600407847C04690030CE091C22CE044 +:10F35400920081E00C1081E01EFF2FE1F8B402005E +:10F3640010680B00009001000020002500E0491CFB +:10F374000C782600093E052EF9D3202CF7D02D2C2D +:10F3840001D1082501E02B2C00D1491C0E7820273F +:10F39400202437436E2F28D1491C0D782543612D35 +:10F3A40004D1491C0D782C436E2C01D0009918E02F +:10F3B400491C0C0025780420282D12D1641C2578C2 +:10F3C4002E003700613F1A2FF8D33700413F1A2F20 +:10F3D400F4D3303E0A2EF1D35F2DEFD0292D00D186 +:10F3E400611C002B4AD0196048E0692F28D1491CC0 +:10F3F4000E7826436E2E04D1491C0E782643662EC1 +:10F4040001D00099EDE70320491C28430D782543DA +:10F41400692DE6D14E1C357825436E2DE1D1761C3D +:10F4240035782543692DDCD1761C35782543742D38 +:10F43400D7D1761C35782C43792CD2D1711CD0E7E6 +:10F44400302E19D148780443782C15D1881C0378C0 +:10F454002E2B00D1401C00780300613B062B06D301 +:10F464000300413B062B02D330380A2802D2022083 +:10F47400891C02E0012000E0012028431160F2BC55 +:10F4840070473600F5B590B017980E00C1001C0007 +:10F49400002508182E2800DB2D20256065600195C5 +:10F4A4003178302905D10121761C01913178302938 +:10F4B400F9D0002704A905E02268521C2260012229 +:10F4C400761C019232781300303B0A2B05D2B842E5 +:10F4D400F2DB303ACA557F1CF1E72E2A00D1761CA4 +:10F4E400002F0BD13178302908D12168761C491EB0 +:10F4F40021600121019131783029F6D031780A0058 +:10F50400303A0A2A0CD2B84206DB04AA3039D15563 +:10F5140021687F1C491E21600121761C0191EDE7C1 +:10F52400B84215DA04A909180A78052A03D3491E32 +:10F534000A78521C0A700700206807E004A8C01962 +:10F54400401E007800280AD120687F1E401C2060DD +:10F55400012FF3DA002F02D16846057401270198C0 +:10F5640000285CD00920009038000921F3F780FEC0 +:10F574000920401A00900921F3F77AFE0295002928 +:10F5840000D00125012F1FDB029804A9085C092182 +:10F5940003900098F3F76CFE002904D103996D1CC5 +:10F5A400A800215008E0A800201801688A0051181A +:10F5B400039A4900891801600098401C0090029841 +:10F5C400401C0290B842DFDB3078202101436529DA +:10F5D40025D10096761C30782B2801D02D2801D116 +:10F5E400761C00E02B200023002109E0134B9942F4 +:10F5F40004DA8B005918490051183039761C01235C +:10F6040032781700303F0A2FF0D32D2801D108009B +:10F614004142206840182060002B00D1009E1198C0 +:10F62400002805D00198002800D1109E119806608A +:10F63400280012B0F0BC08BC1847C04600E1F5052C +:10F64400000000006749F8B5040060681600000D6A +:10F654001F000840884201D100250EE0010004D1BA +:10F664002000FFF725F80128F6DA61685E4A0A40AF +:10F674005E49114361605E49451A03CC32003B0088 +:10F68400083CFAF795FA03C4083C2904091420003D +:10F69400FFF76EF8F2BC08BC18470000FBB5140075 +:10F6A4001F0082B0002C06D002A803C80022002349 +:10F6B40000F0D8F905D102A803C805B0F0BC08BC15 +:10F6C400184747496A46002003C2002C4AD56042C5 +:10F6D4000400C0464BA608250EE0E00709D568469D +:10F6E40003C802000B0003CE083EFAF761FA6A462B +:10F6F40003C2640808366D1E002C01D0002DECD125 +:10F7040003983849000D0840884201D100250EE0D5 +:10F71400010004D102A8FEF7CBFF0128F6DA039911 +:10F72400314A0A403149114303913149451A02A82B +:10F7340003C86A460CCAFAF739FB02AA03C22904B1 +:10F74400091402A8FFF714F8050036D5002CB2D02E +:10F7540028A20CCA02A8FFF775FF05002DD5641E68 +:10F76400F6D1A8E7012C28DB26A60825E00709D551 +:10F77400684603C802000B0003CE083EFAF718FAE5 +:10F784006A4603C2641008366D1E012C01DB002D8D +:10F79400ECD168460CC8FFF755FF05000DD5012CC8 +:10F7A40089DB16A20CCA02A8FFF74CFF050004D59A +:10F7B400641E012C00DA7EE7F3E72D042D1402D039 +:10F7C400012D00D077E7FFF7B5FD22210160002F5E +:10F7D40000D170E738680121014339606BE700000C +:10F7E4000000F03FFF070000FFFF0F800000E03F34 +:10F7F400FE030000436FAC642806C80A3CBF737F55 +:10F80400DD4F1575000000000000244000000000DA +:10F8140000005940000000000088C34000000000C0 +:10F8240084D797410080E03779C34143176E05B50B +:10F83400B5B89346F5F93FE9034F384D321D30F919 +:10F844004877825A3CBF737FDD4F1575F5B58DB08F +:10F8540014980C00C1001E000027081A00902428E8 +:10F8640001DB2320009037607760019720783028EF +:10F8740005D10120641C019020783028F9D0C046BD +:10F884006BA00025029005E03068401C3060012028 +:10F89400641C01902178162265A0FEF729FE002839 +:10F8A4000AD00099A942EFDB0299401A66A1085CCC +:10F8B40004A948556D1CEAE720782E2800D1641C61 +:10F8C400002D0BD12078302808D13068641C401EEC +:10F8D40030600120019020783028F6D0217816225B +:10F8E40053A0FEF705FE002810D00099A94209DBB9 +:10F8F4004FA1401A54A1085C04A9485530686D1CF6 +:10F90400401E30600120641C0190E7E70098A84283 +:10F9140015DA04A908180178082903D3401E0178D0 +:10F92400491C01703068009D07E004A84019401E7E +:10F93400007800280AD130686D1E401C3060012D0B +:10F94400F3DA002D02D1684607740125306880007F +:10F954003060019800285AD0072000902800072121 +:10F96400F3F786FC0720401A00900721F3F780FC88 +:10F974000297002900D00127012D1DDB029804A95C +:10F98400085C072103900098F3F772FC002904D166 +:10F9940003997F1CB800315006E0039AB800301870 +:10F9A40001680901891801600098401C00900298C0 +:10F9B400401C0290A842E1DB2078202101437029F9 +:10F9C40025D10094641C20782B2801D02D2801D146 +:10F9D400641C00E02B200023002109E0134B994212 +:10F9E40004DA8B005918490051183039641C01237A +:10F9F40022781500303D0A2DF0D32D2801D10800BE +:10FA04004142306840183060002B00D1009C0E98B1 +:10FA1400002805D00198002800D10D9C0E980460A0 +:10FA240038000FB0F0BC08BC1847000000E1F50531 +:10FA34003031323334353637383961626364656660 +:10FA44004142434445460000000102030405060701 +:10FA540008090A0B0C0D0E0F0A0B0C0D0E0F0000FB +:10FA6400704737007847C046020050E11EFF2F114F +:10FA740003C081E18CC090E11EFF2F01030051E11E +:10FA84001EFF2F1180C9A0E381007CE10C003C31F2 +:10FA94001EFF2FE180B5002000900023002269465C +:10FAA4006448F1F75DFF0098002811D0F7F7B5FD21 +:10FAB400002803D1B4480221016006E0F7F7C2FD33 +:10FAC400002802D1B048012101600320F3F75CF85B +:10FAD40009BC1847704700B5B34800680021C94302 +:10FAE400884207D0B048006893490968042251430A +:10FAF400884207D29048006804214843C01CAA49A0 +:10FB040008600EE0A84800688B490968491C042273 +:10FB14005143884205D38848006804214843A249D8 +:10FB2400086008BC184710B50024A04800680028E5 +:10FB340010D0042060439E490858002807D00420B0 +:10FB440060439B490858F2F7D3F9641CF1E79748DE +:10FB54000021016010BC08BC18477047704700B50D +:10FB6400944800680021C943884203D19148FF2189 +:10FB7400016006E08F480068FF2802D98D48002103 +:10FB8400016008BC1847E0B58B4800680021C943F0 +:10FB9400884203D18848FF21016006E08648006856 +:10FBA400FF2802D98448002101608348016868461F +:10FBB400F4F7DCF96846F8F7E5FB0FBC184700B525 +:10FBC40083B07E4801686846F3F7CBFA6846F3F7DA +:10FBD400A8F80FBC184780B579480068002806D0FB +:10FBE400F4F723FAF4F72AFA75480021016009BCF6 +:10FBF400184780B573480068002804D0F4F74EFD18 +:10FC040070480021016009BC184700B583B0002387 +:10FC1400002201A96C48F1F7A3FE042101A8F8F71A +:10FC2400BFFC00900023002269466848F1F7E8FE13 +:10FC34000FBC18473C0D010080B500230022694623 +:10FC44006148F1F78DFEF4F74DFE6149884214D105 +:10FC5400009860490968884209D05E4802680D210D +:10FC64000020F4F799F95C48F5F719F861E0F5F725 +:10FC74005CF85A48F5F713F85BE0F4F733FE58499B +:10FC8400884219D1009853490968884209D05148DB +:10FC940002680D210020F4F77FF94F48F4F7FFFFC5 +:10FCA40047E0424801210160FFF73DFFF5F73DF8C9 +:10FCB4004C48F4F7F4FF3CE0F4F714FE4A49884258 +:10FCC40019D1009843490968884209D0414802681B +:10FCD4000D210020F4F760F93F48F4F7E0FF28E035 +:10FCE400384801210160FFF784FFF5F71EF83F480B +:10FCF400F4F7D5FF1DE0F4F7F5FD3D49884218D12E +:10FD0400009834490968884209D0324802680D21B4 +:10FD14000020F4F741F93048F4F7C1FF09E028481E +:10FD240001210160FFF757FFF4F7FFFF3148F4F7B3 +:10FD3400B6FF09BC184700007C55004000B583B0ED +:10FD4400244800682C4988421CD1224800210160C3 +:10FD54002A48009004216846F8F722FC0190002309 +:10FD6400002269461848F1F74BFE0023002201A93E +:10FD74001648F1F745FEF4F7D8FFF4F7D6FF174815 +:10FD8400F4F78DFF0FBC1847E855004080B51C48B8 +:10FD94000068002805D00220F2F7F6FE184800217A +:10FDA400016009BC1847000080550040845500409C +:10FDB4009005010090550040945500406455004062 +:10FDC400985500409C5500408C170100BC17010059 +:10FDD400145B0100A0550040845D0100A45B010098 +:10FDE400745B0100C05D01008C580100F05D0100EE +:10FDF400BC580100205E0100CD6CAC00570400002B +:10FE0400A4550040000005800F800A001B801E00DE +:10FE140014001180338036003C00398028002D8086 +:10FE240027802200638066006C00698078007D80F2 +:10FE340077807200500055805F805A004B804E00DE +:10FE440044004180C380C600CC00C980D800DD8056 +:10FE5400D780D200F000F580FF80FA00EB80EE003E +:10FE6400E400E180A000A580AF80AA00BB80BE00B2 +:10FE7400B400B180938096009C00998088008D80A6 +:10FE840087808200838186018C01898198019D810C +:10FE940097819201B001B581BF81BA01AB81AE01F6 +:10FEA400A401A181E001E581EF81EA01FB81FE016A +:10FEB400F401F181D381D601DC01D981C801CD815E +:10FEC400C781C201400145814F814A015B815E01C6 +:10FED40054015181738176017C01798168016D81BE +:10FEE40067816201238126012C01298138013D812A +:10FEF40037813201100115811F811A010B810E0116 +:10FF040004010181038306030C03098318031D8381 +:10FF140017831203300335833F833A032B832E0365 +:10FF240024032183600365836F836A037B837E03D9 +:10FF340074037183538356035C03598348034D83CD +:10FF440047834203C003C583CF83CA03DB83DE0335 +:10FF5400D403D183F383F603FC03F983E803ED832D +:10FF6400E783E203A383A603AC03A983B803BD8399 +:10FF7400B783B203900395839F839A038B838E0385 +:10FF840084038183800285828F828A029B829E02FF +:10FF940094029182B382B602BC02B982A802AD82F5 +:10FFA400A782A202E382E602EC02E982F802FD8261 +:10FFB400F782F202D002D582DF82DA02CB82CE024D +:10FFC400C402C182438246024C02498258025D82C5 +:10FFD40057825202700275827F827A026B826E02AD +:10FFE40064026182200225822F822A023B823E0221 +:0CFFF40034023182138216021C021982B2 +:020000040001F9 +:1000000008020D820782020202000636000000008C +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000010002000100EB +:1001100003000100020001000400010002000100D0 +:1001200003000100020001000500010002000100BF +:1001300003000100020001000400010002000100B0 +:10014000030001000200010006000100020001009E +:100150000300010002000100040001000200010090 +:10016000030001000200010005000100020001007F +:100170000300010002000100040001000200010070 +:10018000030001000200010007000100020001005D +:100190000300010002000100040001000200010050 +:1001A000030001000200010005000100020001003F +:1001B0000300010002000100040001000200010030 +:1001C000030001000200010006000100020001001E +:1001D0000300010002000100040001000200010010 +:1001E00003000100020001000500010002000100FF +:1001F00003000100020001000400010002000100F0 +:10020000030001000200010000C09FE51CFF2FE178 +:10021000CD02010000502DE9FAFFFFEB0020A0E124 +:10022000000092E50030E0E3030050E10400000A22 +:100230000210A0E10200A0E3563412EF0000A0E398 +:10024000000082E5040092E5030050E10400000A8A +:10025000041082E20200A0E3563412EF0000A0E393 +:10026000040082E50140BDE81EFF2FE110402DE9AA +:1002700010D04DE20040A0E1E2FFFFEB0020A0E142 +:10028000040192E7010070E30B00001A34108FE2C2 +:1002900000108DE5000054E30010A0030410A0132B +:1002A00004108DE50310A0E308108DE50D10A0E10A +:1002B0000100A0E3563412EF040182E710D08DE272 +:1002C0001040BDE81EFF2FE13A74740000487047EB +:1002D000600A00400D0A0D0A2D2D2D2D2D2D2D2DDE +:1002E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3E +:1002F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2E +:100300002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D +:100310002D2D2D2D2D0D0A53746174697374696B25 +:1003200061206F6273686179612E204B6F726F7408 +:100330006B69652073636865746368696B692E0D0A +:100340000A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D00 +:100350002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCD +:100360002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DBD +:100370002D2D2D2D2D2D2D2D2D2D2D2D2D2D0D0AF0 +:10038000000000000D0A2D2D2D2D2D2D2D2D2D2D94 +:100390002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8D +:1003A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7D +:1003B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6D +:1003C0002D2D2D0D0A53746174697374696B61204E +:1003D000706F206B616E616C616D2E204B6F726F60 +:1003E000746B69652073636865746368696B692EF3 +:1003F0000D0A2D2D2D2D2D2D2D2D2D2D2D2D2D2D70 +:100400002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1C +:100410002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0C +:100420002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0D1C +:100430000A0000000D0A2D2D2D2D2D2D2D2D2D2DD9 +:100440002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDC +:100450002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCC +:100460002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DBC +:100470002D2D2D0D0A53746174697374696B61209D +:10048000706F206B616E616C616D2E20446C696EC3 +:100490006E79652073636865746368696B692E0D96 +:1004A0000A2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D9F +:1004B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6C +:1004C0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D5C +:1004D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D0D0A8F +:1004E000000000000D0A2D2D2D2D2D2D2D2D2D2D33 +:1004F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2C +:100500002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1B +:100510002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D0B +:100520002D2D2D0D0A53746174697374696B6120EC +:100530006F6273686179612E20446C696E6E7965B3 +:100540002073636865746368696B690D0A2D2D2DCE +:100550002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCB +:100560002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DBB +:100570002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DAB +:100580002D2D2D2D2D2D2D2D2D2D0D0A0000000092 +:100590001C0F0100BC0B01007C0C01000C0D0100C4 +:1005A0003C0D0100BC0E01005C0E01004C0F01006F +:1005B0007C0F0100AC0F0100DC0F01000C100100EA +:1005C0006C1001009C100100CC100100FC10010017 +:1005D0002C1101005C1101008C110100BC11010003 +:1005E000EC1101001C1201004C1201007C120100F0 +:1005F000AC120100FC1301002C1401008C0E010050 +:10060000CC160100AC0C01008C1701009C190100F4 +:100610006C0D0100CC0D0100FC0D01002C0E010041 +:10062000AC180100DC1801003C100100DC0C0100DA +:10063000000000000D0A2D2D2D2D2D2D2D2D2D2DE1 +:100640002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DDA +:100650002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DCA +:100660002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DBA +:100670002D2D2D0D0A4B757075726F707269656D39 +:100680006E696B2E0D0A2D2D2D2D2D2D2D2D2D2D21 +:100690002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D8A +:1006A0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D7A +:1006B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D6A +:1006C0002D2D2D0D0A0000000D0A2D2D2D2D2D2D67 +:1006D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4A +:1006E0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D3A +:1006F0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2A +:100700002D2D2D2D2D2D2D0D0A5A6875726E616CB3 +:1007100020736F62797469790D0A2D2D2D2D2D2D81 +:100720002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DF9 +:100730002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DE9 +:100740002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DD9 +:100750002D2D2D2D2D2D2D0D0A0000000D0A2D2DD6 +:100760002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DB9 +:100770002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2DA9 +:100780002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D99 +:100790002D2D2D2D2D2D2D2D2D2D2D0D0A5A68751C +:1007A000726E616C206F736869626F6B0D0A2D2D1C +:1007B0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D69 +:1007C0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D59 +:1007D0002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D49 +:1007E0002D2D2D2D2D2D2D2D2D2D2D0D0A00000003 +:1007F0000102030405060708090A0B111213141558 +:10080000161718191A1B1C1D1F2021222324252806 +:100810003335363738393A3C3E3F40414243444510 +:100820004647484A4B4C4D4E4F50515253545657E1 +:1008300058595B5C5D5E5F606162636465666768B2 +:10084000696A6B6C6D6E6F707172737475767778A0 +:10085000797A7B7C7D7E7F80818283848586878890 +:10086000898A8B8C8D8E8F9091929394A0A1A2A354 +:10087000A4A5A6A7A8A9AAB0B1B2C0C1C2C3C4000A +:1008800000000FE11F00C0E3130080E300F021E14E +:1008900054D09FE51F00C0E31B0080E300F021E17E +:1008A00048D09FE51F00C0E3170080E300F021E17E +:1008B0003CD09FE51F00C0E3110080E300F021E180 +:1008C00030D09FE51F00C0E3120080E300F021E17B +:1008D00024D09FE51F00C0E31F0080E300F021E16A +:1008E00018D09FE518009FE510FF2FE1805B0040C6 +:1008F000D05C0040E05C0040C05C0040805C004098 +:10090000805A00405C1C0100C0600100403D004076 +:10091000CC600100803D0040B0510100C03D00406E +:10092000D8600100003E0040E4600100403E00400D +:10093000F0600100803E0040C0510100C03E004018 +:10094000983D0100003F0040D0510100403F004071 +:10095000E0510100803F0040F0510100C03F0040E5 +:1009600010402DE940109FE50F1081E03C1081E21E +:1009700038409FE50F4084E0344084E2040051E1B8 +:100980000700000A002091E5040081E2011082E0E6 +:100990000FE0A0E111FF2FE10010A0E1040051E100 +:1009A000F7FFFF1A1040BDE81EFF2FE138130000CB +:1009B0005813000080B5F8F718FAFBF773FD05230C +:1009C000044A00210448F7F74FFAFBF7C4FD09BCBD +:1009D000184700003C390040DD09010010B5040053 +:1009E000F8F7EEF8FA208000F6F7C6FAF9F72EFECF +:1009F000F9F708FFFCF712FCF0F776F8FA20800010 +:100A0000F6F7BAFAFAE738000102060A0B111314D6 +:100A100017181A1C1D1F232438393A3C3E3F404109 +:100A200042434447484C4E51525354575B64676AA3 +:100A30006B70717475767778797B80818283878813 +:100A4000898A8BA0A1A3A4A5A6A7A8A9C2C40000B7 +:100A500010402DE910D04DE20230A0E100008DE5FC +:100A600004108DE50040A0E108308DE50120A0E3F1 +:100A70000D10A0E10500A0E3563412EF000043E0A2 +:100A80000410A0E10000A0E110D08DE21040BDE80C +:100A90001EFF2FE141A042A1E045A3A4A5034BA75F +:100AA0004D484FA8504354A9AA58E1ABACE2ADAEB3 +:100AB00002AFB0B161B2B3B4E365B6B7B8B9BABB0F +:100AC000BCBD6FBE7063BF79E478E5C0C1E6C2C348 +:100AD000C4C5C6C77C20567365676F2064656E65A4 +:100AE000672C207275622E207C20567365676F20FC +:100AF0007365616E736F76207C20567365676F2017 +:100B00006E617261626F746B6120683A6D3A732036 +:100B10000D0A000030402DE90CD04DE20140A0E16B +:100B20000250A0E10100A0E3CFFDFFEB00008DE546 +:100B300004408DE508508DE50D10A0E10500A0E30F +:100B4000563412EF000045E00CD08DE23040BDE895 +:100B50001EFF2FE17C204B616E616C207C20446580 +:100B60006E65672C207275622E207C205365616E45 +:100B7000736F76207C204E617261626F746B6120AE +:100B8000683A6D3A730D0A00000051E30000A003BB +:100B90000000001A1EFF2FE100502DE9010050E374 +:100BA000020050130100001AD9FFFFEB000000EA19 +:100BB000A6FFFFEB0240BDE81EFF2FE10002000090 +:100BC00000000000000000007C5500402C62010085 +:100BD0000000000000000000FC54010001000000C3 +:100BE000A009004001000000000000000002000019 +:100BF00000000000000000007C5500402C62010055 +:100C00000000000000000000304E01000100000064 +:100C1000A0090040010000000000000000020000E8 +:100C200000000000000000007C5500402C62010024 +:100C30000000000000000000085501000100000055 +:100C4000A0090040010000000000000000020100B7 +:100C50000000000000000000D6190000E46201005E +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000002010170 +:100C80000A000000BC0B01000400000034620100F7 +:100C900000000000040000001455010001000000E5 +:100CA000100A0040000000000000000000020101E6 +:100CB0000A000000BC0B0100F40000004C620100BF +:100CC00000000000040000002055010001000000A9 +:100CD000E0090040000000000000000000020100E8 +:100CE0000000000000000000E61900005C62010046 +:100CF000000000000000000064620100010000002C +:100D0000180A00400000000000000000000201007E +:100D100000000000000000001C0600007C620100D2 +:100D20000000000004000000385501000100000030 +:100D3000200A004001000000010000000002010044 +:100D40000000000000000000240600009462010082 +:100D500099FA0000040000009C62010001000000FC +:100D6000280A00400100000000000000000201000D +:100D7000000000000000000040060000A462010026 +:100D800000000000040000004455010001000000C4 +:100D9000300A0040010000000000000001020000D5 +:100DA0000000000000000000E855004000000000C6 +:100DB0000000000000000000AC6201000100000023 +:100DC000EC090040010000000000000000020100EA +:100DD000000000000000000048060000A4620100BE +:100DE0000000000004000000404E0100010000006F +:100DF000300A004001000000000000000002010075 +:100E000000000000000000004C060000A462010089 +:100E10000000000004000000505501000100000027 +:100E2000300A00400100000000000000000701003F +:100E3000000000000000000050060000B462010045 +:100E40000000000000000000BC6201000000000083 +:100E50000000000001000000090000000002010085 +:100E6000000000000000000020060000C462010035 +:100E7000D9FA0000040000005C55010001000000E8 +:100E8000380A0040010000000000000000020100DC +:100E9000000000000000000034060000CC620100E9 +:100EA0000000000000000000685501000000000084 +:100EB000000000000100000001000000000201002D +:100EC000000000000000000028060000D4620100BD +:100ED0000000000004000000146501000100000093 +:100EE000400A004001000000000000000002010074 +:100EF00000000000000000003C060000DC62010071 +:100F00000000000004000000504E0100010000003D +:100F1000480A00400100000000000000010200013A +:100F20000A000000BC0B0100EC530040E462010029 +:100F300000000000040000007455010000000000E3 +:100F4000000000000100000000000000000201019C +:100F50000A000000BC0B01002C000000EC62010044 +:100F60000000000004000000604E010000000000CE +:100F700000000000010000001E000000000201014E +:100F80000A000000BC0B010054000000F4620100E4 +:100F900000000000040000003438010000000000E0 +:100FA0000000000001000000030000000002010139 +:100FB0000A000000BC0B01007C000000FC62010084 +:100FC0000000000004000000805501000000000047 +:100FD00000000000010000001400000000020101F8 +:100FE0000A000000BC0B0100A40000000463010023 +:100FF00000000000040000008C550100000000000B +:1010000000000000010000000500000000020101D6 +:101010000A000000BC0B0100CC0000000C630100C2 +:1010200000000000040000009855010001000000CD +:10103000C80900400100000000000000000201019A +:101040000A000000BC0B0100EA1900003463010033 +:101050000000000004000000A45501000100000091 +:10106000F80900400000000000000000000200003D +:101070000000000000000000805500403C630100BB +:10108000DBFA000000000000A7650100010000007D +:10109000F80700400100000000000000000200000E +:1010A0000000000000000000805500403C6301008B +:1010B000DBFA000000000000A7650100010000004D +:1010C0009C08004001000000000000000002010137 +:1010D000280000006C1001003C0400004463010083 +:1010E0000000000004000000B055010000000000F6 +:1010F00000000000000000000F00000000020101DD +:10110000280000009C1001009C0300004C630100BB +:101110000000000004000000BC55010000000000B9 +:1011200000000000000000000F00000000020101AC +:10113000280000006C1001007C05000054630100D1 +:101140000000000004000000704E010000000000DC +:10115000000000000000000001000000000201018A +:10116000280000009C100100DC0400005C6301000A +:101170000000000004000000804E0100000000009C +:10118000000000000000000001000000000201015A +:10119000280000009C1001001C0100006463010095 +:1011A0000000000004000000C8550100000000001D +:1011B000000000000000000000000000000201012B +:1011C000280000009C100100BC0100006C630100BD +:1011D0000000000004000000746301000000000033 +:1011E00000000000010000001800000000020101E2 +:1011F000280000006C1001005C0200007C6301000C +:101200000000000004000000D455010000000000B0 +:1012100000000000000000000000000000020101CA +:10122000280000006C100100FC0200008463010033 +:1012300000000000040000008C63010000000000BA +:101240000000000001000000180000000002000083 +:101250000000000000000000885500409463010079 +:101260005FFB0000000000009C6301000100000023 +:10127000500A0040010000000000000000020000D1 +:1012800000000000000000008C5500409463010045 +:1012900061FB000000000000AC63010001000000E1 +:1012A000500A0040010000000000000000020000A1 +:1012B000000000000000000090550040B4630100F1 +:1012C00063FB000000000000E0550100000000008A +:1012D0000000000001000000000000000102010108 +:1012E00000010000AC120100D2070000BC63010045 +:1012F00000000000080000000000000001000000E5 +:101300000000004000000000000000000102010198 +:1013100000010000AC120100D2070000BC63010014 +:1013200000000000080000000000000001000000B4 +:10133000A8020040000000000000000001020101BE +:1013400000010000AC120100D2070000BC630100E4 +:101350000000000008000000000000000100000084 +:1013600050050040000000000000000001050101E0 +:1013700000010000AC120100CE07000000000000D8 +:101380000000000008000000000000000000000055 +:10139000000000000000000000000000000200004B +:1013A000000000000000000094550040C4630100EC +:1013B0008BFB000000000000EC5501000000000065 +:1013C0000000000001000000000000000105010114 +:1013D000000100009C130100CE0F0000000000007F +:1013E000000000000A0000000000000000000000F3 +:1013F00000000000000000000000000001050000E7 +:1014000000000000000000006455004000000000E3 +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000050000B7 +:1014300000000000000000006455004000000000B3 +:10144000C3FB0000000000000000000000000000DE +:101450000000000000000000000000000102010088 +:101460000000000000000000D006000000000000A6 +:101470000000000000000000CC630100000000003C +:101480000000000000000000000000000102010058 +:101490000000000000000000D8060000000000006E +:1014A0000000000000000000F855010000000000EE +:1014B0000000000000000000000000000106010024 +:1014C0000000000000000000D40600000000000042 +:1014D0000000000000000000D463010000000000D4 +:1014E00000000000000000000000000001020100F8 +:1014F0000000000000000000B8070000000000002D +:101500000000000000000000CC63010000000000AB +:1015100000000000000000000000000001020100C7 +:101520000000000000000000C007000000000000F4 +:101530000000000000000000F8550100000000005D +:101540000000000000000000000000000106010093 +:101550000000000000000000BC07000000000000C8 +:101560000000000000000000D46301000000000043 +:101570000000000000000000000000000102010166 +:101580000A000000EC0B01005806000000000000FB +:101590000000000004000000CC6301000000000017 +:1015A0000000000000000000000000000102010136 +:1015B0000A000000EC0B0100A8060000000000007B +:1015C0000000000004000000F855010000000000C9 +:1015D0000000000000000000000000000106010102 +:1015E0000A000000EC0B0100800600000000000073 +:1015F0000000000004000000D463010000000000AF +:1016000000000000000000000000000001020101D5 +:101610000A000000EC0B0100400700000000000081 +:101620000000000004000000CC6301000000000086 +:1016300000000000000000000000000001020101A5 +:101640000A000000EC0B0100900700000000000001 +:101650000000000004000000F85501000000000038 +:101660000000000000000000000000000106010171 +:101670000A000000EC0B01006807000000000000F9 +:101680000000000004000000D4630100000000001E +:101690000000000000000000000000000002010047 +:1016A00000000000000000002C060000DC630100C8 +:1016B00000000000040000000456010001000000CA +:1016C000040A0040010000000100000000020100C7 +:1016D000000000000000000038060000E463010084 +:1016E0000000000004000000EC63010001000000A5 +:1016F000580A004000000000010000000002010044 +:10170000000000000000000030060000FC63010043 +:101710000000000004000000A865010001000000B6 +:101720006C0A004000000000000000000002010000 +:101730000000000000000000C607000000000000DC +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000002010086 +:101760000000000000000000CA07000000000000A8 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000002010056 +:101790000000000000000000CE19000004640100F9 +:1017A0000FFC0000000000001C56010000000000BB +:1017B00000000000000000005704000000020100CB +:1017C0000000000000000000D2190000000000002E +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000020000F7 +:1017F0000000000000000000A0550040046401004B +:101800003DFC0000000000001C560100000000002C +:1018100000000000000000000000000000020000C6 +:101820000000000000000000A0550040046401001A +:101830003DFC0000000000002856010000000000F0 +:101840000000000000000000000000000002000096 +:101850000000000000000000A05500400C640100E2 +:1018600041FD0000000000001464010000000000C1 +:101870000000000000000000000000000002000066 +:101880000000000000000000A055004004640100BA +:101890003DFC000000000000345601000000000084 +:1018A0000000000000000000000000000002000036 +:1018B0000000000000000000A4550040A4620100E8 +:1018C00091FD0000040000004056010001000000EE +:1018D000480A004001000000000000000002000073 +:1018E0000000000000000000A85500401C6401003A +:1018F0000000000000000000904E01000100000008 +:101900004009004001000000000000000102000149 +:1019100018000000DC180100A85100400000000081 +:101920000000000004000000A04E010000000000C4 +:1019300000000000000000000000000001020101A2 +:1019400018000000DC180100DC06000000000000A8 +:1019500000000000040000002464010000000000FA +:101960000000000000000000000000000102010073 +:1019700000000000000000003C0700000000000024 +:1019800000000000000000004C56010000000000B4 +:101990000000000000000000000000000002010044 +:1019A0000000000000000000540600002C6401004C +:1019B0000000000000000000585601000000000078 +:1019C0000000000001000000000000000002010013 +:1019D0000100000000000000DA1900000000000013 +:1019E00000000000040000000000000000000000F3 +:1019F00000000000000000000000000000020100E4 +:101A00000100000000000000DE19000000000000DE +:101A100000000000040000000000000000000000C2 +:101A200000000000000000000000000000020100B3 +:101A30000100000000000000E219000000000000AA +:101A40000000000004000000000000000000000092 +:101A5000000000000000000000000000185A010013 +:101A6000245A0100305A01003C5A0100485A010032 +:101A7000545A0100605A01006C5A0100785A010062 +:101A8000845A0100905A0100000000007C202020B0 +:101A90002020204E6F6D696E616C2C207275622E55 +:101AA00020202020207C20202020204B6F6C696388 +:101AB00068657374766F0D0A0000000038B5002564 +:101AC0000400ED43AC420AD0684604700122694626 +:101AD000012000F009F8012801D1200000E02800D1 +:101AE00032BC08BC184739007847C04600502DE981 +:101AF000000050E30100004A22FCFFEB000000EA76 +:101B00000000A0E30240BDE81EFF2FE14B726974A4 +:101B100069636865736B617961206F736869626B73 +:101B200061206B757075726F707269656D6E696B2F +:101B3000610000004E656B72697469636865736B60 +:101B4000617961206F736869626B61206B75707574 +:101B5000726F707269656D6E696B610010B40021FF +:101B60000268001D002A0BD00368001DDC0702D5A7 +:101B70004C46641E1B1919601B1D121FFBD1EFE799 +:101B800010BC70470A4350555F41524D5F45584362 +:101B9000455054494F4E2023256420747261707063 +:101BA00065642E0A000000004F736869626B612053 +:101BB000737679617A692063206B757075726F70C6 +:101BC0007269656D6E696B6F6D00000056796272A7 +:101BD0006F73206B757075727920707269207472E2 +:101BE000616E73706F727469726F766B650000005E +:101BF0007C2020202020202531336420202020201C +:101C00007C2020202020253131642020202020200D +:101C10000D0A00005265706F72742066726F6D203D +:101C2000736F6C617269756D206465766963652098 +:101C300069642025642E000000C09FE51CFF2FE191 +:101C4000811C010000C09FE51CFF2FE1B5090100C8 +:101C500000C09FE51CFF2FE1851C01000100A0E3EF +:101C6000F4FFFFEB000050E33CFBFF1B0000A0E390 +:101C7000F3FFFFEBF5FFFFEB030000EBFDFFFFEAD7 +:101C80000120704780B500F011F8C04600502DE9E2 +:101C90005FF9FFEB2620A0E3802B82E30210A0E196 +:101CA0001800A0E3563412EFFBFFFFEA7847C04666 +:101CB0000070B0E10700B0E1F3FFFFEBFDFFFFEACA +:101CC000030008001968002A02D1491E19607047F4 +:101CD0000878002802D10020C0437047481C1860D3 +:101CE0000878704779FEFFFF084C0000780A004032 +:101CF000000000004B6DFFFF780A0000B4480000B0 +:101D00000000004000000000567962726F73206B83 +:101D1000757075727920706F206D61672E646174C3 +:101D20006368696B75000000567962726F73206B8F +:101D3000757075727920706F206964656E7469665C +:101D4000696B616369690000567962726F73206B19 +:101D5000757075727920706F207665726966696B2F +:101D60006163696900000000567962726F73206BCD +:101D7000757075727920706F206F70742E64617445 +:101D80006368696B75000000567962726F73206B2F +:101D9000757075727920706F20656D6B2E6461743B +:101DA0006368696B750000004F736869626B61203E +:101DB000736B6F726F737469207472616E73702EBF +:101DC0006D6F746F726100004F736869626B6120A0 +:101DD0006D6568616E697A6D6176797261766E693A +:101DE00076616E69796100004F736869626B61208A +:101DF000465220307843334F736869626B612046E6 +:101E00005220307843340000207C202050656368E5 +:101E1000617427206F74636865746120697A206239 +:101E20007566657261200000207C20204F73686910 +:101E3000626B61206F74707261766B6920652D6DC5 +:101E400061696C2000000000207C2020452D6D6120 +:101E5000696C206F74707261766C656E6F2075733B +:101E6000706573686E6F2000B8590100C459010095 +:101E7000D0590100E8590100DC590100F459010072 +:101E8000005A010000000000C45C0100D05C0100A9 +:101E9000DC5C0100E85C0100F45C0100005D010015 +:101EA0000C5D0100000000004B757075726F707260 +:101EB00069656D6E696B2062796C20707573742E24 +:101EC0000D0A0D0A00000000253032643A25303238 +:101ED000643A2530326420253032642F2530326454 +:101EE0002F253032640000003230253032642F2537 +:101EF0003032642F2530326420253032643A253068 +:101F000032643A2530326400567962726F73206B06 +:101F1000757075727920706F207A61707265747552 +:101F2000000000004F736869626B61207374656B19 +:101F300065726E6F676F206D6F746F726100000065 +:101F40004F736869626B6120737679617A69207377 +:101F5000206D6F64656D6F6D00000000600900000A +:101F6000C012000080250000004B00000096000019 +:101F700000E1000000C20100405C01004C5C010077 +:101F8000585C0100645C0100705C01007C5C010035 +:101F90000000000041545E534943533D302C636FB1 +:101FA0006E547970652C47505253300D0A00000072 +:101FB00041545E534943533D302C696E6163745400 +:101FC0004F2C223230220D0A0000000041545E5393 +:101FD0004953533D302C737276547970652C2253DB +:101FE0006D7470220D0A000041545E534953533DF5 +:101FF000302C616C7068616265742C2231220D0A8C +:102000000000000041545E534953533D302C61643D +:1020100064726573732C222573220D0A0000000080 +:1020200041545E534953533D302C746370506F726A +:10203000742C222573220D0A000000004B75707568 +:10204000726F707269656D6E696B20707573742E36 +:102050000D0A0D0A0000000054657374206D65734D +:10206000736167652066726F6D20736F6C61726952 +:10207000756D2E0054657374206D657373616765AB +:102080002E204465766963652069642025642E00EE +:10209000496E636173736174696F6E2E2044657657 +:1020A0006963652069642025642E0000000000003B +:1020B0001F003B005A0078009700B500D400F300E1 +:1020C000110130014E01000038B505000C00200060 +:1020D000FFF7F4FCA04200D00025280032BC08BC69 +:1020E00018472300EA2FEF3A3531682DEEF8E8E182 +:1020F000EAE020F1EAEEF02E00000000D4D03A3001 +:1021000041682DF4EEF0ECE0F220E4E0EDEDFBF5BB +:1021100000000000D4D03A3042682DEDE5E8F1EF40 +:10212000F02EFFF7E5E9EAE000000000D4D03A31F4 +:1021300037682DCEF8E8E1EAE020EDEEECE5F0E0DE +:1021400000000000D4D03A3232682DCDE5E2E5F04F +:10215000EDE0FF20E4E0F2E000000000D4D03A34EB +:1021600046682DCDE5E2E5F0EDFBE920EFE0F0EE8D +:10217000EBFC0000D4D03A3634682DD4CF20EEF2F8 +:10218000F1F3F2F1F2E2F3E5F2000000D4D03A38D4 +:1021900044682DCEF2F0E8F6E0F2E5EBFCEDFBE969 +:1021A00000000000D4D03A3933682DC2EEF1F1F2CC +:1021B000E0EDEEE2EBE5EDE8E5000000EDE0EAEE53 +:1021C000EFEBE5EDE8FF20EFEE20EDE0EBEEE3E0F6 +:1021D000EC000000EDE0EAEEEFEBE5EDE8E920329F +:1021E00020E220F1ECE5EDE500000000EDE0EAEE94 +:1021F000EFEBE5EDE8E9203320E220F1ECE5EDE559 +:1022000000000000EDE0EAEEEFEBE5EDE8E9203458 +:1022100020E220F1ECE5EDE500000000E7EDE0F75D +:10222000E5EDE8E520E220EFEEEBE520E4EBE8ED7C +:10223000FB000000E4E8E0EFE0E7EEEDE020E8F28C +:10224000EEE3E020F7E5EAE000000000EFEE20E238 +:10225000EEE7E2F0E0F2E0EC20EFEEEAF3EFEEEA98 +:1022600000000000EBE8ECE8F220EEEFE5F0E0F62D +:10227000E8E920E220F7E5EAE5000000CDE5EAEE36 +:10228000F0F02EF4EEF0ECE0F220EAEEECE0EDE41B +:10229000FB000000CDE5E2E5F0EDFBE520E4E0F237 +:1022A000E020E820E2F0E5ECFF200000CDE5F220A0 +:1022B000E7E0EFF0EEF8E5EDEDFBF520E4E0EDED25 +:1022C000FBF52000567962726F73206B7570757222 +:1022D0007920706F20646C696E6500005A616D69C9 +:1022E0006E2076206B757075726F707269656D6E99 +:1022F000696B65004F736869626B61207472616E0F +:1023000073702E6D6F746F72610000004F73686997 +:10231000626B61206D61676E2E6461746368696BC6 +:10232000610000004F736869626B6120656D6B2E00 +:102330006461746368696B6100000000D1EFE0F1D3 +:10234000E8E1EE20E7E020EFEEEAF3EFEAF3212107 +:1023500021000000D3F1EBF3E3E820F1EEEBFFF016 +:10236000E8FF2C20ECE8ED2E00000000207C20206F +:1023700050656368617427205A2D6F7463686574B3 +:1023800061200000207C2020506563686174272054 +:10239000582D6F746368657461200000207C2020D4 +:1023A0004E657665726E6979207061726F6C272058 +:1023B00000000000CC570100D8570100E45701008D +:1023C000F0570100FC5701000000000020580100F8 +:1023D0002C580100385801004458010050580100A1 +:1023E00000000000A85A0100B45A0100C05A0100C0 +:1023F000CC5A0100D85A010000000000B05B010077 +:10240000BC5B0100C85B0100D45B0100E05B010024 +:1024100000000000F85B0100045C0100105C01009A +:102420001C5C0100285C01000000000041545E5368 +:102430004943533D302C646E73312C222573220D99 +:102440000A00000041545E534943533D302C7061F3 +:10245000737377642C222573220D0A0041545E5356 +:102460004943533D302C61706E2C222573220D0A96 +:102470000000000041545E534943533D302C7573B6 +:1024800065722C222573220D0A00000041545E5310 +:102490004953533D302C636F6E49642C2230220D1A +:1024A0000A00000041545E534953533D302C75736C +:1024B00065722C222573220D0A00000041545E53E0 +:1024C0004953533D302C7061737377642C2225730C +:1024D000220D0A0041545E534953533D302C736D15 +:1024E000417574682C2231220D0A000041545E535C +:1024F0004953533D302C736D46726F6D2C222573FA +:10250000220D0A0041545E534953533D302C736DE4 +:10251000526370742C222573220D0A0041545E53BD +:102520004953533D302C736D5375626A2C222573C9 +:10253000220D0A00686A6C747A4C00006E616E00AD +:102540004E414E00696E6600494E4600C2DBC1C571 +:10255000D0C8D2C520C4D02ECAC0CDC0CB00000088 +:10256000CEEFEBE0F7E5EDEE2025643A253032645E +:1025700000000000CFD0C5C2DBD8C5CDCE20CCC076 +:10258000CAD12EC2D02E0000CFCECB62C7CEC2C0E1 +:10259000CDC8C520D3D1CBD3C3CEE900D0C0C1CEE6 +:1025A000D2C020CDC5C2CEC7CCCEC6CDC0000000A3 +:1025B000212121212121212121212121212121210B +:1025C00021000000D6C5CDC0202564F0F3E12E2FF8 +:1025D0002564ECE8ED2E0000C0CFCFC0D0C0D220E3 +:1025E000D0C0C1CED2C0C5D200000000C4CBDF2015 +:1025F000CDC0D7C0CBC020D0C0C1CED2DB00000040 +:10260000CAC0CD2E3120CFC5D02E3120C2DBD52E71 +:1026100000000000CAC0CD2E3120CFC5D02E322000 +:10262000C2DBD52E00000000CAC0CD2E3120CFC5A0 +:10263000D02E3320C2DBD52E00000000CAC0CD2E24 +:102640003120CFC5D02E3420C2DBD52E00000000B3 +:10265000CAC0CD2E3220CFC5D02E3120C2DBD52E20 +:1026600000000000CAC0CD2E3220CFC5D02E3220AF +:10267000C2DBD52E00000000CAC0CD2E3220CFC54F +:10268000D02E3320C2DBD52E00000000CAC0CD2ED4 +:102690003220CFC5D02E3420C2DBD52E0000000062 +:1026A000CAC0CD2E3320CFC5D02E3120C2DBD52ECF +:1026B00000000000CAC0CD2E3320CFC5D02E32205E +:1026C000C2DBD52E00000000CAC0CD2E3320CFC5FE +:1026D000D02E3320C2DBD52E00000000CAC0CD2E84 +:1026E0003320CFC5D02E3420C2DBD52E0000000011 +:1026F000CAC0CD2E3420CFC5D02E3120C2DBD52E7E +:1027000000000000CAC0CD2E3420CFC5D02E32200C +:10271000C2DBD52E00000000CAC0CD2E3420CFC5AC +:10272000D02E3320C2DBD52E00000000CAC0CD2E33 +:102730003420CFC5D02E3420C2DBD52E00000000BF +:10274000CAC0CD2E3520CFC5D02E3120C2DBD52E2C +:1027500000000000CAC0CD2E3520CFC5D02E3220BB +:10276000C2DBD52E00000000CAC0CD2E3520CFC55B +:10277000D02E3320C2DBD52E00000000CAC0CD2EE3 +:102780003520CFC5D02E3420C2DBD52E000000006E +:10279000CAC0CD2E3620CFC5D02E3120C2DBD52EDB +:1027A00000000000CAC0CD2E3620CFC5D02E32206A +:1027B000C2DBD52E00000000CAC0CD2E3620CFC50A +:1027C000D02E3320C2DBD52E00000000CAC0CD2E93 +:1027D0003620CFC5D02E3420C2DBD52E000000001D +:1027E000CAC0CD2E3720CFC5D02E3120C2DBD52E8A +:1027F00000000000CAC0CD2E3720CFC5D02E322019 +:10280000C2DBD52E00000000CAC0CD2E3720CFC5B8 +:10281000D02E3320C2DBD52E00000000CAC0CD2E42 +:102820003720CFC5D02E3420C2DBD52E00000000CB +:10283000CAC0CD2E3820CFC5D02E3120C2DBD52E38 +:1028400000000000CAC0CD2E3820CFC5D02E3220C7 +:10285000C2DBD52E00000000CAC0CD2E3820CFC567 +:10286000D02E3320C2DBD52E00000000CAC0CD2EF2 +:102870003820CFC5D02E3420C2DBD52E000000007A +:10288000CAC0CD2E3920CFC5D02E3120C2DBD52EE7 +:1028900000000000CAC0CD2E3920CFC5D02E322076 +:1028A000C2DBD52E00000000CAC0CD2E3920CFC516 +:1028B000D02E3320C2DBD52E00000000CAC0CD2EA2 +:1028C0003920CFC5D02E3420C2DBD52E0000000029 +:1028D000CAC0CD2E313020CFC5D02E3120C2DBD59D +:1028E0002E000000CAC0CD2E313020CFC5D02E32F0 +:1028F00020C2DBD52E000000CAC0CD2E313020CF43 +:10290000C5D02E3320C2DBD52E000000CAC0CD2E8C +:10291000313020CFC5D02E3420C2DBD52E000000B0 +:10292000CAC0CD2E3120CFC5D02E3120C1D3C42E68 +:1029300000000000CAC0CD2E3120CFC5D02E3220DD +:10294000C1D3C42E00000000CAC0CD2E3120CFC597 +:10295000D02E3320C1D3C42E00000000CAC0CD2E1B +:102960003120CFC5D02E3420C1D3C42E00000000AA +:10297000CAC0CD2E3220CFC5D02E3120C1D3C42E17 +:1029800000000000CAC0CD2E3220CFC5D02E32208C +:10299000C1D3C42E00000000CAC0CD2E3220CFC546 +:1029A000D02E3320C1D3C42E00000000CAC0CD2ECB +:1029B0003220CFC5D02E3420C1D3C42E0000000059 +:1029C000CAC0CD2E3320CFC5D02E3120C1D3C42EC6 +:1029D00000000000CAC0CD2E3320CFC5D02E32203B +:1029E000C1D3C42E00000000CAC0CD2E3320CFC5F5 +:1029F000D02E3320C1D3C42E00000000CAC0CD2E7B +:102A00003320CFC5D02E3420C1D3C42E0000000007 +:102A1000CAC0CD2E3420CFC5D02E3120C1D3C42E74 +:102A200000000000CAC0CD2E3420CFC5D02E3220E9 +:102A3000C1D3C42E00000000CAC0CD2E3420CFC5A3 +:102A4000D02E3320C1D3C42E00000000CAC0CD2E2A +:102A50003420CFC5D02E3420C1D3C42E00000000B6 +:102A6000CAC0CD2E3520CFC5D02E3120C1D3C42E23 +:102A700000000000CAC0CD2E3520CFC5D02E322098 +:102A8000C1D3C42E00000000CAC0CD2E3520CFC552 +:102A9000D02E3320C1D3C42E00000000CAC0CD2EDA +:102AA0003520CFC5D02E3420C1D3C42E0000000065 +:102AB000CAC0CD2E3620CFC5D02E3120C1D3C42ED2 +:102AC00000000000CAC0CD2E3620CFC5D02E322047 +:102AD000C1D3C42E00000000CAC0CD2E3620CFC501 +:102AE000D02E3320C1D3C42E00000000CAC0CD2E8A +:102AF0003620CFC5D02E3420C1D3C42E0000000014 +:102B0000CAC0CD2E3720CFC5D02E3120C1D3C42E80 +:102B100000000000CAC0CD2E3720CFC5D02E3220F5 +:102B2000C1D3C42E00000000CAC0CD2E3720CFC5AF +:102B3000D02E3320C1D3C42E00000000CAC0CD2E39 +:102B40003720CFC5D02E3420C1D3C42E00000000C2 +:102B5000CAC0CD2E3820CFC5D02E3120C1D3C42E2F +:102B600000000000CAC0CD2E3820CFC5D02E3220A4 +:102B7000C1D3C42E00000000CAC0CD2E3820CFC55E +:102B8000D02E3320C1D3C42E00000000CAC0CD2EE9 +:102B90003820CFC5D02E3420C1D3C42E0000000071 +:102BA000CAC0CD2E3920CFC5D02E3120C1D3C42EDE +:102BB00000000000CAC0CD2E3920CFC5D02E322053 +:102BC000C1D3C42E00000000CAC0CD2E3920CFC50D +:102BD000D02E3320C1D3C42E00000000CAC0CD2E99 +:102BE0003920CFC5D02E3420C1D3C42E0000000020 +:102BF000CAC0CD2E313020CFC5D02E3120C1D3C494 +:102C00002E000000CAC0CD2E313020CFC5D02E32CC +:102C100020C1D3C42E000000CAC0CD2E313020CF39 +:102C2000C5D02E3320C1D3C42E000000CAC0CD2E83 +:102C3000313020CFC5D02E3420C1D3C42E000000A7 +:102C40003143683630682DE2FBE1F02EEAF3EFFE07 +:102C5000F0FB00003143683631682DE2FBE1F02ED5 +:102C6000EAF3EFFEF0FB00003143683634682DE2F2 +:102C7000FBE1F02EEAF3EFFEF0FB00003143683693 +:102C800035682DE2FBE1F02EEAF3EFFEF0FB0000E9 +:102C90003143683636682DE2FBE1F02EEAF3EFFEB1 +:102CA000F0FB00003143683637682DE2FBE1F02E7F +:102CB000EAF3EFFEF0FB00003143683638682DE29E +:102CC000FBE1F02EEAF3EFFEF0FB00003143683643 +:102CD00039682DE2FBE1F02EEAF3EFFEF0FB000095 +:102CE0003143683643682DE2FBE1F02EEAF3EFFE54 +:102CF000F0FB0000EA2FEF3A3433682DE7E0ECE810 +:102D0000ED20E22000000000EA2FEF3A3533682D75 +:102D1000EEF8E8E1EAE020ECE5F52E00EA2FEF3AE4 +:102D20003637682DEEF8E8E1EAE020E5ECEA2E001F +:102D3000D4D03A3031682DEDE5E8F1EFF0E0E2E58E +:102D4000ED000000D4D03A3032682DEEF2F1F3F20B +:102D5000F1F2E2F3E5F20000D4D03A3033682DEE20 +:102D6000F2F1F3F2F1F2E2F3E5F20000D4D03A30FE +:102D700034682DEDE5EAEEF0F02EEF2DF0FB0000CB +:102D8000D4D03A3036682DD4CF20E220F0E5E6E802 +:102D9000ECE50000D4D03A3037682DEDE5EAEEF0EE +:102DA000F02EEF2DF0FB0000D4D03A3131682DED3C +:102DB000E520E2E2E5E4E5EDE0000000D4D03A31C0 +:102DC00032682DE7E0E2EEE4F1EAEEE9000000000F +:102DD000D4D03A3133682DF2E5EAF3F9E0FF20E48C +:102DE000E0F2E000D4D03A3138682DCEF8E8E1EADC +:102DF000E020E4E0F2FB0000D4D03A3139682DCD78 +:102E0000E5F220E4E0EDEDFBF5000000D4D03A312E +:102E100041682DCEEEF8E8E1EAE020D4CF000000D2 +:102E2000D4D03A3142682DC7E0E2EEE4F1EAEEE9AF +:102E300000000000D4D03A3144682DCFEEE2F0E536 +:102E4000E6E4E5EDE0000000D4D03A3146682DCE4E +:102E5000F2F1F3F2F1F2E2F3E5F20000D4D03A320B +:102E600030682DCFE5F0E5EFEEEBEDE5EDE8E500C0 +:102E7000D4D03A3231682DCEF8E8E1EAE020F1F31F +:102E8000ECECFB00D4D03A3233682DCDE5F220E7EC +:102E9000E0EFE8F1E8000000D4D03A3238682DC203 +:102EA00020D4CF20E1EEEBE5E5000000D4D03A33AA +:102EB00033682DCDE5EAEEF0F0E5EAF2EDFBE50052 +:102EC000D4D03A3335682DCDE5EAEEF0F0E5EAF2FC +:102ED000EDFBE900D4D03A3336682DCDE5EAEEF0CB +:102EE000F0E5EAF2EDFBE500D4D03A3338682DCEB8 +:102EF000F8E8E1EAE020E220CFC7D300D4D03A33AB +:102F000039682DC2EDF3F2F0E5EDEDFFFF000000B2 +:102F1000D4D03A3341682DCFE5F0E5EFEEEBEDE5A7 +:102F2000EDE8E500D4D03A3345682DCFE5F0E5EF84 +:102F3000EEEBEDE5EDE8E500D4D03A3346682DCF71 +:102F4000E5F0E5EFEEEBEDE5EDE8E500D4D03A3461 +:102F500030682DCFE5F0E5EFEEEBEDE5EDE8E500CF +:102F6000D4D03A3431682DCFE5F0E5EFEEEBEDE566 +:102F7000EDE8E500D4D03A3432682DCFE5F0E5EF46 +:102F8000EEEBEDE5EDE8E500D4D03A3433682DCF33 +:102F9000E5F0E5EFEEEBEDE5EDE8E500D4D03A3411 +:102FA00034682DCFE5F0E5EFEEEBEDE5EDE8E5007B +:102FB000D4D03A3436682DCDE520F5E2E0F2E0E5F4 +:102FC000F2000000D4D03A3437682DCFE5F0E5EFB9 +:102FD000EEEBEDE5EDE8E500D4D03A3438682DCFDE +:102FE000E5F0E5EFEEEBEDE5EDE8E500D4D03A34C1 +:102FF00041682DCEF2EAF0FBF220F7E5EA0000008E +:10300000D4D03A3442682DC1F3F4E5F020F7E5EA74 +:10301000E0000000D4D03A3443682DCFE5F0E5EF6E +:10302000EEEBEDE5EDE8E500D4D03A3530682DC89B +:10303000E4E5F220EFE5F7E0F2FC0000D4D03A3509 +:1030400031682DCFE5F0E5EFEEEBEDE5EDE8E500DD +:10305000D4D03A3532682DCFE5F0E5EFEEEBEDE573 +:10306000EDE8E500D4D03A3533682DCFE5F0E5EF53 +:10307000EEEBEDE5EDE8E500D4D03A3534682DCF40 +:10308000E5F0E5EFEEEBEDE5EDE8E500D4D03A351F +:1030900042682DCFE5F0E5EFEEEBEDE5EDE8E5007C +:1030A000D4D03A3545682DCDE5EAEEF0F0E5EAF208 +:1030B000EDE0FF00D4D03A3630682DCFE5F0E5EFF3 +:1030C000EEEBEDE5EDE8E500D4D03A3631682DCFF2 +:1030D000E5F0E5EFEEEBEDE5EDE8E500D4D03A36CE +:1030E00032682DCFE5F0E5EFEEEBEDE5EDE8E5003C +:1030F000D4D03A3633682DCFE5F0E5EFEEEBEDE5D1 +:10310000EDE8E500D4D03A3635682DCDE520F5E27E +:10311000E0F2E0E5F2000000D4D03A3636682DCF78 +:10312000E5F0E5EFEEEBEDE5EDE8E500D4D03A367D +:1031300037682DCEF8E8E1EAE020F1E2FFE7E800A9 +:10314000D4D03A3638682DCDE520F5E2E0F2E0E55E +:10315000F2000000D4D03A3639682DCFE5F0E5EF23 +:10316000EEEBEDE5EDE8E500D4D03A3642682DCD42 +:10317000E5F220F7E5EAEEE2EEE90000D4D03A36D7 +:1031800043682DCDE5F220EAEEEDF2F02E000000CE +:10319000D4D03A3644682DCDE520F5E2E0F2E0E502 +:1031A000F2000000D4D03A3645682DCFE5F0E5EFC7 +:1031B000EEEBEDE5EDE8E500D4D03A3646682DCFEC +:1031C000E5F0E5EFEEEBEDE5EDE8E500D4D03A37DC +:1031D00030682DCFE5F0E5EFEEEBEDE5EDE8E5004D +:1031E000D4D03A3732682DCAEEECE0EDE4E020EDC1 +:1031F000E5000000D4D03A3733682DCAEEECE0ED9C +:10320000E4E020EDE5000000D4D03A3734682DCE5C +:10321000F8E8E1EAE020CEC7D3000000D4D03A3786 +:1032200038682DC7E0ECE5EDE020CFCE00000000CF +:10323000D4D03A3739682DC7E0ECE5EDE020D4CFA3 +:1032400000000000D4D03A3743682DCDE520F1EEE0 +:10325000E2EFE0E4E0E5F200D4D03A3746682DCF63 +:10326000E5F0E5EFEEEBEDE5EDE8E500D4D03A383A +:1032700034682DCFE5F0E5EFEEEBEDE5EDE8E500A8 +:10328000D4D03A3835682DCFE5F0E5EFEEEBEDE53B +:10329000EDE8E500D4D03A3836682DCFE5F0E5EF1B +:1032A000EEEBEDE5EDE8E500D4D03A3837682DCF08 +:1032B000E5F0E5EFEEEBEDE5EDE8E500D4D03A38EA +:1032C00038682DCFE5F0E5EFEEEBEDE5EDE8E50054 +:1032D000D4D03A3839682DCFE5F0E5EFEEEBEDE5E7 +:1032E000EDE8E500D4D03A3841682DCFE5F0E5EFC0 +:1032F000EEEBEDE5EDE8E500D4D03A3842682DCFAD +:10330000E5F0E5EFEEEBEDE5EDE8E500D4D03A3899 +:1033100045682DCDF3EBE5E2EEE920E8F2EEE300BF +:10332000D4D03A3930682DCFEEEBE520EFF0E5E26E +:103330002E000000D4D03A3932682DCDE0EBEEE615 +:10334000E5EDE8E500000000D4D03A4130682DCE2C +:10335000F8E8E1EAE020F1E2FFE7E800D4D03A4102 +:1033600033682DCDE5EAEEF0F0E5EAF2EDEEE500AA +:10337000D4D03A4134682DC0E2E0F0E8FF20DDCA45 +:10338000CBC70000D4D03A4135682DC0E2E0F0E868 +:10339000FF20CAD100000000D4D03A4141682DCFAF +:1033A000E5F0E5EFEEEBEDE5EDE8E500D4D03A43EE +:1033B00032682DCFF0E5E2FBF8E5EDE8E50000002E +:1033C000D4D03A4333682DCDE5F1EEE2EFE0E4E509 +:1033D000EDE8E500D4D03A4334682DCDE5F1EEE2D6 +:1033E000EFE0E4E5EDE8E500EAF3EFFEF0EEEFF004 +:1033F000E8E5ECEDE8EAEEEC00000000EFEE20E896 +:10340000E4E5EDF2E8F4E8EAE0F6E8E800000000C0 +:10341000EFEE20EEEFF2E8F72EE4E0F2F7E8EAF361 +:1034200020000000EFEE20E5ECEAEEF1F22EE4E001 +:10343000F2F7E8EAF3000000F1F2E5EAE5F0EDEE7C +:10344000E3EE20ECEEF2EEF0E0000000F2F0E0ED52 +:10345000F1EFEEF0F22EECEEF2EEF0E00000000004 +:10346000D4CF312CD4CF3220E8EBE820F7E0F1FBC9 +:1034700000000000E7E0EFF0EEF8E5EDEDFBF520F1 +:10348000E4E0EDEDFBF50000EDEEECE5F020F3E619 +:10349000E520E2E2E5E4E5ED00000000ECE5EDFC0E +:1034A000F8E520E4E0F2FB20E220D4CF00000000A9 +:1034B000EFEEF1EBE5E4EDFFFF20E7E0EFE8F1FCF4 +:1034C00000000000EFE0ECFFF2FC20F0E5E3E8F1A3 +:1034D000F2F0EEE200000000E4E5EDE5E6EDEEE3FB +:1034E000EE20F0E5E3E8F1F2F0E0000032F520F143 +:1034F000E1EEE9EDFBF520E7E0EFE8F1E5E90000BA +:10350000EFE0F0E0ECE5F2F0FB20E220EAEEECE0A8 +:10351000EDE4E500EDE0EAEEEFEBE5EDE8FF20E2BB +:1035200020F1ECE5EDE50000EDE5E2E5F0EDFBE98D +:1035300020F0E5E32EEDEEECE5F00000EDE0EAEE44 +:10354000EF2EEFEE20F1E5EAF6E8FFEC00000000D8 +:10355000EDE0EAEEEF2EEFEE20F1EAE8E4EAE0EC4F +:1035600000000000E4E8E0EFE0E7EEEDE020F1EA43 +:10357000E8E4EEEA00000000E4E8E0EFE0E7EEED6A +:10358000E020EEEFEBE0F2FB00000000E4E8E0EF0B +:10359000E0E7EEEDE020EEEFEBE0F2FB20320000A2 +:1035A000E4E8E0EFE0E7EEEDE020EEEFEBE0F2FB49 +:1035B00020330000E4E8E0EFE0E7EEEDE020EEEF9E +:1035C000EBE0F2FB20340000ECE5EDFCF8E520E850 +:1035D000F2EEE3E020F7E5EAE0000000EDE0EBE8E2 +:1035E000F7EDEEF1F2E820E220EAE0F1F1E500008B +:1035F000EEEFE5F0E0F6E8FF20EDE5E2EEE7ECEED9 +:10360000E6EDE000EDE0EAEEEF2EEFEE20EDE0EB90 +:10361000EEE3E0EC00000000E1E5E7EDE0EB2EF189 +:10362000F3ECECE020E1EEEBFCF8E500EFF0E5E296 +:10363000FBF1E8EBE020323420F7E0F1E00000009D +:10364000EDE0EAEEEFEBE5EDE8E920E220F1ECE574 +:10365000EDE50000EEF8E8E1EAE020EAEEEB2DE22D +:10366000E020F1ECE5ED0000EAEEECE0EDE4FB201B +:10367000EFF0EEE4EEEBE6E5EDE8FF00EEF2EAF067 +:10368000FBF220E4F0F3E3E8EC20EEEF2E00000084 +:10369000E4E8E0EFE0E7EEEDE020EDE0E4E1E0E299 +:1036A000EEEA0000E4E8E0EFE0E7EEEDE020EAEE2D +:1036B000EB2DE2E000000000E4E8E0EFE0E7EEEDF3 +:1036C000E020EEF2E4E5EBE000000000E4E5EDE5EB +:1036D000E320EFEE20EDE0EBEEE3E0EC0000000095 +:1036E000EFEE20E2FBEFEBE0F2E520E220F1ECE58B +:1036F000EDE50000EFEE20E2EEE7E2F0E0F2E0ECD4 +:1037000020EFF0EEE4E0E600EFEE20E2EDE5F1E59B +:10371000EDE8FE20E220F1ECE5EDE500EFEE20ED36 +:10372000E0E4E1E0E2EAE0EC20E220F7E5EAE500AF +:10373000EFEE20F1EAE8E4EAE0EC20E220F7E5EA47 +:10374000E5000000E8F2EEE320F1EAE8E4EAE82030 +:10375000E220F7E5EAE50000F0E0E7ECE5F020E242 +:1037600020EDE0F1F2F0EEE9EAE0F500E3F0E0ED63 +:10377000E8F6F320EFEEEBFF20EFE5F7E0F2E800EC +:10378000CEC7D320EFF0EEF8EBEE20F3F1EFE5F843 +:10379000EDEE0000E2F0E5EC2EF0E5F1F3F0F120C3 +:1037A000DDCACBC700000000CFE5F0E5EFEEEBEDA2 +:1037B000E5EDE8E520EAEEEB2DE2E000CFE5F0E50F +:1037C000EFEEEBEDE5EDE8E520F1F3ECECFB0000CE +:1037D000D3E6E520E0EAF2E8E2E8E7E8F0EEE2E04E +:1037E000EDE00000E8F2EEE3EEE220F7E5EAE020AB +:1037F000E820DDCACBC700004B617373657461209C +:103800007A61706F6C6E656E610000004B6173735E +:10381000657461206F747375747374767565740064 +:103820004F736869626B6120737679617A6920737E +:1038300020465200CFE0F3E7E020EFEEF1EBE52C7D +:10384000ECE8ED2E00000000CFE5F7E0F2FC20EE02 +:10385000F2F72EE8E720E1F3F42E0000CEF8E8E1DD +:10386000EAE020EEF2EFF02E652D6D61696C00004C +:10387000452D6D61696C20EEF2EFF02EF3F1EFE56E +:10388000F8EDEE00207C2020566E6573656E612099 +:103890006B75707572612000207C2020566E6573F8 +:1038A000656E79206D6F6E6574792000207C202014 +:1038B0004E616368616C6F207365616E7361200097 +:1038C000207C20204B6F6E65F1207365616E736103 +:1038D00020000000207C2020506563686174272050 +:1038E000636865636B612000207C2020536D656EEA +:1038F000612072656A696D6120000000207C2020D3 +:10390000496E63617373616369796120000000002F +:10391000207C20204E657420736F62797469796110 +:1039200020000000C2E2EEE420ECE0F1F2E5F02D30 +:10393000EFE0F0EEEBFF00002D2D2D2D2D2D2D2D88 +:103940002D2D2D2D2D2D2D2D2D2D2D002D2D2D2DD4 +:103950002D2D2D2D2D2D2D2D2D2D2D2D2D2D2D00C4 +:10396000005701000C5701001857010024570100AF +:10397000000000002D2D2D2D2D2D2D2D2D2D2D2D2B +:103980002D2D2D2D2D2D2D002020202020C2CDC805 +:10399000CCC0CDC8C5202020202000002020202021 +:1039A000C8CDCAC0D1D1C0D6C8DF20202020000099 +:1039B0003C5701004857010054570100605701006F +:1039C0000000000078570100845701009057010063 +:1039D0009C57010000000000D1C5D0C2C8D120E230 +:1039E000E5F02ECFCE2030332E333000CEF7E8F185 +:1039F000F2EAE020F1F2E0F2E8F1F2E8EAE80000B1 +:103A0000D1D2C0D2C8D1D2C8CAC820C2C2C5C4C8C7 +:103A1000D2C5000020C6D3D0CDC0CBCEC220C2C2FA +:103A2000C5C4C8D2C5000000C8580100D458010060 +:103A3000E0580100EC5801000000000004590100AA +:103A4000105901001C590100285901000000000014 +:103A5000CACED0CED2CAC8C520D1D7C5D2D7C8CA3F +:103A6000C8000000405901004C590100585901009C +:103A70006459010000000000C4CBC8CDCDDBC520D7 +:103A8000D1D7C5D2D7C8CAC8000000007C590100F0 +:103A90008859010094590100A0590100000000005C +:103AA000D3F1F2E0EDEEE2EAE020EFE0F0EEEBFF42 +:103AB00000000000D3F1F2E0EDEEE2EAE020E2F0F7 +:103AC000E5ECE5EDE80000002020C2C2C5C4C8D284 +:103AD000C520D2C5CAD3D9C8E900000020CDC0D1C5 +:103AE000D2D0CEC5CA20C2C2C5C4C8D2C50000004B +:103AF000CDC0D1D2D0CEE9CAC820CCCECDC5D2CE91 +:103B0000CFD02E0020CDC0D1D2D0CEE9CAC820CC93 +:103B1000CEC4C5CCC0000000245D0100305D0100B2 +:103B20003C5D0100485D01000000000020CDE5E2A1 +:103B3000E5F0EDFBE920EFE0F0EEEBFC000000002B +:103B4000785D0100605D01006C5D0100785D010041 +:103B500000000000202020D3F1F2E0EDEEE2EBE5E2 +:103B6000EDFB202000000000905D01009C5D010045 +:103B7000A85D0100B45D010000000000E45D0100EB +:103B8000CC5D0100D85D0100E45D01000000000093 +:103B9000145E0100FC5D0100085E0100145E01007E +:103BA00000000000CFD0CED1CCCED2D020C6D3D012 +:103BB000CDC0CBCEC2000000CEF7E8F1F2EAE020A3 +:103BC000E6F3F0EDE0EBEEE2000000002C5E010019 +:103BD000385E0100445E0100505E010000000000FC +:103BE0005A2DEEF2F7E5F220E8E720E1F3F4E5F0F4 +:103BF000E0000000685E0100745E0100805E01006C +:103C00008C5E010000000000CDE0EFE5F7E0F2E09F +:103C1000F2FC20F1F3F2EEF7EDFBE900EEF2F7E54E +:103C2000F220E1E5E720E3E0F8E5EDE8FF3F000002 +:103C3000C4C02D535441525420202053544F502D72 +:103C4000CDC5D200A45E0100B05E0100BC5E0100E3 +:103C5000C85E010000000000CDE0EFE5F7E0F2E013 +:103C6000F2FC20F1F3F2EEF7EDFBE900EEF2F7E5FE +:103C7000F220F120E3E0F8E5EDE8E5EC3F0000009C +:103C8000E05E0100EC5E0100F85E0100045F0100EF +:103C900000000000205A2DCED2D7C5D2DB20C8C7E5 +:103CA00020C1D3D4C5D0C000CDE0EFE5F7E0F2E00D +:103CB000F2FC20F1F3F2EEF7EDFBE50020EEF2F777 +:103CC000E5F2FB20E8E720E1F3F4E5F0E03F000057 +:103CD0001C5F0100285F0100345F0100C85E010025 +:103CE00000000000EFE5F7E0F2FC20EDE5E2EEE792 +:103CF000ECEEE6EDE00000007C5F0100885F010073 +:103D0000945F0100A05F010000000000B85F0100A7 +:103D1000C45F0100D05F0100DC5F01000000000013 +:103D2000D3D1D2C0CDCEC2CAC020C2D0C5CCC5CDA1 +:103D3000C80000002020CEC1D9C0DF20D1D2C0D21F +:103D4000C8D1D2C8CAC00000CAEEF0EEF2EAE8E577 +:103D500020F1F7E5F2F7E8EAE8000000C4EBE8ED4F +:103D6000EDFBE520F1F7E5F2F7E8EAE800000000F6 +:103D700020D1D2C0D22DCAC020CFCE20CAC0CDC043 +:103D8000CBC0CC0084600100906001009C60010009 +:103D9000A8600100000000005B736D74705F7061CB +:103DA0007373776F72645D3D000000005E5349538A +:103DB000573A2025642C2025642C2025640000001F +:103DC0007C20202532642020207C20253131642075 +:103DD0000000000053797374656D6E6F6520767214 +:103DE000656D79613A2000005672656D79612069D0 +:103DF0006E63617373616369693A20000D0A0D0A8D +:103E000053756D6D61202564207275622E0D0A0058 +:103E10002020D1D3CCCCC020257520F0F3E12E009A +:103E2000C2EDE5F1E8F2E520E4E5EDFCE3E80000B1 +:103E3000CFF0E8EDFFF2EE20256420F0F3E12E0054 +:103E4000CDC5C4CED1D22EC4C5CDC5C3000000009F +:103E5000CAD3CFDED0CECFD0C8C5CCCDC8CAC00063 +:103E6000CDC5D220D1C2DFC7C820D120D4D0000018 +:103E7000C2CEC762CCC8D2C520D7C5CA00000000D8 +:103E8000CDC5D220C2CACBDED7C5CDCDDBD5000093 +:103E9000C4CE20D1CBC5C42ED1C5C0CDD1C03A002F +:103EA000C2DBC1C5D0C8D2C520CAC0CDC0CB0000BE +:103EB000523020203A203078253038780A0000002F +:103EC000523120203A203078253038780A0000001E +:103ED000523220203A203078253038780A0000000D +:103EE000523320203A203078253038780A000000FC +:103EF000523420203A203078253038780A000000EB +:103F0000523520203A203078253038780A000000D9 +:103F1000523620203A203078253038780A000000C8 +:103F2000523720203A203078253038780A000000B7 +:103F3000523820203A203078253038780A000000A6 +:103F4000523920203A203078253038780A00000095 +:103F5000523130203A203078253038780A0000007D +:103F6000523131203A203078253038780A0000006C +:103F7000523132203A203078253038780A0000005B +:103F8000535020203A203078253038780A0000003D +:103F90004C5220203A203078253038780A00000032 +:103FA000504320203A203078253038780A0000002D +:103FB000435053523A203078253038780A000000B8 +:103FC000EEF8E8E1EAE020F1E2FFE7E820F10000A6 +:103FD000EEF8E8E1EAE020F0E0E1EEF2FB000000BC +:103FE000EA2FEF3A3431682DEAE0F1F1E5F2E00032 +:103FF000EA2FEF3A3432682DEAE0F1F1E5F2E00021 +:10400000EA2FEF3A3434682DE7E0ECE8ED000000E9 +:10401000EA2FEF3A3435682DEFEEEFFBF2EAE000DD +:10402000EA2FEF3A3530682DEEF8E8E1EAE00000DB +:10403000EA2FEF3A3532682DEEF8E8E1EAE00000C9 +:10404000EA2FEF3A3534682DEAE0F1F1E5F2E000CD +:10405000EA2FEF3A3635682DEEF8E8E1EAE00000A5 +:10406000EA2FEF3A3636682DEEF8E8E1EAE0000094 +:10407000D4D03A3038682DEAEEECE0EDE4E0000010 +:10408000D4D03A3039682DEDE5EAEEF0F02E00009C +:10409000D4D03A3135682DD1ECE5EDE000000000D8 +:1040A000D4D03A3136682DD1ECE5EDE000000000C7 +:1040B000D4D03A3234682DCEE1EBE0F1F2FC0000CE +:1040C000D4D03A3337682DCAEEECE0EDE4E00000DE +:1040D000D4D03A3343682DDDCACBC73A0000000084 +:1040E000D4D03A3435682D43F3ECECE00000000006 +:1040F000D4D03A3444682DC2EDEEF1E8ECE0FF0094 +:10410000D4D03A3445682DD1ECE5EDE00000000054 +:10411000D4D03A3536682DCDE5F220E4EEEA2E0013 +:10412000D4D03A3537682DDDCACBC73A000000003D +:10413000D4D03A3538682DCEE6E8E4E0EDE8E50085 +:10414000D4D03A3539682DC4EEEAF3ECE5EDF2004F +:10415000D4D03A3543682DCFEEEDE8E6E5EDEE003C +:10416000D4D03A3544682DD2E0E1EBE8F6E0000027 +:10417000D4D03A3546682DCEF2F0E8F62E00000095 +:10418000D4D03A3641682DCEF8E8E1EAE0000000EC +:10419000D4D03A3731682DCEF8E8E1EAE0000000EB +:1041A000D4D03A3735682DCEF8E8E1EAE0000000D7 +:1041B000D4D03A3736682DCFF0E8EDF2E5F03A008A +:1041C000D4D03A3737682DCFF0E8EDF2E5F03A0079 +:1041D000D4CF3A3741682DCFEEEBE520EDE5000076 +:1041E000D4D03A3742682DCEF8E8E1EAE00000008A +:1041F000D4D03A3744682DCDE5E2E5F0EDFBE90097 +:10420000D4D03A3745682DCDE5E2E5F0EDEEE50096 +:10421000D4D03A3830682DCEF8E8E1EAE00000006A +:10422000D4D03A3831682DCEF8E8E1EAE000000059 +:10423000D4D03A3832682DCEF8E8E1EAE000000048 +:10424000D4D03A3833682DCEF8E8E1EAE000000037 +:10425000D4D03A3843682DCEF2F0E8F62E000000B4 +:10426000D4D03A3846682DCAE0F1F1E020EDE500FF +:10427000D4D03A3931682DC2FBF5EEE420E7E000F6 +:10428000D4D03A3934682DC8F1F7E5F0EFE0ED000D +:10429000D4D03A4132682DDDCACBC73A20000000A5 +:1042A000D4D03A4136682DC8F1F7E5F0EFE0ED00E3 +:1042B000D4D03A4138682DC7CACBC73A00000000B5 +:1042C000D4D03A4139682DDDCACBC73A000000008E +:1042D000D4D03A4230682DDDCACBC73A0000000086 +:1042E000D4D03A4231682DDDCACBC73A0000000075 +:1042F000D4D03A4232682DDDCACBC73A0000000064 +:10430000D4D03A4330682DCAEEEDF2F0EEEBFC006B +:10431000D4D03A4331682DDDCACBC73A0000000043 +:10432000EAF3EFFEF0EEEFF0E8E5ECEDE8EAE000AE +:10433000EFEE20ECE0E32EE4E0F2F7E8EAF3000031 +:10434000EFF0E820F2F0E0EDF1EFEEF0F22E0000F9 +:10435000EFEE20E2E5F0E8F4E8EAE0F6E8E8200035 +:10436000EAF3EFFEF0EEEFF0E8E5ECEDE8EAE50069 +:10437000E2FBF0E0E2EDE8E2E0EDE8FF0000000043 +:10438000E220EAEEECE0EDE4E520EA20D4CF000004 +:10439000E2FBE2EEE4E020E4E0EDEDFBF5000000FE +:1043A000E220EAEEECE0EDE4E520D4CF00000000EE +:1043B000E4EBE8EDE020EAEEECE0EDE4FB200000C9 +:1043C000EDEEECE5F020EDE520E2E2E5E4E5ED00E0 +:1043D000EFEEE2F0E5E6E42E20E7E0EFE8F1FC00A6 +:1043E000E0EAF22EEFE5F0E5EFEEEBEDE5EDE000D3 +:1043F000EDE520EFEEE4E4E5F0E62ED4D000000099 +:10440000EEF8E8E1EAE020CFCE20D4D000000000B2 +:10441000EFF0E5E42EEAEEECE0EDE4FB0000000056 +:10442000EDE0EFF0FFE6E5EDE8E5203234C2000014 +:10443000EDE520EEEFF0E5E4E5EBE5EDE000000072 +:10444000EFF0E820F3ECEDEEE6E5EDE8E800000043 +:10445000E4E8E0EFE0E7EEEDE020F6E5EDFB00005C +:10446000E4E5EDE5E320E220F1E5EAF6E8E8000026 +:10447000E4E5EDE5E320EFEE20EDE0EBEEE3F30025 +:10448000EDE5F220E8ECEFF3EBFCF1EEE2000000EA +:10449000F0E5E4E0EAF2E8F0F3E5F2F1FF00000015 +:1044A000EEE1EEF0F3E4EEE2E0EDE8FF0000000004 +:1044B000E8F2EEE320EDE0E4E1E0E2EAE80000000B +:1044C000F4E8F1EAE0EBE8E7E8F0EEE2E0EDE00046 +:1044D000F1EEF1F2EEFFEDE8E520DDCACBC700001A +:1044E000E220F1EEF1F2E0E2E520DDCACBC7000008 +:1044F000E4E0F2FB20E820E2F0E5ECE5EDE8000086 +:10450000F1F3F2EEF7EDFBE920EEF2F7E5F2000051 +:10451000EDEEECE5F0EEE220F1ECE5ED0000000060 +:104520005A616D696E2076206B61737365746500E6 +:10453000506F7079746B61206F626D616E61000005 +:104540004F736869626B61206F7074696B690000FA +:104550004F736869626B61204652203078303100B9 +:104560004F736869626B61204652203078303200A8 +:104570004F736869626B6120465220307830330097 +:104580004F736869626B6120465220307830340086 +:104590004F736869626B6120465220307830350075 +:1045A0004F736869626B6120465220307830360064 +:1045B0004F736869626B6120465220307830370053 +:1045C0004F736869626B6120465220307830380042 +:1045D0004F736869626B6120465220307830390031 +:1045E0004F736869626B6120465220307830410019 +:1045F0004F736869626B6120465220307830420008 +:104600004F736869626B6120465220307831310007 +:104610004F736869626B61204652203078313200F6 +:104620004F736869626B61204652203078313300E5 +:104630004F736869626B61204652203078313400D4 +:104640004F736869626B61204652203078313500C3 +:104650004F736869626B61204652203078313600B2 +:104660004F736869626B61204652203078313700A1 +:104670004F736869626B6120465220307831380090 +:104680004F736869626B612046522030783139007F +:104690004F736869626B6120465220307831410067 +:1046A0004F736869626B6120465220307831420056 +:1046B0004F736869626B6120465220307831430045 +:1046C0004F736869626B6120465220307831440034 +:1046D0004F736869626B6120465220307831460022 +:1046E0004F736869626B6120465220307832300027 +:1046F0004F736869626B6120465220307832310016 +:104700004F736869626B6120465220307832320004 +:104710004F736869626B61204652203078323300F3 +:104720004F736869626B61204652203078323400E2 +:104730004F736869626B61204652203078323500D1 +:104740004F736869626B61204652203078323800BE +:104750004F736869626B61204652203078333300B2 +:104760004F736869626B61204652203078333500A0 +:104770004F736869626B612046522030783336008F +:104780004F736869626B612046522030783337007E +:104790004F736869626B612046522030783338006D +:1047A0004F736869626B612046522030783339005C +:1047B0004F736869626B6120465220307833410044 +:1047C0004F736869626B6120465220307833430032 +:1047D0004F736869626B6120465220307833450020 +:1047E0004F736869626B612046522030783346000F +:1047F0004F736869626B6120465220307834300014 +:104800004F736869626B6120465220307834310002 +:104810004F736869626B61204652203078343200F1 +:104820004F736869626B61204652203078343300E0 +:104830004F736869626B61204652203078343400CF +:104840004F736869626B61204652203078343500BE +:104850004F736869626B61204652203078343600AD +:104860004F736869626B612046522030783437009C +:104870004F736869626B612046522030783438008B +:104880004F736869626B6120465220307834410072 +:104890004F736869626B6120465220307834420061 +:1048A0004F736869626B6120465220307834430050 +:1048B0004F736869626B612046522030783444003F +:1048C0004F736869626B612046522030783445002E +:1048D0004F736869626B612046522030783446001D +:1048E0004F736869626B6120465220307835300022 +:1048F0004F736869626B6120465220307835310011 +:104900004F736869626B61204652203078353200FF +:104910004F736869626B61204652203078353300EE +:104920004F736869626B61204652203078353400DD +:104930004F736869626B61204652203078353600CB +:104940004F736869626B61204652203078353700BA +:104950004F736869626B61204652203078353800A9 +:104960004F736869626B6120465220307835390098 +:104970004F736869626B612046522030783542007F +:104980004F736869626B612046522030783543006E +:104990004F736869626B612046522030783544005D +:1049A0004F736869626B612046522030783545004C +:1049B0004F736869626B612046522030783546003B +:1049C0004F736869626B6120465220307836300040 +:1049D0004F736869626B612046522030783631002F +:1049E0004F736869626B612046522030783632001E +:1049F0004F736869626B612046522030783633000D +:104A00004F736869626B61204652203078363400FB +:104A10004F736869626B61204652203078363500EA +:104A20004F736869626B61204652203078363600D9 +:104A30004F736869626B61204652203078363700C8 +:104A40004F736869626B61204652203078363800B7 +:104A50004F736869626B61204652203078363900A6 +:104A60004F736869626B612046522030783641008E +:104A70004F736869626B612046522030783642007D +:104A80004F736869626B612046522030783643006C +:104A90004F736869626B612046522030783644005B +:104AA0004F736869626B612046522030783645004A +:104AB0004F736869626B6120465220307836460039 +:104AC0004F736869626B612046522030783730003E +:104AD0004F736869626B612046522030783731002D +:104AE0004F736869626B612046522030783732001C +:104AF0004F736869626B612046522030783733000B +:104B00004F736869626B61204652203078373400F9 +:104B10004F736869626B61204652203078373500E8 +:104B20004F736869626B61204652203078373600D7 +:104B30004F736869626B61204652203078373700C6 +:104B40004F736869626B61204652203078373800B5 +:104B50004F736869626B61204652203078373900A4 +:104B60004F736869626B612046522030783741008C +:104B70004F736869626B612046522030783742007B +:104B80004F736869626B612046522030783743006A +:104B90004F736869626B6120465220307837440059 +:104BA0004F736869626B6120465220307837450048 +:104BB0004F736869626B6120465220307837460037 +:104BC0004F736869626B612046522030783830003C +:104BD0004F736869626B612046522030783831002B +:104BE0004F736869626B612046522030783832001A +:104BF0004F736869626B6120465220307838330009 +:104C00004F736869626B61204652203078383400F7 +:104C10004F736869626B61204652203078383500E6 +:104C20004F736869626B61204652203078383600D5 +:104C30004F736869626B61204652203078383700C4 +:104C40004F736869626B61204652203078383800B3 +:104C50004F736869626B61204652203078383900A2 +:104C60004F736869626B612046522030783841008A +:104C70004F736869626B6120465220307838420079 +:104C80004F736869626B6120465220307838430068 +:104C90004F736869626B6120465220307838440057 +:104CA0004F736869626B6120465220307838450046 +:104CB0004F736869626B6120465220307838460035 +:104CC0004F736869626B612046522030783930003A +:104CD0004F736869626B6120465220307839310029 +:104CE0004F736869626B6120465220307839320018 +:104CF0004F736869626B6120465220307839330007 +:104D00004F736869626B61204652203078393400F5 +:104D10004F736869626B61204652203078413000E1 +:104D20004F736869626B61204652203078413100D0 +:104D30004F736869626B61204652203078413200BF +:104D40004F736869626B61204652203078413300AE +:104D50004F736869626B612046522030784134009D +:104D60004F736869626B612046522030784135008C +:104D70004F736869626B612046522030784136007B +:104D80004F736869626B612046522030784137006A +:104D90004F736869626B6120465220307841380059 +:104DA0004F736869626B6120465220307841390048 +:104DB0004F736869626B6120465220307841410030 +:104DC0004F736869626B6120465220307842300030 +:104DD0004F736869626B612046522030784231001F +:104DE0004F736869626B612046522030784232000E +:104DF0004F736869626B61204652203078433000FF +:104E00004F736869626B61204652203078433100ED +:104E10004F736869626B61204652203078433200DC +:104E2000D3F1EBF3E3E820F1EEEBFFF0E8FF000055 +:104E3000CACED02ED1D72ECAC0CDC0CB0000000024 +:104E4000CEF2EFF02EE6F3F0EDE0EBFB0000000019 +:104E5000C8E3EDEEF0E8F02EEEF82ED4D00000001E +:104E6000CFE0F3E7E020E4EE2CF1E5EA2E000000CD +:104E7000C7E020E2F0E5ECFF2CECE8ED2E000000AE +:104E8000C7E020E2F0E5ECFF2CECE8ED2E0000009E +:104E9000202020CDCECCC8CDC0CB202300000000E8 +:104EA000C7EDE0F7E5EDE8E52CF0F3E12E000000BA +:104EB000D3F1EBF3E3E820F1EEEBFFF0E8FF0000C5 +:104EC000CFE5F7E0F2FC205A2DEEF2F7E5F2E00034 +:104ED000CFE5F7E0F2FC20582DEEF2F7E5F2E00026 +:104EE000D1ECE5EDE020F0E5E6E8ECE000000000C4 +:104EF000CDE5E2E5F0EDFBE920EFE0F0EEEBFC00C4 +:104F0000207C2020566B6C756368656E6965200097 +:104F10006E6574207A61706973690D0A0000000083 +:104F2000D6E5EDFB20E220E1F3E4EDE8000000002F +:104F3000D6E5EDFB20E220E2FBF5EEE4EDFBE5003B +:104F40002020C8E4E5F220EFF0EEE2E5F0EAE00030 +:104F50002020EEE1EEF0F3E4EEE2E0EDE8FF2100E8 +:104F600020202020C220E6F3F0EDE0EBE500000079 +:104F7000202020E7E0EFE8F1E5E920EDE5F2000090 +:104F800020202020D1D2C0D2C8D1D2C8CAC00000AF +:104F9000D1F7E5F2F7E8EAE820EAF3EFFEF00000E7 +:104FA000202020C4CBDF20CED7C8D1D2CAC8000071 +:104FB000685801007458010080580100000000008A +:104FC000202020C4CBDF20CED7C8D1D2CAC8000051 +:104FD00098580100A4580100B058010000000000DA +:104FE00020202020CDC0D1D2D0CEE9CAC8000000F8 +:104FF000CEE1EEF0F3E4EEE2E0EDE8E500000000E3 +:10500000D1E1F0EEF120EDE0F1F2F0EEE5EA0000A2 +:10501000F05A0100FC5A0100085B0100000000008A +:10502000C2C2C5C4C8D2C520CCC0D1D2C5D02D0003 +:1050300020202020C4CBDF20D1C1D0CED1C00000A1 +:10504000505B01005C5B0100685B01000000000038 +:105050002020C2C2C5C4C8D2C520CDCEC2DBE90063 +:10506000202020CEC1CED0D3C4CEC2C0CDC8C50072 +:10507000CCEEEDE5F2EEEFF0E8E5ECEDE8EA00006D +:10508000202020CDC0D1D2D0CEE9CAC820D4D000B3 +:10509000945C0100A05C0100AC5C01000000000019 +:1050A0002020202020CEF8E8E1EAE02000000000E7 +:1050B00020202020E7E0E2EEE4F1EAE8E52000002D +:1050C0002020202020E7EDE0F7E5EDE8FF000000DC +:1050D00020202020EFE0F0E0ECE5F2F0EEE200002E +:1050E00020202020D1F2E0F2E8F1F2E8EAE000002E +:1050F0002020202020EEF7E8F9E5EDE00000000098 +:105100002020202020C6F3F0EDE0EBFB2000000083 +:105110002020202020EEF7E8F9E5EDFB000000005C +:10512000C6F3F0EDE0EB20EEF8E8E1EEEA00000077 +:10513000C6F3F0EDE0EB20F1EEE1FBF2E8E9000070 +:10514000202020202020CED2D7C5D2DB00000000B6 +:105150002020202020582DCED2D7C5D2000000001C +:1051600020202020205A2DCED2D7C5D2000000000A +:10517000202020D4D020EEF2EAEBFEF7E5ED00008F +:105180004C5F0100585F0100645F010000000000F7 +:1051900024600100306001003C600100000000005C +:1051A00054600100606001006C60010000000000BC +:1051B0005B61705F70617373776F72645D3D000057 +:1051C0005B736D74705F757365725D3D0000000008 +:1051D0005B736D74705F6D61696C5D3D0000000014 +:1051E0005B736D74705F7365727665725D3D000010 +:1051F0005B736D74705F706F72745D3D00000000D2 +:1052000041542B434D47523D25640D0A00000000D8 +:105210005E534953573A20302C20310D0A000000CC +:1052200041545E534953573D302C25640D0A00000C +:1052300041545E534953573D302C302C310D0A00F8 +:105240005E534953573A20302C20320D0A0000009B +:10525000253032643A253032643A25303264000019 +:1052600025643A253032643A25303264000000006B +:10527000001F1C1F1E1F1E1F1F1E1F1E1F000000C1 +:1052800002000C340000000000000000CEC6C8C4BC +:10529000C0CDC8C500000000C2CACBDED7C5CDC88E +:1052A000DF000000CCC0CAD12ED1C5C0CDD10000D6 +:1052B000C0CFCF2EC3CED2CEC2000000CDC5D220EB +:1052C000D1C2DFC7C8000000CED8C8C1CAC020D430 +:1052D000D0000000D1CFC0D1C8C1CE20C7C00000CF +:1052E000CFCEC6C0CBD3E9D1D2C00000CAC0CDC09A +:1052F000CBCEC22100000000CED1D2C0CBCED16235 +:105300003A200000C820CDC0C6CCC8D2C5200000BD +:10531000253032643A25303264000000CEF82EEA9F +:10532000EEEDF42E00000000CDE5F220F1E2FFE703 +:10533000E8000000D4D03A3035682DEDE5F20000E9 +:10534000D4D03A3134682DD4CF000000D4D03A31D3 +:1053500043682DC5F1F2FC00D4D03A3235682DCD2A +:10536000E5F20000D4D03A4131682DDDCACBC70048 +:10537000D4D03A4137682DDDCACBC700EFF0E82022 +:10538000E7E0ECE8EDE50000EFEE20E7E0EFF0E528 +:10539000F2F30000EFEE20E4EBE8EDE500000000A2 +:1053A000E7E0EFEEEBEDE5EDE0000000EEF2F1F30B +:1053B000F2F1F2E2F3E5F200E220EAE0F1F1E5F2E7 +:1053C000E5000000ECE0E32EE4E0F2F7E8EAE000BC +:1053D000F1E2FFE7E820F120D4D00000EDE520EF76 +:1053E000EEE4E42ED4CF0000EFE0ECFFF2E820D4AE +:1053F000CF000000EBE8F6E5EDE7E8FF0000000075 +:10540000EFE5F0E5EFEEEBEDE5EDE000F3E6E520AE +:10541000EEF2EAF0FBF2E000EDE520EEF2EAF0FB5E +:10542000F2E00000E0EAF2E8E2E8E7E0F6E8E800AF +:10543000EFE0F0E0ECE5F2F000000000EFE0F0E07B +:10544000ECE5F2F0FB000000E8F2EEE3E020F7E527 +:10545000EAE00000EFE5F0E5EFEEEBEDE5ED000052 +:10546000E4EBFF20EFEEE2F2EEF0E000EEEFE5F02D +:10547000E0F6E8FF00000000E8F2EEE320F7E5EADE +:10548000E0000000EEF2F0E5E7F7E8EAE0000000F7 +:10549000EFEEE4E4E5F0E62E00000000EDE5F2209A +:1054A000F1E8E3EDE0EBE000F4EEF0ECE0F220E414 +:1054B000E0F2FB00F1E2FFE7E820F120D4CF0000AA +:1054C000EDE0EBE8F7EDEEF1F2E80000EFEE20EFB3 +:1054D000F0EEE4E0E6E0EC00EFEE20EFEEEAF3EFD2 +:1054E000EAE0EC00EDE0EFF0FFE6E5EDE8FF0000BC +:1054F0004E6574206F736869626B690020202020FC +:10550000CAC0CDC0CB000000C4CB2ED1D72ECAC09C +:10551000CDC0CB00D1EEF1F2EEFFEDE8E5000000EA +:10552000CDE0E7E2E0EDE8E500000000D3F1F2F0C5 +:10553000EEE9F1F2E2EE0000CAF3EFFEF0EEEFF07A +:105540002DEA0000CEEFEEE22EEEE120EEF82E0086 +:10555000CEF72EE6F3F0EDE0EBFB0000CCEEEDE550 +:10556000F2EEEFF02DEA0000D0F3E12E2FE8ECEFA1 +:105570002E000000C2F02EF0E0E1EEF2FB00000091 +:10558000546D61782CECE8ED2E000000546D696ECE +:105590002CECE8ED2E000000C2FBF5EEE4EDFBE59F +:1055A0003A000000CEF2EBEEE62EF1F2E0F0F2006F +:1055B000D6E5EDE02CF0F3E12E000000D6E5EDE0BD +:1055C0002CF0F3E12E000000CDE0F7E0EBEE2CF73D +:1055D00000000000CDE0F7E0EBEE2CF7000000004B +:1055E000C7E0EFE8F1FC202300000000C7E0EFE88F +:1055F000F1FC202300000000C4E5EDFCE3E82CF002 +:10560000F3E12E00C7E0EAF02EF1ECE5EDFB00003F +:10561000EAEEEB2DE2EE2AF6E5EDE0002020CFC029 +:10562000D0CECB620000000020202020CFC0D0CE02 +:10563000CB620000202020CFC0D0CECB6200000083 +:10564000CEF2EFF02EF2E5F1F2000000C2F1E5E358 +:10565000EE20EAF3EFFEF000494420F3F1F22DE2F0 +:10566000E0000000C2ED2EEAF3EFFEF0E0200000C3 +:10567000C2ED2EECEEEDE5F2FB200000CDE0F72EC2 +:10568000F1E5E0EDF1E02000CAEEED2EF1E5E0ED10 +:10569000F1E02000C2EAEBFEF7E5EDE8E5000000EE +:1056A000CFE5F7E0F2FC20F7E5EAE000C8EDEAE03C +:1056B000F1F1E0F6E8FF00006B616E616C2025649B +:1056C000200000006E617374726F696B61000000EE +:1056D000253032643A2530326400000000010304B2 +:1056E0000607090A0C0D0F10EAE0EDE0EB20256437 +:1056F00000000000EDE0F1F2F0EEE9EAE000000069 +:105700000000000038390100000000000000000027 +:10571000404F01000000000000000000504F010059 +:1057200000000000000000004C39010000000000F3 +:1057300060390100000000000401000000000000CA +:1057400074390100000000000000000088390100E9 +:1057500000000000000000009C3901000000000073 +:10576000000000007454004000000000B039010047 +:10577000000000000401000000000000A965010015 +:105780000000000000000000604F01000000000069 +:1057900000000000704F0100000000000000000049 +:1057A000AA65010000000000C439010000000000EB +:1057B00004010000CDE0F1F2F0EEE9EAE8000000BB +:1057C000D1F2E0F2E8F1F2E8EAE0000000010000C6 +:1057D000D83901000000000001000000B4570100AA +:1057E0000C5A010001000000C05701005C58010084 +:1057F00001000000746401005C5E01000100000013 +:105800007C640100985E0100B423010000000000E8 +:1058100005000000CFEE20EAE0EDE0EBE0EC000058 +:1058200000010000804F01000000000001000000A6 +:105830001458010078600100010000008464010038 +:105840004860010001000000904F01003459010040 +:1058500001000000EC3901008C580100CC2301004C +:10586000000000000500000000010000A04F010042 +:105870000000000000010000003A010000000000EC +:10588000020000007C18010000000000B04F010081 +:105890001D8200000300000000010000C04F010055 +:1058A0000000000000010000143A010000000000A8 +:1058B000020000007C18010000000000D04F010031 +:1058C0001D8200000300000002030000EC0B010039 +:1058D00000000000020000007C1501000000000034 +:1058E00002000000AC1501000000000002000000F2 +:1058F000DC15010000000000283A01000000000053 +:105900000401000002030000DC1801000000000098 +:10591000020000000C19010000000000020000005D +:105920003C19010000000000020000006C19010099 +:10593000000000003C3A0100258200000401000044 +:1059400000010000503A01000000000002000000C9 +:105950005C14010000000000020000008C14010033 +:105960000000000002000000BC1401000000000064 +:10597000643A010000000000040100000001000082 +:10598000783A01000000000002000000EC14010061 +:1059900000000000020000001C15010000000000D3 +:1059A000020000004C150100000000008C3A0100CC +:1059B000000000000401000000010000E04F0100B1 +:1059C00000000000010000008C6401009C5A0100EE +:1059D00001000000F04F0100345C010001000000F4 +:1059E000A03A0100145B010001000000B43A01007C +:1059F000186001000100000000500100745B01000C +:105A000002000000DC0C010000000000681E010024 +:105A1000000000000700000002030000BC0B0100B2 +:105A200000000000020000007C0C010000000000EB +:105A300002000000AC0C01000000000002000000A9 +:105A40004C0F010000000000020000007C0F01006C +:105A50000000000002000000DC0F01000000000058 +:105A600002000000AC0F0100000000000200000076 +:105A70000C10010000000000020000003C100100BA +:105A80000000000001000000204F0100E45A010066 +:105A900001000000304F0100EC5B01005C1A0100C6 +:105AA0002D8200000B000000020300009C1001008A +:105AB00000000000020000008C1101000000000046 +:105AC00002000000BC110100000000000200000004 +:105AD000FC10010000000000020000005C11010049 +:105AE00000000000E42301004982000005000000DE +:105AF00000010000C83A01000000000002000000A0 +:105B0000EC17010000000000010000002439010032 +:105B1000445B0100105001005D82000003000000A2 +:105B20000001000020500100000000000200000001 +:105B30004C18010000000000205B01002C5B0100FC +:105B400000000000385B01005D82000003000000DF +:105B500000010000305001000000000000010000C2 +:105B6000DC3A010000000000020000001C180100E7 +:105B700000000000405001006582000003000000AA +:105B80000001000050500100000000000200000071 +:105B90008C17010000000000805B01008C5B01009D +:105BA00000000000985B01000000000002000000FF +:105BB000020300006C100100000000000200000061 +:105BC000EC11010000000000020000001C120100A6 +:105BD0000000000002000000CC10010000000000E6 +:105BE000020000002C11010000000000FC23010055 +:105BF0004982000005000000000100006050010023 +:105C0000000000000100000030650100885C010018 +:105C1000020000000C0D0100000000000100000067 +:105C200070500100B85C01000100000094640100A4 +:105C3000185D0100142401000000000005000000B0 +:105C40000001000080500100000000000200000080 +:105C5000BC0E010000000000020000009C160100C4 +:105C60000000000002000000CC160100000000004F +:105C700002000000FC16010000000000020000000D +:105C8000EC0E010000000000781F01000000000081 +:105C90000600000000010000F03A010000000000D2 +:105CA000020000005C0E0100000000000200000085 +:105CB0008C0E010000000000905001000000000068 +:105CC0000300000000010000043B01000000000090 +:105CD000020000003C0D0100000000000200000076 +:105CE0009C0D010000000000020000002C0E0100CD +:105CF0000000000002000000CC0D010000000000C8 +:105D0000020000009C1901000000000002000000D9 +:105D1000AC18010000000000881E01000000000017 +:105D20000700000000010000B45400400000000023 +:105D300000010000CC540040000000000001000001 +:105D4000E45400400000000000010000FC5400404A +:105D500000000000183B01002D0C000004010000B1 +:105D600000000000A0500100000000000000000042 +:105D70002C3B01000000000000000000AB650100AA +:105D800000000000403B0100000000000401000092 +:105D900000000000543B0100000000000000000073 +:105DA000B05001000000000000000000C0500100E1 +:105DB0000000000000000000D050010000000000C2 +:105DC000683B01000000000004010000000000002A +:105DD000E05001000000000000000000F050010051 +:105DE0000000000000000000AC65010000000000A1 +:105DF0007C3B0100000000000401000000000000E6 +:105E000000510100000000000000000010510100DE +:105E10000000000000000000AD650100000000006F +:105E2000903B0100000000000401000000010000A0 +:105E3000A43B01000000000001000000205101000F +:105E4000AC5F01000100000030510100E85F01007B +:105E500001000000B83B0100BC580100CC3B010030 +:105E6000000000000400000000010000405101009B +:105E700000000000010000009C640100D45E0100ED +:105E800001000000A4640100105F01000100000097 +:105E9000E03B0100405F0100F43B01000183000092 +:105EA000040000000001000050510100000000004B +:105EB00000000000083C010000000000000000009D +:105EC0001C3C01000000000000000000303C01000C +:105ED00000000000443C0100298300000401000090 +:105EE00000010000605101000000000000000000FF +:105EF000583C010000000000000000006C3C010064 +:105F00000000000000000000303C01000000000024 +:105F1000803C010029830000040100000001000012 +:105F2000943C01000000000000000000A83C0100BB +:105F30000000000000000000BC3C01000000000068 +:105F4000D03C010029830000040100000001000092 +:105F5000AE6501000000000000000000705101006B +:105F60000000000000000000E43C01000000000010 +:105F70008051010000000000030100000203000046 +:105F8000AC1201000000000002000000DC12010061 +:105F900000000000020000000C13010000000000DF +:105FA000020000006C13010000000000F83C01003A +:105FB0003B83000004010000020300009C13010069 +:105FC0000000000002000000CC13010000000000EF +:105FD0000000000014550040000000000000000018 +:105FE0002C550040000000000C3D01001185000010 +:105FF0000401000000010000203D0100000000003D +:10600000020000002C14010000000000F45F0100F9 +:1060100000600100000000000C60010000000000B2 +:106020000200000000010000343D010000000000FB +:1060300001000000483D010070590100010000000E +:106040005C3D0100AC5901009051010000000000CE +:106050000300000000010000703D0100000000008E +:1060600001000000483D0100F85801000100000057 +:106070005C3D0100B4600100A0510100000000007F +:1060800003000000020300001C0C010000000000DF +:10609000020000000C1601000000000002000000D9 +:1060A0003C16010000000000020000006C16010018 +:1060B00000000000843D0100000000000401000019 +:1060C0005B72656365697665725D3D005B61705FFB +:1060D000646E735D3D0000005B61705F69705D3DE3 +:1060E000000000005B61705F757365725D3D0000CC +:1060F0005B61705F61706E5D3D00000041542B4339 +:1061000050494E3F0D0A000041545E534953433DF0 +:10611000300D0A0041545E5349534F3D300D0A0083 +:106120007C20253764207C20000000007C20253165 +:1061300036642020000000007C20253132642020BD +:106140007C20000002000630000000000200063340 +:1061500000000000020006350000000002000641B9 +:1061600000000000CAC0CD2E25642000CED8C8C1D2 +:10617000CAC00000CDC0C6CCC8D2C50025302E3361 +:1061800066000000EEF8E8E1EAE00000EEE1ECE095 +:10619000EDE00000EEEFF2E8EAE80000E4E0F2F7FC +:1061A000E8EAE000ECEEE4E5ECE00000D4CF2031DA +:1061B00000000000D4CF203200000000EDE52042B6 +:1061C00043440000F1ECE5EDFB000000E220D4CFF9 +:1061D00000000000F120D4CF00000000EFE8F2E062 +:1061E000EDE8FF00EBE5EDF2FB000000E4E0F2E09B +:1061F00000000000F7E5EAE000000000EFEEEBE54C +:10620000E9000000F120DDCACBC70000DDCACBC722 +:1062100000000000D0F3F72E00000000C0E2F2EE14 +:1062200000000000C1F3F4E5F000000000000000F1 +:10623000090000000000000001000000E2FBEAEBA2 +:106240002E000000E2EAEB2E00000000000000003B +:1062500002000000D1EEEBFFF0E8E90000000000D2 +:1062600001000000CAEDEEEFEAE00000D1D2C0D09C +:10627000D2000000CFD3D1CA00000000000000000F +:1062800001000000E2FBEAEB2E000000E2EAEB2E48 +:10629000000000000000000001000000CCEEE4E57A +:1062A000EC0000000000000001000000D1F2E0F26C +:1062B000F3F10000000000009F05000054EEF2EF33 +:1062C000F02E0000000000000100000001000000AE +:1062D0000F27000000000000010000000000000087 +:1062E0000100000000000000FFFFFFFF00000000B1 +:1062F000E703000000000000630000000100000050 +:10630000E703000001000000E703000000000000B8 +:1063100004000000EFF22DE2F1000000F1E12DE2B7 +:10632000F1000000EFF22DF1E1000000EFF22DEF9F +:10633000ED0000000000000001000000000000006F +:10634000FFFFFFFF010000000F2700000100000019 +:106350000F27000001000000E7030000010000001B +:10636000E70300000000000018000000000000002B +:1063700018000000CAEEEDE5F62CF7000000000062 +:10638000180000000000000018000000CAEEEDE553 +:10639000F62CF70000000000010000005A2DEEF27C +:1063A000F7E5F200EFE5F7E0F2FC0000582DEEF221 +:1063B000F7E5F20000000000FFFFFFFF0000000013 +:1063C000A900000000000000FFFFFFFFC7E0EFF39F +:1063D000F1EAE800C2F02EF0E0E12E00000000003B +:1063E000020000000000000001000000D7E5EA3ACA +:1063F00000000000F1F3ECECE00000000000000001 +:1064000000000000000000000F2700000000000056 +:10641000FFE0F505CFC0D0CECB6200000000000049 +:1064200017000000CAEEEB2DE2EE000000000000B5 +:106430000F2700002564207275622E007261626F62 +:10644000746100002575207275622E00EAE0ED2E61 +:1064500025640000256420F0F3E12E00F0E0E1EE79 +:10646000F2E00000257520F0F3E12E00EFF3F1F2E9 +:10647000EE000000C6F3F0EDE0EBFB00CEF2F7E536 +:10648000F2FB0000CEE1F9E0FF000000CAE0EDE021 +:10649000EBFB0000CCEEE4E5EC000000582DEEF242 +:1064A000F7E5F2005A2DEEF2F7E5F20041540D0A3D +:1064B000000000004F4B0D0A000000004552524FF3 +:1064C000520D0A0020207C20200000003130000006 +:1064D000CEEA0000EDE5F200D4CF0000313100003B +:1064E000313200003133000031340000313500001A +:1064F00031360000313700003138000031390000FA +:1065000032300000323100003232000032330000FD +:1065100032340000D4D00000EDE5F200E4E00000E9 +:10652000EDE5F200EDE5F200E4E00000EDE5F2005B +:10653000D4D00000785634120EF0B0E101000A0009 +:10654000000001001000A00001000C001400020077 +:10655000050000001F0001000100050000001400FC +:1065600064000100040001000400180004000100A0 +:106570000400010001000100800001001100000082 +:10658000000080000100010020004800E803010035 +:106590001D0101001000000008000A002400400254 +:1065A00008004000B40B00000000000000000000E4 +:1065B000D4640100C03F0100D03F0100402C010025 +:1065C000542C0100682C01007C2C0100902C01004F +:1065D000A42C0100B82C0100CC2C0100E02C0100FF +:1065E000E03F0100F03F0100F42C010000400100F9 +:1065F0001040010020400100E42001003040010073 +:10660000082D0100404001005040010060400100A1 +:106610001C2D01008461010084610100302D010006 +:10662000442D0100582D01006C2D01003453010050 +:10663000802D0100942D0100704001008040010078 +:10664000FC20010014210100A82D0100BC2D010037 +:10665000D02D01004053010090400100A0400100F6 +:106660002C210100E42D0100F82D01000C2E010069 +:10667000202E01004C530100342E0100482E010051 +:106680005C2E0100702E010044210100842E0100C7 +:10669000B040010058530100982E0100AC2E0100BB +:1066A000C02E0100D42E0100C0400100E82E0100E0 +:1066B000FC2E0100102F0100D0400100242F01000A +:1066C000382F01004C2F0100602F0100742F0100B2 +:1066D000882F01009C2F0100E0400100B02F010035 +:1066E000C42F0100D82F0100EC2F01000030010061 +:1066F00014300100F0400100004101005C21010064 +:10670000283001003C3001005030010064300100AD +:1067100078300100104101002041010030410100AA +:10672000404101008C3001005041010060410100F6 +:10673000A030010070410100B4300100C8300100F8 +:10674000DC300100F030010074210100043101004F +:10675000183101002C310100403101005431010099 +:1067600080410100683101007C310100903101005D +:10677000A4310100B8310100CC3101009041010089 +:10678000E0310100F431010008320100A0410100B4 +:10679000B0410100C04101001C3201003032010053 +:1067A000D0410100E041010044320100F04101000C +:1067B0000042010058320100104201002042010055 +:1067C00030420100404201006C3201008032010081 +:1067D00094320100A8320100BC320100D032010025 +:1067E000E4320100F8320100504201008C21010026 +:1067F0000C330100604201002033010070420100AF +:1068000034330100A421010080420100483301001B +:1068100064530100904201005C33010070330100B9 +:1068200084330100A042010070530100B042010016 +:10683000C042010098330100D0420100E042010053 +:10684000F04201000043010010430100AC3301009D +:10685000C0330100D4330100D4640100E8330100E7 +:10686000204301007C5301003043010040430100FC +:10687000FC33010050430100103401008853010033 +:106880002434010094530100A0530100AC530100D3 +:1068900060430100B85301008C61010038340100ED +:1068A0004C3401004C34010070430100AC53010032 +:1068B00094610100C45301009C610100A4610100C6 +:1068C000D053010060340100AC610100B4610100EB +:1068D000804301007434010090430100A043010093 +:1068E000DC530100B0430100BC610100E85301002A +:1068F000F4530100883401009C340100005401006D +:106900000C54010018540100C4610100C46101006D +:10691000CC610100A6650100C0430100D043010025 +:10692000B0340100C4340100D8340100A665010070 +:10693000A665010024540100E04301002454010035 +:10694000EC34010000350100305401003C540100DA +:10695000F0430100A6650100004401001435010068 +:10696000283501003C350100503501006435010037 +:10697000783501008C350100A0350100B4350100E7 +:10698000C8350100DC350100BC210100485401007C +:10699000F03501005454010004360100183601009E +:1069A0002C360100A66501001044010040360100AC +:1069B000D4210100EC2101000422010060540100F7 +:1069C00054360100683601007C3601009036010023 +:1069D00020440100304401006C540100785401004F +:1069E0004044010050440100A4360100B8360100C3 +:1069F000A66501006044010060440100D46101000B +:106A0000CC360100CC360100DC610100E4610100FC +:106A1000E46101007044010070440100E0360100AF +:106A2000D864010084540100905401009054010086 +:106A3000A6650100DC610100804401009C54010056 +:106A4000A6650100A665010090440100A044010074 +:106A5000EC610100A85401001C2201003422010055 +:106A6000B4540100B4540100B4540100B454010002 +:106A7000C0540100CC540100D8540100F436010088 +:106A80004C220100083701001C370100303701009B +:106A9000B044010044370100F4610100C04401002A +:106AA000583701006C370100FC610100803701009C +:106AB0006422010004620100AC5301007C22010049 +:106AC000D0440100A6650100E044010094370100B4 +:106AD0000054010094220100AC2201000C6201006C +:106AE000A8370100BC370100D0370100F044010095 +:106AF00000450100E4540100E437010010450100A5 +:106B0000F0540100A81B01000C1B0100081D01002E +:106B1000CC1B0100281D0100481D0100681D01005B +:106B2000081F0100881D0100C4220100F837010080 +:106B30000C380100DC220100204501003045010035 +:106B4000241F0100A81D0100F4220100C81D01003E +:106B50000C380100404501000C23010024230100F2 +:106B6000341B0100401F0100203801005045010086 +:106B7000604501007045010080450100904501001D +:106B8000A0450100B0450100C0450100D04501000D +:106B9000E0450100F04501000046010010460100FB +:106BA00020460100304601004046010050460100E9 +:106BB00060460100704601008046010090460100D9 +:106BC000A0460100B0460100C0460100D0460100C9 +:106BD000E0460100F04601000047010010470100B7 +:106BE00020470100304701004047010050470100A5 +:106BF0006047010070470100804701009047010095 +:106C0000A0470100B0470100C0470100D047010084 +:106C1000E0470100F0470100004801001048010072 +:106C20002048010030480100404801005048010060 +:106C30006048010070480100804801009048010050 +:106C4000A0480100B0480100C0480100D048010040 +:106C5000E0480100F048010000490100104901002E +:106C6000204901003049010040490100504901001C +:106C7000604901007049010080490100904901000C +:106C8000A0490100B0490100C0490100D0490100FC +:106C9000E0490100F0490100004A0100104A0100EA +:106CA000204A0100304A0100404A0100504A0100D8 +:106CB000604A0100704A0100804A0100904A0100C8 +:106CC000A04A0100B04A0100C04A0100D04A0100B8 +:106CD000E04A0100F04A0100004B0100104B0100A6 +:106CE000204B0100304B0100404B0100504B010094 +:106CF000604B0100704B0100804B0100904B010084 +:106D0000A04B0100B04B0100C04B0100D04B010073 +:106D1000E04B0100F04B0100004C0100104C010061 +:106D2000204C0100304C0100404C0100504C01004F +:106D3000604C0100704C0100804C0100904C01003F +:106D4000A04C0100B04C0100C04C0100D04C01002F +:106D5000E04C0100F04C0100004D0100104D01001D +:106D6000204D0100304D0100404D0100504D01000B +:106D7000604D0100704D0100804D0100904D0100FB +:106D8000A04D0100B04D0100C04D0100D04D0100EB +:106D9000E04D0100F04D0100004E0100104E0100D9 +:106DA000E81D01000000000000260100142601007B +:106DB000282601003C26010050260100642601001F +:106DC000782601008C260100A0260100B4260100CF +:106DD000C8260100DC260100F0260100042701007E +:106DE000182701002C27010040270100542701002B +:106DF000682701007C27010090270100A4270100DB +:106E0000B8270100CC270100E0270100F42701008A +:106E1000082801001C280100302801004428010036 +:106E2000582801006C2801008028010094280100E6 +:106E3000A8280100BC280100D0280100E428010096 +:106E4000F82801000C2901000000000020290100A1 +:106E500034290100482901005C2901007029010042 +:106E60008429010098290100AC290100C0290100F2 +:106E7000D4290100E8290100FC290100102A0100A1 +:106E8000242A0100382A01004C2A0100602A01004E +:106E9000742A0100882A01009C2A0100B02A0100FE +:106EA000C42A0100D82A0100EC2A0100002B0100AD +:106EB000142B0100282B01003C2B0100502B01005A +:106EC000642B0100782B01008C2B0100A02B01000A +:106ED000B42B0100C82B0100DC2B0100F02B0100BA +:106EE000042C0100182C01002C2C010000000000D3 +:106EF000A6A1000062C4000092D00000CEE4000011 +:106F000036F3000086F4000066FA0000060A01006D +:106F1000E61A0100CC640100DC640100E0640100B9 +:106F2000E4640100E8640100EC640100F064010025 +:106F3000F4640100F8640100FC64010000650100D4 +:106F400004650100086501000C6501001065010081 +:106F5000A6A1000062C4000092D00000CEE40000B0 +:106F600036F3000086F4000066FA0000060A01000D +:106F7000E61A0100CC6401002065010014630100E1 +:106F80001C630100246301002C6301000000000069 +:106F9000E2200100546201002C550100D064010080 +:106FA0001C530100285301002465010028650100DD +:106FB00000000000146201001C6201002462010054 +:106FC0003C620100446201006C62010074620100D5 +:106FD000846201008C620100846201008C62010005 +:106FE000846201008C620100846201008C620100F5 +:106FF000846201008C620100186501001C650100BB +:107000002C650100A463010010560100F463010027 +:10701000FFFFFFFFFFFFFFFF14000000204E0100F5 +:0870200018000000010000004F +:04000005000108806E +:00000001FF diff --git a/Flash/Exe/solarium.out b/Flash/Exe/solarium.out new file mode 100644 index 0000000000000000000000000000000000000000..8ba0e494efda35c6d9e5a14055ba4ac16ba795b5 GIT binary patch literal 974341 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 EA5@ndWdHyG literal 0 HcmV?d00001 diff --git a/Flash/Obj/CCRSProtocol.pbi b/Flash/Obj/CCRSProtocol.pbi new file mode 100644 index 0000000..8177de8 --- /dev/null +++ b/Flash/Obj/CCRSProtocol.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 00s +C:\work\solarium\DRIVERS\ccnet\CCRSProtocol.c +C:\work\solarium\DRIVERS\ccnet\CCRSProtocol.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/app.o b/Flash/Obj/app.o new file mode 100644 index 0000000000000000000000000000000000000000..01f77bb449bab5d023e108847178910ea76453a8 GIT binary patch literal 8916 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/app_serv.pbi b/Flash/Obj/app_serv.pbi new file mode 100644 index 0000000..1764f26 --- /dev/null +++ b/Flash/Obj/app_serv.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 15s +C:\work\solarium\PROJECT\app\app_serv.c +C:\work\solarium\PROJECT\app\app_serv.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/bsp.o b/Flash/Obj/bsp.o new file mode 100644 index 0000000000000000000000000000000000000000..d1940455086dd7821add046e7e4da2712322c801 GIT binary patch literal 135044 zcmeEv2Yi>+_4j?A-!CD9kwAhhLs$wbnEVnTC@3Kb5M{(9I4U-T5Fi?on4#dPIBVTo z9Bm!AN7YK*qpoVz)=^h$>t1zKYwNDO-*fK0&vWh*K;R9@|9$^`^2zT!-+Ruz=iGbF z9nU_dY|c#2^OW5@HCBa4sp?Z1B^9b%h>TV9V!#vHmbbOHw%0Dk-l`Rv8eG@BVnuyZ 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

!4QZ4JkN)n}iLD}$Uf86(`!wT3 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 laNc~XQAVDbfPh_-~VlyA;ACu literal 0 HcmV?d00001 diff --git a/Flash/Obj/data.o b/Flash/Obj/data.o new file mode 100644 index 0000000000000000000000000000000000000000..4633c894e4e15455139c6d4e90a89617b342dd92 GIT binary patch literal 35548 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 Le)TX=9O3OBg28F9 literal 0 HcmV?d00001 diff --git a/Flash/Obj/datadesc.pbi b/Flash/Obj/datadesc.pbi new file mode 100644 index 0000000..6555722 --- /dev/null +++ b/Flash/Obj/datadesc.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 19s +C:\work\solarium\PROJECT\data\datadesc.c +C:\work\solarium\PROJECT\data\datadesc.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/fiscal.o b/Flash/Obj/fiscal.o new file mode 100644 index 0000000000000000000000000000000000000000..48041186e4633692a0bc62a678202c3a152be25b GIT binary patch literal 83868 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 WU}9&1V_z}kP5_VEyIwUw_WeItlg2Or literal 0 HcmV?d00001 diff --git a/Flash/Obj/fiscal.pbi b/Flash/Obj/fiscal.pbi new file mode 100644 index 0000000..8afa3ca --- /dev/null +++ b/Flash/Obj/fiscal.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 02s +C:\work\solarium\DRIVERS\fiscal\fiscal.c +C:\work\solarium\DRIVERS\fiscal\fiscal.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/fr.o b/Flash/Obj/fr.o new file mode 100644 index 0000000000000000000000000000000000000000..7bb1a3495b4d0a915e680e3a14708a163a07abb0 GIT binary patch literal 50320 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/fr.pbi b/Flash/Obj/fr.pbi new file mode 100644 index 0000000..4b41f4c --- /dev/null +++ b/Flash/Obj/fr.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 32s +C:\work\solarium\PROJECT\service\fr.c +C:\work\solarium\PROJECT\service\fr.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/fram.o b/Flash/Obj/fram.o new file mode 100644 index 0000000000000000000000000000000000000000..5cc8a939ee67aa00c050198078ad8bd17182e1a9 GIT binary patch literal 21692 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/fram.pbi b/Flash/Obj/fram.pbi new file mode 100644 index 0000000..c49fb5d --- /dev/null +++ b/Flash/Obj/fram.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 04s +C:\work\solarium\DRIVERS\fram\fram.c +C:\work\solarium\DRIVERS\fram\fram.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/journal.o b/Flash/Obj/journal.o new file mode 100644 index 0000000000000000000000000000000000000000..1c2b5a8543437019829f08dc28fee3f9e746f1d7 GIT binary patch literal 60292 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/journal.pbi b/Flash/Obj/journal.pbi new file mode 100644 index 0000000..77071f1 --- /dev/null +++ b/Flash/Obj/journal.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 17s +C:\work\solarium\PROJECT\app\journal.c +C:\work\solarium\PROJECT\app\journal.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/keyboard.o b/Flash/Obj/keyboard.o new file mode 100644 index 0000000000000000000000000000000000000000..43bbb92d6b60dd27b5b8786ee214c923eadad7a1 GIT binary patch literal 42996 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/keyboard.pbi b/Flash/Obj/keyboard.pbi new file mode 100644 index 0000000..eae0a4c --- /dev/null +++ b/Flash/Obj/keyboard.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 05s +C:\work\solarium\DRIVERS\keyboard\keyboard.c +C:\work\solarium\DRIVERS\keyboard\keyboard.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/lcd.o b/Flash/Obj/lcd.o new file mode 100644 index 0000000000000000000000000000000000000000..fea3551898ba1762e909a623e63ae8ac4334d982 GIT binary patch literal 45164 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

k*%<$FvJ^$n}t1k2o^*=c0eI z1Na?#l0n69>}tNq_u=o%6A$|7#VwL_Pajegiqye!=JCkg$}2tG&>{=6XaUq${#Ch{&w@{|5nJo&SYB=*}b^4n7XAYtfvMC3jxr@t9b`yC{S z{SJ%#SE=W}?~Qh_gx@UD9+qei{e5q`zK-Bn%?=|TMHZ8Uz8NCVCK*wxTx6A$Um&s$ zlG;&E7lCy^Vad=p{Vqrdr1@^e!D1;WsOFG=YCvf%qg zJ|uE4Bmgt|?s2=BsHz2c%mHH#eiAw#a;J=D= z(f8Rn=rc%y7ZI69ax!jn3LZ~#3gVF@^w8gWCp<&s*(9OoT*2ic>Fpomx`=iZ&nxv)k@%4UwpSoBDzZW({cZEebI8LavENOCHr<$ZrTmbUGftkesOJSM&fMRs6@95n@Uqk07*^ zLS6tB$wkix=_dtvK7!*IhYA}7m5qYRMnPqx(@0YMlZ4UfBw=(0NyPV=Bw?(CB#fO! zvROa7q%XmqL%3Z(tE5R=8R0d^XC%9nI*(+J{^bIi#LXhyPb=?I?S%>CV2cg~vk>oQ zD)cSX&pc*Qz7w3gkUwZ&ggr0R$JC#;zB&}X$%CXhW=;KOo2ff>)bD9}aPkzC$oj!9idt!{!pkj*q0t^Y;ts+k}1ni=VftEVWVE?$aEz);i{nWoh zfr&+`I||-nKM8mnK1i#HrQ$N3V_lSRPK2a*e*hm_UmbYeDDyA=<98=`6yyHI-;OD8 z?x3Fp>~F_w;5DY;Z9|#ejtg<%Qy!ysMDd{|RXZBMdstU{*8X2l z1<&7(=oRU;qYpgO4nC(qcdB-50PpK5?E2d=vq9e@@KgQm*b3fGKMC01j)p5SXG_7` zhBA9Rwt;8b!RI{Gr)tMe@a|5b&)<&vrTX57pXzVN4)FH-Nx=Sg^kMFjPCNF4XWDVT z=uOp*L*S*;j*iCk+HnxP18KBl%T?*M<2CS1J7}&zOR9Ff4c=Z|?O9g>+4*44^7M|6 znJaM3>CvQte>`3T4^1AmY(t41R~KT?OgrWYJ5@Ux!28}PZ3@4v>1{_A=BgW0@ceOg zJ9s-&@ciw#@S61U?ndxTJ1!QzsoJp_ypa@k{q5L{iAp+om*(7CQt0!yV+(lcjK@*% zOgnIj9u1Uc%~h6EkR4F zcI*T%opwZ9(rd>C@Sf4;JZt}WG_i=ba$4o+I>^h+0b>F7I>CU0eTdhOkiCU3_vcrT*OcKjU%@2wR5@_&51 zgSb~$VecsW{29{DFOGRut)3RG+@%-(bGLT+B*MVpH`3sglzum>)nSL&`cz(NmY1-Xv z+5MuW&u@3DWp|>*^V{8@rro2K-EEdWzun(~w+Z!h{7$oYe!IhiN=2pK7XJLa1w7Nw zU$ON0?QR3_TGW$WbDYqAe!Fj_X}5SNY4`r)*o}f`?3P(PzujT*C=UFKzrEWmyI&VF zwZq@u?cgCrb9>7zp5Jcq+VuLl7Ch6>J1l*EyLI3hyR$8x-|kNE(rNEu%kFn9eSW(~ z!0SLgjc={R^V?ng;pF%WjfKCTyTCK;ebCb9w>t=)8DE;K(?a|C?LL#H-QQVuce6IF z&u{lF@TmW&y^}1S-)?l6AIAzKDg5od5Iob~J(fPd-FomAqn_+uYVrJbZwD_b^|tWa z-C^1NzNOD^cNciqqMqztX7T)XbJnFdz7^n^_Wsb)=eJu69!#^{28-vnyA!;q)Z4<} z-h-CiM=gDRyNAK+Ks~khDvRg0TX$1>c2|LC+PmM<=eOGdo@wtj7SC_@NSb!l`lQ__ zEq#8wS>PGFxOK-1`Rlj40lZSFw}ro-w_A3f79#2M+uaG?Vw6)qufm6xRCeD2FUqyv zmEUeLZl2Qqr0-dwrm`Ca&)7Bh2U6MX0MDGSY|DPTw_A1(9>?xx%Pua3c}ZpWMes_c z-WGnl!H*={`M^-HG3o8@?~w@NI1Q!U;_KHg05Xg*B(&ailXeHU8# z&a`-bef8iO|7KV`zrH3*pXncJuU}uArSF{M=)2j{H_PJr^=-8D&9r!a|F&BCsw|#g z-+h+8N{i>$x7X4)*W&s0?FTQ4dK!-!i|5z(vZe1ri|5z(nx*f37SFFQ=cCE^n{V;_ z`ij7-Kt1_aXYu^{>MebXES_Iq19&E0%zZYB1HZmDOP{$8vk^6zqdXi25- zc1vHQrZLa&-)74{JR0RCmA)O8zN;;sU*9gvzm*ox-`+!(zUwTWU*C(Cz7JSDzrMFE zeR$NsORD}0;^vGQj}KWqzrHEp(f-uWZ5Ge(Ux}r!)#CZ}U1;gUElplh`B!i0>#%tE y8E()0rY7*VKmqw@?rV|0>%qhS#Pa5+@a}U0B{w>K`bsw8yoNH;_a~u|zW)LSX&Hq8 literal 0 HcmV?d00001 diff --git a/Flash/Obj/lcd.pbi b/Flash/Obj/lcd.pbi new file mode 100644 index 0000000..8a29026 --- /dev/null +++ b/Flash/Obj/lcd.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 06s +C:\work\solarium\DRIVERS\lcd\lcd.c +C:\work\solarium\DRIVERS\lcd\lcd.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/lib_mem.o b/Flash/Obj/lib_mem.o new file mode 100644 index 0000000000000000000000000000000000000000..01fef25a2d58a94950a75ac6b4838bd32c8ef11e GIT binary patch literal 12972 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/lib_mem.pbi b/Flash/Obj/lib_mem.pbi new file mode 100644 index 0000000..f36d768 --- /dev/null +++ b/Flash/Obj/lib_mem.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 11s +C:\work\solarium\OS\uc\lib\lib_mem.c +C:\work\solarium\OS\uc\lib\lib_mem.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/lib_str.o b/Flash/Obj/lib_str.o new file mode 100644 index 0000000000000000000000000000000000000000..03407a6869aba78187911388bed6cb30b55eb2f2 GIT binary patch literal 26112 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/lib_str.pbi b/Flash/Obj/lib_str.pbi new file mode 100644 index 0000000..e29de77 --- /dev/null +++ b/Flash/Obj/lib_str.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 12s +C:\work\solarium\OS\uc\lib\lib_str.c +C:\work\solarium\OS\uc\lib\lib_str.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/menu.o b/Flash/Obj/menu.o new file mode 100644 index 0000000000000000000000000000000000000000..ffc9f767c8fec55996838e6d223f74760365273e GIT binary patch literal 68204 zcmd_T3w#vS**|_}c4xEMWJ5v{2oPX_1j9WEAp`^r5UwI}(^5@MLJ~|QBrz8V2tpMV zEh@ICSgA#&6|cn#)vC2xFQu)o1=PM+ZN*B}SFOcrEw57feV^x?**P;=;?h#y|L5}` z*nQ^voaa23bDx>BlXcVPOg9We*oPtVgoA|0*~ckXk%-_VPqdTl$kw{nwwAW4B{*BP zTvCOro0c!HZEO=G>#JHuwzMs8s;O-dBWr4xv|n7&P~TWj#XRxGWpsH?52scjJz6=ic~O{thSZNZ|M3#Lsj>%^$2Z>)z7 zX=rIn)pA&BscmpG$S2*E$qUXIS=H9oQop3Vtro^rT2r-sTD4?JOYI6>lk{5(Hn%Tn zgdy@eYRTbAndMd0GK(W3i-EA$AL7ZfpcF)Lv6I)uv1`krdY$>j$HxadNjUrX_ymRh zpoYj6a}`czJWwokr4JA*T{t2(Dr~ZRU$NDN`-`0}+)q3PJX|?th{57{;L4yBBK$H= zYc%{e@J0=P3cN|f7Ibaaa1Y=u8a@MftAcxOMn|Ryc)P!!`A_~ zY52Rq9U8t5c#Vc12VSq?UjuK@@b7_lhn@0x5BM<+9|e9=!$B1MF%9>iib!$t4+fr~ z;UeHt4VMAeX!tzfG7Z-P&(v@`@Ei?a1w2o~Hv=!y@DG3&Yj_WExrUzyuGH|W!1;)g z4r&jFfr~W!2{6^6oo@ONpN7+bOEnw;F4OQR;F%hp1RSKskAv);4V`@I_O2|Q85xxkldcr@_s8lDV%rH0Q1zFEWH0Pc$q9b~T!=QA|?Eu2r&@Lf2s z(C}k8zgEL9;rtp6AIABE8vY#TuW2|HW&N^-2Ltcd@C4v-sy@iSSvdbdOFtiYw3c3t z^N%&$hVv&hd@at~HGBuo_h|SLoL8v&AbZaOe^bLR1Gj4UZQyw!S$@?1jsQQR#skX# zPvA2XWjf&`fFO5gN__{+_09An@y&zoUR3Op@hA`lxT*uH`=)_)ZOf9r$BS-^IYMYq%ZwEe%uO zxnI+N6L7AEzYkom;Rk^YExsp!|E~GF7x)8B{&&D1Yxpqmvs(VY0Z-JhfUa+9I0d+u z7GE~7Ps2lj6E$1{JWRvWfxoHYMZis3{8hlqwDcz6OEtU}_%;oH3%Fj(PjmNtt^ND} z_(vN4F>tPie-2!r<`b&Vmw?A=_z%DzqfF@F_5}QvhW`P49zJ%uAG&ijoCaKhK53`- z1>Udb6Vg`zT&v+}z?qn{Z21d-3pCsWJVV19fN#_=_06>!ehBzl4L=J^bF8iZAn@xN z{tNJY%n5e7iL(8tmfjQiR?XjGz~eOeQs7n%p9lPR4POGhN5kuY|El3Fz`xS)y}cMFq+}(rIJvhUIGd;M62lw>gED!GG!M#1Wk2s{2kHGbc8~63#ejeQ4gCib1 zz=H>R@E{M)@!(wXw&tG? zdVunehx~Re|5R808#%w8z7XlV)%->I%U$wYL<8`XT6()H{WkXBzW%2CS0R0en(qkT z;F7o}{pW7h zucwoK`}&viKMHxjn(qlavXp-(=hxFIzkPj7^7~x&^29+GevtFq(b0Xc_gv{iI36c` zi1^%bwU1GiqPZ1R^JXu`o!c)aM7k*e=@4_?0?JhiB zJm|tR#S<ZRScP>0h9CqO! zi@&+>9NcWs%jay--G$E)5f^?$jCA4oVuB0L6LVd7fhc$3-Qp4#K3{aW@Ok1o7yg>q z>cV@(4_){|vD<|&5HGlJxp>8eeUilnM2QREAZEDm)8afA z{-(C27!k?kX z|E%cl!gq=RF1%e7x$s?LstZ3S=DY9@MWqY>K(xB>J>m)%eqL;L;rqq+UHCrnV;6ov zJfmT1+WRz2RejKd-}T^6JorlwPRw-5hxBE6@E{M)_uvu_KFfn=dGKNnUh2V39(=h6 zU*o}BJopX|-s!=6JoqIIQ~AEBVJeSzHB9NBX_$syUk`k#gK)ZrDgQtZF3>Q^mui^g zXL|6t9(=wBe*?G=u1{zQ*&XY#OMw50^L`3FcDi*LHp)5K;MP8D|mTX6mg$dmu~ zsq|9L9~Qe^@+smOV7iA#_w7mk*D9R~BuylX-vL`#Gur;Y1$-RWpLTiu1^8zuza7fn zXTWDc*Kmcu1U?7B{22FqNPkL}jE%0b3HMPL5I9fdDcqZJq8R1ENun5-4p~0ALQEZB zzOt!hS$S(yLsd(C`||R63(lQAZR(Zg+z({WEz)3DnZhm3Sc>414J2Bcl5)(Xlq6beRd{!BrpD(If(okFA z0v=S+3Fo`TD+)SE6nZ5_dl^Mu#uzW7*u(JZ^s4k~^eXh~8|%?u;=$uw*loSgQz(TM z?sT_rqdn4YPm8>%6$S1BF7hZZs&K0>s_-gwhh9|S4!x+t9ePoPJM^LocjzAfJl=Sm z@%U2VcE#g~+Ywh(o-!Nlw(1ICtlPn{9#OZ0u24(dIZNC*OFTKB#bA@o7;G{Q z_FU|o>8!)URVqAOrC}a6xOCRw;VKOtZfp%y5Hp$N}Ed=k0STsjIUa7U6_ zfP<(7IEY$+gQ(d%h?=s4sLw``%Uq$$u|k()g>FfgV}&lq3SEvBx*RKXIacU$tkC6{ z%fM)tW20S;jdnRU+MUnk*l3qyqg{@Tb~!fM<=AMKV=k3NF2{;ojup8aD{?tjg3wo0(S{otSLjo1OjeGO2z#Wv3GE z#H8};#H4cU#H8}<#H4cdGGn>PeY2Bbtn%QV+DS52l-zGSNydtjd$CtCmdaS=7E58Q zQj1k+vC7OYGHQs?X^xzWGVEfBGVBtKGHl zRHB8sQc6TljZDGlp{I-;E!h4fDvuM*c8M*Ifko$!v*j_wxcE`| zu`Yf=el&yI(SrPF4tLZAn1`gR7*=!>1qF5vj4-Z*!e|b+vjrIQl`6Nl1sJ(ig2yW= zPA;cnREbs|1r)DLDE1^ob9f>jW9KOGs2XGEDDgy&3YRvV6LpZaL_=ld z*5a~eulT^SFkJqmo=fQ43UTR9&7zc3Bx4 z^_BBR{h_=iohqorRR$$4yG|PC?PS+!`xH-!%Pv`Rn$WmTcE`EwI(>qC*1Ukv<2u)OnPKFEeU6u>--62P-L1yn{yTIK@3-aC8qn>eg8rj`dRe&{yR?h_m zZtF1T6k0(+XX^z~161S%1#asOqS&$Q_FBi>uUp3iZ`-3{cQvyD%+#H-yRBmlu4i|( zv;vx=Jh5Z(ty_0yE2?y-L2%JwQQaxK+d3B7nssVnTG3&s^k#R)S1vkd?qlmtNl?*I z@Ao)gSzx0WOwE}wvLsv?JmXcZgpciTXzp}1LUhFP; z_wYg;Oe?z16F`A8U$XP=DM0IgRCJx^fCBd%8Iu}25(K4vhvzN5gOk07A01`U~zx5%yu(n#vnOas+ z-B4TABG1}eTANxbnwBng!A3?GH?=kKNppK!bw%y+CABp+Y!&A&r0edfEwxo`wF;CW z8nEk^*OoP`5(^ehomy90y^OF}SY6c!1_G@m3@7UwFJ92zDi+qZtf;T9b&3PmGF%)B z+p1dl3PzSvMMYI@)sp&(`kML`nDrfiJG)W5ymonY^C}&-*0x1qJAADv60Pz!glKJr zPfJB>TT69S8U{L>%|cAYtF~ z;S>9&4g>u*jj%6D1x4)KcVei#kX1qH%bWfy>Z>XiQEB5R@c?yX@|r-wt-*U z2-g}XHq^JZHIT~c=Jtt*YwV)3b7qZL7#TslrQpqNVv98m^-C(Mn;MtaUmO_-@8`8N zU5uaZMW&;eS|fQKCB;L^sSp>+2Q1~&XmF^ht%-aMPiB_XHdfa~ibv*`SG6oJpEY-C zd3AZ&94N%Y7bvWl+tjkWs$pc^z{m*HfcI(6xeLpynwwEBvD22co;a<&x*TzxFe{P~ zR#(YQtrhk4<;_hkZC@?b+SJ}sT^n1jY{9Jar!81m-cViBwZO94RZE(xTE0SxE}Fa6 zQ(fIydjg+rUzXNmz-#DQ4gDze1eWZFY%%M_PCQ}7*#fO{xR33HEku2^Yl#|6m|aV> zH8nM~LSzJPIoGz(^FrC^(T8ekBW-o<%a=q(oJ)PFy|uQYde|^rIZ|)KZwo49qeg>m zscKmzsO5smJz^=Ee?<)j|CajZwx$-5A5FllU4i9D71F8uqXlsy7D5#*wU@Tnx70=| z=JEY+(cZYMv1w)FaClbH+FV;*U)9hGJuXq2FPGwXUwE!+inaL0k9(~UzU2>sPeqTU zA?@Gj*7c3(Y~`KDMNe}(u|TxxpIC&tPv=xMK*UU-(IIAn8X8WNM&rVX(zHRLYY{af zbQZE3Hg%5^r*fk{aWeOc6DQj}3qQ6*gY^!z!g%R#4}a(nb6Q#L(yI1`w$_n#!hC7{ zhL8M*5}1$HP}5%BM(mG{-+9D;q0X(q3JFt6G;t9pE~=wNmDEHAo-(W3RyEhMX2QQT zYg<|xo1%DLeNzSQc(gQe7Pj&|qoICzz4Ycq%Cn%gt){AlEwR(}!1b)+(;e@8=-+Ar zqrOPz)d%-|=zrPgxWfjZI;#5>e zd6y~{Mv5qJx6!e@ts@EtceFJ)rSKbL73SdTWzpn0t6J+<*K*0S*&IxpDkjD=R;|Dw zK;j(0M}9e2gW>zd7jIn|_?FM^EnxYdB~~sv2Y|((5G|{sdMTAz;CV_dLicQF$4C|B z^guJ#C9XHnSCE>(^40ZC4b9bsql-(3^#ZAQI2Us%P>|7H69_}!QsVrQ(yv0jEm53A z=Dg=84i;RHk(_s#gX)QLZZ*jdRvh9?e>U2yxrad{>DQ$AqZEpU+A~B$Rm_*Y8P`Cdg z@w7H9&7%k#TlQfyj{FIR-{`bpv3oanP-XVy7nroYg%7j6v9y%G2V853TGgVx=KwbL+FeipaPr43EE!14P7w;_szUNDq! zCeEzi8VP3;{cj_1GchX(95w=!7$9wdD{z*=GfuZKB#4JyL)}QlrASIm5NQK(-jJFk zx{b62`ipL7;+%f6or--!-PZynr&C^I4kp+|7#@TOd>XUW4BT;=uST%45nuzMuV>ONLB(|{;|MV z#5+{x=ZnRtHf7RKZehtlYkFidC1+Nv9f?n>WVjH+2Pw|jY8cFz)mT$Yrh-&je8FrE zN~ZG#RgD+d;&QT`5mLZ9ZaC0fqqWJ$1!Zef^%0wR-|mR|-1)1wQ|V>^Ea*I>Mm@o@4Gcsln6cp`dC zop)ZvthtNwOU@Gw1M2(Pcy!@H@sKf~v0sl0D)u(9HtSwr-ySrASG0-G5_)8$_BeN8 z#ll5ri?xF<$#SxtC)N&FF4at*hZ}rP8Uvd8^;i^bv`?5LhMEqR_54qBM80Cm%j=tc zBgzy*UOd0$8*wfePQ{)#=iIq7#Ag4no?uhmQwv+z)`GcPJnSE~l!O;et>9MiXdu5E z@cGy&hh1-QYFomvG&Eim20r*{syGXu$@omcXDU9s@Y#z`^B%tliyop-3=t7={2yN) zkBH_cgHLA7ka_X59Z`nQbbP=PGx2#CpWonP=N&2vI_1T_J3;R}q5YK;@yW&Ycy0|o z_U=3IgyHiC5)wnn;cltGOVP9fihsaCXe@Wf(JL{&CHv>dsATdRrFFlmkVdkB; zzixVDfYE$>rhsheKB75+oRkey#_z{@T_m6QS^Mgz&&noDT5N5{XGu*q*0qm42KLGQn$IE(t~e_0a80sQAa+iFT~vU5KFK2=UE3RrL^DiS;6M+ z#O+`oS6|z2;}q-nPMV+7*0UUQvn^pDQt5Ah(o!c@Q=C^#$@0XTvRI6?_B#<-hh*IO zTu#fgYqDQIaoipL0Wmv!j+XVi7nQ8~rZF3UN|E~8F%xdc#0GddnSK^>9DB5wlqAJu1yx&M@+ zkEKQ9ncRC;HuXS`Z+7>N^;vdH$mUur?XdFvtfRCeA+P%h^Bq6?yX8(^Y7NFA`u>>P z`0<$r+5xp~{Yc$|(JLYbrenYPg6!ngeFA+_?w*o-fXdfDXyMf4y0;f+cNoLXec2u6 z@DKKLK&8!>#_1q3)gt;%b z!yNI!{w$?I_RIV|K8#2;*&$e`G7v)y^ry^2sbUJ-LCx%AUn29S_N~iXY_TQ_n*Ops zLsYVi-NVrfQQpD4!Q8@w+=`CR?p_y~$9%@YENVfRR)FMkc9KZ@Z;+ z>mi-QHoSbQcgm&LHJz`)3to~j7r{El7Bg=UM*3W|i@NFg112|9-9J%OlzIY>%6@Q6lHrKWI`q#DTL<-2 z+3I9EdhMQTc9H*7XFLL^Nc{Vc&$ey5V=9Q+&)Dz3S8Dd}ByR<3U7qe#M`n43-IbL#$@?9U_X#fB+KzyCZ^3hH~k5-o-1xC*B4?)wH)|Go=lsUp^| zF-Pos^bpO`=2rYnV*f*j%&q>s{`-FWav<;Qeb&ptyp(+_UQWzgx$lK{pG7S^t4iZ( z8XchHiFcm@_bJ7FLUDJ!`%`d4U7)TRbM)X>+w1C3HxX|0#=Wvvq$nCx)Yw|u&)95i zO}TC36yM9itp=!Z0F+DB&P6uA`R-jO)Nc2=1f?~ssMuPXO>2P!)*jv}SbM@&yUwIf zq)jr z%|ZJD(e{`eJ)`!FN-~4htugssP@(0V0&mtWWr6VD) zPuw~J9vxq>4!b;(qNQL(&nQY>!&TB*5|@Xim50@-JSvr6W?oj*FVc|Mp~sY;H-~4> z{hlOV5tE&o z7-#Z|fl_I1BI?es`(vLU!+@ zIA-r{`ZWz9S^5xi`r9gQ`l`0-Y9pt$Oz0l4wx^04N~$x&Z#tdzL%z5+biGNHl;(JY z_hFrGf3*E%vTTM&TkmQ2#o5dzUFjQj<@B~)swepbfF8aLPthvqw3i9{K@a4(Nboe! zS)819Uuf?jZ5gB|j>D4@HCIk=yLD|Td_`K~r^FlMK(d+zxcCZ~(U6radPn)y?_ z&yDC~c<&o1FA(|L>;R-=z9C-4Lt4WWR!3UH5WLL6paVigUhQj&uxW~GvwgmlpwDmk zuFB5*V<0&HNMdO1!g1F_fhk((`xNduQrm^(<`lKj#Mx3}@J^! zbA!qGfxx9HL&Cn zOy|9S8T8AuZfotc^i@(>9~RCSl4fTN`2)*RhFHmg;Oe(+1y)=77k0+LI@^yF%IY%$ zqwBkpBJq7Ywm-Mp&u+`&&sqqhO>J%x5vfheupA zMDBwxr(=AiHfJ9+J|?}4Fa0;e!Z;%!8yONvI@EyeIu*@WIT&a3`w$G8vO>+cY%|Un zO_OFda58p?Ey0}+V@L|!{8$0j$&Hl}&LO}0flN-nd;|B2HD{wo$PU4C=Nqa&yeMyOe6ZeNr*_IPSt5bd@DoFb&Z6^mX z4yN?Be7!AW2>$v8X2{22<8;(Nm92en{XY)GznP)MD&HhA&UYFBiOae^zdzM=8E|s7 zFczl}`kK^qGIL^<%);OFelpba4aQV$ZS+S~zkk5rG(h^lSiiYgIGLvZGt{q7*6-h_ zeh0r0HZxYrLEy5~UqXL5KBu;B529{;sg{w61)5>dO5$|XE0v{vaJ|xs#`Rk$qui-h zDSa~amTW5rrP+u3;vrR6xcsC+LDm(0pTs)WXPVYARFm18XP~20O^Kn)16H3kUnfnc zwBP-a>L$s|kZaQI(0@AWhRVx6sBRMP#FyunVaAfML09qiVdpuSIwD#7pm(=TPG7yj zy2^jG?;4DxzVi*f4*8`vmcFg(?@xGtH{@mg1);(jOZm(LSxyQ=_A5r(@Ayse8de#B zD{eN7df6Ah<}9`q)*`D1?Ltmw)XXIk|m#?Lmx{)uyO?W3mt;l*16E0&kWz6k;MW7~6%QxkWN08|<9h4Dz{M3mvMvjBEXbUGdnhT8TYSHj z@S|PGur_ef>i@Bliu0tqesafJ-T$w4V1czMsfnQ#11|~r$NbewUy!VYWpxD3D87o7 zoO8>dK==8dhplb5C5Ct{gr(EUJ}(B6@Ql+>%n%nuVqis|7g3mz1u2|w&Bkly%$5Rd zdQc_-676+3lmPF(v7mdvDt_87DR;Srl2L36Qv4zRHY*UQxHX(`=)S~|#g_a5-;j*k zJ_`E3I7~ROIHgB8n6VOtL~u|~yLJ;p-(81g90n7*C_J@&`!MxwpD*1?$j!{O(lV^1 zNQu?2mz9)c4fd@WVI}y?Eby#^QC89@Yw{q-LEcEuv3mBh&d9)+JzN~3xIY(mX)vCxo0Yr>0&LkmUv?T9dbXmBpN1;N~< zyh+@6T(YkMJ4{>9Q}LOCPjWM56~;EBJ1L_%Q-sGO;W2zLeu(7dQs7}Ja6bv0-1<_V zzi5Qx`Rg4u{^4oozdV2WO*7#y7~0e_<9}|({MGva#-g#?PyO2Bw+78$meJb`p2oEW zm6v^R+o83E{u^K8Wy5JWQaTSJ@!mU&*vdgC;iK06<`w*{jYECM zyWW^+ivFe<`~>wCPUZE+U#Y$<3lq*O1D1s>Yi;fpDRyDQ#Y!3q5HEwcRti(eTPr1q2l$J5w; z-r@F>Y56cmb#6b&=pd(~{ZN_P2e%)3+R^#F2FClI=0o{Z^LgJGYB!%yOKmm1^#bB& zMkgEDq&{@o5KT>gk&v29m}1Sw3BB{!Zc;~NliC0lAOC8bnvLAiHnqglran?_>M!^k zV~{)fF=@6ba!oUIGul*&9FuNxwJFnDJ7R2N=rSvD?&D}+D~BFN0~@e>rgwm9&$tKn zX%=x$lT-XMe@J%ONM*8J0%!S}l5o_60a!aYgoZ zQ{QAcfX?bKHc&bWue}hq{-6#E2)%hpb zpNVu?=k$FtL%}Rl3^mR06R7T>tnNqUP>}bWm4tzyJ@v~#zltj^e+)MmF2jwOtU##Z zUh4Sj#!6kFKE+53wT<1rj4Yqhe*ZnH?^LS?_4}OBCDtHZN#{_nr`xJxJM5i~K2K$D zA6)O-f%v!0+N-pMai`V*qFGL+uj}V$O5vJ&4 znkmnt!qsz+XSl-sfubS39)CS-%KJfh?h%-lk_mkk_?+5$y+_uoHN!Gy;4i77F1NwP z>8ML8SNq_)B*Rpf(N}8Wwh(biE~=o0o99ra62HwG+EoPJu@EGngL0N@OV>z+Yd7=&*UL`)f^Zj?JJZJ?NJ0{ z61_x#FLJR^!(T@c;sSh<@e;D-c!h(p$LvmbKJBaAe|KG{GWV=eFln#6`bj}!hzBm=4U)AakVhh1_hH0k0iFT*<5WG(9ZtyPy6Ut@HfI!lUrgX59PbW5quBC?f}b|?<{gp*E)yVm3?sExF5)Quc7h0 z)-y;pc>y>4eP$*mDDE03*QRNlv5z25xc#Du^0;{X-@7lHcH^zl`?BA<6|J(*8r+vH z{;V8!PHo+OOm)lmWod)n7U(}6^BI+weQ;gf3S_@|()hbpQ&KVy$^Xhd*&WD-eMz)O zsl%L`zD{jVl68fxGh9~~)($~VHXnL=+4Tqmfv*}|zJtMKfoXQX8MW9~&S^JMErx=D z^x~g{{O8RHgfU{MT}l~`(*%|n>cQPT+&6OJ!LZtUl=5=eimVHDqm=wd!hwNf=`0Y= z`#@$%@te%l#UDkpth4qPot7BB;;B_ z+{hb@Z9@12$KZ4b9zu1bP2=k~#Es~-$U-{on1p*1cN4gU^bbWfxX zpX8P{Y!SJ}mqtHhD5KO@@ios*rB^cv<6FKSG*vDJ7Xp2uy#*&*@k!>_$r#`ECDE3< z2IA1$X23`z#(H9qNQL6|ATISeI!>mIXUi=7O@B*ma{6V?^YY2*4LlZEs(t$n{u^?# zeWxN1w{NGBJJ8{=u=5p5#Nm+}U$Mx0CBYOMv9Be454yxYBf?KG9;QAq<*A(W!lt|( zleVVE_XGbWif;}30zY5Z=e5upZr^zD`G}P?|4}Pc);sK%Pr5^|39CBLl471eIrNGc z^^H(#C>ZJ%8XTG!dPbb{WnjpQ-waz;;@Rn>0k?jZ3^~)zniy(G8;mFD!?1xba3Yb~ zw854yFmlMaP$r(HG?lem;ec6oX(-iN+2@lfd%_87%OLIS3(9Fdb6_}8o~68u8QNDi z)5_TJn$=MFMmVITSK#Tg3Lr5wx7*YIX%mmG>-O~Er@~40?tn+urS8YBfj&dhtWg#B zI<7pl&IW#Fc?H0FS`dgIO84boKk^Z48-v8znC>^sKPH7MQktZYX@l6Q|Dj)|GJ?AM&r- z_Hp25pry~REbH8EiJ@L-&g&MWpL`UyCM-{_w3Y8r5iSd~E=V8r^Kdu28m;t~ax%iH z5~i=}SuN}HXP1)~k=}(r3UdAal(ATiA>!1|DYyDktOV>YOzUGMC0hxZR?=$Pv5=45 z5IwALF1ANRtju#qXJY%q=u9h;Ze{kjhW4>~rCNQnv0JsbHLlR=n`!kLYGwBPisban zbZgEa>!J)Rl4@m^C^Zv$S+g>%-czk!eMm(&7^01@eXVX0D}9;Ob68GJj&;rit7q?G zs}GjGWAm)+p*Wjkl@(gqMfO>Gep+nVNw!26vN`>%^juH={1L>jpu-*nY zg7W}C5Y*o0@suy}Ay_oMhi?F%wvBQ+y@XL1&-jKu4-T!4!q+4D7dXL;$va4%^X1V@ ze*;)@B7e>|j2L$_13!l~p7Z4s<54hhguB6+5Hc?%1!|kg%hLXDC_M$~S$4X#|2t{_ zkCYrnas53K^1LqnS+mX?ppsq zDvL#skj`D}KZ6)`lqLLo$Ynr5IX+VUhf;n`RQ`ujelyF5AV=@bYr{v%KP%;TMCG5A z@)Qg<-9UZ|WZ#I&ACU4dM&%Dk`L{^kIZkHXmE~mPzoEjIkUsK@0qVr4@ zo_W_?q~|M^Or@siYnmB1-e%yTAg`CcbsN@8dCimNPCR$w|DJVDAY3-fzJ>^7^l7p8 z;w6S!1H0Fy^oNNhWcie?`9Jp4y@1|0`sC6U@B|)*Xz@!?qDlNme90o6}zkTawpfh0W{LFC0i6FSjvTsezQ@1L1^$8ERjn zb!neZf+}-jXlY-zU zJc1y^GsGgr;XkDHyHMBaBPh#W*agk%j7T7@$x)Kbb>th z6P+Z_@huOkAL1EezT)uDJ|rtzzhq6a7T8ibI4Q&jw@YjmQQZe+E1761r>*r9og&Zi zEf4a6c!r2-cUV!k$OkDEb&FbuWJP_*1FM*IMJoiz?bme1YmY*#y%Vl~N(e?7& zPxK0Tj&FGcL5QdIJBJl5bcYq~W8IPI0(|tY2uO$SGi^_&_=t9w=YFE}+(Y-Ds+4%% zvLeg6oL4`UG1C1+x6AVg(YxfipXd&Gj&FHP0;$6Xu15zxYWIrQAf=p}sd|VlNZcy( z*2Ivjw0T7Ja!`I|5T)xGpIEyuDocYXF}0D1;+CvvB~XdWtT#Qj&d$3VCv**|jcZRv zS<$KH7hut)q)*(mJDSyI>fvcTDiJ=Yy67@eGeK8*k`*-(0gJ8{VPaR*gw2GBIkq~D z7cD`$(4s3vtrczsr0Xfos(q0MZ8L3c8n4pk*%x<^qwda!#w)XV_C+1!7RTU~+C2MW z4xv364b5gEbF_w32EE=(z@zq0RLvWek&-3q?cd$-%8K+^=|ZIONhW4vOZbB0 zyPer>T(?=N*zGRDNf5#M4TY8-7PHa|lYGGvJh9FI$h1MA8&YuH3<4ck?)ieb!Stlm zz*J}m+K{xQ2Hu$)cz13p`fWNCCw0Rul1!Xn&DR5#XJty;LS*(-$*BXxC`g$(NKWcD z3CrAs!EDVB0&7VlA!z%2R#Is|I-BTb&q}oul8ZbM`iL6VGs(iS{={ zn@Z0nijRC_d?f$p&jB7kfn9zAyZi)ZKL;v52YrQ~ z^a2On&m03?csOn|`us`0P^RCPl;ukTIm`5&VfcN8KEL0$$Lz+u zhKS|&g(AKlLC~Z#e8aQ-z7hTWzLA50!vlQN2ZE*yg3%nmFE!U!jchdmzppkyW?h;n z>BUKqOYe^_bA;dL8|m{8_4$Xu?Ox=De;Ces!|6VLU&1ID&hz^c^J#*y>+edGm-!n* ztRjl`!u6MH$od;>hzRlV5!}+KHtZXe^uiu_u&y(lHt|ic&AoE|r;SnTuyx88 zBauedm*?o)Kze>m1_fyc%5dSwpNL8bfCe@j2%veA_;1 zFZ|*(_wyA9D!G=|>J^-sRii~r=o`fz8JDaJx>Pk29k z{Ow7_jz8H(2kRN-=wttOoveTK;!1h2zI;dDda%uh4Svf-{PE7ApE&Zt`U)I<>>t(( zCs%&7??%&C=+XD%lhsErrquL}_UL=$r1jyMy{50o(YGFK^G7FJe*8jHR>AzO^C55S-n)tmj zuRSI>b9#jM_z3X|KGgbLFQTCYS&kDOAHM^h`MMCdD#|_rvyY%R5`U7x50}U%_7(VH z;sftd>Fm>4%BRv;K0OIZ^2z;j6fmSulO3P9-2R}-4U~NXWuHK~+;9VjZBA7-%VOEw zrrWgth%uRzHm5l@w}NNBDR}QRQML)nHbHqkiFmh=+;nAohO#}=v7JNd_{b|wir4dE z3Qkk@XF2w72H*UX5VtA%Pelzw@@cyerDG|_l>Gx{|3Ggd`PrU&0(R9C@UtX`IDV<* zUsD*x%K48d{HelptxocMjgI^nW*K9+V0o^CvsF3FiB%30AZfQn{cktJ01h5|&T-0t z>;BKG?m;vIn>wc~(|8teyd5+x(beg1?Ym)5hKdj~iX>-0~^Lt>M?+J0IqFffh zZz;?^0J9IETvsR)uB!!x_z}qgKSC7v8HJx$c%Q=5D=FPo#=u;L3so$OoLKTm9v^wP zShXcy>YQL5b)FLwwS4mfbsq$jZGv*Wf^tlt91|$FYs9dX@}2Lwt^oc8@sa+5O6ORB z4=Vh&N`F^jA8MWC=@C5X;~2lDVqEORm_zdT;C2QiRg9iL;7zIAPQLDm?=LDoP>v6j z;{)aRKsi28S9}+E;sbWY2keRu*cBhJD?VV3??M${`B%i}`GI9LzHd13@wod}A$WWS z<#<3j9?)+glX;OL+bqiY2MV(v70QoF#}8-C_y8oiobf{q{zV;`m*rdK*yn!su@KxJ zLD@bi+XuZ4dCVp9cSBUqI}~R7)yjTNSN826dy#czzt*wO^U)_l+>SI8liY?*dBM}H8*DQt7OW0TAHs2cM?4?v23!}2>t*#}_u0hH^e(KFTq?cp@aJoA|9XQ1peDEkb$ ziPBpPc`p_|{ZL`{p;h_N=J=3J>G;TQWQ%mPJdHT_7C#x zA1L?d)dv5q1**e`Ne=i$qQLtU#!$u>U69kiRM@0(7V=Zeq%0`t58nnZqrvfrTWH)xUK zmne$qk>xOjFx{f)Rz-I!`k10GEBfDxW}q>Voh(I*6fIG7v7+UQ)+$=BXp5pN6kVt2 zm5TmI(MJ@0Q_;5-?dFsA(-r0Vhd*5Zpj`i#d-@0P9x6A~=TC_OzpU_oD|`mUhjiTT z;B+ia8Dpu&7(+B;43&)0)fl4-Fy5f>MuqQD_&%~1HW<}W^FxvyYp7>WQd)Fv?sASt-gwpZR*U4^+ z%I39>O}3G%Yz#KUI@0l&k^}8V7{dwkpHO^I=I0pvnk%{<=CKr%`M4I%pnN+G(TnJJ z4Y?6vvw=TQ27I5vzdIYXYy z8SNmC{6IV4a>l^K<&5?+miVy4_Kz#QpsW{jHS-PCenFX!IgRbztL)vW?0sL^yF=N- z1jG3;Hgnvdod26DKgyBY>$g>Yv={al^~3(6{@7o{#s1!?{Jp`D`$S-OGWm~ko=z0y z!1hqC^9WxrpMRQ&;{w9)o6|9tus@*e&sEAF^e^`3b|r@~faO40?ph_cP069%ayfrb z`3*hn_ji=vh%W_pLqAaThlWT6P72{6BJolF5u)gK6kpPC`AjnjK~p?QBL(llAxi#- zP>&Z8f0W$+8A5$7C7h3UWl}nDBjE!1tex=X#E1Tk#D|_ugrR4%!gOCPgbC{o!f@g) z!pQeS!q9u4!apGjJueW&IC4PYL!cDTVZw;#h~lHjSRPGZgl;wjidH0z#y&bw^Le#4 zdD!504bpwrQsO^kh`CCx95jS+qfKF$6rugNMk4y4As$ftrwQL?@V;iE`xO5W@gej+ zQRMrG_(j-jMs$o2UlN5sG{+L3wm1==);NS|jYH`<3J+E3`3e^+JYLbcL?K_JD6MhG z&kaOjf1AQPC>{DAAPRY!n+ZQh6!u>Mr8xei`0ptGXNvFlN%>@=$lp)lfkctN5R~$l zC_ZiTCjK17pGTPdRJc*m7UCBRv6?6bg{u|aOcefYAqqX)iI(7skmxue9s&(v+}=$X z`JPgAFHz)sktp&VB#L}*5JkR2M8^y9J}Bk?h$zPWPl=-5zohgtQ9pjPi{}hM8wKfE zSt`*NP(GkZ6OdogzY(2?dly6}Veg>go0jC$Hut2nu;H92@^x3V2T{oPRJG%+P&eKF8x0h%V%3I+>3V#S1`Z>xMl=|OMqUd+Wi0(mW z2!P@OAQ?0%8T+t6Lw94GC5leBm?--9MJl~c(GEq|Q2I?6XF$zIu_u7&s~Bg9{tEYe ziSEU{F`}r?ZA4L@cY!8l2(goBCiXNEh5t_yg&$8V{tHBVpgj@Ar1}ccEL`6ch1~B! zLzpN2sPJLJ7}q``j6wYfVO-FBPPjMj1}cm{pu+i6iS|LeP`C#u#gnc0{S<#7@iBf5 zR(LpJ*eN0$#y%6G&{INujH442oR+q!7jWpf@Px z>qi**auhBknvOksM3KLk(qV6oN}op<@{0(=|4LA5S2aY@uIq@RJvR_VJ8LG2aifjs z!v_A`G$<}~*ARWg5bKHl7~?fj%tM=qqF-zwx(n@=DEiHIq8M8q0uB8Z_lbyp8}Smw zDEi|PO2?#GM-=(DfhJ{Ro>%lC;=|r< zg&!jfyH67Ci(O@kzM$v@p?I*-LM4|tE&=A&RM-={?Xn(W|qLA~W&l3(3 z1x{8tRpBg!@#ob!J%=dtj#T_Yq7k$cl|Di7OBKIN@n9GZ-zoYhMc-HSh@zhoMR|Tk6#730rFy_0K4%;vigKry>yTWA!dVJuD;!ZcPvPMT z7lBg$Dj|ygH-Y%DGo2{(&L)a_nM)M<7b*T?#V=RW|A6A}R{X~l|4GGvjwtLLQ1o}8+#eM_L>TpQm@w+) zeMLV~^m9c`%ng(tR5Y0=$|Hp+^y5!?alK>_M!7{49jxeZqL3S}=p<0`qfFtMgyF{= z!mzVI(eo8uqUa@xHY?gj6n?BA3jM1=seP;`3_msy9e{O-!dn#mE@efd`@&Q<`<%8;Cg~+9>x#Q&?|=c zknj-9<3xuF@i*e*I_(%Jjq`M&MeB|rXlNV8MWR^$cPEPLvmQi$fpJpd2vJ<8<$)#* z!+MACZw--8co5dn3Qqu~@xPQP)-h#7(cWhg#e6b{D8|=$MA7~i5yd)ZG11>(UMKo% zLsSyI4)YVy?eG_GD8kQx)WK)Oz(FjPppY#UrAUruC23r9(L+QmnT2>AV=2);@Q*o# zcvD`}(~nIs1@i`aOjZ2TT}&w$KoK`lTvK9b;2%1n$qIpMNE9vqZUQa~@h5ptK>Qg` z842SW0@E&UqQ|m82(0ljT?_G^ytWk|U?VHxzsTP-iN6ZI7eY6)v78X%6T#Qo;_vb| zH?%<))4ZS?5@?24Kna0nECj9<&^(1WDg>G%Um!<_o+$*HCI4Uq%}I!fg6|#B4;Rp^ zgg8qGG%J4Wi)MwF%m{&Ig>skI=oBoP6OV&vPV6+A0XsdMDAt-Ih+?gYB4VdeMC>#! zi`i)u5j%~`W-crg3AaOB_HbdLNVu>N8W$EqLr3S(xUdi!ZzIQL5C@HrIOqvP5i~-A ze+K^+gMvp$7#M^oC7LSleNZ7xA&f$pN)*AD5k>IRh$8suL=pT9qUcjIi6Zz}L=pUK zq6q$MqG(hgY?z$r0>?}9oL%AlW|Zz;8qkLWIL))RnQv9*>y!i z_IWkVZ6Aog9&)ztgzfWIoRgfLZv*7?!`86@%y{Iy<2dQts4G+$J(E>5{Q7sQ@_z2$rma`BXNB|3hr`P{4TL&$B8qkh+v z$EPp&jrioYKrWs*vM-8H-_AJYiYj93`>yIAc1L;|a*JY=%RS&FYW$2!x#p+-$7@i~ zAU==b!+lS6%$&;D`l9PACD#GDEy(LVqV=ZalB?t|z`SzaI9`EVJaObLapEXbN@K-Q z0=ZcFym4%TTs(0^FwpJw1_2z6L#4e3IdsiVhqpdTYn(WE4UZhIIFyEYkekO9jC02fc8F<^b>Ejbk3^mb{rUj`G^(A1CVQ^#^*V_^^x6#{-qbZlJ~Z&oMx1B3^{Kcm6yg>AKM^j$AO`S zkC<^lE}r_Jx0zNdJv#BmQ3<(ix_~*u$V(9bM z$3DoRs5>3rI7*@HSSP8@?P@}Md~s}ooE-<64j-}N*ao?H;z(T)UmWWphub}!4sU&I zUKw8;hahLifu_SptT>K9?wg&g@~uJFy1lIl`^PcJ)y0tW z#!<62zBp1Zk8d7a3^_ZF^~!#%IO-s`A%=h6I6j12a|}6e9Odicn?D4cni)f%cf6Vj zIXe!!yko_&7;>1ZJ00FQo?9Q^x+D*sZF?teoyV)akXsZ(&KpPe6;2%2Dfw7&42RrJ zG4y%kcp7r?)JOi6*oPBCpSOSHpb^ZAA?J;w4RUsU+}K4N8z5H_W1RHH@gypBa}2xQ zb~Wef`1;3D$W4f$&l^Y4HBKB`x`?9;a12RmQOEjpHcfw#Jb2*2m_J@zuv6 z$l3K_kE^lT)e*=Yj$zju$1B$gu|9^JH;zSU#E}^F>y4xBTiEXwL*G5%C2IVqA!o;N zhvLVIV;|(c=GQW+Q*Ru3XjJQC_~(sd=S_I7;p?o=8^?!eBr`jU@$ZNAIErp|;<#JM z$BLs2au_-~9o{(hLawfpROjoD{9EE%C%y=|c;d*o)rn)LvL7ps9LW7PhJW5TK82jU zPSeG`^-+n=u}v3H=h6BwCF2<6;_2rl=oEIldQj=2IQHU$YHwC7F%xprY@pGDIOk@h z>~4nKrCPdu>Xq}u;V$J=#tz8Y^MS34XjGqK`frziZ%LPlCD#nO;a(wNufA=N%ZNj6 z7v!FbL#`Q>7LUFSki*o_>G1j&{GR;HqF2x>w>?g|5)3M5dzAru^=*h#ZXe|0Dd%Hx z%H@4O_IlFm-!90-6UQ;g#Zw=t+p*s>j&gYna(|C8o_6x@uK3F3jT6Yd4PSIKK@6hV zIz##TF{nQ7=IoI37Io99N{0G5wivkj?+(aCRJu;mAgAkl4sw*A^wC&B2Vt+>7d5*x zSxU-z?aui@e0CckXWRXarZ3lyL-E=mmj#~p@cOsuhw^WpP#iSY(n0#8{xJu8P9c}0 z&UNA~mxGYA{j@J2}Jn^p4?7rHC-3^-Ev6`H>oF7nfN+e3W@xG$jr9MUn#o>+j4bAR&mWo}!{+;o~ zn+G|vL*@6nrq63PA98t0Zk#6Pjd!tv+X zYj?e7m-k#jmi+bF-5ICdy_((kyRf@YvpY(Y^V&Tcr`@dkoN~tYH$Es1Z@dx6+2vfU z$$9P0gj__W>%`lh>omJZG<{yX&6?eOP0nj~Yn*l;)9ikt>GRrsTC-cA$$9O*7pL9e z{Z2W5rs?zAO@*9Y&b+4&va#A#3FIP5k50VhyjZjQze+Gx{Z?vri!?cJyc^@RyHm4! zOw;F$cb8^&j3(!`dk}K*%tyyGyT>(sUc3GWoN~6;sj=d68y!l2RDU?i$F&6YqA-uGNLzosjEL{+-i>-3TrMLT7lkejLOeyt0;c@M=G?;Ob4@uqZPcM;^~DZAxe*xdoSJe95! zZ@YR?vrB1okRRUm{0ih~9YpP~3LiR1&fAY3_)&azUxAz*Z$=k(-+-z&VRs(nw!;?LU4{=GvFsj!+;Exf`u3J{_QQ_d-d)(ufgDt_-DagR zmfcq%m*=u5f!FRa&2HZ=?D~J~*lq8^?rzA%WA_cnk>6B)kuK~WhTLK$x4H|v6CR0g zoGgc&ZFf)?c55JK+g;a%-6!L;`-WzBa2IwDLvE&ucS9F;hwqNBoEJgPj(12GcFQ4W z+r736yE`Bk&-lDovpc*CyZa!wRmFQl7k2CR#AkOC%`lSl7HgZE$qT>2ITB=rnu=Kf4$>mIpiXg=sCQ0*JyUfbYXV`c zIgiF?w*hjLpY++!kqCc`Pa;0{(FVDr5F)v|6f>6HhR5Txy9si(-7~w0cMIfZ!XDYh zB{(0k?7k7F-D8^FNnP0WKjGNLlIMhW=Rhu=e$)&(JKo7%*zJH^7OYXc3DPX*D?%Q< zJ~nImrf70y9=WZMOI7+NYjR$FJ2ibXG&!%nU7Eh>nw(eP)0)0Hnw(ePUdWXoo#H)P zlk@7M&1-h~&DZ3-`ht+N%Ws}0=hYX{^qsHCdG+OK`p(njy!uKteHUtSUVSqmXV=FC znw(ePVohJACg;^x2|2reRA_QueLFRMwVIq)-!9F+8coit?`cinC7PU9-(F2$y(Z_? zcTm&Uq{(^p9n$nQYI0tEM>KtHnw(ePQB7Z~Cg;@`{F&4KR%voxeW{R(Af4KChbHIM zm#^u&T$A(aE7A0=)#SYT7Hj&h)a1PSDj{e0k1I4euf7gV-$qT&t8cxg?;1_ct8c5O z?|Mznt8Y8xB1ot5+oZ{P^*ycW`?e0DEzO1L5`n^??^XiL0&hEdr zXmVbC`I^3Mnw(c(3FPeY?{-bjtFKwpcc&)j)z<+zsxOLnyC&z=Cw}h4i$@52(D>@r z7ld2{eA0(UA$*XWS6`l{54TRDa$bG;kSj$h>BB8AK1knU!#%$>Yx?YYFP2<~CYRKO pzV#%RBJB>=5MYG4hS0FbJK~Nm6N&)%z{{SVfJ<0$8 literal 0 HcmV?d00001 diff --git a/Flash/Obj/menu.pbi b/Flash/Obj/menu.pbi new file mode 100644 index 0000000..71a06f6 --- /dev/null +++ b/Flash/Obj/menu.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 20s +C:\work\solarium\PROJECT\menu\menu.c +C:\work\solarium\PROJECT\menu\menu.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/menudesc.o b/Flash/Obj/menudesc.o new file mode 100644 index 0000000000000000000000000000000000000000..11442d1c222e7364adec16f58809657c562895d4 GIT binary patch literal 236000 zcmd2^2Y6IP*PfZ(4Jjmaq^K+i(jjGc12#a4fHVPnG=yZ4XquZu0lQ#tVDE~(cPyU` zQ4|pnuzxl{QB*)c{ZLW)&y;&-&g=$RmOs0jCwuQZ<(>D=oH;XhZrSsOj~PKJCC-PE z9z-KT{6{bzuX5Ay6_ChF}1dq^ovxNmDH7p?8RqH3l~oh zmz0Ggq_}w4m{ErpPZ&ON^2mw9hYX7fC@!xm2M$@#v`9%MloSb9-~g`4lrm)E*nTB- zb&>L^^>tw=T*XzFI=dxPr$)kOm`qZ)OjuJtwF(O2s@;-wm`qbyQYy3PB(fSfw)OBZ zSr>fIsEU4YM5kyTp3e>8&4WK?`+3RMoxM=>)}4bD=IJPDPR1*oE^sqag>Y+fmBL;T z--g_&aBG3H$#R983!Fv%LbxgEtprK_95PDbrXqa{QjKscawkgPmb`&*OR@oQjS8cn z{(rDvXW%q2*%=0I3wVn#V}88jNmtna)xZJR|J}gDVE-=zPv-j`c~Crm8Q=*9jsTu) z;0poIFz|JN&o=OVfX_GZ0>E<&{5IfA4g3k@LU7`0r+|YXTtt*2JQg+MF#E# z`%?^j5bT#3cr@%!H}DCtUt!==VZX+}vtYl@z?Z{*Z)F1v>g!>^c?Mnrc#vuz9=`_g zNe2EM@bLz24u)55;2stp47dg4;UCU-9N_*2t^wTJz?T9(*uZxKKGMK10&ZoLw-WGY zP{$7cM!j{TA+Q;Vu?Fz`|WE+|9xVTDZG~dsw)qg?m}Jw}tyyxUYr#S-8K2b1j@_ z;d~1hSU6zepoK#gF0}9f3lFsLK^8vP!iQM+PzxVs;XxK2Y~djmKHS1XEj-M^!!10* z!bezmq=iRWc(jF&wD1@UkG1ePa+~2lJm8P+MfiQo|BSctPq6S&7M^I~Nfw@L;iD~l z40#sx@VS`$j3=)meIGLH|BkitA7|m?EqsE7Pqc86g-^2Z$rdiQ@DvM|Sa_<1OD$Yx z;V@Ya$Is`kPJMiW>f)fTR?@aYzgSh&{0 zbr!C-@EI09)50?>Jk!FnEPR%Q&$jS67CzU)=UMoC3twR23oSg`!gDNqk%cd|@Ff<$ z)WVlp_;L$hVc{z+e3gZ-w(vC;o@?QGL%rJV)w zkZ-K?*IDIVZ{Zs(e4~YLvhd9ozQw|~l8&Hfq@k}H(zn6Vcbk>}b_?HO;X5sSmxb>p zK`3v6QT`xQ{wAyZ`BwgWEPStp@3Zjz7Jh(?hw_dy%0C{Jzs)NDK`Z}57Jk^mk68Fo z3qNMz$1VJXg`c$WQx<;O!p~UvSqndB;RP0c-oh_f_(co9Wa0l<_+<;fV&PXU{F;Sd zx9~y>zhU7;7Jk#hZ&`S;h2OUDI~HDI;dd>()WYvsc$tNlTX=9Y72j0 z;SVkRk%d3D@Fy1j)WV-x_`eqZ+`?a2_)80aW#O+ayoQuRf1P6V-&)jvw_E*pt(AYB zg}<@zw-#P+;qNT`y@fYe_y-IBXyKnMywSp&EWFvmKU;W)FS=Oy53q1o3wN{dffnv=;T{(5Y2jWL?oICiz5A;5NdoiF z2a$g2!S>$A%HP+*{Vd$y!nqdCvv9tJ3oIP4aL~db3l~~=fQ1KI_#g`(Y~e#Je5i#F zv+y7b54P|S3m0~7f$$u<65+?#*9bq(HY5B5`y1gW zS<_6jK8|1=5gy5UAv}r=M0hkCiSWzxScGq-(-5A+>Jh$(%|ZBLb{)c(uzL`0&YniN z1zU)4OZGm(t=LxxKS4Jkd>Q=<;Y(RomRTQ{u?`4d&Uzwz1si~HYjy;}ZP+mgw`F03 z_hEGiKS^gJd^x=q;oI1Jgl}h0A$$jW9pO9K3WV=sUm_f08xbyKI}jegGWm@G>f?bc zmF*Eei1k4D1zL#k^>hTn&$6QtevXwPynxjr{5-o5;TPCEgvYVF5gyN;M0f&w4dJ8M za)c+cFA#o}{)F%y^iPDVSVp!}8~iqeYSs?neLM#uyqX0OUd2Wt`~f=_;k9%c!s}=~ z!r#z22;WbyLwE+g2jL3#G{Ti^A;RrED-iyKeTneLYzxAlvYiNjMRRh@`uLjehwvKO z2jTnZ!3dv8MEk$5tZbkSZehZWP@sP71y>x=M1>=1+> zW=A6Y2s;7cM_D<-gV_v(hp3#@*Li-^6DLokB&**4`|4WZY_;WfP;V4MzAtHXh;b z>|}&{uu6n`va=EH#jZg38G0+i*U*O%p3h!Hcwf)k2>--BLik6v0pX2oJHm&uv{q() z9LCxpJcxBg_$69^@Qw6vgs)*oA-tcb7~w6f3gMsG1qg3ta}jRG?n1addjjF7=&J}{ zMVBFb1N$7|8`+Nt@9+5?;on#jej}s$c;L>!4ha8`^+dQo8-Q>wI|AW6b_~J`Xc*yZ zX&u6Mv)KqA%&tZF5H=s-7wJ<7-#}kSxHDUUa2NI^!UwR82zO;W5bnk@+c>qs=Nr$` z_6X0VJrF*F6(W2l8-ef)b~M5>SsB7V(^`bL&mi12>w4}|w;>HC=V(TVMYu%8`>@Y6Ji z@YQq}!Y{E&2>*voMfhcQI>N88^AUcPU4w8Z&m9Q=$sR-a5B563JJFu|kB;Vj~bfn;nhtue1!|-)Jqu|DzWod@h}b@cHy^ zgzsTbB784<4dMIPa)j?^Um$!O`w8LW*`ElXz%tsK_HiO>hw#m`JHj{75W-Kf;Rrv? zCL{a|D@C}7MG!uTU4Zb(Y%apL)4LG9jXr_!mF!i7uVTv(zM6fG@X_o?gpXl=Abc!K z?_k!)m2@A3ub>AaJevg(ZpwxsoXsX7oWrIf+>D)$@FnzogfFGnAbb<)zeo<|Yh$^L`zKWsU|#PbEh&(WU{o=5*g_zjk^uUQ|9SUZH@ zWZe;di-iy_Wy29JW0MgMvr>eou?WJQJ?A6r^<0Cn$8!(DKF`w#FQf|*Uc%l-crp75 z;kVf)gx_I*A$$tU+Rv8u07<*X;dr?LSEzd?^c_+54k!mqI~!mqPBgcq{e2p6+! z5uU>4BV59sLU<~B9pTsM3WOKYFA+YEZAAEdwgce{Smyp_eRx=VguSc>!ai1r@MClY z!WYq_5#CPA5dNLkBK!xv5aB=RJcPS=?m{@j^8~`_o;MKA^sGeq5&AX4=h4jwpUeJ6 z_#D=>lUW}-Xh($qqP-CQn+`n7!dF`OZVNwV;a4rZ!or_hc%y}PTDWZ& zw>k*d+ug#0EPSGcPq*+D7QV;AuUdGuh1Xm74-01=fc3Vwa8C;#Y~hg>o?_vMg)gx1 z?G|2O;kPaPv4wxM@Lv{g*%cpOR|_9xV7^pyxP_0h@DvMISh(K87hCu`19SU$)WUCC z_)`mSvM}j}kFU9f{T9x(@L&V;;~#Bcu5Xfsr&zek!e?9fQVZX0;TJ5t+`{WD{Huk1 z2kPVJ`a2ky>+fUXLk!H*4>K@Nf1HIYEPS4YueI=f7JkXX%Pst|g}=A(9~Sm?2a)Q- zmzrA|m>*AP1M~P?1M~O+79M2b5eoCmU@gcg6Uplc zPbSL|UPZn@cq-kDa6L)u0m9%T^;MA$2rnYN6z0onEyyNvFp3{bk3x7enS$`q^bC}L zJ-GO~JUhq7t5#JT?C<6}w{2O3?*gX9h!23Y~+*Ua*0n9(L zy>B5i5PpGN4fq^L9}#)RlLr8oK>F+9pXYx8r9XhagYcu|D}>wA-w+;5(t7jKo${X| z9T2{Y^hWr1ayyvxg?;l%zpwIhwvm4MtCJTQ(<|$mE;

&T-D^JS_Q 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/menudesc.pbi b/Flash/Obj/menudesc.pbi new file mode 100644 index 0000000..3085ac9 --- /dev/null +++ b/Flash/Obj/menudesc.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 21s +C:\work\solarium\PROJECT\menu\menudesc.c +C:\work\solarium\PROJECT\menu\menudesc.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/mode.o b/Flash/Obj/mode.o new file mode 100644 index 0000000000000000000000000000000000000000..ffd3e4c62e72b5616004012613247e3b7ded46f0 GIT binary patch literal 16400 zcmd^GdvKgrbwA%@AKKNfR+42a@*`_UekJi*FFzCru_CSQCAOqW%7dbIvs$gB#j9Ph z4@U+<0!?UU2uvuHW;%3ATG}xkXp<%>X(v;{OeiT$!JQ_RTRl*`QL%9Kuzol4!9o=i^7oSaIIjIAT2^Tj->NzDu8%raD$bA?6% zJK?rHGIctUsaDJRxmq;`(~4KhQev@Os;y|sawaPslmeN#xpMBTTfdvTQkyHnJk-_g zH>1hsvy9g*ra8TkKw}oAel6=z^eEMH_gLBV)3yC|7D_)|y8+LK6wRa-I*sz5x$t{Y z{;CV-QU00>-+}To3LB_@56aKF@TXC};KF}`^7AhI2+A+H@KY#%$A!O*@D z!aqj&w-jdo{~P733kT2v@ux&H5t%<-YxCf(z_9(@nU^{ z*T4@6zEhn-^lSq^O#jh)PTF_(FVMQzSe+y>01qWD}AQ{_s}a1cpJUmfcH|1 z2da*E@U#cddGHGGr%>-O{yH$;9{?_)yi4Ja0`m}ZOfmoC zsy@@&DM+6M=J{g-??ik*1kCeA<1YjA{LuIbV4e>eKMlTf^;4QLQ(EK|+QWabJvX4OHO>$#wZ+gLL_)F^zY5gu-YM*vgUlpJRr z&`-xx6a8bUDV?Y1uy---^vLv0PQjs0rp5&kxu79GJu#LXBwf(d>EtOvquf(?jO+VOF5@URAI#~pG!VbT7hnk|r1Qy@4mcV~ePH6TZ=;0J2O4}G zXsGIF6;etes{@YjY}M&_t~$8R>R^M_!9kjsp2;ug#tP?9N{>$7oSvRaPvt7r zQaR_MOlQvKXtGqP-i*nVJj>@UXS&ddoQOoyQAks{EF?HODLsQcxS&kPn zm8IEfvfL#s>AkRNdo}Zt1E&S_PI_4_cq_ZaAZj)9*fE>8L`zgl zr9uTF2l7SC4c^ve&|?nG=i=3++VWidzy!~wS|yjxUULn$1DkL-w8r^a#%nOdP*Ni321t-J4e#l9F2boBOoEn8*sD{Bw^#D1@vn#Mf? z)?9}E%r&207DN=|5I{0%c#E*DDf%8Jet6%uukL(9cVDvca{Mbtueq=vq)m;;W=dC-kOSo^)0-v!~ zv1FI#;XZCYv@N0g@Tv@I$H9*pijvMcwD&6#rjkQ@%vfEnt~zkfYPC@Bg?}>6VUx<9 zaoDHMRq`LmiJlc^d$F&mHVJ&<+}Vt*FBK=7q}0sum9pdf5$(Ba4ys^Gabri z1eROk69%FeTwBOz^QFQ{c3|-EQ6~KZt9WELHV+`5K+l*!nCc5m`3Cdv#W>6jX+D8t%}s^RBg$8NpbFedxc{fEiCifnU-#z!RH zrtwjUdo&)FxLe_YK8ZJL+%NGajRz#|(0EYdn8rgAM>ReqajVA4zmUetzo5p-KflJx zKi$4T<)5keI8KZ95``~dK(&~ZGOkooQpnJqBHLhW*E)m>LwAvEfw5I_WdjV|VbXu& z3dNP~8@l_X_r?~*mChTwGx1`@&Kg~cjkhX+b?4%3O5je-mz`_q&hA&PwQIieO?SQ; ze4|bCm3MkD@RB9;M>Jpg=M0YWFRb`@LlW}NU@8AvG++7W44(2Yp!v!_XE0Ug`7~eo zr$-GhQo^34`N}_Mu$6y?;;X?&_=kVNgCFr@dKgdoLI}O8DraZHg&w2;p%;UBy`W^ebs zEvj22L=+SQZyK!% zijg;su!3UfO(UeB7<@X^y3lqZAhH+3oKaLP6R}?ejC6YLTs7AxF4n+_ zl{AGHB#MevB=)nQqV}(o6JteDvB<=J(4yo9*2#%6q^Jnc*u{{NlNWk!yJBo9%JFN) zeiDY9I2IHfg&1Q^lP-#rLF~s7O|CT&tw~XFl8EtnAvG?pdSJQz=Qv(yg04zYaRyPM z@?O#{D=2kgaaLhrec{Bi5uCI%p)M*;G+I<#NHxeZr7rv;pM111-&i%sg5ZdD@cmh8 ze5UW{%~aZv-_hY*snL_hRcE?8(&?3av63r@9n9wL(8^+y1Ws zY$vhDsdw$?|FdS(+DTekOBu)3P8zpwq#P%%XT`|yV*BfTZ(Vas(v$)mf+A2EEw zK6c8t+85Ui>7SwlwtsW`3CEfHL3k_s#eGG4o}GEoz&OQ*uJCUm;ozj2Yo?*Fc1s| zTY{lrIM5o5#v!W{f4dv${O~>ICyi?7T~Cj6QcINMk1yWMZTLRN`BtKbkz=YL;Z#ZH z2k{WF{$Sp381%vw22RA}TWv4wk3xtOL^*q*XwnhWq|e=N7@LfsWgFIm_ZwYT`+R(r5Mfj2_cMGhyvZ_)~M(_kaAZU;mtsQy0wodD1vvWsDZT95WDEGQc+^ z63 ze2e0Ohe0P17motfztbH)&LHD?^6&CMByX-jj)5$bNvI7(MEXADzMa|Uj6 zw<-?4(T_||kIbYd#%bGn8h(K>o|-;M+jWSGIjHC20H`PjITz0Y`RN$FD>ljl<|p+luY7vZyxix2;@2R$XY3`C=Gyo!js*_u7`V z+s2B~VjD(hsw>=vpS49O)j1Hhf=98PMkL^348<-@Z>@uHTcoWO_1YwfMX_{R!QH{m zaLhl7J3^m^SW%6b|9j*9?~liDnCpa1w%DpF#>$v5ezzDklRrOpF&ox;!KZ_-ca*LYH?@H0`@Df~R~OZdre z$!Ux+&XcX7yj;*zXj!Y!QW@y$QM<9M&+O2yr1X`oMQ~nE6k&1 zVzH@kK1jsB`({2~FU7hf-!3_toHrMgm0c`M+Wu!iGqLGEsB&Q+SlCC-(Z+f?Ld-+* zx9E(&sPGet|D?jgFD!7vuOrR;dK!}Kmp);mh$Q^MSz7z`SdNz8_FeN)`{|{hMqM69 z!AIW482!D8bNsmf3eMj}gsvs?dJ@0y=l&P+$b~%m!7DHH#+4j$AqW42+%b8B5Q6>? z^o9di(>M?EZ-^z{%y|n@kD{}E#(Z!KqtYJE(V15(oZ!5bi1#z5^Pa^RCMonTq8mAf z|HnCp-BZkukT_w6VSJV`@_FV%ULhlmZAo^#~^oG6MgKf zTVE?2?uBh{N`b(AtzGZi-dIoT7>5j(#W*2nxtEdaq+OT+LDykkw;pRHsO9FBobKyw zkaH)kqqadgZ+lta{ceS-?3FveLAjwT-T#iHuGp*ZX~=EF?qqyp`YuAQnZA$11>HyN zO<^bD--9+E>ptZZ`=OM@az;XI+MYoYV?O+Dd!;pJPl_f{=rrn!Ir261;g zo`>A4Zbhp6Lyz1u*TO${MJ4wd@)lL*?7{(g7tJp6S%4F_i|e|pzXmyk*1FUUA-BG5 ziF&`lRgqYq*KRN5&^4m}biX#UdkS(JvAg23i=s%)?5?`(MqP5=_I@668?pN|ipmTe1oENE? zz6&mWe8%O}Oy5h8i-X7d_}zz7GkveQ^u>i#bA9|mr27R&Es)jvM>KF@uUJXr{2AtV7FLV$!NWFsuH1lf^If=d+*Aqga!%`6B4f)%W7 ztyRn0qP3{4wYH_!wRNjStJYez;8wKOQmfUr)}pnwU+XKs&p9*q-kF;x5G^nL<9C&u z`#E#w%$b=p>z#X_ZS$7Qw=7GzmnDjXkA%4X2!}Y8B8HnHv6Ey=x|+JWJG<-F;%-x` zqzc!!x3)I6b&Hbby3Uf$?$-8(#uic1(73i|eQir~Tcdm5+_tV=l&tOQ5+&V@8zJA> z-cZ+FCrZ|Lw)b>!^x6&U8f%*x>lzw6MQ!ceC5uk3T`_Ovs)Z}(&7RwfQQO?s3@tLD zb)9vsNU5{2#bl68x+$|)E-k6+?(S?}+tb|$OH^2Uy?fhQS1%2fA$4olb~bL%73-lL zJ!{*LF7)^b$K%OjAeo>ah#JGVqg3OQOY({kf^9Jl6ts@GpwynCd`55nEMM`kLV z2x^G}QDflYqRGI8VynXGEFTls88}b;Sm6{7A0ZAH;X}o{MtH7BQ3lHNhlmjh=WzV7 zVxhwMj7N!fBfLm_%?KYO9x=j;#oGoRCo*kmfV6M4C^hh8u|#2+-b8VsfhUM>DlF|Q z5lWvOcDYNd`Vi zoTjiW-;tu#!1>~{3d{1y5Z4)afVk7Z1H~^Cmg%L7KN{hK#1R9hi6M?|U$&@JI1_A3 zWQiIhJV&${c(C}QfiuM|3R5zc7$)vhSn8W5UNYpThz|@rU1UXscs@beWQkNU68NBo zD}Z0o@EqVn8m<9;UBmUjiBVtQ1;8m9z63a3!&d`mYWODL91Y(A9831~{S>%R!@mM< zpvuBU_Wu^RNyC2yzCyzv17D@#0kD0ShGW3HHCzUKy@pQ)zEQ(9z&C5S0r*x8_Wt2O)#@EQ&O z4!A+Xhk=_kY$c(5H9QEoL&GD1yER-1JVnEEfv0PD6>znN8-V9(xEpw(hIarj(eN(d z6&k)7c$J3l2A-?>O!DW4fw!wZj_@jz`HbD z47^*zQ-H76@B-i)HGDeo%^Ge5UZwgxvbPiXObuTGe1(Ru1inhc-vHjF;l04SHT(eZ z^%{N>_(l!C1bnlG-vYi>!yf>@uKGZ-FO0rqF8Tzz2oD5asA1}RmS}h)@KYL|4xEoR z=Eh$HOnr!p&jc>i@OofXT*5|r-N3`8IO9uz2W$9B;AHqTT_pb8HN0Si=tk57Fdb2419v z{~fqh!zrmkWNGrFfN#*kX95pV?Ssl=3GiKNPDA)C;1@L91Uyue-vIn~Eqn*?3@!W` z;D2c8e-rqZ8om?wCJp}#cp`ktE#F@Q=b_A9{1@N~E&K>@mxeRaglN|A7~rcld=l_o z8eR_kf`;pX|DoXvfwQ#qzX*JihHn5q2W9TscNg$v4L<>VhK7F&JWGrJF7Q?jJLtQ* zG&}_O>l&T_e4mDA1HYu<(}4eM;4Td(Vq#aJ;UU1YG&~kqmp=)(P77ZG>}dYh0Gy=ZEhMkm z|0Uq>YIqOudJX>&c&CQ<0dLmu0pK5M_%-0KY54EJ^HhIC<>3qz;%N;J25!`FG4O>N zJ_-104KD@$u7+!YAJ*^%z;CGjlG3{jI718nI&i9nZwF4&@MFM(HT*L0o0@<86}T96 zMi=Q9gWw+^F3tpgQ^Q5Tf7kGI;H%-&uKWt%Bn>wJkJIo*;8ZQWD}ZaX@Ed{8*6`iH z7ijni;D2cL{|0!c7XCNjA80s~f%4SwVBi-tJP!Cz8lDAAZPLw84RA=y?>gWy8r}rF zK*Lu6uh;Mmz&ka3C-8SQ{21_0HGB~Gf7SR(_3=00leGGeU|}*z!$W~bXt)x1mWEFO zrZtG0pS8es8r}fBO~YRRZq)D|;2sU%34E!B9|wL|!!H9rpy79bzoTJ0ONhrboDF=R zhQ|UoYyHp3zz=BnEZ{F{xD)vM8vX+C8(RPIb>O9H{zB!s7x>>=_)mZbYvIoTPt@@5 zfEQ@^Fz`znwzDxm(CRA__%02P0e)ALp9&n(!cPIt)9^XK6Exfo?5=6a{!4(HweYV1 z@6_`!_&2~OY51?er)c;HaQ?m{vxsG3eS+?U`V$!`HZ z8~0}^{CVI%;C{Tq-vBPd{aA&+4?K6DeF%{Adv^do3>?TgA_T-Sr!VKMA}LWh1Xt@th&w$@$mA|A6p)n*7^_{DrLFT@RA}j}X3B^#_EV zA#Pe!-dk9|9!~bT>obzig8XXLz6lRA;$On?^>B*suHQ($1oC^e_>+zJm&x?CaEkA) zzbO6!$iJo9JK+^Z{4a8RJ)Fx|^|vIy2J$O3e4Y{iDvqy*Q+#**M)5C#{C+L|4kP~m zaC|+S;=AiTioXl;MQVORc#jePI*zZ0Q+#*7jpPaYS6ToM2;lSp9vHxb0yrapGXpp) zfU^U5Z~*57@Q?t`4dA>0&JW&{o;KBeN6~LndcuW8n1#ocy zj}72)0X#l{Cj@Xw08b3y(f}?C;PL>j2;j;9o)o}U0X#W?rv&iS0G<}WCk62I0G=Uk zLwk8kYd`lI?dJyB{!MKz&w=TaED9 z;sFDnES@v)AH?ehP7v=JI3hka@M|JH&$lKd7Kvd7UMR*Jc%GPM;Q3;qfftC=4Lnyg z7A{$~ zLgI9hY2Y(Ofq|bAr3PLtW*YcxvBJRTh;t46v}iGKow&%rYs3`>UMsFM@H6681FsW5 zHgKbO(!lG*O9uXxc+vUJdrfiEe)Fgw1^x7?-!#D+#x0zxLqtX@CD)w10N8L z2JR8v2JRN0Gw=rSRRcdOZZ_~m;w}Sk5|0~rvv|S4&xt=6c$;|7z!wW=n4bUbBGbUn zivk1h5M>6wRLnK-PEljv7et+bKQB5Ae7U&Pz+Vv882CkTqk*p!KQ!={#3Kg&vN&Mi zUyI)v_$%Ta179O7cQYNu5E8pYx`7XhVFunUCK&i@qT0aMisc4=Nt|QgZ-^EHUoW;9 zc#pW!z^91o4g9kBo`Jt9?lbUB;wb}vOZ>*bzY%{j@OQ+&419}7j_LkztH?F*E27B2 zd&Oh}e_t#%@DIdi4E$TM-oST=4F$9MZyT-T_N$H$TsjHQE1?OqQbyG74r@JusF@YzZdleeoS;4_))Rbz>kYv z8phV8xLL#4`V)IKOyNJ)Foi#?VG4gHfPbxFlK*`G|22R=2w=-!eA8B{NDJVc03I8_ zQv-Nj0Ivw(vjcct0ACQmTLXA!0ACTnUkTvr0{AB20hSO|_%{giq3;9#3G>Yj3hx7^ zXRNfpLg7yV-=*P$z?T4*tME5~hhjb$R`LG)N_w1>@!{U2w*{X;-?u=0lt21=PsEl}8IaqpxT+HHbETR97G2D;6!A6*nj@^W2(6b82Rkj<4%z z8^5{$N(+uER^Q&XYEwt!_ysFgmXwtA%9N|Ep{=W|KkAy>>gu~!Er)1%=`m97sO##w zu%SOnd%7Ask0DnxXGUpX`K(!flrS!;hKA0@uC8Mx!J;i4O?7JG8S2?g`SL^Ja?xubu-PJn3v%R%H`RQt1S>HjqIhv!W#A|xip4TtQ&JFBR zs|#vc`|v5&*j?YTqP??UiTB3?&On*>(KO-3H56PrzATQD%v-r~`N}x_<)_49o?X{b zi>7tXj6hQ%J{n0}esf1$HdlOmXG7dT%5m?2&c^!2<_+;ex>~zCYFq1?TY5+0puQ86 z!KjEnV#1KVQ;ch7oMPh|m=;4fr~Uw`Kd-7=+tOH8DrV`Z zwk&|l1Gpl9D-Ar!L;-D+YE5mEYE5mEYE5lbhPJAJw#i25L8Cy4DzUegFGtRAdiYQ z$fFVs@~AL1UJcE-$cclzKt5QGyS83}@gxH|=GcK8GcS;1<^^)hyg-hb7sxU50y$=$ zm*bUquk7Sa-Hm>JJ&u#nW2XrZr)m>Diz&Ju`HsXNk`Aj3FkEC4Tw(EF%#q z<+mkGES{WUi;8QQqIhvE;aL{9S1k>rXjEL!$uv37&orLblzd(s^LW}ENS0^LL0-JL zak9o!=wMv0&V5tjM2%A@aU#Ykk~k$2r$CJISbhrHVQ)wC*+%X9Y@-x>wvij3ZRE&j z8@XD33au+mM^wCk4J;QhfO&z`nHNZ!dGXRUic_U)l&9hu1*&*PiK5q7iY=|W^;(xr z)vfW3{Ahe5Pa5CI7x-o&5hJM4@77h)esAb9jDjH@Ua6eX+1%Y|B;#?sbbO9C4tp#w z8y?5YfXDGt_c*XREYVDmY2?1veKos zYw_YX@#Zd)JW!9fbau@t97s1Fw`SfdW`asyXJaGx3BsM%3x-SD>(7^WG!D{m@1vUT zP6Mc+Q}WzA3hY!bT|ReSnRmnKfm<_g2{VZ@udbn?xx2Z&t*)hZZO=N?-N_1%pP@@05T{q^_OCr=fHc(t8g46m&!H-e^Ax_mRr zl&LNs0`lE;ekXpaCqK#Ld-7EVzpT`YFgXwaqm;R|Rfw%6Qic`2w03f7Aizy#ikXcv z^y)Ik6w|J4BJR%h!!L!=GPmh7#2+N^1*R^L~)Ty zAg*EI6f<4VUP^aruXLvx=}z@iBAY$G;JCfg_1g~ReyW+SXA{NcCSw|1R%)bNR%#~g z6{U>cEA6sUF9Axttkg{1N0d4>zCh~OdDQ%-%x{ET;BaTz@HlnsANGoFre5Z!hjPPw zT#rr-FOWK>uzKp{M&5nXICW|b!RTh{J?_{KBA(l=$(3nnRXl~dULY6Uq~57dGE?_EII4H5Xszfb^-g_~ zmjHX+BrkPt|Gx30%nM^%Xy^@8W0h%(->I@KrVm#2w#Dx^*%rUoqUcyS=~XVIn@Ew$mpWHijvs)~i?B|wJM{-(0_U`V=%>J&-?C`YqKt9;J$19s+)`QvS(R4sd zy?3WqX7+kzX1C`Lhn)ARz4LB%d}ZkQ=C#q2H=Z@lZS1P2i6pIQ)JbG_)t|p4-Lg8 zOlWAXTVLDN)6qdkKw>NEN-L(uCbY+T9XgudQrFeAdimP(RwGhddu@GJqrB;9>uhgn zk@wAQ)P|G*mMyid?X-rGjPA8{bt(ux+1&`wS}$=|eN!V&D@n{v8GKY>b6wkvmges6 z7E)Q?(K7=%o4ji7(nS+$ViSnB4!mXUoMJ;u^V(W0jo?AC0$9JIvwb}t&BW%Tpt@p3 z8>dtiucl(Gkq4w!&ud-V*wE0}5IX~BtJXHQ)i=eeN=jGPb+)cvv~14m`qgunK%sQW z+GXvXt#vIWO$D(DsDt2ntmQSU>pD76F7dN6^Wk*%Wzw|CVxH?Qu% z@r7ecb+z|&);GqNbI+8u)HfVm;QYo-YuoEOk0C|t$D`}1uWxJY!)Di(b86ty-wC|Fx7-5M_2S%<-gd>2e^6YJ0b zY8x<0bvAckn83TDZa_~p06xTln6}h*HeS%v+}RkbT_O8_#4*@4JRFE8 zaA?sMkKivp^yftJmp=H%M;8C%_D5aVf1sqf4NYtHvHHQ@;i@sm4WO1BH$XMxzQU*t z_Z6l!;G>JE*4taibun_~zC+moaq<+N5$x53^~`&Byd6&Eu(^%v>UvtbyGojb{mk|q z?}QH}FdtRX&{N+{?01gbbU1vr&aK5%0KK;txQYW;HDQ9&AT?0}583tIIBUt83IE(~ z?Cfl7_wb75b{yfV?`-ENoXR(>mgd%GY0XmFqJ^Jt8UmE#Ng2YV<&+4IhAGFKhL2wJ&Sp*~e7|B~!|wK)v&4`jbs? z7u}tQKVcOw@|czIw3YCfm6(Yn!x&OT*s;%ptgn%o3E>Ux%?*g1u)|8|vgt!S11QRG ztn}wBF))VPNjUsIC@M0>;{Gvf&@7QLN!}f?L`Jo`4T;RjI7A=L>atdp(wQuKqzK!? z6r3z!zJgOE%vErzggFvoDa&!Q6)cl5Q^9fx2Ps$~VY-5q5~e9QNx~Ebl~qv%l~suf zDyt$2DyvkEDwI{W48@)b8;MUfW@7YHLQ=*WE@h;MrOH6sZ4FiNIl83^L|Sd-$uMcO zrAkNIYz>iN(qu~&m9*FzEW@P1mMS;wN|A+DmJGx$6GK&u*dk+?p+aRbTB=mBCC{M) zRj9H^6|$;aYk&$>HmNelJ_yH6RiVl%w+fV1$uboC4lL}}h_Wh4g(|Du3Q|@js8D5< zTVJZ692KgpQZ<7;GfpU^LX}l+Z7QoQ8LBE5o}Ec=ZG^Ks&;l&P&%RdPSlN%r8$0_i z@&@kz5Y2+Jc39;9tk1F%6y#i5RzyM0rDZt^axN_^tRUyovO)@SE-lMekaLMymV%s1 znsa5&z$-5<_rH+*ga6&+>4QrD#oVt#^5JayYAd_REO}##%v15=lAZNGzEjv}HWIQ^ z*jAc?>=d?@svtXsZKWv4PGMWg3bIq!R#ZWD3foFjke$M|5*1|Ex8aO3U3PsN&Zx{_ zXR+ap3M;$9E>?zxT&yf}b0zx<8y>0RE8F0bG{m`LDwY4=WPUJx1{RZ-#trm+a})-R zq7OScH`}eiBuJ<-IksGmBhqsW}fOE5VB1g6!oYms+x&^Lz>fc>;#V z_1G+>wBhY8Pg+USFFWTzn#=BqBibWHX}T89!Awb=41m5NcTveIh8t7l(mYQ|%991U zD06&Snhuhzdpd$dUm>lE;Y-q-(Us&4Nkh~-JOQrArRkC3$wK(x(#} zh9nqX`uVhPy=d90(kZ8j9oC5EVfo(9wRqDSeSVHBP*Hvw7$aJT<*&kVhBFHOnNY9!S;LHP(tbVghdQ8 zDf>wRvInH>2XDqU5~m^mZ*QhQm+v?%$;d-TjuM)Ah~uj~S|co#JI@x@MP(AE zGC_R2@+R&kCC zBZX-a!$3c%2Agq&|(jP2e8(nOx%&rNaUxLe5eR*<+=Su8%sM{^Ec!-1wPj~qGjF}-U|?@#+>JW@=EOh_9W%|2H!K^`x;K+B^SBlpmexSG<4@0W=u539LsU2jvDWE^zc2G-kyNAOtEA>KPf`h3Vh@*+{R{D3aQsb8CvU_|%y+62 z;MooNpLxTTUH>qs=5=eU1irrW}rCJo(D3^#J>33zHjuMTi@)R-I^3v}Sg_IW_ zOTGDo^g209!i=L(&N)~HqlJU9gvMP9voJ@^Q;LLu|H}R~5TpN+(A}3#*>+uDaVcBB zkYgm*TgonVOS=-`hx#nd zNeDfl#s@d1OI;0Bkol>n0bCw;CWCu-FYXj@zpHWW{ZqlY5h)}HcZNSjM6TujwP@i1 zIitbGW#QhF-+Os%o}0EyX)QPn8X}_OkbSGT%KCojdu~{0w|%WOM-)d66y;ghUVgIu z8*4X>iYKxBneZ^{TB)D3OlR&=&9=~i8O)n=$l6_)QywFm9(dE$?ox_7ljSBFac41a zl)1^rDZb27e9(nIVFVU&@u4JqRLPA)pG?wZ z7o5RBevJvgJwcye0S6f0T%tJm+y{Tc2v0WMZxhv&avTn$Z~XxIa_&cm@XetD7SqD` z!$tVIjSTSPa49#8S0O$hrRp*{|E?`m@_vA{gTC_9r9O6pZ{2iva3X$Ko%^w%f->DM z{`d{@hOYw^D1)^)>RUvf$uch-r!O1gM?Ybvkvk}_o`Mm+ZElXs8HjAJD&6! zFI4;W#uH$Qf-jAUpW|QR0;%Y75ZWWd%KQX84-YM+x15&HD_Ctva!AG?;c)7ln-gq{ zI-g0KnBRdhvHONDusm!2JGRgf(!FHM&i}qGyk&d`8FP(h%zvj`XiNG>WXfL66mjBh z@ec7mK*qe6zua?}|B5Yqh764608I}A(R+SbP^+p35kh`Nr}qc`U8@lPc8WdK5|!ZF_~_^7KzY#NmSSJzLdgR<)eYh$P0^YG0?WfpT2BaNmgPgY=z$VvXwP<^p=Q|cUh{v_%DemrIBbPt=O@bKHzMK zY)uP=F3#JX8Y;+4ie5;8Nzv}aXlUDr^F%Y*B&z9e@Opg)WZT*vg^&-HLyze@ObjJp)Iz;9j)R9sMr;c<*Cd z*y(jIl1#=yQDNn#(<8?5D&W)BKk7@?|2(b!r>puu$>QIhlXXoc=GQ+ZdyJ|twnc(% zTmL}Shh){iOI05U7mrM}C*C3Jb~9=`3%brB?V_6g9=E!Up>ES1YdHLm>vK1>pP2fj zQgtt`&+CBZdvDrXg?@!9(N9u;F;_L{So}l#-CU0j2b<~7Fo7!{~I-$AZzpks?lh)YTwDxR6FyAXqal%NuE?J8}Md^ zt@-bzhV}Lwxv+RTQd>us9OpV8jXKYAlJcCwVNTL;#~NjaxbpWRtrJuCR3q-ib$=TW z&*!}_BUoeo`X})e9Q+m5*fINYKSjpq6M?sXP!W@lWq!`T_WEc7{e#d+|G#~%N= z>lmd7x2u(3%(BG2!2hvdY_P=y+Yar#%CbhJawmVuRq%_d=c9v19&w@-CC)`7u4Vs7 zB!`HGCM+rINQ!Qlm^kr$aunGWTsY{WNw=kjGp~{|&bFb~mpzsgZJC%@`u@aoCMHJD zFKlw67$rIfoRJi5oS1ki<>fg0PidNylttaf;K5GPKqock49w1QQnPabb3x%-gR`>I zoxEX=lbU6R$+_r+@QLv)s$KUY-%1^fq}jLl^*{2W$`nD91NWjB(!DB&KZkpAuas`Q zG}+$M4dL=G;8XA~nGPM*){};+BvMd|e`(oJkHxuI=1K@_Y9rot?2|M|fxGGI;PR_F(0}?7t@~|DA0K>RA6{|2@+d zgKazfUHET`^xtoj|2ol#Gxq}LqLC-F?*k^lJd7H=a4o^G0^WvoZ*ui+`WYm-POS=0`?a+b`R;o%`TQse`yHyoX#Vl6LAxnDjgrb;v&=k*d9^ zA;+5dlJu61p^&pVa(>=TnDU0U(oaU=q2KZMo7dqt&Il)ItmA}2V=&d-nrS=ezz!p= z6XP@PY!wL#_L=u^s)D9t%+g-KeD~{?ZAYGj6E2WW_&E1x2@$7wsc#TYyy zH6ppu@Sx4K&|I04n&5;Brc4+>$tpOsYy~cw=*^BSTi<|Ow@6OF2lXKWv8mX^3nCeLJj7_N#+3JRL zr6$Z+D~A$ikRGjxqn#7!iWhBgPimrrkR=|(h_M)oh=bO&wr%{rBSjz(Ne zC3T$V-H%upoAR@riXx{P^O@YNTxaA2r&QezEpo=vZEm)ja*J1B!-*NQ$dlZQ{ry!S z9<$U(G2HK9SdUw#>r>2>HoU2h*Aoypibg5&{S^9+8F8k%<5qIBu%57@k0DTb{wMK! zl69|#aAVAO?A6AEhy8zv^8ZsTvBmR$yqlo;Keq|~<9mIeIZ%?vXaqN6D5|yX#2=s$ z6v{^MU1|g&%Wnob!&5`5L8RnekQ$z`jJoE?=CtBeNBVmt1b$@Vlgi@@;kpSj23Cjc zx{D*5$#vt4G%AtPt6q-gSA>^{NObPPzJz5{SRAqXXHPZN&`{JMY5Oq}aA- z3UNy3O*$hn9D81wG_-1~Z_*M_ zH*@3-RO-jMEght`G&C!#FxROna^_IOac}Z5lEiYIX+_S0OkU8Ab<$Ft)X`Z^)ku;| z&2{pII1`3BsX305mSyMB`t~i@cw*Wbd9QnMTl));KR?9hZLC)Ujf|qG2K9=SI7##H>Gh! z&J-SuoXR3+HnY62lO{L|!O6?AlX%-vJOP_dOxqz3bT4i@zW~z5DPirj%>jy{cmvc< zdzd#ssn)a8uB4_yt%t5p(l%loL;i91b9l|fyE$^n#OCpT?0EatF7m7Ftdim^JBvK!#Q90DeVbpRJlRkDFN#^a1D?V=H_9t^+XdtmG?Vcr z_Se}wvzMOoN&H0L5uo1~oSm`R-@Bfju~9Cu1N+x!D4#hU-(;{|pP_w9-$~-#`TZ;3 zNmoOxV>r|8AzNIJ^>p(4aHlcSoeuLX#$Nuh>rhzTs*UW3MYEX2N7U3{3_340gNHkD z=e00$Ue!yfks0fiNR}>gK8ave{F%u4m_0;Sr1`zvI*#2uZF^sFYx|CSmW&(OR`s%L zXx7Hm1U11*;)Q=)lb3SDh3NfXLbvYD!E$ty=d;M^k!IEVCwZ$3>ixaUKeUbIR$#97 zQfhSKuc+-sZRg@hPnwk!4LP(e_AD6NBHLCDauOm1RnKAm|-QTQ+Y4yyKS z;e1{k>CYC1wkWaflpC+HtYK-qD}4Pmv@0B% z>&?tEpYhveG;KmO62_iX7%eGEZeDgrs)N-C?^-2AJI1G=t=y3q_E{~(H{zhgNq%ZlQnYy*cH_HY*zs-yzoa&hpPfhR2q$%{GjOakD4YJK=4W8hVJBlSJ8^4ss!jJ| z-~BC+H|O!cX=(i`;J_47?kE4s9_B3?yys%Svdd`un1(Z2njes^M@t5}K8f#x5e6f9G1_1ISAcOTZm_9mBvMKY$WCh9`a-ON1G=o%%3bu|T@wPoyi- z0}9!R4jLUzcET0oD$21k*PrS0Lwx_4zFMB+L2hWPlazTw$acC)rh3jB(VREI_tf>h zowwd|-a2yLHE`a~Q;v^w|NS=k?g)4*mcH5QfIx0&>kxG6c1~Xoohaw=Z^51u(;t(U zxEK5MUw|~9o=czBwGIaynqo>1N+ZM4%?H-!+8}94}VX3_?9pz1HI2o0h))pZ2Y_wis>OX@7!4=Szovx%FVt*rN@%+vGZm_i*&nxwPeTpU>Zg(i(b2zUD-5r{!_n_B>cmg1M&`;8T>SOo! zkfguILdTr~&)(K6|5|4WEGL6~r$21_J*MB4QV|@Z@7!+N;xyYH@P)5f))2Y9a@kjC zS^22jb7H5Gw)EXuayF*F#+LrqoioRM84shLjPgO4lCw48!MZT50>19lL@q9#ks86K zBR@8FhE+Z5>uX?$eS!*K`|Zgwr~%%g~8cQQIRtVbKq^d>+g}l(cxV_M>J-3&Y?pL?1`vQ%H;?PEmKu7@&ILgH{ z_s$Q5w3YLxpIdBzQY@GKwX=P%F}dKqmanV!ah)ah_HG}3Tlkdi<7Kpu2e431{|Oq% zT-iYGqXvS-93DIuobPO%`1^@TXe{dC^GUb3kDdo@j*fA{W5e!4sHAv zNv1}e`Y%66cab$|#nGq}t$aS3GnSm^W}NDbjtu(N{YhAH554*+ux7{Q~ z&kC(}60_e6jdZ$;-zvKu`Z*)f(4xmz-i+v_2}#i{q0K6~gXmik-7A`sB)4diq7Q8w zc!0XzJG?3aJ9x3y*Xq1yW$w^9evND~4F=x;edLV$CA#-r{Efsg?IU_Tj ztZZl2bSEp>nKRvKn(W{-oV+OuZ5iMU425%sI}<}q18~43C&w8QT1^wIk(gl7ybFtl zQCZHo(B=VPIyt#ndGg>Aj^Lc2_De0ry}142q=x_edLF$NslL^3y&Y)A6qVKk@5s@N zcfiggm_cXaPJz~B`DpKNA%3L5v#YM|y6&DX%-BNwWSdXUxeveJ3-QzMorsx6B|y7j zRiJ4&i6j;RjHeWFI<%Jiik;zsVV-H(qxy|+SommzJFZf18|Wy&Io23DgWm@jxMP?1KEU=}ZVxd9M^ondO+Y`I zf+ymUZFEq)fl@ur>w+JK(GJiI2I35cW99OR;k%K}i5X9*F?tXF1b;=rx+_dO zA@ZUa-ua0ih1rG37wP)6^|!#*M1}Z?MF6$Vo#!UH#9o#Sq&bbT#Tf zO>U)r$*+GJA$$+Odl=#3w8+NIqf7tpcZS^=7p;d4$J+-UWFKHBaFQx9-^i11fjoh< zPK+N=4Y(KgOHTqBKMP{*3#VAr)3_H!@f_i2z9V=$YLA6^+D$zZu21V5V-eT$4Q<-Z zzVS`v8#m!B0p$J@-Ye(~oH{$rko5#m5!srClT*BU_O(wX%_>S_6TP$%0sWq#7R!&U$KfcGc+WNwTMoLl8a9vowp z^3eAM#SOmTSr9BFL3zqF{Xk!WDnq~8j?Y;1q6Ekj;x4Rej&-VfGe!v|67rd;0;Q6J#eMYe`On2Zn&xG|s z*gF?Xnm+9~Jqb`E~BFRizdWU;R`?YX`r_XJw=b<~=F z2!A`?bLsCp@!E2(*OrH>w(L>Wc83P3E9bZElW2@Rac!GglzYW%+w_?qVg1lC+cw4W z+V&mJr*7LcUb@#BwAtAioBaK~*%{rTaaP9W*|b&*oR9gTYU{UQ?uAZJX2N?1#UE$` zV{8C&H2xDOfPNa~7~}D!5nJ4j*M$ckK)>*9ORn~w{vQm;RokO>`MYvJZgASBjZ4MT zEcxmjo&OlR06T6Kzs4JN*nctEofW?xKh52ej!Zx&;>h+npeQwBG&}Eva3k8s7_<*p zaBE+JXG1W{7tFe_FTqnGXkq+RGl2*lTlN!Qk73?Rd_m^ZGu}*1RL5*AJRRsqr2DB! zXCr|m_enyerMT8tded3&Y+ajBb8)m&x62&PVp6=v!CpyVi$+&0% zO?b-cQj;A^y|=S%*t^k9g-0R-s`k0XhM7zX9x#M>GxfaUhNS3}>Lrl@MIWW6%G0FL z(2!q5&c5Tiq-Z$;vJsGW(tS$4iR34ModPyxN~&osu1$&-RWBKS`@}>lBkZS=`jB0; z%PXctRkkt)E6Qg@{~J^^nA!hM44e7~fo&E2o6ABf*-F-=RxcSXyj0v8)KYP(mkdkr z%lx+&XO4^{RQf^OEW)oe0RO%T_kOZO^&|HWBPC8M1j@BZ~8>R+?zK?%>5=(S|* z;VLpX*onHGr#pelb8pnd$tQHMV+0;X#`w)=JZBj=7D@+IIs+FHbp}q9gt?fDh3o>- zg*Q<%B*BL?2q}`G0taOc9-ccq%PywAdkxCt#LUa6$8<05yYckdf3C^T9N?X5E76W3&wP=7TWrNYA!71Ak!XRu z$6t9-xa3_;1?pYIcjJ@YxKAX?BOCPUmo7V6$r7cqLA)?gT0xUO_X;bXC04mCrn;`v z!9koHqG!tcFwwK*J^spzbP-R}<+5yXb(509mwa8Z(_B^*H_PzP;sbQdrA$f|CCeAp zlVqK$IFjhLs{ExB9glyMZ=xmg9)IOUMi9>uo)JFFD~d!<$}>VnhhABZL{<6bXyqH$ z(pNF?T|L~9En4~bEH43{MTZIb@>!m-#Mf;ohr=PS=|n5#eV8acS<&m8;t)@>f$B)I zJnb$E)z(2N`InxiJZrZ#o#+Pqqp~JS4y>n11xq|FO`qkZ>9UTV=KWH44$%kYeVFJ& z@*aQXMcRmG39n#%mRGPo%d2vqqC~5igK$$uhK? z`upp{R7(LL_E}zrq%FGrB!v2*pRIF!C8qgGn4E!5yXtjFE=WABh59V7h+P)yutBCP zyF!BNntZxne|h`-d^! znn*Mz@54k3x4?Rz4h{>r!J=I#HgBpdTelkGgcfCSAnSbWvqW)=|oOwA7PM zv`F6fcP>Es$Ksz>IzYH|`~R=?BXueV>~Vt1`!G@3PYjk1@wD>kWowm;lSowcabcpg ze-YG0yrb!&`aqm~qGzE%a9>JvwY<+Hdak?=6I~~DBxDT@g_A?ktZ*nfCzK2_%MOjP z!lCj|I2^ji9>Bbm9Duh%4*sTO6DJ%>9gIIX?MX3HvcsVPVc~x2!%u4gTkSW134fq%~il52`S+azLN-@;ZQUd%1#7L9upd$9}Z0z77mq+22LFj znqL5#HWG;zhC}J2LiLE&5DAAG6J*qNNs_KlhFr#Q{IPSxq0rb+xCr;oI2bxUJKNW-Q7OB7<+Tuvo&+l_X9ZaMFOO0~V#@A-YI+#3Jz1k|Bv@0?Kkos#ug! zo*YV?k|ad71ayn<94^Xo`B^?l9*{a9Wq=TQl0~98^+%~DfIv5vAECrii5bc15qzIs zB)O21OOO0(-S=|T*KjTxcDWN6ByTe=yLMfO8Qem2ZrlqC(vr$+}Xfk7k0M975; z5u7|=CYF7PqdDma2;xOcSgDLRE4ex%vzThK7p1!a$(4cP2@zvax~srWdTSXHaVBvh zyg;z;v-k^J_GfH4*4}T)Z|6N=$?r=&Xo(mc6>R|575LYNfB0;(`-^(S#zh^Njo)@= z3Z0h`#<#CF6a54_0p)7rYuM|_?1{Z$*^pQTmm(d+0cNKm~u(h0U& z_cOX+$UOhd*LgX3c7-Ls;}NIc3n`o;3Rh>~)5RR7^ginAy%c;KpEce@G>+bU;&WWr zNBJ=sf99OnTsMye^r1iQzrI%b&}%Jyve(o1xUcW?VA_){v5jaP`+DbF>hnLl%W9>a zKlk-gDbcrbcPUD#6FyH-%B}r`C2k~&bZ=IeYRmqG#UInN@v$hLUnATvr@fG%nY8yQ zSlp{}`lX*fy)b9vTdn`2D5nq1>4Wln@lRRo9rn{Iy=UU3cRe&vdj6+M0c3uE<)_E# z;G3e?BFqNm^gua1P_}2kCB9AJ$j^6)0&{*3sPv!p(~nU&{t0nA{!#ku7vASGDI|h_ z_H(`sy9v*-1X)br2Ykm*d%b5R!(i{CPhxWxf2yx0TNZ z;PmRZNH-|k3d**EevSCBS2n-q+w8Y{x4iw&Y9XpD>p%E*-bniJ4J+AxL^<8~7X&f^bFf&wkUlnadR49b#Vw zWt&0SW>CYI-?GH_DL!oaAyHt%mw}CT3e4>v@_$tFoQFTDJp9?uLyW@lPl&hi&&vb1 zLwsh2FSh+J0o(EY7PcLfZ3kuBK@HpAw!{yhg>1irDDXaoA61xb`>V3;op`oA1xe2~ zRlZ>1V%z@a+s5r_r6suifwFC&Y#ZoT5Ql8x_IFtI4ZwF2AJ}Mjz--&Q%C`4>+x#)o zu+9H;1Q~~m?fbiL-*w>Gr(0r=qO>+8oTw<<3(WR{UPE%Q@2f=LSN$|FjSz&nZ2|vG zVZ#p){s$HRO%?uu!v9t{i_%5>Aw(h1`Td8=??3(g#z-Fjgor`Xs|)YdcnaaXe&FYo z>)rvXJ|0*jdltA9O;4luZaR1?Gl*t@V_b# zANzUm{mW>V37GMsFiIVD^7t z_9Nh*6CeNa*a*zy4=~$n*>bLigNE*0&A0az#Ps}w>~&wA1Yg;UgHmia)*sv+)~WUY z%Jzb?y`YBwhi$VT1bz@Y$^Lyrf!RL%szE1V9K3MtixI{@!C#p1?DJk#qY$|niqmbsO^E$145!1iVjwE9rO^N%LJ6` z?taz(CgE@ig#+`r25j^Rz($_{{DzX}IRx#q}mugW^bFB5K0-%w*TDCZfJ^9;)EF4dOvRM^IO24-8*lq~~% zTYP_{QJ!oGzDhz?C_B=9JGg9bP-P3sc7U=SpvKsSkM0;_8}P%>NoB`<7ckp5NZFU+ z+ZQ7_{1d_*Ka5u#IE4Ks)3=Sw=q6Q0plll`+XiaP?Xv=91-uVh$+ky{0<&$|%C^D% zunh+}DGpt1TTZ~XZzd(vR}t{LEH% zE>n6zSufHx?1Vnn3w^8?<;{AbkM%;otC#J>8iw-?%KBh`Tzx1<)(1Tt4{HgI2g>nK zK1MvG&vqbvHy+yoe_=b|e{2Wr;rt<=TwiWJ&rYqwhQ&f@nDBh?yerpZCMW}>%kneU+J$?@jy8q=6^=Hz+O%t<>=bY=_B7< zE^a%&PU!(+=RB2g-7peaK;6!1_R0 z4r6v)ecw`Ype%>+Gp-!QOV$UAIgXG>G~nYH;xa=@i7j4qWBnp zI6f%HM?cN+VF&ve^l^Q`9xi9t!|B5wt}ocZehj``EkX<<+A73o;-lX!CESif0EE&1PAA+U zL^aV1@Qpf!X_lVciSr?fze3?vM7!{uT2VA9obSZ%R1xjLZ@DPkMidLIjf!purE=Io z7=!SYie5wXLLqjk@au_U9JrDAC@;8zh+;fIl`_7QaIqzRM0leR_Y&PC1d3inQJ;?} z{3zjNws?kU5%vd&k74~q6@HNTkUymGYlI<>Ehv_MPtku8MR{U5&gF<@B$p$aFy{wN zP(0BZ$>#2MdiWuL=@xFc*RGRi{!01I7jqioF$-ej8|#UE6OZMCn{Q?XrZDp zMNx@!5s#i9!Bj4X(}}LM`P=~IvxzYJ)i$Ci?~O!P*kU_TgnvPWU!}r#6J3PzR^fXU z|8}C#bGPC@P88+-q~h-fP2MKNvqVw;&l4Zzc~Ie(376oR1L5sL98&z(h!21LGf~*{ zz6$@R3jdc1rvuOwo()R+^NB*wFok0j4n0LgAy-cPOK?6-g;xO9lv_Db$W>A}Kuk^c<}ZzK#Sy_hKUTmfoVVXa3riuO))oGo?}Ey2fQiB5nY z5=EoAnP`F#cY{)T_kt$lLGS&9QLc{=-XX-JL@yWOapJ@7XNV%bSBZ|p9=F2(QZ&(# zd>pu7xdKH?h(d2AQS`&pK}r8iqR?MWeCS_D6#7>ZAA`jz6@EJLQD5h(@FvA?BU*v) zqbb};;i#{Rh(gZ}#lM^|{PQY>_b7UcqI-!}BL75T*Mo}x5GdL8Bw^I!Q;PqL;vXc6 zbY2Iw3xs%wFxvI|M3LXb2q^4M2Th)YLmz};UyN{-5QPfQ1;zKe#hHW=zkw*muQsCS zXEqQ;xm`&V`o0QE`mQ4keYX&XzV9jg6e#)di-e)?6{4``eWHl}5oj_E!teo#pATw- z7bBVoyNJS{##1=_qZ~AO3jCKa;!h`ve9t95^vqY`3yBYXD-~Wv81k!$LcT%q*AYg2 zv?=}u#ot17Dt_NX;q4R-eU}qO{Hqjy7h%NTqwrou?^g7FqNvYDK&kv5CyMw7LGf`F zafm4D>vf_dgg6YEj7h`$pfnzRNEnk7DhnFd^NB9D#T3xwlZ2Q~80nv>@D@e4EB;jq zf0b~xExxDlLyA7D=pPmRP|;lY0NFdADC}4QN_MOy3_I2;ev{(25uJgPl`8x)6@G;Z z-=)I8slxA7;SVYPQ;PqZ;=e`wnL_+i@l(*3kRPNIg->S^t*}H6QEU#xK*_!mQ1%nT zv*0I07h^moKKiX`gjb^66n`f1(SOY+T!Rk{DgI*OLw*_IRe1G9@mCTb@@El6`7{wl zeRfj#X*jb=bTP_-_=tZIVWhW3@h>Jm;$KFT{D}Ccqn{*th7eyRx){H&1WNI*Cye-e z6#quzBmS*K5&ur&BmR$wVsd&f(Z%RLKq>x1gb{zA;y*%s#D9_~;y+LPYP3(Hv+6hR zQKE>Ssb~z8#^FMu7>CD$QvFY(aI||mY?eG1{WDSMIhpv-Kc6u4FI4=+#E1Tsgi)WX z6#sPML;ftnsL$1ke=hMMzn1VkyvIZs_1Z}k_H7~leDniEk?wZlL(dMvNcS?uznu8c za}`mt^grIk$DBd38Bi=U&Bi_x5e+%&u?>3@{cQ5f5qW*|3LjO+`@gJga#D9b^ z;yW?TE8?O*W{8vFK{%eF0|8>RxBk>Xc9ioW;FXCfy`61C| zLVQFN@js?;#J5vq{4i1QBcK#NjVR*h5Pv!5BPu+f_=p!HjC2bWzmWKdH=ZcsRS|y$ z=F3D+MZFV+{^=Bs_|=3F|769VOMJv%LKN{&SF{0?{0P69C+t+rTZp3H=q5S{?U3jI z)FV-v_YqCQ@2L|_$B9A3zltdS?NWF*(SfK>qWP#lqFFctPc$1}9U}^Tw-e38d`97W ziDEJOpu+oz4o3YE#iH>E#ea(EP_#eLf`4Ez2`^emfS#G`RJ4Zf9pE)M<@ zg}sA7$=+Wb-74fnEa28?6uOYnL799$A5{2Gw;v+v_APPIK zBK{g7u2JE;h>vu46NaAa6#shSqn!3C{%wkXJMp1!pW;8F_>U_7^MvbA9*TdE_$ZIJ z2&10=toUyeAL$+@jC9{q{P&5Ebi-(iR6lg2nc}4pMSjwWk9e7c*WzR}VdN{9F!baT zh1@XWLr(!w=qUxIc37$C6rw}Wj}S#aFjw&x63xZF2hlu???ll*oJlkT;{(xBls8e# zGa85vhyN0th<=4=41Ph_18*+(pnqT&g>IgoJKe z(7|zZ^B7=+fSU+9q#Pr9u@IQn3p!|9Ky^OV@BM3ER&b7D}WJ2(%7`}btq_g!oq5^_#;p+RQDsD% z_!cjY^DQ=7`IZyKEhmbmz=^{3IZ?Pi|1c9=mlJI#ibOkza-wwOUzPr?ac2RAG!Dsq znV5l#+MliQXb<*wI5EY=))`;v_?v-$y1wo)z=bkg|Cc@jhiPaFPEd;-8zB{cA9P(+a><9ZybA;AnDg7$xoA z$JN)*bX^^~KDaKM6Coxp%E!h5e9M2_IMgnvT->AfAVofKlR-TxtxBayRV;e2m2{^xSw)~o&779!hXtCL#{vhJ+q(s@I$Np(sxBa zGOlWL^}P$?_ot8xnO-<4>>m17pxEpeAK6ot-!Fc(26mkzD zEO-U;vHcP}7YGUg2lJ8mS&VPGqp3K-e8eu5`)@&&!F+T>&dmq)-E_sv#}3Htk-^5_ zU_J`bVRsl35(M+H3vvhJ$OZG!va^5n@hIfnd^9P&@$&IJp?~$!fKGBnocsp; z>Tbxn`M}hTuXy=*6mmGK*6Rx9<6jueX)X}Fg8A6;B|JY43IPZGYW0=<^Q*fd=jH=L zCtq>%0lDq{$j98P@H|iH(Md2LZ$a*DUEu#~?EGRQo8mZL*@jA1Y=oo<4ve?itD<#E-5tWoIibX|HEQ%$AU22t`rB<Af@ObHCs7J?G4wJAdw7x2`$%-y1itviH?<;3Xm{p&VV{&Wp$~ zazDQRayq=w9BqL1G2qrU$0E2~fYW)^{Xjj(t&R`n$bow>pr`X{0o;ZFr#aR^EG9?m zL+-O$(bOCR;QYM8E+i?T97Eua@(0(XsX4|T#_uku-mhwoUUYmWFupn-n;(grSF_-J z4uAX<%25ILwr>QR`;9{QVbK`O2(f&j|2c~vXLOG5H_q?m;h2~fQH^6{f*Brf1;`bi`PUltE zQ*k-Afb-*F8dgF%#=zn0t%jmGmax+uZJ-*DueLm0J7ZT-&9VNOxOuf5oX>%wPD&`p z6u44Ej{b@8yw~wq_Z;3=1oSk=R!oANhQ)o|U(JK_IsEHaD8~}Gn*(|}9s@79@0^6y z9N&VQ6vpm0U)_JuboX_#TV=c!FZfJJFJ=8Q`cE4@#54hzVmfW27JxxvB z!q{Eq`oXnFaHHVPh~VbIVOQQz)OQ4fwW)z>Y+v)c;r+Af4THNjLT@>eD@@1vE`hr^ z!gu|9aoi4YuSe+h?~Uuf3b>&Ny$zUjG2<}@E+%gmCT=;xw+b$1UakEg&UafR*Zg6e z-Ue_n?JGrc%is=pqPjl%Ssq^g2*<$(HFn@%!Zm-4{bYbMk3(tm4WHD0`(?YO)7;~> zf3bZXZ@vXw8*S%TGon`lXWN_JFAlQ%>N`okJ;bSRCDOO~)4J~h>8bB(a9Pw_`%WfK zeLKO$ARhL{~$f}-9f&m5~sf3M*23**8BNS(o^3SaK4|{ z5~sc$;9~lDJ^3z?p8EEZ?>getcPP?#f_(obJ@qY-@9D&;@0{Ztva-m?^T;lu)Ph=@ zr~f$0?yGMLIN#4F5vRT#;4-eB7wVfM-~UKYee>jdCUNRpjPxBRU-PmO$~!^6XVtKT zQ{P#~Ib>y_d8_2RD#h0>OqPd=jmNo8&Dy8Fd2kt5&kOY(1ZUfu-oYupMQ}ZiGk+@~ z-mPYTp51WFPEnHcJ7b!&4cs4ho|`V zfh#)SD^h$bk-p8J*L{yj@m&pW#QFO7t)cN90~b0T*LgKVzDK3_&VuuKH>KpweGxaG z3*dY|`|l_1eiPcj#~Xv-yzliXzEyBBdE36M`yQQ=w;i1C=bKV|r@+O$9#zQKu7_bI zly?DK0d+Q?i?~?{jc*=rTw;7TgY*4-Y>Mv?IPZIV%{J(}1TO39d7<;_n6K)-Z7IHO z;K~rPymvamP~LfPF?n0QuKU{cxvZF;&Z{-xig?(3@4?MV$ae%>%)FW+UtAhvMNfUF z!TEW$wT1Bfw;i1K?MU(M z1n1|~V=2Ddz{QO34Ef^Jr=*1P&VsWXme;@UGEQHAtBy;A=#S>jd{@tlQ?-&3^38&) zpw@h!N~mx@w|pNruR6h*kLewk;(I)}yyGTPe7Azjx_Vw{-YN36>+@I%<(&rS#}^-2 zC&f7J=guGE#y1bnwzs@E?J6lD-#&2O_mvu!Y^T1nk-kghdt!?3GWouq;@e+|%R2(j z=e6qwS_$PHt<*lpw0@Z~2*o(fTdl;6Z|29kum9dBb4dyL&Vg%n+#xkA*$$U+IN-Qs zk@U_XZmn=ta2cm}HgT%giVtpl`z|0(^)ldm`_3m$^}0x}mpIky2A4&>^~;6CsoqA? zyM#E^E0A6vajG{;dY2QYdgG*b8F8vNLwZ*cr+TyCGN`w_R}!asi==1!87nqEs#gU! zh{sLu8r-ZHr+S6?`uJX#P+`46a6PCuy#eA>uS|M35~uB(0he=nHxQ?Kt@!ZG+HJnK z5T|+>aK3#v6Q_C`NpFZa)hmGOK)w0iMx5%6linS~son%Q|2jBKoa)(sJmB-*O`Phr zfb;FUi#XNmBE9>GQ@w6*-Ke*`_YtRhMbaB3PW6VVeGd_*dXuF0C~>M+ruK~yr+Q7l z*8A^C;#98%TsP`1?-RtSUJvO#OPuQEz-3Txde0E2dIi$kPMqoulHLo%sop5*y-b|y zjgwx9IMpkY-fP6E-VEvOBu@1fNbgPJRBsVn7wWD5b`hs~*@gP}mWfln4sc#?H*u=B zk@VgpPW1}lim12tO%s)mz)rO1;)YpoZ(T(s4ySFOeVt^B`l?|o+WIT+HSHlgnn$n`2p)a5hU6iUblO>j5dTD?|i4gS^m}j<$-D=4fN@vijCod(_#FwJ+@uC5_$PqNFF<2mP*& z=7ydIS+0J?(rA54w4piLCF<*|=he)tUod-N?c9a4XH@rN)W_OmD6Tv#?P_R)i>_#^ zo55hr7-lRyy`-V1rz_Uj+Y?0yTGr9z?6x&DsR)&%p|P5{{Gc zRQ;*rjfXtd43wZ2%anabH_maoDNfD43W)zbG$AhG&i@{op>ZmxC5{$nX*^2e@nV(6 z5s8b$w>4Jsqr}r17f5-5_`AkA5@(B{Ism0VPMqk%$B1T)mHx5fDvblO{1CB4<82b> ziAOZvF7a^jHy0i$@_Z0r+k~GbMu}N291-m@Z= z5*Z=`co&UpJQ8@ffhPdJYv2=r4;uJ%;13LZ0Wi$UjrKc$_ZsrcfS)t)b-*te_*=mH z4EzJ&{RVy*_*Db{7Wj1o{}=FE27Z&}RXDP~9|FH>;0zn(4Ll0?Edx&ge%HX$fDanD z2KWO5F9wDqxv~Dsfa`(@+ylJCz*hh_8~6s`76ab_yw$+p2Y$i8KLg%p;NJjer6m0Q z0l3=0`+?^g_#NPR2KK?$0s{{Qt~GE3c(H+x1FkdhNx(}Cd^&Kmf!P)<23`&v2qog} z15P#Y)xhZnz6p4`fxiu0ZQvgQw;1>l;8p`a1Kergmw|f>{5Ei(fqjT|m4Sx72p~J9|Zoh zfkSAk?;3ana1q83r+p>>|ILt}0DP1oKOK0vfiD1l-@xs_Qw@9>@G=84H|{g=9l)0w z_=mvXGw^=`|J=ZPfnPK5{{Wwb9CzY>5BM6Rzf;0O6dO1X_+g`c3xUrt**;MKry>G+sm*8u;)@OLY4jgb%c0Y`Ls>i--#X2_oc<}u*Z??vEu z(5DW56Zi)Pw$g<7vVpUK?=|o^;J+Do3h=`Qt^xjwfzJm%WZ*WIH{w|X{5u0*2RzBp zza98rhWviuV-5Kuz&u8r`aBCf%fS1A+YJ17;Af5g2x4yhgMo(urx^Z@1x_>Y6yR}a zGsoX-;HwS12zVrZj=T~3Pr;{yF9QCxp}!XRPX@jY_#Xzo4VZ22l)n%7kRjgzJlv2! z37lcz=Yfwh@Lzy0Gs^!1_;^De#9D=Ym0RD%8{|-C| zZQ{fe$VB@ZI2-t01Lp%TGvX@+zSzJg0bgn0dBEQ>@Oi*v4SOxX9Y#DWfS<*fom#_0N;n>f$MSNcYwKZNU}t_ z@DGwu<4iHgg$IcdE}SMJE?g`sG^Q0l?4RJm$BWYp%!TuOV8*Vt3~`Pj_lxObDeyi= z4E-2zK#!L!-{sPuE$y3fmUrfR>eK%Vdj2A&+!>D@`9VECJ920Ib>tKEcv!Y7J(E_|{$&xKct78jl+R=Ds?vEGHN#Z4}JiMY#!=ZYV? z@G0U^7p@V{xbUT7p9`NZ-f-c0LJTq6W4_3A;Zj{&PIIz=MlDc(Mo2G%)Lbwg*QI%&Dl?gRk)5O$MgD zdp-D924?(EdGKD~HmoN%iiO?nfo7U$k!C(;*2Z6_8J+K+qU?}(H zLBI`bfWabF4AM9P)?g79dB8t`jE52Rj{&|B>yZr_mjMq3F46dS;5PW5rtzu3xron^ zF9PPK;+ZIxXw3UXgT(|~9GO;kaYxtky6%qFhOSs|Tit?%XPi2FR&8BFXJ;L6AGX!^ zG;}X7X~La9+#IX#UfJCfZR;*5fULJQDo#FOR!4hxPeXf8BtH^a6^Z1ZjmGexzDwZ+A~gT~}Q@ ze;$hqqn#aHJ&~nd9c>Y(a*_TP7s>jxcSIvAx}t3>8>V?HP#f*;iQw*Hcf+!1+**G- zrdqtB{ngHvP9ibYDowFiKYvN8LRNAAt-tjnDb|;{`sIkK}E^BFGgN!>izxBVkGoIY_E+hybfvq}mF`Mcx+`7ju5@L+tL)Agcp~ux!Z=Qe_RMZ;h_x>2 z>8ht=6SJLMxSv8l4K}5#2%~o~7{80b8n_s&gNwmhxEQR5i{Y(_Hw@XPW{Gld~Dw(Dg7l{dIIr z3>{q+gQM$WaCB`9j;>FF)6Z}}yZy}ev)a$7Zl#15-AoCFZl}|^wy(v~-f5=u>324w9G$hsSlH8&vZZ9vxAfUI)@y4}hF#1Oh; zl!J#Mb;l?N4nyjWQ4Si0)E%Q7Fbt_XMz$c;rs@n=Hx(E+!E{Jx;I+|tr8Ia9yKvvCwlLUtPSuG9i?NQ8Y4Lz9K z`g7)Wv@avqnf~3 zsmJLp{zTiG>!n0KDvFha`Hbu2siFXn!SW%}dW?>ysIo#7G;7ghk7%mHpX@3!rNZG) zaq}JhO1GUVN58V%rC;UfPjN>()zP2gwm;R;=Z^76Z&|5RpsdvGxvbPFQdU~#E`zld zAG9@|Ca$RL_xNzdlzuGvL~%uxV@y5!TZW|85%JO7c-VZVx6+a5r-sWgZ5q0XHfPC- zc+H3=$77Z#-U|}Nt+aMDm0^_7Hl<6*+z$~~x-3=3qm^ajGFcYEd&`y8 zC{WcY{rpae+h*BBKg+U-C|I_i-zhG?Q`~;hdx=N3tNQt^a`~-Fcw$?{+mZFH>gTu0 z<+sZ1H!fq@sr~#;b@`nd_bYqMjS@9rOs3YIesPtRx&kXJbsLKd+25EYj6N&F$&V+|%5Z*U92sSaK};5p z3uP=g*XdV0?oL({XFoGzt*x^S95Ji4 zYj#&xN7tOzhGjx?_2_;&2V_-5**Ezd;giS~_O>VI9!9?w1AUSLWP3{x_X~+kk596^ zX8V=%l!@!B>!UT*GN##bo|1FescNoTgek}n$tg`@%x}Dm!+DNWPl~fw;7yQ)(WZ{B zW+9hS%?S!(J3^s_mGIRy;k{j(q{O`h|GIMLJ&??bho9RhvZ(E23uGp+Gr}ibcAa zK@(XkS0M;iTbGTgE-K5Ic~I2XH$)p6WA(A-*owA}<~Z&p!;L6b3z9}0S@k%2>YG&h zYc^l->1eN)Qb*E_>*nn}OGS52S8KGLS)h88FZKX9>vq-3XZA+BR;pdD{u6tPdK}Q$ zDi)yGWv57;!~zU$(B3Sq%RN>;*4-0p>Xwk61ge0W23#}sc8hMP*LSLgUMnrbdc8BK_`jAoIIh>dt7qunvXVJL;RdqiUzOy{n_O zRqe;xITUII)C^8T?8qxRdOJmC-`G|f&SI08EUKN>xw(5=) z_El9D)v+a2u65VV#$ngo9Bq!AgWEZc(e|d6NM%WBT|-w}UCsPibxn2E^I(w2aco)r z{En`+hSrjn{75mn!Fvnnj79S9&*5Z^-JNK&QJvEiBYX1i95RMW3f8ky7_3W zZXD1}(d2s73v14vy>L-oYg6-)6_!U=Hg+_0eS{X@Y&)`@rl$7jVPbY-SsLqZYG^&O z8F}<1S8?vlC2f00$lG>DROpU&@h04nmGBPXVLH+A(~NoM$ToU9I$FD-QjD=F+QplU zD(P_yHAf>oEtn@F#b@wX>g|r!H%*v;g+Grr42UYHk*{417^|4LV9EnxDYC!58G~w9 zth1-13(uuGf?f=lSj99z&Z8d*B!xT!>55*|8|#Wj>g5!%R9qZu?rG^3LL4$LwCFtIN#)Ay5r~{7uHH)ZA%x{7|IeI{KD7Nv$8WPEffFR7wzh5 z?}+0Cv5tD2!*+GZBGSvPR%@&+rlQ%!G7GzVnj5;LCmA&6)aIBp@$Ov*UJq>c0i#1` z^Qz}|zaDtjp9oDd_WCbwYQbBsj>0B?A0~^AW`vJ7gdJbfc4ePBpyB~uZfQ<^Q=E5^ zX5k=?^B%DJ+Isrp@R+`y)|c>lfy1e_7o$d;GZcAgYFuL> z`5_HT{iaw)YiCpWq{=F?9;1o-$6;CnN|ESs9}tG2rR4mY@+;9#jhd4xIj;uDX^XZ& zM{!<}9CSyV^9>*4kcLCD(EnJyP4bX|O87T4{6;2g!~6v+O|nkGs-OpJlsF^rLUn#X z#*-}cBTKf3^W=tN?zRo4qdAHP4$7s=a@Sad9A3%VMN>bwda#xT%y^2B&$)EsSr+w3 ze8B2ALYarF;jifvtoq`Q?fYWb4fM8m$CkBYfrI%(1X2PkI&kJ8Z2KxJAUSsMB&spF zg_UaGY9&fIyz8wD>fCBsnWvvoJ^S?f+8K*ZtDk?y{Mka7oJF(eSJyA9ol#q}sJ3R- zBH>b(!rIx3YU@v5bc*nq=Ir->EgF3fX;lgiH$DA~xsH+(ZBP@KB-PUvW#mSUBoXO<^8U68X(X zkZn<=l%+#=C{(s1bw}PQU$j3|vEP;ve~w&?f=fh*5Fm2D1u9k8lI_0HBklTeBd-xKizgYa~q?c68MMBl3 zZPYujoC=*Fbo|f>LT6$Uof*(cfld%QVd#uVqEiK(RK#+RE0();ovfEiArBd`9NgDG zmSdq4HexxDL}xT~(u`R4Ceg`-PI}?gJ%@~*Nco;R(o!~y!oj-lAeT86g8uYTsWquf zQskbEy{+1=qjUSdopV&?9{KMfSjZ?Gi#CsRvfbIHm+!NV9xwbl0zV>1+pTKvza=m> zHtW!-3l}?nG=F2;sFz-$t<1tv(iYo3z4%Md(^61d3L2Jz{VcVOIv_0!(iYNTVMy@_ z(t@om*oFoBuokj(eTKk7Uhzn2A)qY;3=4sz7Iw~Yj(yf=I>xuuB_eY7KB7Zohm@_K zdBXGD7lo;)>CRbO_L(hwXs*>Vcxw7qIX@|R3ZZOGsO8Y9U(Fkvr}9>7Y1@p(X-R7zTW!$xQaRR}Z7261ykoK z*0}G?Jp!|eCF62v#&*sc%2L*Ymt&l6nF9-*7tXQ9%68!FL|&gLw04V#wQuYaD>BsO zKkLDOpspwk8+~)gIU-SpQD-H}AkM=?C8JLk8zUTy3H8kn4;@m`;`7FPG(gg`<(#g%}S4A~><{`9NgJEF1-k@u+i2+HPfUk_e1#&?A8vO;9wC+Aoh| zf8hveB?v3&6VDo;mF7{e%F+Q{Ivu5lOsxEvrEOh$2ukNo9QH9vvzKkz3QoSRNc6eW zQ=hQ!o#LMbee1z1w+HczdX6X)et9$$33XKXx2|1jeeWwP*UwDbud^zKX(Q_o&s2I({vTJ|lL^F_9zTTpw~UxKCjp^Bh=9cMq3Vg8LNp zu`eKfnppwrwTja4_wXxfq{2tK_WXEX>Sn9({M`>e>j%1TpLk~7zChvkWjygQWHZOm zyClyXW8(XmIsC;r7-Iv%KQa6~eK7m&-T#cN6-3RW-hRbD(f=pzw;^Z!#i@T1`Gdv^ z8GS(h&BK@>Ho8U$a~w1G^U(#e%z3Y<)z8QCZ5zJR_ldYQMo0fny(WBW>jA@h;1$}p z&@+x7XSSiw#QNccv6QE5^lw&sc#RiwXI0?a5|H^D+!B&BfZR*jvVNv`X77Q(*6Do@ zVehvGLdf2L%--}pA!K+!W_S?$)3MJC7khRbuw)w|zqVLQ9z4J?9huD;6aI~{TOWX9 zXGO0*+_9K-tXtxJrkqkdNG=}?=RU{o{;xBTpAqi=_Q1#BWQ3jjJj)v*9gW>B4J#W; zBByn9b@VKcMI*f1(bLotTOKR<)Q(i0l02>+QM~SGLwk3}3Owu>xxZ@iR;b1$>-LpqBYbK%jQdj?F?y`CBeI;Y2{g2Q zex0@|lH^SU^wOeuf6aII6gukjs$>5y`E2s?Q^)Im$>}o*%54(wOyPwn9`7pmBi!6C zuaJX*1lwsHtuY+A-90NhT>9>JV$|y^vH-O{bsL=5A|JcMD_M;zdtxg;wY|^cSaD+N z=x&KMb}auaV&a-wHZEI*_m-J_A+N+Gi@#bHQw5W}Pli6i zP-VXVgpTv%iF&`z$Q5}@-}{=Lj*Yow;m7N6e2*{{KfIzS^s9vO-NY~Sda(a=K4PFA zWVi@{j1Q+-wv2#b{=4GglM;M}g4c4#hm45UBc^{t`_$qw4qj^>pJv3e@e7Z|`?xKy zUXRbr7KskyyRBbr``~_1{E=T7&+|Sbpnq39ywM_LIDaz35$pa9?ZaoEuZQ398R_w! z+Vq9Tk?iSf*+6gl|E>L{ZfxmCoMb>x`_tn?&=-G<^?S-{GrMk=KXKp}f^i6&U-(vK z4#^NHBE?GarT9|=sdj2GH6=AQHIy1oO-o5n&5S_T**dW^BYV|4|CPRLt={a*9{tsf zY!S-zmxAy6y$}_ozr#1wK;_^o_%SQrY6nVQ;t$y3OiTQ3xFsx~u=@tL7Gz{vU6$a>oZJRo7?uPJJyky)-y@cZT1#gIy#4MwAh-FAZkY zpUeGWPdYlm%QB0omC%{>8)^gtBfC60L&p3?+Oh5S@-prX-ouik|0=n#KB<&@p>RX6 zBNN|bVhzPC{`EdL;(l7gycdes^yPDLJ?dq8OWtqYjmEM$t>T+&{>)6<9#wQwQAN>l zwpHTuqdD+xV94~?nDV*bYh`CUTN-v!=^YOc&T_wRVIhBAhb*@`-C<|6O19>KUG~@&%one-dH`F5{`Ok})54tW1oWQsuCE4C5ol)LrR5 zvCa1Re1Ap~zinm8QT30^;_$mxFtz$iXWbDVTz39^k>ShF;ZQfCE5m=>{oEVgjo~$C z%qBS$+IDOCRon~SV2!*80z3GJHF|*cV-VhIRbCzn@3W{99vj@fX5_A5@tOaf8c?<} z$7cl906yp$7EY8@L-X(_9Qoj5q;b=>RXs+=)8pvipbOZ}p^{<@-LR~OZp1XHG!%YV z1r!{$B6zQL=1bD_pH16$%D8{x#Ql3u+=JFQJ~P)Oi+kizj$G9%Xxi3sk9a(;Q#jDL zH>-d`qb?5KiMX9+41Swa8ykOdq6LG;vgxnWC4y&;+*Na9c!OmJ%D)^8R*!}Hpvc!{ zC#KpLm0iufQ1}x68apL(K{({M>=nh=p~Mv*yTm^QeEdFWAIV2*=69rz-r{M&JJP?{31Vnf(#f+MT*P6DVBE!bSOJt`9 z=VeAR0{P{t+q?aJw*Tn=31|9K?7os~rP*WIi!eK)^2&jm4TV?uFTwh80oo(eAG9wn znF?cd;o-IoW2=M1KfW<^xHh(;c)v83_9=}au8Z343WdM6=G;l)+~ANkmMx|g+=7eyd^6cOTqW&9BpN9RxD=*6&I_2R|_+P8fofI5exf!jT zH~L1lWk#CaGU-a$mrL1~??EG65*&Nu2evPG;ld_+^~C+*Krp-V-r%dEt-`SxJS}rr zMzH%4*|+}S+{~hBLqg%d(7aW-g`GI&WN97)Soxo%`QtF&>Jlhjl##B6)L^O{hjWgS z>*5Ry&=to~A43+0K@}v2K^5fFLaLVqogB%q&j>m>@*{mPnuDkGeF>}fIHC)Mf4#co zJwAo@Ijnz6vECSAhsNdF8Tli|l-QXS*oj~{%mpz)#KW2l))>hfYY)${2amKP{x!vR zrr*l5GmgL-o6!2S<@3iB*@H%v6il=;H`!@pbM0X{cE%|1M%o#3?a}_e(Fi9cFD@D; zMPvMz%mF{B_<1Oz_>m*=L;he{fgK)dhbG!bkG4ZoC!nFm*`bJ?F|xo84K0Cis+|MQ zFbKxmp|Mp;GOVO(%yA{BKyDB7WnvXK5hoO1*g1v#4?pxuiRTn)C2);3oO=I@Ck_?q z@=Al&kzbxxXA~8qxq3SjzjXeW2wB+i;re6xpRvR5m(9g5+||=0tP_ScK%p5}r2jws zS%BY9@l&TB)pgyPLD1+mN{EFZ;@JwpCrq>@^gIJeB2-C-a{|0^$ z%4E@>siMcTs7R+jCdpD=_AyoV43<3~vMTT!<7I!N$~LO9{Lo!HWLtIFy{haAmi-1~ zmw{nFTy^wE*>|I^$SYB+izUq_D&prn^GpSxaM{9k}m(6^7U0KEr{ZDr7 zgx}=DX~4DCjO?y+voBK@PQWY0&-bc6AHao^uK+7o2rlXQ0N5Y3#6QI+j`I2Z&)#HN z;S#yN|Lsj!-&b@5E2?Ya=b&pc$EOC=WS6@u!++v@j_;YzW(1Dg8wz(3z*8fm`0TH5 z-0i~vKWyaqq5>b^wZZ?Z1V88!Y=O`J+6Ftr+2lC%G!S2AbZ(U56-MhGpKb9daW)nT z<4z6U+!WR}pFCZxCaX9rHpW&(tL zc3-e}X>0Egevlw`vFjp#kVyMq&{}s6sQdbHNFjvCC z%Au#86U?f=Jj18fp2(137ng>8CGUMs*F=BLF(Vg?oPsf2y`;!-;{nv|3mZ4s;LaxV zf-^qyBK}gf^-Is7!4hf#^Gn|_=lT;(e9}J0?cw-5f=+kOBk$@ye@Ec!(N3R#ig{#) zPYm<h zZiH`?Oat*a{Cr_~z)o;BnFsXF`9r?*Zaw8m0;`T@KuJm7p`NQ`FFFQVF%pd>M`SHFGWf+gtn1BV4F@H#2;t#EV#B}l(zfbJ4e7=;c zzhPPDr^^ZDif?d`7+g7Y!PX3)T3F&#cnYyMjxhxzEu39)Pcyi@`NKejLGOukqXUVQBDZTniO1iv~GF2MO zS65OhUPu^AW!OoKVd#usKS}5H6I}9m3D-}Cs!JXfS0_vyE*@nDgzJx=77Bm&vU4XP8F;4hIULW=>#;q*04Mw5lk8Cb2s>?9N&Xl+JlRgc zxpa08&SeYiG@SCzwMXz=I?Quvw`e5KnQ@Iq@pIxuMjeSC@~7t6fl+!P$}_1iY#iYM z>uhoyp?AzD@&O!vZBJM)dd3nKQ4`9GzC33_N$0(}bo{2{r_O@^Tb;I?28Kw-d>~Jd z*Mh2Zyw}vZPCXbR{W#cMkDbRT#_8b)zBH~*x+p7wY!h}Kp-i40uJy~)q$|OId^zM? zJqJKp_G^Awb~9xcg2$B;2O3rOI#u>wGDZ4#!B59;Cgmu*MV0*pWp{&@haX?jRAp~f zW%sDE{|)}B_^qWJWxuP+?q}JT!8;qjRg}q??^R|0A&qNiJ@aoteEz)<^KZr%GXMU>@65mD{}<-pC(x&yf8~KAte^Ycr*5tZ_+fv) zQ@5Rd^VIEQt?;FT`LC8|a4URZ$lHI9{o1`&8)K>GB}QBF88xIT zHcZOKTujbKOun@~F~{c%{Sz57T%F6kr!yp2zr|Ub=jJ=pVAvNd8rg+YxZwPhkuM;R zQY&wMXgs)U?!PJ&?ry#TC;laObjnC(@$YB(Ov6*mnPbO9?9ejX#&y}bbM4T0uHRwW;p^@jIdLNpJJ~rdC9p=JrvilayEwZxSYeyru#GWwXN_F-ddX# z%CI5zQ5p){WxjcHGJ+1{xalW;JtJkv%i#dUl?yXc^K+m?kpD(IyEBVs*98kkUf^7f%jt9Wg3Xylh~HOvZ&6=3Tz+18M@G8s&-oU;goF0#$QyPV zZUFWU#xmPE55G8jWjI)RTk#WqYv|J%DNaZoIa%S9$!|=4BqKvD$Oo^=$YjkjX)L&M z0QWpesj&?%GdCJ+teRy3o6u$E^oa_x77c+ya$jitwgBvsZV+9v*f(wPi z49V}$&r1!cSc4biF4tgHmEd@sDCjUl;V)knJT-GD11UeRq+7Pph>Rg-7-MIByf8}N z38q*6l2r|ij)__jYq zjj@nXH`G~=PxuJyZU3-q!79ct%;y4y^{!uDB%DD`Hx@VebQLa3|6Os{dI(Zg0r@Er>puHvmfjU-<8vdu z_>c$$B^2zVKt1itS}R-MSGIU216#Pw_kFvN%4|$|w+3_P4{UksZ=}P*-1!50G-p_z z;i&DCuKROPTwiNFrQfyIae5BLBBlX)${E}mb11!k#B^8W6Jeh(?Y%9QPi15Kcl(rAj>YP9(uFqjVD;m2rxpN}PA5HE?FUHJe-!O*0P-vmudQ>h z9<^QKRCNJ%eu|%8T)*Qohsg^E)o6V%ABrI&xuNFVEQcB^EjQ-|xuNFV7l+zB zN6onxZm2o8z@awRQFHEkgU880Za1L=d7m4+>6#@B-eQMGimKtK@?7_SfV5Ka@wIMs zfHCKJpiNVJ{8bxu6)zE!!HZXi+DUw+Qg@=1t7nM__6+MtuLYz-bG9c31RGYX>A5@|#gI5};4Pz9IfX4hmnf^dbWMt(ACvK#}x z(5v&gIu?jq_$FBLilXl>OK_Rwn`ns`X|W~RNO1!vLW-X{!@CGHem=@~l;tLE;WWvy zc{RAcJ1sebd<>iFJ#1xC*(y!gyplG*W6878WHz}rRB>`-OvH(Im*pm7!$lA$#>=Vy zta_R=nY}#9Wl4_4w5R?bAF`y4@`NopKJOMn+Dy`h1t_CzZNeUHdEaFQ3!Ah%DPi}U z;PIWv+clMa11$RnbTj!Cme@uLzuPtbnZ^%m{G`Ue)tC|Z@Q7+JX{9ArYI!2g=fL6o zkNb(9clN+kaZX9Zc{_MM6uC=N87Hue6I9ltO2>ydAD|wvj1TxfHJ0%Kqg$k0#yM5T zIV}-qA?5f9@dAEH0Q!Ywa zp6eA-+=7u5m%t@On3D3|BjsFtke;V$x26|s%2N=^yzbqrHFK#rnn#=@eEC8YsxDc)Qf7mTGKCUdaI^)X!;XPf3E5Cn!c#%2byByk#=R@ z!@lf$&>Prp=+m1>Pq4&28h>Boy&5y)D1Tey_cYF8JyAY~6mslJjG;l|xf;*YII1x} ze@p$#HNHyYZ)yB(jdy6gQ{z8r{9hU$)c6C9hqAs1VgxDd;~_VRt2ADy@!1;l8^_e| z(fC@8Z_s#~#@jXijmA%F%#%Zwe_P{BwlnY$Quyb&Bypj}@|ZbMA2Uco=h%+0J@La? z4>a{L6MuGI3e+)ja^hH##|WM)z7t{}sO(!%*|(swPvKi0Q`0T+L+Szl2PyEcG=4&3 z8QTmU+ss64iE#&msEm#GV~yu&!R028;aQ3J!~YXEQ0T2mCV!#I=1TL0 zM_h}T-`|iXm8}H{o1DFU�F9I5y>#V`Wm=#06L%0T~DSd$cLeoEL`e#iK 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 HoRZ&<LJ&y6L?J{Hly1`wlbJ~}GRef534*m6 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 LQFfaoa(({~tXm^% literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_cpu_c.pbi b/Flash/Obj/os_cpu_c.pbi new file mode 100644 index 0000000..3f92b8a --- /dev/null +++ b/Flash/Obj/os_cpu_c.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 12s +C:\work\solarium\OS\uc\os_ii\port\os_cpu_c.c +C:\work\solarium\OS\uc\os_ii\port\os_cpu_c.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_dbg.o b/Flash/Obj/os_dbg.o new file mode 100644 index 0000000000000000000000000000000000000000..33bdd8838291df0312ba4a7e89489ae3c9dcc579 GIT binary patch literal 33576 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 Hq3`8i%>HIv literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_dcc.pbi b/Flash/Obj/os_dcc.pbi new file mode 100644 index 0000000..f189d14 --- /dev/null +++ b/Flash/Obj/os_dcc.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 12s +C:\work\solarium\OS\uc\os_ii\port\os_dcc.c +C:\work\solarium\OS\uc\os_ii\port\os_dcc.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_flag.o b/Flash/Obj/os_flag.o new file mode 100644 index 0000000000000000000000000000000000000000..1adb27aa00ce48a964a99dfe96a5594d94f451f0 GIT binary patch literal 31608 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_flag.pbi b/Flash/Obj/os_flag.pbi new file mode 100644 index 0000000..67289df --- /dev/null +++ b/Flash/Obj/os_flag.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 13s +C:\work\solarium\OS\uc\os_ii\source\os_flag.c +C:\work\solarium\OS\uc\os_ii\source\os_flag.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_mbox.o b/Flash/Obj/os_mbox.o new file mode 100644 index 0000000000000000000000000000000000000000..d8ba6f79938e0923a3e08204ea8fe00778d7a69e GIT binary patch literal 21460 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 R)z<^LJHaP?_PL1k{eRu%Y61WN literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_mutex.pbi b/Flash/Obj/os_mutex.pbi new file mode 100644 index 0000000..0938d06 --- /dev/null +++ b/Flash/Obj/os_mutex.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 14s +C:\work\solarium\OS\uc\os_ii\source\os_mutex.c +C:\work\solarium\OS\uc\os_ii\source\os_mutex.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_q.o b/Flash/Obj/os_q.o new file mode 100644 index 0000000000000000000000000000000000000000..b889d60765e588a8b953d094ff2013ba142fd31b GIT binary patch literal 28424 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 CzGm0} literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_q.pbi b/Flash/Obj/os_q.pbi new file mode 100644 index 0000000..28da040 --- /dev/null +++ b/Flash/Obj/os_q.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 14s +C:\work\solarium\OS\uc\os_ii\source\os_q.c +C:\work\solarium\OS\uc\os_ii\source\os_q.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_sem.o b/Flash/Obj/os_sem.o new file mode 100644 index 0000000000000000000000000000000000000000..b27cbacfcf0cf6c3302089e20e4aaa568e4a0966 GIT binary patch literal 22632 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

-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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/time.pbi b/Flash/Obj/time.pbi new file mode 100644 index 0000000..d131b39 --- /dev/null +++ b/Flash/Obj/time.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:03 57s +C:\work\solarium\PROJECT\service\time.c +C:\work\solarium\PROJECT\service\time.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/uart0.o b/Flash/Obj/uart0.o new file mode 100644 index 0000000000000000000000000000000000000000..2d37ee456ce502e3dd776f8de593e0fcc329e918 GIT binary patch literal 42420 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/uart1.pbi b/Flash/Obj/uart1.pbi new file mode 100644 index 0000000..53fed18 --- /dev/null +++ b/Flash/Obj/uart1.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 01s +C:\work\solarium\DRIVERS\ccnet\uart1.c +C:\work\solarium\DRIVERS\ccnet\uart1.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/uart2.o b/Flash/Obj/uart2.o new file mode 100644 index 0000000000000000000000000000000000000000..ff184c3854b488d9b55b3398757a07878e43a849 GIT binary patch literal 35884 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 P4x*a+ +#include "app_serv.h" +#include "lcd.h" +#include "spi.h" +#include "keyboard.h" + +static OS_STK AppTaskStartStk[APP_TASK_START_STK_SIZE]; +static void AppTaskStart(void *p_arg); + + +/* +********************************************************************************************************* +* main() +* +* Description : This is the standard entry point for C code. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void main (void) +{ + BSP_IntDisAll(); /* Disable all interrupts until we are ready to accept them */ + + OSInit(); /* Initialize "uC/OS-II, The Real-Time Kernel" */ + + OSTaskCreate(AppTaskStart, (void *)0, (OS_STK *)&AppTaskStartStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO); + + OSStart(); /* Start multitasking (i.e. give control to uC/OS-II) */ +} + +/* +********************************************************************************************************* +* AppTaskStart() +* +* Description : The startup task. The uC/OS-II ticker should only be initialize once multitasking starts. +* +* Argument(s) : p_arg Argument passed to 'AppTaskStart()' by 'OSTaskCreate()'. +* +* Return(s) : none. +* +* Note(s) : (1) The first line of code is used to prevent a compiler warning because 'p_arg' is not +* used. The compiler should not generate any code for this statement. +* +* (2) Interrupts are enabled once the task starts because the I-bit of the CCR register was +* set to 0 by 'OSTaskCreate()'. +********************************************************************************************************* +*/ + +unsigned char arr[256]; + +static void AppTaskStart (void *p_arg) +{ + (void)p_arg; + + BSP_Init(); /* Initialize BSP functions */ + +#if OS_TASK_STAT_EN > 0 + OSStatInit(); /* Determine CPU capacity */ +#endif + + OSTimeDly(1000); + // + InitLcd(); + InitKbrd(); + SpiInit(); + + // + UserStartupFunc(); + + while (1) { /* Task body, always written as an infinite loop. */ + OSTimeDly(1000); + //PostUserEvent(EVENT_SEC); + } +} + diff --git a/OS/app/app_cfg.h b/OS/app/app_cfg.h new file mode 100644 index 0000000..69d63f4 --- /dev/null +++ b/OS/app/app_cfg.h @@ -0,0 +1,52 @@ +#ifndef __APP_CFG_H__ +#define __APP_CFG_H__ + +/* +********************************************************************************************************* +* TASK PRIORITIES +********************************************************************************************************* +*/ + +#define APP_TASK_START_PRIO 5 +#define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2) + +#define USER_LOWEST_PRIO (OS_LOWEST_PRIO - 3) +#define USER_HIGHEST_PRIO 6 + + +/* +********************************************************************************************************* +* TASK STACK SIZES +********************************************************************************************************* +*/ + +#define APP_TASK_START_STK_SIZE 256 + +/* +********************************************************************************************************* +* uC/OS-II DCC CONFIGURATION +********************************************************************************************************* +*/ + +#define OS_CPU_ARM_DCC_EN 0 + +/* +********************************************************************************************************* +* TRACE / DEBUG CONFIGURATION +********************************************************************************************************* +*/ + +#define TRACE_LEVEL_OFF 0 +#define TRACE_LEVEL_INFO 1 +#define TRACE_LEVEL_DEBUG 2 + +#define APP_TRACE_LEVEL TRACE_LEVEL_DEBUG +#define APP_TRACE printf + +#define APP_TRACE_INFO(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(APP_TRACE x) : (void)0) +#define APP_TRACE_DEBUG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG) ? (void)(APP_TRACE x) : (void)0) + + + + +#endif diff --git a/OS/app/includes.h b/OS/app/includes.h new file mode 100644 index 0000000..98dfc89 --- /dev/null +++ b/OS/app/includes.h @@ -0,0 +1,22 @@ +#ifndef __INCLUDES_H__ +#define __INCLUDES_H__ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + + +#endif diff --git a/OS/app/os_cfg.h b/OS/app/os_cfg.h new file mode 100644 index 0000000..c599dfb --- /dev/null +++ b/OS/app/os_cfg.h @@ -0,0 +1,141 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* uC/OS-II Configuration File for V2.8x +* +* File : OS_CFG.H +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_CFG_H +#define OS_CFG_H + + /* ---------------------- MISCELLANEOUS ----------------------- */ +#define OS_APP_HOOKS_EN 0 /* Application-defined hooks are called from the uC/OS-II hooks */ +#define OS_ARG_CHK_EN 0 /* Enable (1) or Disable (0) argument checking */ +#define OS_CPU_HOOKS_EN 1 /* uC/OS-II hooks are found in the processor port files */ + +#define OS_DEBUG_EN 1 /* Enable(1) debug variables */ + +#define OS_EVENT_NAME_SIZE 0 /* Determine the size of the name of a Sem, Mutex, Mbox or Q */ + +#define OS_LOWEST_PRIO 31 /* Defines the lowest priority that can be assigned ... */ + /* ... MUST NEVER be higher than 254! */ + +#define OS_MAX_EVENTS 10 /* Max. number of event control blocks in your application */ +#define OS_MAX_FLAGS 5 /* Max. number of Event Flag Groups in your application */ +#define OS_MAX_MEM_PART 5 /* Max. number of memory partitions */ +#define OS_MAX_QS 4 /* Max. number of queue control blocks in your application */ +#define OS_MAX_TASKS 16 /* Max. number of tasks in your application, MUST be >= 2 */ + +#define OS_SCHED_LOCK_EN 1 /* Include code for OSSchedLock() and OSSchedUnlock() */ + +#define OS_TICK_STEP_EN 1 /* Enable tick stepping feature for uC/OS-View */ +#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */ + + + /* --------------------- TASK STACK SIZE ---------------------- */ +#define OS_TASK_TMR_STK_SIZE 128 /* Timer task stack size (# of OS_STK wide entries) */ +#define OS_TASK_STAT_STK_SIZE 128 /* Statistics task stack size (# of OS_STK wide entries) */ +#define OS_TASK_IDLE_STK_SIZE 128 /* Idle task stack size (# of OS_STK wide entries) */ + + + /* --------------------- TASK MANAGEMENT ---------------------- */ +#define OS_TASK_CHANGE_PRIO_EN 1 /* Include code for OSTaskChangePrio() */ +#define OS_TASK_CREATE_EN 1 /* Include code for OSTaskCreate() */ +#define OS_TASK_CREATE_EXT_EN 1 /* Include code for OSTaskCreateExt() */ +#define OS_TASK_DEL_EN 1 /* Include code for OSTaskDel() */ +#define OS_TASK_NAME_SIZE 0 /* Determine the size of a task name */ +#define OS_TASK_PROFILE_EN 1 /* Include variables in OS_TCB for profiling */ +#define OS_TASK_QUERY_EN 1 /* Include code for OSTaskQuery() */ +#define OS_TASK_STAT_EN 0 /* Enable (1) or Disable(0) the statistics task */ +#define OS_TASK_STAT_STK_CHK_EN 1 /* Check task stacks from statistic task */ +#define OS_TASK_SUSPEND_EN 1 /* Include code for OSTaskSuspend() and OSTaskResume() */ +#define OS_TASK_SW_HOOK_EN 1 /* Include code for OSTaskSwHook() */ + + + /* ----------------------- EVENT FLAGS ------------------------ */ +#define OS_FLAG_EN 1 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ +#define OS_FLAG_ACCEPT_EN 1 /* Include code for OSFlagAccept() */ +#define OS_FLAG_DEL_EN 1 /* Include code for OSFlagDel() */ +#define OS_FLAG_NAME_SIZE 0 /* Determine the size of the name of an event flag group */ +#define OS_FLAGS_NBITS 16 /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ +#define OS_FLAG_QUERY_EN 1 /* Include code for OSFlagQuery() */ +#define OS_FLAG_WAIT_CLR_EN 1 /* Include code for Wait on Clear EVENT FLAGS */ + + + /* -------------------- MESSAGE MAILBOXES --------------------- */ +#define OS_MBOX_EN 1 /* Enable (1) or Disable (0) code generation for MAILBOXES */ +#define OS_MBOX_ACCEPT_EN 1 /* Include code for OSMboxAccept() */ +#define OS_MBOX_DEL_EN 1 /* Include code for OSMboxDel() */ +#define OS_MBOX_PEND_ABORT_EN 1 /* Include code for OSMboxPendAbort() */ +#define OS_MBOX_POST_EN 1 /* Include code for OSMboxPost() */ +#define OS_MBOX_POST_OPT_EN 1 /* Include code for OSMboxPostOpt() */ +#define OS_MBOX_QUERY_EN 1 /* Include code for OSMboxQuery() */ + + + /* --------------------- MEMORY MANAGEMENT -------------------- */ +#define OS_MEM_EN 1 /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ +#define OS_MEM_NAME_SIZE 0 /* Determine the size of a memory partition name */ +#define OS_MEM_QUERY_EN 1 /* Include code for OSMemQuery() */ + + + /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */ +#define OS_MUTEX_EN 1 /* Enable (1) or Disable (0) code generation for MUTEX */ +#define OS_MUTEX_ACCEPT_EN 1 /* Include code for OSMutexAccept() */ +#define OS_MUTEX_DEL_EN 1 /* Include code for OSMutexDel() */ +#define OS_MUTEX_QUERY_EN 1 /* Include code for OSMutexQuery() */ + + + /* ---------------------- MESSAGE QUEUES ---------------------- */ +#define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */ +#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */ +#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */ +#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */ +#define OS_Q_PEND_ABORT_EN 1 /* Include code for OSQPendAbort() */ +#define OS_Q_POST_EN 1 /* Include code for OSQPost() */ +#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */ +#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */ +#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */ + + + /* ------------------------ SEMAPHORES ------------------------ */ +#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */ +#define OS_SEM_ACCEPT_EN 1 /* Include code for OSSemAccept() */ +#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */ +#define OS_SEM_PEND_ABORT_EN 1 /* Include code for OSSemPendAbort() */ +#define OS_SEM_QUERY_EN 1 /* Include code for OSSemQuery() */ +#define OS_SEM_SET_EN 1 /* Include code for OSSemSet() */ + + + /* --------------------- TIME MANAGEMENT ---------------------- */ +#define OS_TIME_DLY_HMSM_EN 1 /* Include code for OSTimeDlyHMSM() */ +#define OS_TIME_DLY_RESUME_EN 1 /* Include code for OSTimeDlyResume() */ +#define OS_TIME_GET_SET_EN 1 /* Include code for OSTimeGet() and OSTimeSet() */ +#define OS_TIME_TICK_HOOK_EN 1 /* Include code for OSTimeTickHook() */ + + + /* --------------------- TIMER MANAGEMENT --------------------- */ +#define OS_TMR_EN 1 /* Enable (1) or Disable (0) code generation for TIMERS */ +#define OS_TMR_CFG_MAX 16 /* Maximum number of timers */ +#define OS_TMR_CFG_NAME_SIZE 0 /* Determine the size of a timer name */ +#define OS_TMR_CFG_WHEEL_SIZE 8 /* Size of timer wheel (#Spokes) */ +#define OS_TMR_CFG_TICKS_PER_SEC 10 /* Rate at which timer management task runs (Hz) */ + + +#endif diff --git a/OS/bsp/LPC2368_Flash.icf b/OS/bsp/LPC2368_Flash.icf new file mode 100644 index 0000000..32b5c1c --- /dev/null +++ b/OS/bsp/LPC2368_Flash.icf @@ -0,0 +1,56 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000044; +define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x40000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x40007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_svcstack__ = 0x100; +define symbol __ICFEDIT_size_irqstack__ = 0x100; +define symbol __ICFEDIT_size_fiqstack__ = 0x40; +define symbol __ICFEDIT_size_undstack__ = 0x10; +define symbol __ICFEDIT_size_abtstack__ = 0x10; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000; +define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF; +define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__]; + +define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000; +define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF; +define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; +define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; +define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; +define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; +define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; +do not initialize { section USB_DMA_RAM }; +do not initialize { section EMAC_DMA_RAM }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, + block UND_STACK, block ABT_STACK, block HEAP }; +place in USB_DMA_RAM_region + { readwrite data section USB_DMA_RAM }; +place in EMAC_DMA_RAM_region + { readwrite data section EMAC_DMA_RAM }; diff --git a/OS/bsp/LPC2368_Flash.mac b/OS/bsp/LPC2368_Flash.mac new file mode 100644 index 0000000..eac3241 --- /dev/null +++ b/OS/bsp/LPC2368_Flash.mac @@ -0,0 +1,4 @@ +execUserPreload() +{ + __writeMemory32(0x00000001, 0xE01FC040, "Memory"); // MEMMAP = 1; +} diff --git a/OS/bsp/bsp.c b/OS/bsp/bsp.c new file mode 100644 index 0000000..7f02c00 --- /dev/null +++ b/OS/bsp/bsp.c @@ -0,0 +1,851 @@ +#define BSP_GLOBALS +#include + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + +CPU_INT32U VIC_SpuriousInt; + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static void PLL_Init (void); +static void MAM_Init (void); +static void GPIO_Init (void); +static void VIC_Init (void); + +static void Tmr_TickInit (void); + +static void VIC_Dummy (void); /* Prototypes for dummy interrupt handlers */ +static void VIC_DummyWDT (void); +static void VIC_DummySW (void); +static void VIC_DummyDEBUGRX (void); +static void VIC_DummyDEBUGTX (void); +static void VIC_DummyTIMER0 (void); +static void VIC_DummyTIMER1 (void); +static void VIC_DummyUART0 (void); +static void VIC_DummyUART1 (void); +static void VIC_DummyPWM01 (void); +static void VIC_DummyI2C0 (void); +static void VIC_DummySPI (void); +static void VIC_DummySSP1 (void); +static void VIC_DummyPLL (void); +static void VIC_DummyRTC (void); +static void VIC_DummyEINT0 (void); +static void VIC_DummyEINT1 (void); +static void VIC_DummyEINT2 (void); +static void VIC_DummyEINT3 (void); +static void VIC_DummyAD0 (void); +static void VIC_DummyI2C1 (void); +static void VIC_DummyBOD (void); +static void VIC_DummyETHERNET(void); +static void VIC_DummyUSB (void); +static void VIC_DummyCAN01 (void); +static void VIC_DummyMMC (void); +static void VIC_DummyGP_DMA (void); +static void VIC_DummyTIMER2 (void); +static void VIC_DummyTIMER3 (void); +static void VIC_DummyUART2 (void); +static void VIC_DummyUART3 (void); +static void VIC_DummyI2C2 (void); +static void VIC_DummyI2S (void); + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +********************************************************************************************************* +** GLOBAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* BSP_Init() +* +* Description : Initialize the Board Support Package (BSP). +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) This function SHOULD be called before any other BSP function is called. +********************************************************************************************************* +*/ + +void BSP_Init (void) +{ + PLL_Init(); /* Initialize the PLL */ + MAM_Init(); /* Initialize the Memory Acceleration Module */ + GPIO_Init(); /* Initialize the board's I/Os */ + VIC_Init(); /* Initialize the Vectored Interrupt Controller */ + + Tmr_TickInit(); /* Initialize the uC/OS-II tick interrupt */ +} + + +/* +********************************************************************************************************* +* BSP_CPU_ClkFreq() +* +* Description : Get the CPU clock frequency. +* +* Argument(s) : none. +* +* Return(s) : The CPU clock frequency, in Hz. +********************************************************************************************************* +*/ + +CPU_INT32U BSP_CPU_ClkFreq (void) +{ + CPU_INT32U msel; + CPU_INT32U nsel; + CPU_INT32U fin; + CPU_INT32U pll_clk_feq; /* When the PLL is enabled, this is Fcco */ + CPU_INT32U clk_div; + CPU_INT32U clk_freq; + + + switch (CLKSRCSEL & 0x03) { /* Determine the current clock source */ + case 0: + fin = IRC_OSC_FRQ; + break; + + case 1: + fin = MAIN_OSC_FRQ; + break; + + case 2: + fin = RTC_OSC_FRQ; + break; + + default: + fin = IRC_OSC_FRQ; + break; + } + + if ((PLLSTAT & (1 << 25)) > 0) { /* If the PLL is currently enabled and connected */ + msel = (CPU_INT32U)(PLLSTAT & 0x3FFF) + 1; /* Obtain the PLL multiplier */ + nsel = (CPU_INT32U)((PLLSTAT >> 16) & 0x0F) + 1; /* Obtain the PLL divider */ + pll_clk_feq = (2 * msel * (fin / nsel)); /* Compute the PLL output frequency */ + } else { + pll_clk_feq = (fin); /* The PLL is bypassed */ + } + + clk_div = (CPU_INT32U)(CCLKCFG & 0xFF) + 1; /* Obtain the CPU core clock divider */ + clk_freq = (CPU_INT32U)(pll_clk_feq / clk_div); /* Compute the ARM Core clock frequency */ + + return (clk_freq); +} + +/* +********************************************************************************************************* +* BSP_CPU_PclkFreq() +* +* Description : Get the peripheral clock frequency for a specific peripheral. +* +* Argument(s) : pclk The peripheral clock ID, one of PCLK_??? defined in bsp.h. +* +* Return(s) : The peripheral's clock in Hz +********************************************************************************************************* +*/ + + +CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk) +{ + CPU_INT32U clk_freq; + CPU_INT32U selection; + + + clk_freq = BSP_CPU_ClkFreq(); + + switch (pclk) { + case PCLK_WDT: + case PCLK_TIMER0: + case PCLK_TIMER1: + case PCLK_UART0: + case PCLK_UART1: + case PCLK_PWM0: + case PCLK_PWM1: + case PCLK_I2C0: + case PCLK_SPI: + case PCLK_RTC: + case PCLK_SSP1: + case PCLK_DAC: + case PCLK_ADC: + case PCLK_CAN1: + case PCLK_CAN2: + case PCLK_ACF: + selection = ((PCLKSEL0 >> (pclk * 2)) & 0x03); + if (selection == 0) { + return (clk_freq / 4); + } else if (selection == 1) { + return (clk_freq); + } else if (selection == 2) { + return (clk_freq / 2); + } else { + return (clk_freq / 8); + } + + case PCLK_BAT_RAM: + case PCLK_GPIO: + case PCLK_PCB: + case PCLK_I2C1: + case PCLK_SSP0: + case PCLK_TIMER2: + case PCLK_TIMER3: + case PCLK_UART2: + case PCLK_UART3: + case PCLK_I2C2: + case PCLK_MCI: + case PCLK_SYSCON: + selection = ((PCLKSEL1 >> ((pclk - 16) * 2)) & 0x03); + if (selection == 0) { + return (clk_freq / 4); + } else if (selection == 1) { + return (clk_freq); + } else if (selection == 2) { + return (clk_freq / 2); + } else { + return (clk_freq / 8); + } + + default: + return (0); + } +} + + +/* +********************************************************************************************************* +* OS_CPU_ExceptHndlr() +* +* Description : Handle any exceptions. +* +* Argument(s) : except_id ARM exception type: +* +* OS_CPU_ARM_EXCEPT_RESET 0x00 +* OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01 +* OS_CPU_ARM_EXCEPT_SWI 0x02 +* OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03 +* OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04 +* OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05 +* OS_CPU_ARM_EXCEPT_IRQ 0x06 +* OS_CPU_ARM_EXCEPT_FIQ 0x07 +* +* Return(s) : none. +* +* Caller(s) : OS_CPU_ARM_EXCEPT_HANDLER(), which is declared in os_cpu_a.s. +********************************************************************************************************* +*/ + +void OS_CPU_ExceptHndlr (CPU_DATA except_id) +{ + CPU_FNCT_VOID pfnct; + CPU_INT32U *sp; + + /* If this exception is either an IRQ or FIQ */ + if ((except_id == OS_CPU_ARM_EXCEPT_IRQ) || (except_id == OS_CPU_ARM_EXCEPT_FIQ)) { + pfnct = (CPU_FNCT_VOID)VICADDRESS; /* Read the interrupt vector from the VIC */ + if (pfnct != (CPU_FNCT_VOID)0) { /* Make sure we don't have a NULL pointer */ + (*pfnct)(); /* Execute the ISR for the interrupting device */ + VICADDRESS = 1; /* Acknowlege the VIC interrupt */ + } + } else { + sp = (CPU_INT32U *)OSTCBCur->OSTCBStkPtr; + APP_TRACE_INFO(("\nCPU_ARM_EXCEPTION #%d trapped.\n", except_id)); + APP_TRACE_INFO(("R0 : 0x%08x\n", *(sp + 0x01))); + APP_TRACE_INFO(("R1 : 0x%08x\n", *(sp + 0x02))); + APP_TRACE_INFO(("R2 : 0x%08x\n", *(sp + 0x03))); + APP_TRACE_INFO(("R3 : 0x%08x\n", *(sp + 0x04))); + APP_TRACE_INFO(("R4 : 0x%08x\n", *(sp + 0x05))); + APP_TRACE_INFO(("R5 : 0x%08x\n", *(sp + 0x06))); + APP_TRACE_INFO(("R6 : 0x%08x\n", *(sp + 0x07))); + APP_TRACE_INFO(("R7 : 0x%08x\n", *(sp + 0x08))); + APP_TRACE_INFO(("R8 : 0x%08x\n", *(sp + 0x09))); + APP_TRACE_INFO(("R9 : 0x%08x\n", *(sp + 0x0A))); + APP_TRACE_INFO(("R10 : 0x%08x\n", *(sp + 0x0B))); + APP_TRACE_INFO(("R11 : 0x%08x\n", *(sp + 0x0C))); + APP_TRACE_INFO(("R12 : 0x%08x\n", *(sp + 0x0D))); + APP_TRACE_INFO(("SP : 0x%08x\n", sp)); + APP_TRACE_INFO(("LR : 0x%08x\n", *(sp + 0x0E))); + APP_TRACE_INFO(("PC : 0x%08x\n", *(sp + 0x0F))); + APP_TRACE_INFO(("CPSR: 0x%08x\n", *(sp + 0x00))); + + /* Infinite loop on other exceptions. */ + /* Should be replaced by other behavior (reboot, etc.) */ + while (DEF_TRUE) { + ; + } + } +} + + +/* +********************************************************************************************************* +* BSP_IntDisAll() +* +* Description : Disable ALL interrupts. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +void BSP_IntDisAll (void) +{ + VICINTENCLEAR = 0xFFFFFFFFL; /* Disable ALL interrupts */ +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** uC/OS-II TIMER FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* Tmr_TickInit() +* +* Description : Initialize uC/OS-II's tick source. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void Tmr_TickInit (void) +{ + CPU_INT32U pclk_freq; + CPU_INT32U rld_cnts; + + /* VIC timer #0 Initialization */ + VICINTSELECT &= ~(1 << VIC_TIMER0); /* Configure the timer interrupt as an IRQ source */ + VICVECTADDR4 = (CPU_INT32U)Tmr_TickISR_Handler; /* Set the vector address */ + VICINTENABLE = (1 << VIC_TIMER0); /* Enable the timer interrupt source */ + + pclk_freq = BSP_CPU_PclkFreq(PCLK_TIMER0); /* Get the peripheral clock frequency */ + + rld_cnts = pclk_freq / OS_TICKS_PER_SEC; /* Calculate the # of counts necessary for the OS ticker */ + + T0TCR = (1 << 1); /* Disable and reset counter 0 and the prescale counter 0 */ + T0TCR = 0; /* Clear the reset bit */ + T0PC = 0; /* Prescaler is set to no division */ + + T0MR0 = rld_cnts-1; + T0MCR = 3; /* Interrupt on MR0 (reset TC), stop TC */ + + T0CCR = 0; /* Capture is disabled. */ + T0EMR = 0; /* No external match output. */ + T0TCR = 1; /* Enable timer 0 */ +} + + +/* +********************************************************************************************************* +* Tmr_TickISR_Handler() +* +* Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +void Tmr_TickISR_Handler (void) +{ + T0IR = 0xFF; /* Clear timer #0 interrupt */ + + OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */ +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** LOCAL FUNCTIONS +********************************************************************************************************* +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* PLL_Init() +* +* Description : Set up and activate the PLL. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) The PLL output frequency is calculated by: +* +* Fcco = 2 * Fin * m / n +* +* where +* +* Fin is the PLL input clock (here, the main oscillator) +* M is the PLL clock multiplier. The value (M - 1) is programmed in PLLCFG. +* N is the PLL clock divider. The value (N - 1) is programmed in PLLCFG. +* +* (2) Fcco must be between 250 and 550 MHz. The ARM Core clock must never exceed 72 MHz. +* Set clk_div to divide Fcco accordingly. +* +* (3) When using the USB device, you must choose Fcco as a multiple of 96 MHz, and then +* set clk_div_usb to divide Fcco to exactly 48 MHz. +* +* (4) In this example +* +* Fin = 12MHz, +* M = 12, +* N = 1, +* clk_div = 6, and +* clk_div_usb = 6. +* +* Therefore, Fcco = 2 * Fin * M / N = (2 * 12 * 12 / 1) = 288MHz. +* The processor clock = (Fcco / clk_div) = (288MHz / 6) = 48MHz. +* Finally, the USB clock = (Fcco / clk_div_usb) = (288MHz / 6) = 48MHz. +* +* (5) A PLL errata on early revisions of the part prevent Fcco from being greater than 288MHz. +* +* (6) For later revisions, M = 20, clk_div = 8, and clk_div_usb = 10 will yield 60MHz for +* the processor clock and 48MHz for the USB clock. +********************************************************************************************************* +*/ + +static void PLL_Init (void) +{ +#if CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL /* Allocate storage for CPU status register */ + CPU_SR cpu_sr = 0; +#endif + + CPU_INT32U m; + CPU_INT32U n; + CPU_INT32U clk_div; + CPU_INT32U clk_div_usb; + + + m = 11; /* PLL Multiplier = 20, MSEL bits = 12 - 1 = 11 */ + n = 0; /* PLL Divider = 1, NSEL bits = 1 - 1 = 0 */ + clk_div = 3; /* Configure the ARM Core clock div to 6. CCLKSEL = 6 - 1 */ + clk_div_usb = 5; /* Configure the USB clock divider to 6, USBSEL = 6 - 1 */ + + if ((PLLSTAT & DEF_BIT_25) > 0) { /* If the PLL is already running */ + CPU_CRITICAL_ENTER(); + PLLCON &= ~DEF_BIT_01; /* Disconnect the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + } + + CPU_CRITICAL_ENTER(); + PLLCON &= ~DEF_BIT_00; /* Disable the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + SCS &= ~DEF_BIT_04; /* OSCRANGE = 0, Main OSC is between 1 and 20 Mhz */ + SCS |= DEF_BIT_05; /* OSCEN = 1, Enable the main oscillator */ + SCS |= DEF_BIT_00; /* access to all ports as fast io */ + + while ((SCS & DEF_BIT_06) == 0) { /* Wait until OSCSTAT is set (Main OSC ready to be used) */ + ; + } + + CLKSRCSEL = DEF_BIT_00; /* Select main OSC, 12MHz, as the PLL clock source */ + + CPU_CRITICAL_ENTER(); + PLLCFG = (m << 0) | (n << 16); /* Configure the PLL multiplier and divider */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + CPU_CRITICAL_ENTER(); + PLLCON |= DEF_BIT_00; /* Enable the PLL */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + CCLKCFG = clk_div; /* Configure the ARM Core Processor clock divider */ + USBCLKCFG = clk_div_usb; /* Configure the USB clock divider */ + + while ((PLLSTAT & DEF_BIT_26) == 0) { /* Wait for PLOCK to become set */ + ; + } + + PCLKSEL0 = 0xAAAAAAAA; /* Set peripheral clocks to be half of main clock */ + PCLKSEL1 = 0x22AAA8AA; + + CPU_CRITICAL_ENTER(); + PLLCON |= DEF_BIT_01; /* Connect the PLL. The PLL is now the active clock source */ + PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */ + PLLFEED = 0x55; + CPU_CRITICAL_EXIT(); + + while ((PLLSTAT & DEF_BIT_25) == 0) { /* Wait PLLC, the PLL connect status bit to become set */ + ; + } +} + + +/* +********************************************************************************************************* +* MAM_Init() +* +* Description : Initialize the Memory Acceleration Module. +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void MAM_Init (void) +{ + CPU_INT32U clk_freq; + + + clk_freq = BSP_CPU_ClkFreq(); /* Get the current core clock frequency */ + + MAMCR = 0; /* Disable MAM functionality */ + + if (clk_freq < 20000000) { /* Compare current clock frequency with MAM modes */ + MAMTIM = 1; /* Set MAM fetch cycles to 1 processor clock in duration */ + } + + if (clk_freq < 40000000) { + MAMTIM = 2; /* Set MAM fetch cycles to 2 processor clock in duration */ + } + + if (clk_freq >= 40000000) { + MAMTIM = 3; /* Set MAM fetch cycles to 3 processor clock in duration */ + } + + MAMCR = 2; /* Enable full MAM functionality */ +} + + +/* +********************************************************************************************************* +* GPIO_Init() +* +* Description : Initializes the GPIO pins. All the I/O pins are initialized in this function +* so you don't have to look at multiple places for I/O initialization. +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Note(s) : (1) Refer to the LPC2378 User Manual, Chapter 9 for a detailed Pin Assignment +********************************************************************************************************* +*/ + +static void GPIO_Init (void) +{ + IO0DIR = 0; + IO1DIR = 0; + FIO0DIR = 0; + FIO1DIR = 0; + FIO2DIR = 0; + FIO3DIR = 0; + FIO4DIR = 0; + + FIO0MASK = 0; + FIO1MASK = 0; + FIO2MASK = 0; + FIO3MASK = 0; + FIO4MASK = 0; + + PINSEL0 = 0; + PINSEL1 = 0; + PINSEL2 = 0; + PINSEL3 = 0; + PINSEL4 = 0; + PINSEL5 = 0; + PINSEL6 = 0; + PINSEL7 = 0; + PINSEL8 = 0; + PINSEL9 = 0; + PINSEL10 = 0; +} + + +/* +********************************************************************************************************* +* VIC_Init() +* +* Description : Initialize the Vectored Interrupt Controller +* +* Argument(s) : none. +* +* Return(s) : none. +********************************************************************************************************* +*/ + +static void VIC_Init (void) +{ + VICINTENCLEAR = 0xFFFFFFFF; /* Disable ALL interrupts */ + VICADDRESS = 0; /* Acknowlege any pending VIC interrupt */ + VICPROTECTION = 0; /* Allow VIC register access in User of Priviledged modes */ + + VICVECTADDR0 = (CPU_INT32U)VIC_DummyWDT; /* Set the vector address */ + VICVECTADDR1 = (CPU_INT32U)VIC_DummySW; + VICVECTADDR2 = (CPU_INT32U)VIC_DummyDEBUGRX; + VICVECTADDR3 = (CPU_INT32U)VIC_DummyDEBUGTX; + VICVECTADDR4 = (CPU_INT32U)VIC_DummyTIMER0; + VICVECTADDR5 = (CPU_INT32U)VIC_DummyTIMER1; + VICVECTADDR6 = (CPU_INT32U)VIC_DummyUART0; + VICVECTADDR7 = (CPU_INT32U)VIC_DummyUART1; + VICVECTADDR8 = (CPU_INT32U)VIC_DummyPWM01; + VICVECTADDR9 = (CPU_INT32U)VIC_DummyI2C0; + VICVECTADDR10 = (CPU_INT32U)VIC_DummySPI; + VICVECTADDR11 = (CPU_INT32U)VIC_DummySSP1; + VICVECTADDR12 = (CPU_INT32U)VIC_DummyPLL; + VICVECTADDR13 = (CPU_INT32U)VIC_DummyRTC; + VICVECTADDR14 = (CPU_INT32U)VIC_DummyEINT0; + VICVECTADDR15 = (CPU_INT32U)VIC_DummyEINT1; + VICVECTADDR16 = (CPU_INT32U)VIC_DummyEINT2; + VICVECTADDR17 = (CPU_INT32U)VIC_DummyEINT3; + VICVECTADDR18 = (CPU_INT32U)VIC_DummyAD0; + VICVECTADDR19 = (CPU_INT32U)VIC_DummyI2C1; + VICVECTADDR20 = (CPU_INT32U)VIC_DummyBOD; + VICVECTADDR21 = (CPU_INT32U)VIC_DummyETHERNET; + VICVECTADDR22 = (CPU_INT32U)VIC_DummyUSB; + VICVECTADDR23 = (CPU_INT32U)VIC_DummyCAN01; + VICVECTADDR24 = (CPU_INT32U)VIC_DummyMMC; + VICVECTADDR25 = (CPU_INT32U)VIC_DummyGP_DMA; + VICVECTADDR26 = (CPU_INT32U)VIC_DummyTIMER2; + VICVECTADDR27 = (CPU_INT32U)VIC_DummyTIMER3; + VICVECTADDR28 = (CPU_INT32U)VIC_DummyUART2; + VICVECTADDR29 = (CPU_INT32U)VIC_DummyUART3; + VICVECTADDR30 = (CPU_INT32U)VIC_DummyI2C2; + VICVECTADDR31 = (CPU_INT32U)VIC_DummyI2S; +} + + +/* +********************************************************************************************************* +********************************************************************************************************* +** DUMMY INTERRUPT HANDLERS +********************************************************************************************************* +********************************************************************************************************* +*/ + +static void VIC_Dummy (void) +{ + while (DEF_TRUE) { + ; + } +} + +static void VIC_DummyWDT (void) +{ + VIC_SpuriousInt = VIC_WDT; + VIC_Dummy(); +} + +static void VIC_DummySW (void) +{ + VIC_SpuriousInt = VIC_SW; + VIC_Dummy(); +} + +static void VIC_DummyDEBUGRX (void) +{ + VIC_SpuriousInt = VIC_DEBUGRX; + VIC_Dummy(); +} + +static void VIC_DummyDEBUGTX (void) +{ + VIC_SpuriousInt = VIC_DEBUGTX; + VIC_Dummy(); +} + +static void VIC_DummyTIMER0 (void) +{ + VIC_SpuriousInt = VIC_TIMER0; + VIC_Dummy(); +} + +static void VIC_DummyTIMER1 (void) +{ + VIC_SpuriousInt = VIC_TIMER1; + VIC_Dummy(); +} + +static void VIC_DummyUART0 (void) +{ + VIC_SpuriousInt = VIC_UART0; + VIC_Dummy(); +} + +static void VIC_DummyUART1 (void) +{ + VIC_SpuriousInt = VIC_UART1; + VIC_Dummy(); +} + +static void VIC_DummyPWM01 (void) +{ + VIC_SpuriousInt = VIC_PWM1; + VIC_Dummy(); +} + +static void VIC_DummyI2C0 (void) +{ + VIC_SpuriousInt = VIC_I2C0; + VIC_Dummy(); +} + +static void VIC_DummySPI (void) +{ + VIC_SpuriousInt = VIC_SPI; + VIC_Dummy(); +} + +static void VIC_DummySSP1 (void) +{ + VIC_SpuriousInt = VIC_SSP1; + VIC_Dummy(); +} + +static void VIC_DummyPLL (void) +{ + VIC_SpuriousInt = VIC_PLL; + VIC_Dummy(); +} + +static void VIC_DummyRTC (void) +{ + VIC_SpuriousInt = VIC_RTC; + VIC_Dummy(); +} + +static void VIC_DummyEINT0 (void) +{ + VIC_SpuriousInt = VIC_EINT0; + VIC_Dummy(); +} + +static void VIC_DummyEINT1 (void) +{ + VIC_SpuriousInt = VIC_EINT1; + VIC_Dummy(); +} + +static void VIC_DummyEINT2 (void) +{ + VIC_SpuriousInt = VIC_EINT2; + VIC_Dummy(); +} + +static void VIC_DummyEINT3 (void) +{ + VIC_SpuriousInt = VIC_EINT3; + VIC_Dummy(); +} + +static void VIC_DummyAD0 (void) +{ + VIC_SpuriousInt = VIC_AD0; + VIC_Dummy(); +} + +static void VIC_DummyI2C1 (void) +{ + VIC_SpuriousInt = VIC_I2C1; + VIC_Dummy(); +} + +static void VIC_DummyBOD (void) +{ + VIC_SpuriousInt = VIC_BOD; + VIC_Dummy(); +} + +static void VIC_DummyETHERNET (void) +{ + VIC_SpuriousInt = VIC_ETHERNET; + VIC_Dummy(); +} + +static void VIC_DummyUSB (void) +{ + VIC_SpuriousInt = VIC_USB; + VIC_Dummy(); +} + +static void VIC_DummyCAN01 (void) +{ + VIC_SpuriousInt = VIC_CAN12; + VIC_Dummy(); +} + +static void VIC_DummyMMC (void) +{ + VIC_SpuriousInt = VIC_MMC; + VIC_Dummy(); +} + +static void VIC_DummyGP_DMA (void) +{ + VIC_SpuriousInt = VIC_GP_DMA; + VIC_Dummy(); +} + +static void VIC_DummyTIMER2 (void) +{ + VIC_SpuriousInt = VIC_TIMER2; + VIC_Dummy(); +} + +static void VIC_DummyTIMER3 (void) +{ + VIC_SpuriousInt = VIC_TIMER3; + VIC_Dummy(); +} + +static void VIC_DummyUART2 (void) +{ + VIC_SpuriousInt = VIC_UART2; + VIC_Dummy(); +} + +static void VIC_DummyUART3 (void) +{ + VIC_SpuriousInt = VIC_UART3; + VIC_Dummy(); +} + +static void VIC_DummyI2C2 (void) +{ + VIC_SpuriousInt = VIC_I2C2; + VIC_Dummy(); +} + +static void VIC_DummyI2S (void) +{ + VIC_SpuriousInt = VIC_I2S; + VIC_Dummy(); +} diff --git a/OS/bsp/bsp.h b/OS/bsp/bsp.h new file mode 100644 index 0000000..4a590a3 --- /dev/null +++ b/OS/bsp/bsp.h @@ -0,0 +1,99 @@ +#ifndef __BSP_H__ +#define __BSP_H__ + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef BSP_GLOBALS +#define BSP_EXT +#else +#define BSP_EXT extern +#endif + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define MAIN_OSC_FRQ 12000000L +#define IRC_OSC_FRQ 4000000L +#define RTC_OSC_FRQ 32768L + +/* +********************************************************************************************************* +* PCLK PERIPHERAL IDS +* (see 'BSP_CPU_PclkFreq()') +********************************************************************************************************* +*/ + +#define PCLK_WDT 0 +#define PCLK_TIMER0 1 +#define PCLK_TIMER1 2 +#define PCLK_UART0 3 +#define PCLK_UART1 4 +#define PCLK_PWM0 5 +#define PCLK_PWM1 6 +#define PCLK_I2C0 7 +#define PCLK_SPI 8 +#define PCLK_RTC 9 +#define PCLK_SSP1 10 +#define PCLK_DAC 11 +#define PCLK_ADC 12 +#define PCLK_CAN1 13 +#define PCLK_CAN2 14 +#define PCLK_ACF 15 +#define PCLK_BAT_RAM 16 +#define PCLK_GPIO 17 +#define PCLK_PCB 18 +#define PCLK_I2C1 19 +#define PCLK_SSP0 21 +#define PCLK_TIMER2 22 +#define PCLK_TIMER3 23 +#define PCLK_UART2 24 +#define PCLK_UART3 25 +#define PCLK_I2C2 26 +#define PCLK_MCI 27 +#define PCLK_SYSCON 29 + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void BSP_Init (void); +void BSP_IntDisAll (void); +CPU_INT32U BSP_CPU_ClkFreq (void); +CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U id); + + +/* +********************************************************************************************************* +* TICK SERVICES +********************************************************************************************************* +*/ + +void Tmr_TickISR_Handler(void); + + + + +#endif diff --git a/OS/bsp/cstartup.s b/OS/bsp/cstartup.s new file mode 100644 index 0000000..b65ea1d --- /dev/null +++ b/OS/bsp/cstartup.s @@ -0,0 +1,132 @@ +; +;******************************************************************************************************** +; EXCEPTION VECTORS & STARTUP CODE +; +; File : cstartup.s +; For : ARM7 or ARM9 +; Toolchain : IAR EWARM V5.10 and higher +;******************************************************************************************************** +; + +;******************************************************************************************************** +; MACROS AND DEFINIITIONS +;******************************************************************************************************** + + ; Mode, correspords to bits 0-5 in CPSR +MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR +USR_MODE DEFINE 0x10 ; User mode +FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode +IRQ_MODE DEFINE 0x12 ; Interrupt Request mode +SVC_MODE DEFINE 0x13 ; Supervisor mode +ABT_MODE DEFINE 0x17 ; Abort mode +UND_MODE DEFINE 0x1B ; Undefined Instruction mode +SYS_MODE DEFINE 0x1F ; System mode + + +;******************************************************************************************************** +; ARM EXCEPTION VECTORS +;******************************************************************************************************** + + SECTION .intvec:CODE:NOROOT(2) + PUBLIC __vector + PUBLIC __iar_program_start + PUBLIC __vector_0x14 + + IMPORT OS_CPU_ARM_ExceptUndefInstrHndlr + IMPORT OS_CPU_ARM_ExceptSwiHndlr + IMPORT OS_CPU_ARM_ExceptPrefetchAbortHndlr + IMPORT OS_CPU_ARM_ExceptDataAbortHndlr + IMPORT OS_CPU_ARM_ExceptIrqHndlr + IMPORT OS_CPU_ARM_ExceptFiqHndlr + + ARM + +__vector: + LDR PC, [PC,#24] ; Absolute jump can reach 4 GByte + LDR PC, [PC,#24] ; Branch to undef_handler + LDR PC, [PC,#24] ; Branch to swi_handler + LDR PC, [PC,#24] ; Branch to prefetch_handler + LDR PC, [PC,#24] ; Branch to data_handler +__vector_0x14: + DC32 0 ; Reserved + LDR PC, [PC,#24] ; Branch to irq_handler + LDR PC, [PC,#24] ; Branch to fiq_handler + + + DC32 __iar_program_start + DC32 OS_CPU_ARM_ExceptUndefInstrHndlr + DC32 OS_CPU_ARM_ExceptSwiHndlr + DC32 OS_CPU_ARM_ExceptPrefetchAbortHndlr + DC32 OS_CPU_ARM_ExceptDataAbortHndlr + DC32 0 + DC32 OS_CPU_ARM_ExceptIrqHndlr + DC32 OS_CPU_ARM_ExceptFiqHndlr + + +;******************************************************************************************************** +; LOW-LEVEL INITIALIZATION +;******************************************************************************************************** + + SECTION FIQ_STACK:DATA:NOROOT(3) + SECTION IRQ_STACK:DATA:NOROOT(3) + SECTION SVC_STACK:DATA:NOROOT(3) + SECTION ABT_STACK:DATA:NOROOT(3) + SECTION UND_STACK:DATA:NOROOT(3) + SECTION CSTACK:DATA:NOROOT(3) + SECTION text:CODE:NOROOT(2) + REQUIRE __vector + EXTERN ?main + PUBLIC __iar_program_start + EXTERN lowlevel_init + +__iar_program_start: + +;******************************************************************************************************** +; STACK POINTER INITIALIZATION +;******************************************************************************************************** + + MRS r0,cpsr ; Original PSR value + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#SVC_MODE ; Set SVC mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(SVC_STACK) ; End of SVC_STACK + + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#UND_MODE ; Set UND mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(UND_STACK) ; End of UND_STACK + + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#ABT_MODE ; Set ABT mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK + + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#FIQ_MODE ; Set FIQ mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(FIQ_STACK) ; End of FIQ_STACK + + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#IRQ_MODE ; Set IRQ mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(IRQ_STACK) ; End of IRQ_STACK + + BIC r0,r0,#MODE_BITS ; Clear the mode bits + ORR r0,r0,#SYS_MODE ; Set System mode bits + MSR cpsr_c,r0 ; Change the mode + LDR sp,=SFE(CSTACK) ; End of CSTACK + + +;******************************************************************************************************** +; ADDITIONAL INITIALIZATION +;******************************************************************************************************** + + +;******************************************************************************************************** +; CONTINUE TO ?main FOR ADDITIONAL INITIALIZATION +;******************************************************************************************************** + + LDR r0,=?main + BX r0 + + END diff --git a/OS/bsp/iolpc2368.h b/OS/bsp/iolpc2368.h new file mode 100644 index 0000000..3848281 --- /dev/null +++ b/OS/bsp/iolpc2368.h @@ -0,0 +1,4785 @@ +/*************************************************************************** + ** + ** This file defines the Special Function Registers for + ** NXP LPC2368 + ** + ** Used with ARM IAR C/C++ Compiler and Assembler. + ** + ** (c) Copyright IAR Systems 2006 + ** + ** $Revision: 24053 $ + ** + ** Note: Only little endian addressing of 8 bit registers. + ***************************************************************************/ + +#ifndef __IOLPC2368_H +#define __IOLPC2368_H + +#if (((__TID__ >> 8) & 0x7F) != 0x4F) /* 0x4F = 79 dec */ +#error This file should only be compiled by ARM IAR compiler and assembler +#endif + +#include "io_macros.h" + +/*************************************************************************** + *************************************************************************** + ** + ** LPC2368 SPECIAL FUNCTION REGISTERS + ** + *************************************************************************** + *************************************************************************** + ***************************************************************************/ + +/* C-compiler specific declarations ***************************************/ +#ifdef __IAR_SYSTEMS_ICC__ + +#ifndef _SYSTEM_BUILD +#pragma system_include +#endif + +#if __LITTLE_ENDIAN__ == 0 +#error This file should only be compiled in little endian mode +#endif + +/* Memory mapping control register */ +typedef struct{ +__REG32 MAP : 2; +__REG32 :30; +} __memmap_bits; + +/* Reset Source Identification Register */ +typedef struct{ +__REG32 POR : 1; +__REG32 EXTR : 1; +__REG32 WDTR : 1; +__REG32 BODR : 1; +__REG32 :28; +} __rsir_bits; + +/* External interrupt register */ +typedef struct{ +__REG32 EINT0 : 1; +__REG32 EINT1 : 1; +__REG32 EINT2 : 1; +__REG32 EINT3 : 1; +__REG32 :28; +} __extint_bits; + +/* External Interrupt Mode Register */ +typedef struct{ +__REG32 EXTMODE0 : 1; +__REG32 EXTMODE1 : 1; +__REG32 EXTMODE2 : 1; +__REG32 EXTMODE3 : 1; +__REG32 :28; +} __extmode_bits; + +/* External Interrupt Polarity Register */ +typedef struct{ +__REG32 EXTPOLAR0 : 1; +__REG32 EXTPOLAR1 : 1; +__REG32 EXTPOLAR2 : 1; +__REG32 EXTPOLAR3 : 1; +__REG32 :28; +} __extpolar_bits; + +/* System Controls and Status register */ +typedef struct{ +__REG32 GPIOM : 1; +__REG32 : 2; +__REG32 MCIPWR : 1; +__REG32 OSCRANGE : 1; +__REG32 OSCEN : 1; +__REG32 OSCSTAT : 1; +__REG32 :25; +} __scs_bits; + +/* AHB Arbiter Configuration Register*/ +typedef struct{ +__REG32 SHDL : 1; +__REG32 BB : 2; +__REG32 QT : 1; +__REG32 QS : 4; +__REG32 DM : 4; +__REG32 EP1 : 4; +__REG32 EP2 : 4; +__REG32 EP3 : 4; +__REG32 EP4 : 4; +__REG32 : 4; +} __ahbcfg1_bits; + +typedef struct{ +__REG32 SHDL : 1; +__REG32 BB : 2; +__REG32 QT : 1; +__REG32 QS : 4; +__REG32 DM : 4; +__REG32 EP1 : 4; +__REG32 EP2 : 4; +__REG32 :12; +} __ahbcfg2_bits; + +/* Clock Soucre Select register */ +typedef struct{ +__REG32 CLKSRC : 2; +__REG32 :30; +} __clksrcsel_bits; + +/* IRC Trim Register (IRCTRIM - 0xE01FC1A4) */ +typedef struct{ +__REG32 IRCTRIM : 8; +__REG32 :24; +} __irctrim_bits; + +/* CPU Clock Configuration register */ +typedef struct{ +__REG32 CCLKSEL : 8; +__REG32 :24; +} __cclkcfg_bits; + +/* USB Clock Configuration register */ +typedef struct{ +__REG32 USBSEL : 4; +__REG32 :28; +} __usbclkcfg_bits; + +/* Peripheral Clock Selection registers 0 */ +typedef struct{ +__REG32 PCLK_WDT : 2; +__REG32 PCLK_TIMER0 : 2; +__REG32 PCLK_TIMER1 : 2; +__REG32 PCLK_UART0 : 2; +__REG32 PCLK_UART1 : 2; +__REG32 : 2; +__REG32 PCLK_PWM1 : 2; +__REG32 PCLK_I2C0 : 2; +__REG32 PCLK_SPI : 2; +__REG32 PCLK_RTC : 2; +__REG32 PCLK_SSP1 : 2; +__REG32 PCLK_DAC : 2; +__REG32 PCLK_ADC : 2; +__REG32 PCLK_CAN1 : 2; +__REG32 PCLK_CAN2 : 2; +__REG32 PCLK_ACF : 2; +} __pclksel0_bits; + +/* Peripheral Clock Selection registers 1 */ +typedef struct{ +__REG32 PCLK_BAT_RAM: 2; +__REG32 PCLK_GPIO : 2; +__REG32 PCLK_PCB : 2; +__REG32 PCLK_I2C1 : 2; +__REG32 : 2; +__REG32 PCLK_SSP0 : 2; +__REG32 PCLK_TIMER2 : 2; +__REG32 PCLK_TIMER3 : 2; +__REG32 PCLK_UART2 : 2; +__REG32 PCLK_UART3 : 2; +__REG32 PCLK_I2C2 : 2; +__REG32 PCLK_I2S : 2; +__REG32 PCLK_MCI : 2; +__REG32 : 2; +__REG32 PCLK_SYSCON : 2; +__REG32 : 2; +} __pclksel1_bits; + +/* PLL control register */ +typedef struct{ +__REG32 PLLE : 1; +__REG32 PLLC : 1; +__REG32 :30; +} __pllcon_bits; + +/* PLL config register */ +typedef struct{ +__REG32 MSEL :15; +__REG32 : 1; +__REG32 NSEL : 8; +__REG32 : 8; +} __pllcfg_bits; + +/* PLL status register */ +typedef struct{ +__REG32 MSEL :15; +__REG32 : 1; +__REG32 NSEL : 8; +__REG32 PLLE : 1; +__REG32 PLLC : 1; +__REG32 PLOCK : 1; +__REG32 : 5; +} __pllstat_bits; + +/* PLL feed register */ +typedef struct{ +__REG32 FEED : 8; +__REG32 :24; +} __pllfeed_bits; + +/* Power control register */ +typedef struct{ +__REG32 IDL : 1; +__REG32 PD : 1; +__REG32 BODPDM : 1; +__REG32 BOGD : 1; +__REG32 BORD : 1; +__REG32 : 2; +__REG32 PM2 : 1; +__REG32 :24; +}__pcon_bits; + +/* Interrupt Wakeup Register */ +typedef struct{ +__REG32 EXTWAKE0 : 1; +__REG32 EXTWAKE1 : 1; +__REG32 EXTWAKE2 : 1; +__REG32 EXTWAKE3 : 1; +__REG32 ETHWAK : 1; +__REG32 USBWAKE : 1; +__REG32 CANWAKE : 1; +__REG32 GPIO0WAKE : 1; +__REG32 GPIO2WAKE : 1; +__REG32 : 5; +__REG32 BODWAKE : 1; +__REG32 RTCWAKE : 1; +__REG32 :16; +}__intwake_bits; + +/* Power control for peripherals register */ +typedef struct{ +__REG32 : 1; +__REG32 PCTIM0 : 1; +__REG32 PCTIM1 : 1; +__REG32 PCUART0 : 1; +__REG32 PCUART1 : 1; +__REG32 : 1; +__REG32 PCPWM1 : 1; +__REG32 PCI2C0 : 1; +__REG32 PCSPI : 1; +__REG32 PCRTC : 1; +__REG32 PCSSP1 : 1; +__REG32 : 1; +__REG32 PCAD : 1; +__REG32 PCAN1 : 1; +__REG32 PCAN2 : 1; +__REG32 : 4; +__REG32 PCI2C1 : 1; +__REG32 : 1; +__REG32 PCSSP0 : 1; +__REG32 PCTIM2 : 1; +__REG32 PCTIM3 : 1; +__REG32 PCUART2 : 1; +__REG32 PCUART3 : 1; +__REG32 PCI2C2 : 1; +__REG32 PCI2S : 1; +__REG32 PCSDC : 1; +__REG32 PCGPDMA : 1; +__REG32 PCENET : 1; +__REG32 PCUSB : 1; +} __pconp_bits; + +/* Memory accelerator module control register */ +typedef struct { + __REG32 MODECTRL : 2; + __REG32 :30; +} __mamcr_bits; + +/* Memory accelerator module timing register */ +typedef struct { + __REG32 CYCLES : 3; + __REG32 :29; +} __mamtim_bits; + +/* VIC Interrupt registers */ +typedef struct{ +__REG32 WDT : 1; +__REG32 : 1; +__REG32 ARMCORE0 : 1; +__REG32 ARMCORE1 : 1; +__REG32 TIMER0 : 1; +__REG32 TIMER1 : 1; +__REG32 UART0 : 1; +__REG32 UART1 : 1; +__REG32 PWM1 : 1; +__REG32 I2C0 : 1; +__REG32 SPI : 1; +__REG32 SSP1 : 1; +__REG32 PLL : 1; +__REG32 RTC : 1; +__REG32 EINT0 : 1; +__REG32 EINT1 : 1; +__REG32 EINT2 : 1; +__REG32 EINT3 : 1; +__REG32 AD0 : 1; +__REG32 I2C1 : 1; +__REG32 BOD : 1; +__REG32 ETHERNET : 1; +__REG32 USB : 1; +__REG32 CAN12 : 1; +__REG32 SDMMC : 1; +__REG32 GPDMA : 1; +__REG32 TIMER2 : 1; +__REG32 TIMER3 : 1; +__REG32 UART2 : 1; +__REG32 UART3 : 1; +__REG32 I2C2 : 1; +__REG32 I2S : 1; +} __vicint_bits; + +/* VIC Vector control registers */ +typedef struct{ +__REG32 PRIORITY : 4; +__REG32 :28; +} __vicvectpr_bits; + +/* VIC Software Priority register */ +typedef struct{ +__REG32 SWPRIORITY:16; +__REG32 :16; +} __vicswprmask_bits; + +/* VIC protection enable register */ +typedef struct{ +__REG32 VIC_ACCESS : 1; +__REG32 :31; +} __vicprotection_bits; + +/* Pin function select register 0 */ +typedef struct{ +__REG32 P0_0 : 2; +__REG32 P0_1 : 2; +__REG32 P0_2 : 2; +__REG32 P0_3 : 2; +__REG32 P0_4 : 2; +__REG32 P0_5 : 2; +__REG32 P0_6 : 2; +__REG32 P0_7 : 2; +__REG32 P0_8 : 2; +__REG32 P0_9 : 2; +__REG32 P0_10 : 2; +__REG32 P0_11 : 2; +__REG32 P0_12 : 2; +__REG32 P0_13 : 2; +__REG32 P0_14 : 2; +__REG32 P0_15 : 2; +} __pinsel0_bits; + +/* Pin function select register 1 */ +typedef struct{ +__REG32 P0_16 : 2; +__REG32 P0_17 : 2; +__REG32 P0_18 : 2; +__REG32 P0_19 : 2; +__REG32 P0_20 : 2; +__REG32 P0_21 : 2; +__REG32 P0_22 : 2; +__REG32 P0_23 : 2; +__REG32 P0_24 : 2; +__REG32 P0_25 : 2; +__REG32 P0_26 : 2; +__REG32 P0_27 : 2; +__REG32 P0_28 : 2; +__REG32 P0_29 : 2; +__REG32 P0_30 : 2; +__REG32 P0_31 : 2; +} __pinsel1_bits; + +/* Pin function select register 2 */ +typedef struct{ +__REG32 P1_0 : 2; +__REG32 P1_1 : 2; +__REG32 P1_2 : 2; +__REG32 P1_3 : 2; +__REG32 P1_4 : 2; +__REG32 P1_5 : 2; +__REG32 P1_6 : 2; +__REG32 P1_7 : 2; +__REG32 P1_8 : 2; +__REG32 P1_9 : 2; +__REG32 P1_10 : 2; +__REG32 P1_11 : 2; +__REG32 P1_12 : 2; +__REG32 P1_13 : 2; +__REG32 P1_14 : 2; +__REG32 P1_15 : 2; +} __pinsel2_bits; + +/* Pin function select register 3 */ +typedef struct{ +__REG32 P1_16 : 2; +__REG32 P1_17 : 2; +__REG32 P1_18 : 2; +__REG32 P1_19 : 2; +__REG32 P1_20 : 2; +__REG32 P1_21 : 2; +__REG32 P1_22 : 2; +__REG32 P1_23 : 2; +__REG32 P1_24 : 2; +__REG32 P1_25 : 2; +__REG32 P1_26 : 2; +__REG32 P1_27 : 2; +__REG32 P1_28 : 2; +__REG32 P1_29 : 2; +__REG32 P1_30 : 2; +__REG32 P1_31 : 2; +} __pinsel3_bits; + +/* Pin function select register 4 */ +typedef struct{ +__REG32 P2_0 : 2; +__REG32 P2_1 : 2; +__REG32 P2_2 : 2; +__REG32 P2_3 : 2; +__REG32 P2_4 : 2; +__REG32 P2_5 : 2; +__REG32 P2_6 : 2; +__REG32 P2_7 : 2; +__REG32 P2_8 : 2; +__REG32 P2_9 : 2; +__REG32 P2_10 : 2; +__REG32 P2_11 : 2; +__REG32 P2_12 : 2; +__REG32 P2_13 : 2; +__REG32 P2_14 : 2; +__REG32 P2_15 : 2; +} __pinsel4_bits; + +/* Pin function select register 5 */ +typedef struct{ +__REG32 P2_16 : 2; +__REG32 P2_17 : 2; +__REG32 P2_18 : 2; +__REG32 P2_19 : 2; +__REG32 P2_20 : 2; +__REG32 P2_21 : 2; +__REG32 P2_22 : 2; +__REG32 P2_23 : 2; +__REG32 P2_24 : 2; +__REG32 P2_25 : 2; +__REG32 P2_26 : 2; +__REG32 P2_27 : 2; +__REG32 P2_28 : 2; +__REG32 P2_29 : 2; +__REG32 P2_30 : 2; +__REG32 P2_31 : 2; +} __pinsel5_bits; + +/* Pin function select register 6 */ +typedef struct{ +__REG32 P3_0 : 2; +__REG32 P3_1 : 2; +__REG32 P3_2 : 2; +__REG32 P3_3 : 2; +__REG32 P3_4 : 2; +__REG32 P3_5 : 2; +__REG32 P3_6 : 2; +__REG32 P3_7 : 2; +__REG32 P3_8 : 2; +__REG32 P3_9 : 2; +__REG32 P3_10 : 2; +__REG32 P3_11 : 2; +__REG32 P3_12 : 2; +__REG32 P3_13 : 2; +__REG32 P3_14 : 2; +__REG32 P3_15 : 2; +} __pinsel6_bits; + +/* Pin function select register 7 */ +typedef struct{ +__REG32 P3_16 : 2; +__REG32 P3_17 : 2; +__REG32 P3_18 : 2; +__REG32 P3_19 : 2; +__REG32 P3_20 : 2; +__REG32 P3_21 : 2; +__REG32 P3_22 : 2; +__REG32 P3_23 : 2; +__REG32 P3_24 : 2; +__REG32 P3_25 : 2; +__REG32 P3_26 : 2; +__REG32 P3_27 : 2; +__REG32 P3_28 : 2; +__REG32 P3_29 : 2; +__REG32 P3_30 : 2; +__REG32 P3_31 : 2; +} __pinsel7_bits; + +/* Pin function select register 8 */ +typedef struct{ +__REG32 P4_0 : 2; +__REG32 P4_1 : 2; +__REG32 P4_2 : 2; +__REG32 P4_3 : 2; +__REG32 P4_4 : 2; +__REG32 P4_5 : 2; +__REG32 P4_6 : 2; +__REG32 P4_7 : 2; +__REG32 P4_8 : 2; +__REG32 P4_9 : 2; +__REG32 P4_10 : 2; +__REG32 P4_11 : 2; +__REG32 P4_12 : 2; +__REG32 P4_13 : 2; +__REG32 P4_14 : 2; +__REG32 P4_15 : 2; +} __pinsel8_bits; + +/* Pin function select register 9 */ +typedef struct{ +__REG32 P4_16 : 2; +__REG32 P4_17 : 2; +__REG32 P4_18 : 2; +__REG32 P4_19 : 2; +__REG32 P4_20 : 2; +__REG32 P4_21 : 2; +__REG32 P4_22 : 2; +__REG32 P4_23 : 2; +__REG32 P4_24 : 2; +__REG32 P4_25 : 2; +__REG32 P4_26 : 2; +__REG32 P4_27 : 2; +__REG32 P4_28 : 2; +__REG32 P4_29 : 2; +__REG32 P4_30 : 2; +__REG32 P4_31 : 2; +} __pinsel9_bits; + +/* Pin function select register 10 */ +typedef struct{ +__REG32 : 3; +__REG32 GPIO_TRACE : 1; +__REG32 :28; +} __pinsel10_bits; + +/* GPIO 0 Registers */ +typedef struct { +__REG32 P0_0 : 1; +__REG32 P0_1 : 1; +__REG32 P0_2 : 1; +__REG32 P0_3 : 1; +__REG32 P0_4 : 1; +__REG32 P0_5 : 1; +__REG32 P0_6 : 1; +__REG32 P0_7 : 1; +__REG32 P0_8 : 1; +__REG32 P0_9 : 1; +__REG32 P0_10 : 1; +__REG32 P0_11 : 1; +__REG32 P0_12 : 1; +__REG32 P0_13 : 1; +__REG32 P0_14 : 1; +__REG32 P0_15 : 1; +__REG32 P0_16 : 1; +__REG32 P0_17 : 1; +__REG32 P0_18 : 1; +__REG32 P0_19 : 1; +__REG32 P0_20 : 1; +__REG32 P0_21 : 1; +__REG32 P0_22 : 1; +__REG32 P0_23 : 1; +__REG32 P0_24 : 1; +__REG32 P0_25 : 1; +__REG32 P0_26 : 1; +__REG32 P0_27 : 1; +__REG32 P0_28 : 1; +__REG32 P0_29 : 1; +__REG32 P0_30 : 1; +__REG32 P0_31 : 1; +} __gpio0_bits; + +/* FGPIO 0 Registers*/ +typedef union{ + //FIO0DIR + //FIO0MASK + //FIO0PIN + //FIO0SET + //FIO0CLR + struct { + __REG32 P0_0 : 1; + __REG32 P0_1 : 1; + __REG32 P0_2 : 1; + __REG32 P0_3 : 1; + __REG32 P0_4 : 1; + __REG32 P0_5 : 1; + __REG32 P0_6 : 1; + __REG32 P0_7 : 1; + __REG32 P0_8 : 1; + __REG32 P0_9 : 1; + __REG32 P0_10 : 1; + __REG32 P0_11 : 1; + __REG32 P0_12 : 1; + __REG32 P0_13 : 1; + __REG32 P0_14 : 1; + __REG32 P0_15 : 1; + __REG32 P0_16 : 1; + __REG32 P0_17 : 1; + __REG32 P0_18 : 1; + __REG32 P0_19 : 1; + __REG32 P0_20 : 1; + __REG32 P0_21 : 1; + __REG32 P0_22 : 1; + __REG32 P0_23 : 1; + __REG32 P0_24 : 1; + __REG32 P0_25 : 1; + __REG32 P0_26 : 1; + __REG32 P0_27 : 1; + __REG32 P0_28 : 1; + __REG32 P0_29 : 1; + __REG32 P0_30 : 1; + __REG32 P0_31 : 1; + }; + + struct + { + union + { + //FIO0DIR0 + //FIO0MASK0 + //FIO0PIN0 + //FIO0SET0 + //FIO0CLR0 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO0DIR1 + //FIO0MASK1 + //FIO0PIN1 + //FIO0SET1 + //FIO0CLR1 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO0DIR2 + //FIO0MASK2 + //FIO0PIN2 + //FIO0SET2 + //FIO0CLR2 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO0DIR3 + //FIO0MASK3 + //FIO0PIN3 + //FIO0SET3 + //FIO0CLR3 + struct{ + __REG8 P0_0 : 1; + __REG8 P0_1 : 1; + __REG8 P0_2 : 1; + __REG8 P0_3 : 1; + __REG8 P0_4 : 1; + __REG8 P0_5 : 1; + __REG8 P0_6 : 1; + __REG8 P0_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO0DIRL + //FIO0MASKL + //FIO0PINL + //FIO0SETL + //FIO0CLRL + struct{ + __REG16 P0_0 : 1; + __REG16 P0_1 : 1; + __REG16 P0_2 : 1; + __REG16 P0_3 : 1; + __REG16 P0_4 : 1; + __REG16 P0_5 : 1; + __REG16 P0_6 : 1; + __REG16 P0_7 : 1; + __REG16 P0_8 : 1; + __REG16 P0_9 : 1; + __REG16 P0_10 : 1; + __REG16 P0_11 : 1; + __REG16 P0_12 : 1; + __REG16 P0_13 : 1; + __REG16 P0_14 : 1; + __REG16 P0_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO0DIRU + //FIO0MASKU + //FIO0PINU + //FIO0SETU + //FIO0CLRU + struct{ + __REG16 P0_0 : 1; + __REG16 P0_1 : 1; + __REG16 P0_2 : 1; + __REG16 P0_3 : 1; + __REG16 P0_4 : 1; + __REG16 P0_5 : 1; + __REG16 P0_6 : 1; + __REG16 P0_7 : 1; + __REG16 P0_8 : 1; + __REG16 P0_9 : 1; + __REG16 P0_10 : 1; + __REG16 P0_11 : 1; + __REG16 P0_12 : 1; + __REG16 P0_13 : 1; + __REG16 P0_14 : 1; + __REG16 P0_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio0_bits; + +/* GPIO 1 Registers */ +typedef struct { +__REG32 P1_0 : 1; +__REG32 P1_1 : 1; +__REG32 P1_2 : 1; +__REG32 P1_3 : 1; +__REG32 P1_4 : 1; +__REG32 P1_5 : 1; +__REG32 P1_6 : 1; +__REG32 P1_7 : 1; +__REG32 P1_8 : 1; +__REG32 P1_9 : 1; +__REG32 P1_10 : 1; +__REG32 P1_11 : 1; +__REG32 P1_12 : 1; +__REG32 P1_13 : 1; +__REG32 P1_14 : 1; +__REG32 P1_15 : 1; +__REG32 P1_16 : 1; +__REG32 P1_17 : 1; +__REG32 P1_18 : 1; +__REG32 P1_19 : 1; +__REG32 P1_20 : 1; +__REG32 P1_21 : 1; +__REG32 P1_22 : 1; +__REG32 P1_23 : 1; +__REG32 P1_24 : 1; +__REG32 P1_25 : 1; +__REG32 P1_26 : 1; +__REG32 P1_27 : 1; +__REG32 P1_28 : 1; +__REG32 P1_29 : 1; +__REG32 P1_30 : 1; +__REG32 P1_31 : 1; +} __gpio1_bits; + +/* FGPIO 1 Registers*/ +typedef union{ + //FIO1DIR + //FIO1MASK + //FIO1PIN + //FIO1SET + //FIO1CLR + struct { + __REG32 P1_0 : 1; + __REG32 P1_1 : 1; + __REG32 P1_2 : 1; + __REG32 P1_3 : 1; + __REG32 P1_4 : 1; + __REG32 P1_5 : 1; + __REG32 P1_6 : 1; + __REG32 P1_7 : 1; + __REG32 P1_8 : 1; + __REG32 P1_9 : 1; + __REG32 P1_10 : 1; + __REG32 P1_11 : 1; + __REG32 P1_12 : 1; + __REG32 P1_13 : 1; + __REG32 P1_14 : 1; + __REG32 P1_15 : 1; + __REG32 P1_16 : 1; + __REG32 P1_17 : 1; + __REG32 P1_18 : 1; + __REG32 P1_19 : 1; + __REG32 P1_20 : 1; + __REG32 P1_21 : 1; + __REG32 P1_22 : 1; + __REG32 P1_23 : 1; + __REG32 P1_24 : 1; + __REG32 P1_25 : 1; + __REG32 P1_26 : 1; + __REG32 P1_27 : 1; + __REG32 P1_28 : 1; + __REG32 P1_29 : 1; + __REG32 P1_30 : 1; + __REG32 P1_31 : 1; + }; + + struct + { + union + { + //FIO1DIR0 + //FIO1MASK0 + //FIO1PIN0 + //FIO1SET0 + //FIO1CLR0 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO1DIR1 + //FIO1MASK1 + //FIO1PIN1 + //FIO1SET1 + //FIO1CLR1 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO1DIR2 + //FIO1MASK2 + //FIO1PIN2 + //FIO1SET2 + //FIO1CLR2 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO1DIR3 + //FIO1MASK3 + //FIO1PIN3 + //FIO1SET3 + //FIO1CLR3 + struct{ + __REG8 P1_0 : 1; + __REG8 P1_1 : 1; + __REG8 P1_2 : 1; + __REG8 P1_3 : 1; + __REG8 P1_4 : 1; + __REG8 P1_5 : 1; + __REG8 P1_6 : 1; + __REG8 P1_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO1DIRL + //FIO1MASKL + //FIO1PINL + //FIO1SETL + //FIO1CLRL + struct{ + __REG16 P1_0 : 1; + __REG16 P1_1 : 1; + __REG16 P1_2 : 1; + __REG16 P1_3 : 1; + __REG16 P1_4 : 1; + __REG16 P1_5 : 1; + __REG16 P1_6 : 1; + __REG16 P1_7 : 1; + __REG16 P1_8 : 1; + __REG16 P1_9 : 1; + __REG16 P1_10 : 1; + __REG16 P1_11 : 1; + __REG16 P1_12 : 1; + __REG16 P1_13 : 1; + __REG16 P1_14 : 1; + __REG16 P1_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO1DIRU + //FIO1MASKU + //FIO1PINU + //FIO1SETU + //FIO1CLRU + struct{ + __REG16 P1_0 : 1; + __REG16 P1_1 : 1; + __REG16 P1_2 : 1; + __REG16 P1_3 : 1; + __REG16 P1_4 : 1; + __REG16 P1_5 : 1; + __REG16 P1_6 : 1; + __REG16 P1_7 : 1; + __REG16 P1_8 : 1; + __REG16 P1_9 : 1; + __REG16 P1_10 : 1; + __REG16 P1_11 : 1; + __REG16 P1_12 : 1; + __REG16 P1_13 : 1; + __REG16 P1_14 : 1; + __REG16 P1_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio1_bits; + +/* GPIO 2 Registers */ +typedef struct { +__REG32 P2_0 : 1; +__REG32 P2_1 : 1; +__REG32 P2_2 : 1; +__REG32 P2_3 : 1; +__REG32 P2_4 : 1; +__REG32 P2_5 : 1; +__REG32 P2_6 : 1; +__REG32 P2_7 : 1; +__REG32 P2_8 : 1; +__REG32 P2_9 : 1; +__REG32 P2_10 : 1; +__REG32 P2_11 : 1; +__REG32 P2_12 : 1; +__REG32 P2_13 : 1; +__REG32 P2_14 : 1; +__REG32 P2_15 : 1; +__REG32 P2_16 : 1; +__REG32 P2_17 : 1; +__REG32 P2_18 : 1; +__REG32 P2_19 : 1; +__REG32 P2_20 : 1; +__REG32 P2_21 : 1; +__REG32 P2_22 : 1; +__REG32 P2_23 : 1; +__REG32 P2_24 : 1; +__REG32 P2_25 : 1; +__REG32 P2_26 : 1; +__REG32 P2_27 : 1; +__REG32 P2_28 : 1; +__REG32 P2_29 : 1; +__REG32 P2_30 : 1; +__REG32 P2_31 : 1; +} __gpio2_bits; + +/* FGPIO 2 Registers*/ +typedef union{ + //FIO2DIR + //FIO2MASK + //FIO2PIN + //FIO2SET + //FIO2CLR + struct { + __REG32 P2_0 : 1; + __REG32 P2_1 : 1; + __REG32 P2_2 : 1; + __REG32 P2_3 : 1; + __REG32 P2_4 : 1; + __REG32 P2_5 : 1; + __REG32 P2_6 : 1; + __REG32 P2_7 : 1; + __REG32 P2_8 : 1; + __REG32 P2_9 : 1; + __REG32 P2_10 : 1; + __REG32 P2_11 : 1; + __REG32 P2_12 : 1; + __REG32 P2_13 : 1; + __REG32 P2_14 : 1; + __REG32 P2_15 : 1; + __REG32 P2_16 : 1; + __REG32 P2_17 : 1; + __REG32 P2_18 : 1; + __REG32 P2_19 : 1; + __REG32 P2_20 : 1; + __REG32 P2_21 : 1; + __REG32 P2_22 : 1; + __REG32 P2_23 : 1; + __REG32 P2_24 : 1; + __REG32 P2_25 : 1; + __REG32 P2_26 : 1; + __REG32 P2_27 : 1; + __REG32 P2_28 : 1; + __REG32 P2_29 : 1; + __REG32 P2_30 : 1; + __REG32 P2_31 : 1; + }; + + struct + { + union + { + //FIO2DIR0 + //FIO2MASK0 + //FIO2PIN0 + //FIO2SET0 + //FIO2CLR0 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO2DIR1 + //FIO2MASK1 + //FIO2PIN1 + //FIO2SET1 + //FIO2CLR1 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO2DIR2 + //FIO2MASK2 + //FIO2PIN2 + //FIO2SET2 + //FIO2CLR2 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO2DIR3 + //FIO2MASK3 + //FIO2PIN3 + //FIO2SET3 + //FIO2CLR3 + struct{ + __REG8 P2_0 : 1; + __REG8 P2_1 : 1; + __REG8 P2_2 : 1; + __REG8 P2_3 : 1; + __REG8 P2_4 : 1; + __REG8 P2_5 : 1; + __REG8 P2_6 : 1; + __REG8 P2_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO2DIRL + //FIO2MASKL + //FIO2PINL + //FIO2SETL + //FIO2CLRL + struct{ + __REG16 P2_0 : 1; + __REG16 P2_1 : 1; + __REG16 P2_2 : 1; + __REG16 P2_3 : 1; + __REG16 P2_4 : 1; + __REG16 P2_5 : 1; + __REG16 P2_6 : 1; + __REG16 P2_7 : 1; + __REG16 P2_8 : 1; + __REG16 P2_9 : 1; + __REG16 P2_10 : 1; + __REG16 P2_11 : 1; + __REG16 P2_12 : 1; + __REG16 P2_13 : 1; + __REG16 P2_14 : 1; + __REG16 P2_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO2DIRU + //FIO2MASKU + //FIO2PINU + //FIO2SETU + //FIO2CLRU + struct{ + __REG16 P2_0 : 1; + __REG16 P2_1 : 1; + __REG16 P2_2 : 1; + __REG16 P2_3 : 1; + __REG16 P2_4 : 1; + __REG16 P2_5 : 1; + __REG16 P2_6 : 1; + __REG16 P2_7 : 1; + __REG16 P2_8 : 1; + __REG16 P2_9 : 1; + __REG16 P2_10 : 1; + __REG16 P2_11 : 1; + __REG16 P2_12 : 1; + __REG16 P2_13 : 1; + __REG16 P2_14 : 1; + __REG16 P2_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio2_bits; + +/* FGPIO 3 Registers*/ +typedef union{ + //FIO3DIR + //FIO3MASK + //FIO3PIN + //FIO3SET + //FIO3CLR + struct { + __REG32 P3_0 : 1; + __REG32 P3_1 : 1; + __REG32 P3_2 : 1; + __REG32 P3_3 : 1; + __REG32 P3_4 : 1; + __REG32 P3_5 : 1; + __REG32 P3_6 : 1; + __REG32 P3_7 : 1; + __REG32 P3_8 : 1; + __REG32 P3_9 : 1; + __REG32 P3_10 : 1; + __REG32 P3_11 : 1; + __REG32 P3_12 : 1; + __REG32 P3_13 : 1; + __REG32 P3_14 : 1; + __REG32 P3_15 : 1; + __REG32 P3_16 : 1; + __REG32 P3_17 : 1; + __REG32 P3_18 : 1; + __REG32 P3_19 : 1; + __REG32 P3_20 : 1; + __REG32 P3_21 : 1; + __REG32 P3_22 : 1; + __REG32 P3_23 : 1; + __REG32 P3_24 : 1; + __REG32 P3_25 : 1; + __REG32 P3_26 : 1; + __REG32 P3_27 : 1; + __REG32 P3_28 : 1; + __REG32 P3_29 : 1; + __REG32 P3_30 : 1; + __REG32 P3_31 : 1; + }; + + struct + { + union + { + //FIO3DIR0 + //FIO3MASK0 + //FIO3PIN0 + //FIO3SET0 + //FIO3CLR0 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO3DIR1 + //FIO3MASK1 + //FIO3PIN1 + //FIO3SET1 + //FIO3CLR1 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO3DIR2 + //FIO3MASK2 + //FIO3PIN2 + //FIO3SET2 + //FIO3CLR2 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO3DIR3 + //FIO3MASK3 + //FIO3PIN3 + //FIO3SET3 + //FIO3CLR3 + struct{ + __REG8 P3_0 : 1; + __REG8 P3_1 : 1; + __REG8 P3_2 : 1; + __REG8 P3_3 : 1; + __REG8 P3_4 : 1; + __REG8 P3_5 : 1; + __REG8 P3_6 : 1; + __REG8 P3_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO3DIRL + //FIO3MASKL + //FIO3PINL + //FIO3SETL + //FIO3CLRL + struct{ + __REG16 P3_0 : 1; + __REG16 P3_1 : 1; + __REG16 P3_2 : 1; + __REG16 P3_3 : 1; + __REG16 P3_4 : 1; + __REG16 P3_5 : 1; + __REG16 P3_6 : 1; + __REG16 P3_7 : 1; + __REG16 P3_8 : 1; + __REG16 P3_9 : 1; + __REG16 P3_10 : 1; + __REG16 P3_11 : 1; + __REG16 P3_12 : 1; + __REG16 P3_13 : 1; + __REG16 P3_14 : 1; + __REG16 P3_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO3DIRU + //FIO3MASKU + //FIO3PINU + //FIO3SETU + //FIO3CLRU + struct{ + __REG16 P3_0 : 1; + __REG16 P3_1 : 1; + __REG16 P3_2 : 1; + __REG16 P3_3 : 1; + __REG16 P3_4 : 1; + __REG16 P3_5 : 1; + __REG16 P3_6 : 1; + __REG16 P3_7 : 1; + __REG16 P3_8 : 1; + __REG16 P3_9 : 1; + __REG16 P3_10 : 1; + __REG16 P3_11 : 1; + __REG16 P3_12 : 1; + __REG16 P3_13 : 1; + __REG16 P3_14 : 1; + __REG16 P3_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio3_bits; + +/* FGPIO 4 Registers*/ +typedef union{ + //FIO4DIR + //FIO4MASK + //FIO4PIN + //FIO4SET + //FIO4CLR + struct { + __REG32 P4_0 : 1; + __REG32 P4_1 : 1; + __REG32 P4_2 : 1; + __REG32 P4_3 : 1; + __REG32 P4_4 : 1; + __REG32 P4_5 : 1; + __REG32 P4_6 : 1; + __REG32 P4_7 : 1; + __REG32 P4_8 : 1; + __REG32 P4_9 : 1; + __REG32 P4_10 : 1; + __REG32 P4_11 : 1; + __REG32 P4_12 : 1; + __REG32 P4_13 : 1; + __REG32 P4_14 : 1; + __REG32 P4_15 : 1; + __REG32 P4_16 : 1; + __REG32 P4_17 : 1; + __REG32 P4_18 : 1; + __REG32 P4_19 : 1; + __REG32 P4_20 : 1; + __REG32 P4_21 : 1; + __REG32 P4_22 : 1; + __REG32 P4_23 : 1; + __REG32 P4_24 : 1; + __REG32 P4_25 : 1; + __REG32 P4_26 : 1; + __REG32 P4_27 : 1; + __REG32 P4_28 : 1; + __REG32 P4_29 : 1; + __REG32 P4_30 : 1; + __REG32 P4_31 : 1; + }; + + struct + { + union + { + //FIO4DIR0 + //FIO4MASK0 + //FIO4PIN0 + //FIO4SET0 + //FIO4CLR0 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte0_bit; + __REG8 __byte0; + }; + union + { + //FIO4DIR1 + //FIO4MASK1 + //FIO4PIN1 + //FIO4SET1 + //FIO4CLR1 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte1_bit; + __REG8 __byte1; + }; + union + { + //FIO4DIR2 + //FIO4MASK2 + //FIO4PIN2 + //FIO4SET2 + //FIO4CLR2 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte2_bit; + __REG8 __byte2; + }; + union + { + //FIO4DIR3 + //FIO4MASK3 + //FIO4PIN3 + //FIO4SET3 + //FIO4CLR3 + struct{ + __REG8 P4_0 : 1; + __REG8 P4_1 : 1; + __REG8 P4_2 : 1; + __REG8 P4_3 : 1; + __REG8 P4_4 : 1; + __REG8 P4_5 : 1; + __REG8 P4_6 : 1; + __REG8 P4_7 : 1; + } __byte3_bit; + __REG8 __byte3; + }; + }; + + struct + { + union + { + //FIO4DIRL + //FIO4MASKL + //FIO4PINL + //FIO4SETL + //FIO4CLRL + struct{ + __REG16 P4_0 : 1; + __REG16 P4_1 : 1; + __REG16 P4_2 : 1; + __REG16 P4_3 : 1; + __REG16 P4_4 : 1; + __REG16 P4_5 : 1; + __REG16 P4_6 : 1; + __REG16 P4_7 : 1; + __REG16 P4_8 : 1; + __REG16 P4_9 : 1; + __REG16 P4_10 : 1; + __REG16 P4_11 : 1; + __REG16 P4_12 : 1; + __REG16 P4_13 : 1; + __REG16 P4_14 : 1; + __REG16 P4_15 : 1; + } __shortl_bit; + __REG16 __shortl; + }; + union + { + //FIO4DIRU + //FIO4MASKU + //FIO4PINU + //FIO4SETU + //FIO4CLRU + struct{ + __REG16 P4_0 : 1; + __REG16 P4_1 : 1; + __REG16 P4_2 : 1; + __REG16 P4_3 : 1; + __REG16 P4_4 : 1; + __REG16 P4_5 : 1; + __REG16 P4_6 : 1; + __REG16 P4_7 : 1; + __REG16 P4_8 : 1; + __REG16 P4_9 : 1; + __REG16 P4_10 : 1; + __REG16 P4_11 : 1; + __REG16 P4_12 : 1; + __REG16 P4_13 : 1; + __REG16 P4_14 : 1; + __REG16 P4_15 : 1; + } __shortu_bit; + __REG16 __shortu; + }; + }; +} __fgpio4_bits; + +/* GPIO overall Interrupt Status register */ +typedef struct{ +__REG32 P0INT : 1; +__REG32 : 1; +__REG32 P2INT : 1; +__REG32 :29; +}__iointst_bits; + +/* MAC Configuration Register 1 */ +typedef struct{ +__REG32 RE : 1; +__REG32 PARF : 1; +__REG32 RXFC : 1; +__REG32 TXFC : 1; +__REG32 LB : 1; +__REG32 : 3; +__REG32 RSTTX : 1; +__REG32 RSTMCSTX : 1; +__REG32 RSTRX : 1; +__REG32 RSTMCSRX : 1; +__REG32 : 2; +__REG32 SIMRST : 1; +__REG32 SOFTRST : 1; +__REG32 :16; +}__mac1_bits; + +/* MAC Configuration Register 2 */ +typedef struct{ +__REG32 FD : 1; +__REG32 FLC : 1; +__REG32 HFE : 1; +__REG32 DLYCRC : 1; +__REG32 CRCEN : 1; +__REG32 PADCRCEN : 1; +__REG32 VLANCRCEN : 1; +__REG32 ADPE : 1; +__REG32 PPE : 1; +__REG32 LPE : 1; +__REG32 : 2; +__REG32 NB : 1; +__REG32 BP : 1; +__REG32 ED : 1; +__REG32 :17; +}__mac2_bits; + +/* Back-to-Back Inter-Packet-Gap Register */ +typedef struct{ +__REG32 IPG : 7; +__REG32 :25; +}__ipgt_bits; + +/* Non Back-to-Back Inter-Packet-Gap Register */ +typedef struct{ +__REG32 IPGR2 : 7; +__REG32 : 1; +__REG32 IPGR1 : 7; +__REG32 :17; +}__ipgr_bits; + +/*Collision Window / Retry Register */ +typedef struct{ +__REG32 RM : 4; +__REG32 : 4; +__REG32 CW : 6; +__REG32 :18; +}__clrt_bits; + +/* Maximum Frame Register */ +typedef struct{ +__REG32 MAXF :16; +__REG32 :16; +}__maxf_bits; + +/* PHY Support Register */ +typedef struct{ +__REG32 : 8; +__REG32 SPEED : 1; +__REG32 :23; +}__supp_bits; + +/* Test Register */ +typedef struct{ +__REG32 SPQ : 1; +__REG32 TP : 1; +__REG32 TB : 1; +__REG32 :29; +}__test_bits; + +/* MII Mgmt Configuration Register */ +typedef struct{ +__REG32 SI : 1; +__REG32 SP : 1; +__REG32 CS : 3; +__REG32 :10; +__REG32 RSTMIIMGMT : 1; +__REG32 :16; +}__mcfg_bits; + +/* MII Mgmt Command Register */ +typedef struct{ +__REG32 READ : 1; +__REG32 SCAN : 1; +__REG32 :30; +}__mcmd_bits; + +/* MII Mgmt Address Register */ +typedef struct{ +__REG32 REGADDR : 5; +__REG32 : 3; +__REG32 PHY_ADDR : 5; +__REG32 :19; +}__madr_bits; + +/* MII Mgmt Write Data Register */ +typedef struct{ +__REG32 WRITEDATA :16; +__REG32 :16; +}__mwtd_bits; + +/* MII Mgmt Read Data Register */ +typedef struct{ +__REG32 READDATA :16; +__REG32 :16; +}__mrdd_bits; + +/* MII Mgmt Indicators Register */ +typedef struct{ +__REG32 BUSY : 1; +__REG32 SCANNING : 1; +__REG32 NOT_VALID : 1; +__REG32 MII_LINK_FAIL : 1; +__REG32 :28; +}__mind_bits; + +/* Station Address 0 Register */ +typedef struct{ +__REG32 STATION_ADDR_2 : 8; +__REG32 STATION_ADDR_1 : 8; +__REG32 :16; +}__sa0_bits; + +/* Station Address 1 Register */ +typedef struct{ +__REG32 STATION_ADDR_4 : 8; +__REG32 STATION_ADDR_3 : 8; +__REG32 :16; +}__sa1_bits; + +/* Station Address 2 Register */ +typedef struct{ +__REG32 STATION_ADDR_6 : 8; +__REG32 STATION_ADDR_5 : 8; +__REG32 :16; +}__sa2_bits; + +/* Command Register */ +typedef struct{ +__REG32 RXENABLE : 1; +__REG32 TXENABLE : 1; +__REG32 : 1; +__REG32 REGRESET : 1; +__REG32 TXRESET : 1; +__REG32 RXRESET : 1; +__REG32 PASSRUNTFRAME : 1; +__REG32 PASSRXFILTER : 1; +__REG32 TXFLOWCONTROL : 1; +__REG32 RMII : 1; +__REG32 FULLDUPLEX : 1; +__REG32 :21; +}__command_bits; + +/* Status Register */ +typedef struct{ +__REG32 RXSTATUS : 1; +__REG32 TXSTATUS : 1; +__REG32 :30; +}__status_bits; + +/* Receive Number of Descriptors Register */ +typedef struct{ +__REG32 RXDESCRIPTORNUMBER :16; +__REG32 :16; +}__rxdescrn_bits; + +/* Receive Produce Index Register */ +typedef struct{ +__REG32 RXPRODUCDINDEX :16; +__REG32 :16; +}__rxprodind_bits; + +/* Receive Consume Index Register */ +typedef struct{ +__REG32 RXCONSUMEINDEX :16; +__REG32 :16; +}__rxcomind_bits; + +/* Transmit Number of Descriptors Register */ +typedef struct{ +__REG32 TXDESCRIPTORNUMBER :16; +__REG32 :16; +}__txdescrn_bits; + +/* Transmit Produce Index Register */ +typedef struct{ +__REG32 TXPRODUCDINDEX :16; +__REG32 :16; +}__txprodind_bits; + +/* Transmit Consume Index Register */ +typedef struct{ +__REG32 TXCONSUMEINDEX :16; +__REG32 :16; +}__txcomind_bits; + +/* Transmit Status Vector 0 Register */ +typedef struct{ +__REG32 CCR_ERR : 1; +__REG32 LCERR : 1; +__REG32 LOOR : 1; +__REG32 DONE : 1; +__REG32 MULTICAST : 1; +__REG32 BROADCAST : 1; +__REG32 PD : 1; +__REG32 ED : 1; +__REG32 EC : 1; +__REG32 LC : 1; +__REG32 GIANT : 1; +__REG32 UNDERRUN : 1; +__REG32 TB :16; +__REG32 CF : 1; +__REG32 PAUSE : 1; +__REG32 BACKPRESSURE : 1; +__REG32 VLAN : 1; +}__tsv0_bits; + +/* Transmit Status Vector 1 Register */ +typedef struct{ +__REG32 TBC :16; +__REG32 TCC : 4; +__REG32 :12; +}__tsv1_bits; + +/* Receive Status Vector Register */ +typedef struct{ +__REG32 RBC :16; +__REG32 PPI : 1; +__REG32 RXDVEPS : 1; +__REG32 CEPS : 1; +__REG32 RCV : 1; +__REG32 CRC_ERR : 1; +__REG32 LCE : 1; +__REG32 LOOR : 1; +__REG32 R_OK : 1; +__REG32 MULTICAST : 1; +__REG32 BROADCAST : 1; +__REG32 DN : 1; +__REG32 CF : 1; +__REG32 PAUSE : 1; +__REG32 UO : 1; +__REG32 VLAN : 1; +__REG32 : 1; +}__rsv_bits; + +/* Flow Control Counter Register */ +typedef struct{ +__REG32 MC :16; +__REG32 PT :16; +}__fwctrlcnt_bits; + +/* Flow Control Status Register */ +typedef struct{ +__REG32 MCC :16; +__REG32 :16; +}__fwctrlstat_bits; + +/* Receive Filter Control Register */ +typedef struct{ +__REG32 AUE : 1; +__REG32 ABE : 1; +__REG32 AME : 1; +__REG32 AUHE : 1; +__REG32 AMHE : 1; +__REG32 APE : 1; +__REG32 : 6; +__REG32 MPEWOL : 1; +__REG32 RXFEWOL : 1; +__REG32 :18; +}__rxflctrl_bits; + +/* Receive Filter WoL Status Register */ +typedef struct{ +__REG32 AUWOL : 1; +__REG32 ABWOL : 1; +__REG32 AMWOL : 1; +__REG32 AUHWOL : 1; +__REG32 AMHWOL : 1; +__REG32 APWOL : 1; +__REG32 : 1; +__REG32 RXFWOL : 1; +__REG32 MPWOL : 1; +__REG32 :23; +}__rxflwolstat_bits; + +/* Receive Filter WoL Clear Register */ +typedef struct{ +__REG32 AUWOLC : 1; +__REG32 ABWOLC : 1; +__REG32 AMWOLC : 1; +__REG32 AUHWOLC : 1; +__REG32 AMHWOLC : 1; +__REG32 APWOLC : 1; +__REG32 : 1; +__REG32 RXFWOLC : 1; +__REG32 MPWOLC : 1; +__REG32 :23; +}__rxflwolclr_bits; + +/* Interrupt Status Register */ +typedef struct{ +__REG32 RXOVERRUNINT : 1; +__REG32 RXERRORINT : 1; +__REG32 RXFINISHEDINT : 1; +__REG32 RXDONEINT : 1; +__REG32 TXUNDERRUNINT : 1; +__REG32 TXERRORINT : 1; +__REG32 TXFINISHEDINT : 1; +__REG32 TXDONEINT : 1; +__REG32 : 4; +__REG32 SOFTINT : 1; +__REG32 WAKEUPINT : 1; +__REG32 :18; +}__intstat_bits; + +/* Interrupt Enable Register */ +typedef struct{ +__REG32 RXOVERRUNINTEN : 1; +__REG32 RXERRORINTEN : 1; +__REG32 RXFINISHEDINTEN : 1; +__REG32 RXDONEINTEN : 1; +__REG32 TXUNDERRUNINTEN : 1; +__REG32 TXERRORINTEN : 1; +__REG32 TXFINISHEDINTEN : 1; +__REG32 TXDONEINTEN : 1; +__REG32 : 4; +__REG32 SOFTINTEN : 1; +__REG32 WAKEUPINTEN : 1; +__REG32 :18; +}__intena_bits; + +/* Interrupt Clear Register */ +typedef struct{ +__REG32 RXOVERRUNINTCLR : 1; +__REG32 RXERRORINTCLR : 1; +__REG32 RXFINISHEDINTCLR: 1; +__REG32 RXDONEINTCLR : 1; +__REG32 TXUNDERRUNINTCLR: 1; +__REG32 TXERRORINTCLR : 1; +__REG32 TXFINISHEDINTCLR: 1; +__REG32 TXDONEINTCLR : 1; +__REG32 : 4; +__REG32 SOFTINTCLR : 1; +__REG32 WAKEUPINTCLR : 1; +__REG32 :18; +}__intclr_bits; + +/* Interrupt Set Register */ +typedef struct{ +__REG32 RXOVERRUNINTSET : 1; +__REG32 RXERRORINTSET : 1; +__REG32 RXFINISHEDINTSET: 1; +__REG32 RXDONEINTSET : 1; +__REG32 TXUNDERRUNINTSET: 1; +__REG32 TXERRORINTSET : 1; +__REG32 TXFINISHEDINTSET: 1; +__REG32 TXDONEINTSET : 1; +__REG32 : 4; +__REG32 SOFTINTSET : 1; +__REG32 WAKEUPINTSET : 1; +__REG32 :18; +}__intset_bits; + +/* Power Down Register */ +typedef struct{ +__REG32 :31; +__REG32 POWERDOWN : 1; +}__pwrdn_bits; + +/* CAN acceptance filter mode register */ +typedef struct { + __REG32 ACCOFF :1; + __REG32 ACCBP :1; + __REG32 EFCAN :1; + __REG32 :29; +} __afmr_bits; + +/* CAN LUT Error Register */ +typedef struct { + __REG32 LUTERR :1; + __REG32 :31; +} __luterr_bits; + +/* Global FullCANInterrupt Enable register */ +typedef struct { + __REG32 FCANIE :1; + __REG32 :31; +} __fcanie_bits; + +/* FullCAN Interrupt and Capture registers 0 */ +typedef struct { + __REG32 INTPND0 :1; + __REG32 INTPND1 :1; + __REG32 INTPND2 :1; + __REG32 INTPND3 :1; + __REG32 INTPND4 :1; + __REG32 INTPND5 :1; + __REG32 INTPND6 :1; + __REG32 INTPND7 :1; + __REG32 INTPND8 :1; + __REG32 INTPND9 :1; + __REG32 INTPND10 :1; + __REG32 INTPND11 :1; + __REG32 INTPND12 :1; + __REG32 INTPND13 :1; + __REG32 INTPND14 :1; + __REG32 INTPND15 :1; + __REG32 INTPND16 :1; + __REG32 INTPND17 :1; + __REG32 INTPND18 :1; + __REG32 INTPND19 :1; + __REG32 INTPND20 :1; + __REG32 INTPND21 :1; + __REG32 INTPND22 :1; + __REG32 INTPND23 :1; + __REG32 INTPND24 :1; + __REG32 INTPND25 :1; + __REG32 INTPND26 :1; + __REG32 INTPND27 :1; + __REG32 INTPND28 :1; + __REG32 INTPND29 :1; + __REG32 INTPND30 :1; + __REG32 INTPND31 :1; +} __fcanic0_bits; + +/* FullCAN Interrupt and Capture registers 1 */ +typedef struct { + __REG32 INTPND32 :1; + __REG32 INTPND33 :1; + __REG32 INTPND34 :1; + __REG32 INTPND35 :1; + __REG32 INTPND36 :1; + __REG32 INTPND37 :1; + __REG32 INTPND38 :1; + __REG32 INTPND39 :1; + __REG32 INTPND40 :1; + __REG32 INTPND41 :1; + __REG32 INTPND42 :1; + __REG32 INTPND43 :1; + __REG32 INTPND44 :1; + __REG32 INTPND45 :1; + __REG32 INTPND46 :1; + __REG32 INTPND47 :1; + __REG32 INTPND48 :1; + __REG32 INTPND49 :1; + __REG32 INTPND50 :1; + __REG32 INTPND51 :1; + __REG32 INTPND52 :1; + __REG32 INTPND53 :1; + __REG32 INTPND54 :1; + __REG32 INTPND55 :1; + __REG32 INTPND56 :1; + __REG32 INTPND57 :1; + __REG32 INTPND58 :1; + __REG32 INTPND59 :1; + __REG32 INTPND60 :1; + __REG32 INTPND61 :1; + __REG32 INTPND62 :1; + __REG32 INTPND63 :1; +} __fcanic1_bits; + +/* CAN central transmit status register */ +typedef struct { + __REG32 TS1 : 1; + __REG32 TS2 : 1; + __REG32 : 6; + __REG32 TBS1 : 1; + __REG32 TBS2 : 1; + __REG32 : 6; + __REG32 TCS1 : 1; + __REG32 TCS2 : 1; + __REG32 :14; +} __cantxsr_bits; + +/* CAN central receive status register */ +typedef struct { + __REG32 RS1 : 1; + __REG32 RS2 : 1; + __REG32 : 6; + __REG32 RBS1 : 1; + __REG32 RBS2 : 1; + __REG32 : 6; + __REG32 DOS1 : 1; + __REG32 DOS2 : 1; + __REG32 :14; +} __canrxsr_bits; + +/* CAN miscellaneous status register */ +typedef struct { + __REG32 E1 : 1; + __REG32 E2 : 1; + __REG32 : 6; + __REG32 BS1 : 1; + __REG32 BS2 : 1; + __REG32 :22; +} __canmsr_bits; + +/* CAN mode register */ +typedef struct { + __REG32 RM :1; + __REG32 LOM :1; + __REG32 STM :1; + __REG32 TPM :1; + __REG32 SM :1; + __REG32 RPM :1; + __REG32 :1; + __REG32 TM :1; + __REG32 :24; +} __canmod_bits; + +/* CAN command register */ +typedef struct { + __REG32 TR :1; + __REG32 AT :1; + __REG32 RRB :1; + __REG32 CDO :1; + __REG32 SRR :1; + __REG32 STB1 :1; + __REG32 STB2 :1; + __REG32 STB3 :1; + __REG32 :24; +} __cancmr_bits; + +/* CAN global status register */ +typedef struct { + __REG32 RBS :1; + __REG32 DOS :1; + __REG32 TBS :1; + __REG32 TCS :1; + __REG32 RS :1; + __REG32 TS :1; + __REG32 ES :1; + __REG32 BS :1; + __REG32 :8; + __REG32 RXERR :8; + __REG32 TXERR :8; +} __cangsr_bits; + +/* CAN interrupt capture register */ +typedef struct { + __REG32 RI :1; + __REG32 TI1 :1; + __REG32 EI :1; + __REG32 DOI :1; + __REG32 WUI :1; + __REG32 EPI :1; + __REG32 ALI :1; + __REG32 BEI :1; + __REG32 IDI :1; + __REG32 TI2 :1; + __REG32 TI3 :1; + __REG32 :5; + __REG32 ERRBIT :5; + __REG32 ERRDIR :1; + __REG32 ERRC :2; + __REG32 ALCBIT :8; +} __canicr_bits; + +/* CAN interrupt enable register */ +typedef struct { + __REG32 RIE :1; + __REG32 TIE1 :1; + __REG32 EIE :1; + __REG32 DOIE :1; + __REG32 WUIE :1; + __REG32 EPIE :1; + __REG32 ALIE :1; + __REG32 BEIE :1; + __REG32 IDIE :1; + __REG32 TIE2 :1; + __REG32 TIE3 :1; + __REG32 :21; +} __canier_bits; + +/* CAN bus timing register */ +typedef struct { + __REG32 BRP :10; + __REG32 :4; + __REG32 SJW :2; + __REG32 TSEG1 :4; + __REG32 TSEG2 :3; + __REG32 SAM :1; + __REG32 :8; +} __canbtr_bits; + +/* CAN error warning limit register */ +typedef struct { + __REG32 EWL :8; + __REG32 :24; +} __canewl_bits; + +/* CAN status register */ +typedef struct { + __REG32 RBS :1; + __REG32 DOS :1; + __REG32 TBS1 :1; + __REG32 TCS1 :1; + __REG32 RS :1; + __REG32 TS1 :1; + __REG32 ES :1; + __REG32 BS :1; + __REG32 /*RBS*/ :1; + __REG32 /*DOS*/ :1; + __REG32 TBS2 :1; + __REG32 TCS2 :1; + __REG32 /*RS*/ :1; + __REG32 TS2 :1; + __REG32 /*ES*/ :1; + __REG32 /*BS*/ :1; + __REG32 /*RBS*/ :1; + __REG32 /*DOS*/ :1; + __REG32 TBS3 :1; + __REG32 TCS3 :1; + __REG32 /*RS*/ :1; + __REG32 TS3 :1; + __REG32 /*ES*/ :1; + __REG32 /*BS*/ :1; + __REG32 :8; +} __cansr_bits; + +/* CAN rx frame status register */ +typedef struct { + __REG32 IDINDEX :10; + __REG32 BP :1; + __REG32 :5; + __REG32 DLC :4; + __REG32 :10; + __REG32 RTR :1; + __REG32 FF :1; +} __canrfs_bits; + +/* CAN rx identifier register */ +typedef union { + //CANxRID + struct { + __REG32 ID10_0 :11; + __REG32 :21; + }; + //CANxRID + struct { + __REG32 ID29_18 :11; + __REG32 :21; + }; + //CANxRID + struct { + __REG32 ID29_0 :29; + __REG32 :3; + }; +} __canrid_bits; + +/* CAN rx data register A */ +typedef struct { + __REG32 DATA1 :8; + __REG32 DATA2 :8; + __REG32 DATA3 :8; + __REG32 DATA4 :8; +} __canrda_bits; + +/* CAN rx data register B */ +typedef struct { + __REG32 DATA5 :8; + __REG32 DATA6 :8; + __REG32 DATA7 :8; + __REG32 DATA8 :8; +} __canrdb_bits; + +/* CAN tx frame information register */ +typedef struct { + __REG32 PRIO :8; + __REG32 :8; + __REG32 DLC :4; + __REG32 :10; + __REG32 RTR :1; + __REG32 FF :1; +} __cantfi_bits; + +/* CAN tx identifier register */ +typedef union { + //CANxTIDy + struct { + __REG32 ID10_0 :11; + __REG32 :21; + }; + //CANxTIDy + struct { + __REG32 ID29_18 :11; + __REG32 :21; + }; + //CANxTIDy + struct { + __REG32 ID29_0 :29; + __REG32 :3; + }; +} __cantid_bits; + +/* CAN tx data register A */ +typedef struct { + __REG32 DATA1 :8; + __REG32 DATA2 :8; + __REG32 DATA3 :8; + __REG32 DATA4 :8; +} __cantda_bits; + +/* CAN tx data register B */ +typedef struct { + __REG32 DATA5 :8; + __REG32 DATA6 :8; + __REG32 DATA7 :8; + __REG32 DATA8 :8; +} __cantdb_bits; + +/* USB - Device Interrupt Status Register */ +typedef struct { + __REG32 PORTSEL : 2; + __REG32 :30; +} __usbportsel_bits; + +/* USB Clock Control register (USBClkCtrl - 0xFFE0 CFF4) */ +typedef struct{ +__REG32 : 1; +__REG32 DEV_CLK_EN : 1; +__REG32 : 1; +__REG32 PORTSEL_CLK_EN : 1; +__REG32 AHB_CLK_EN : 1; +__REG32 :27; +} __usbclkctrl_bits; + +/* USB Clock Status register (USBClkSt - 0xFFE0 CFF8) */ +typedef struct{ +__REG32 : 1; +__REG32 DEV_CLK_ON : 1; +__REG32 : 1; +__REG32 PORTSEL_CLK_ON : 1; +__REG32 AHB_CLK_ON : 1; +__REG32 :27; +} __usbclkst_bits; + +/* USB - Device Interrupt Status Register */ +typedef struct { + __REG32 USB_INT_REQ_LP : 1; + __REG32 USB_INT_REQ_HP : 1; + __REG32 USB_INT_REQ_DMA : 1; + __REG32 : 5; + __REG32 USB_NEED_CLOCK : 1; + __REG32 :22; + __REG32 EN_USB_INTS : 1; +} __usbints_bits; + +/* USB - Device Interrupt Status Register */ +/* USB - Device Interrupt Enable Register */ +/* USB - Device Interrupt Clear Register */ +/* USB - Device Interrupt Set Register */ +typedef struct { + __REG32 FRAME : 1; + __REG32 EP_FAST : 1; + __REG32 EP_SLOW : 1; + __REG32 DEV_STAT : 1; + __REG32 CCEMTY : 1; + __REG32 CDFULL : 1; + __REG32 RXENDPKT : 1; + __REG32 TXENDPKT : 1; + __REG32 EP_RLZED : 1; + __REG32 ERR_INT : 1; + __REG32 :22; +} __usbdevintst_bits; + +/* USB - Device Interrupt Priority Register */ +typedef struct { + __REG8 FRAME : 1; + __REG8 EP_FAST : 1; + __REG8 : 6; +} __usbdevintpri_bits; + +/* USB - Endpoint Interrupt Status Register */ +/* USB - Endpoint Interrupt Enable Register */ +/* USB - Endpoint Interrupt Clear Register */ +/* USB - Endpoint Interrupt Set Register */ +/* USB - Endpoint Interrupt Priority Register */ +typedef struct { + __REG32 EP_0RX : 1; + __REG32 EP_0TX : 1; + __REG32 EP_1RX : 1; + __REG32 EP_1TX : 1; + __REG32 EP_2RX : 1; + __REG32 EP_2TX : 1; + __REG32 EP_3RX : 1; + __REG32 EP_3TX : 1; + __REG32 EP_4RX : 1; + __REG32 EP_4TX : 1; + __REG32 EP_5RX : 1; + __REG32 EP_5TX : 1; + __REG32 EP_6RX : 1; + __REG32 EP_6TX : 1; + __REG32 EP_7RX : 1; + __REG32 EP_7TX : 1; + __REG32 EP_8RX : 1; + __REG32 EP_8TX : 1; + __REG32 EP_9RX : 1; + __REG32 EP_9TX : 1; + __REG32 EP_10RX : 1; + __REG32 EP_10TX : 1; + __REG32 EP_11RX : 1; + __REG32 EP_11TX : 1; + __REG32 EP_12RX : 1; + __REG32 EP_12TX : 1; + __REG32 EP_13RX : 1; + __REG32 EP_13TX : 1; + __REG32 EP_14RX : 1; + __REG32 EP_14TX : 1; + __REG32 EP_15RX : 1; + __REG32 EP_15TX : 1; +} __usbepintst_bits; + +/* USB - Realize Enpoint Register */ +/* USB - DMA Request Status Register */ +/* USB - DMA Request Clear Register */ +/* USB - DMA Request Set Regiser */ +/* USB - EP DMA Status Register */ +/* USB - EP DMA Enable Register */ +/* USB - EP DMA Disable Register */ +/* USB - New DD Request Interrupt Status Register */ +/* USB - New DD Request Interrupt Clear Register */ +/* USB - New DD Request Interrupt Set Register */ +/* USB - End Of Transfer Interrupt Status Register */ +/* USB - End Of Transfer Interrupt Clear Register */ +/* USB - End Of Transfer Interrupt Set Register */ +/* USB - System Error Interrupt Status Register */ +/* USB - System Error Interrupt Clear Register */ +/* USB - System Error Interrupt Set Register */ +typedef struct { + __REG32 EP0 : 1; + __REG32 EP1 : 1; + __REG32 EP2 : 1; + __REG32 EP3 : 1; + __REG32 EP4 : 1; + __REG32 EP5 : 1; + __REG32 EP6 : 1; + __REG32 EP7 : 1; + __REG32 EP8 : 1; + __REG32 EP9 : 1; + __REG32 EP10 : 1; + __REG32 EP11 : 1; + __REG32 EP12 : 1; + __REG32 EP13 : 1; + __REG32 EP14 : 1; + __REG32 EP15 : 1; + __REG32 EP16 : 1; + __REG32 EP17 : 1; + __REG32 EP18 : 1; + __REG32 EP19 : 1; + __REG32 EP20 : 1; + __REG32 EP21 : 1; + __REG32 EP22 : 1; + __REG32 EP23 : 1; + __REG32 EP24 : 1; + __REG32 EP25 : 1; + __REG32 EP26 : 1; + __REG32 EP27 : 1; + __REG32 EP28 : 1; + __REG32 EP29 : 1; + __REG32 EP30 : 1; + __REG32 EP31 : 1; +} __usbreep_bits; + +/* USB - Endpoint Index Register */ +typedef struct { + __REG32 PHY_ENDP : 5; + __REG32 :27; +} __usbepin_bits; + +/* USB - MaxPacketSize Register */ +typedef struct { + __REG32 MPS :10; + __REG32 :22; +} __usbmaxpsize_bits; + +/* USB - Receive Packet Length Register */ +typedef struct { + __REG32 PKT_LNGTH :10; + __REG32 DV : 1; + __REG32 PKT_RDY : 1; + __REG32 :20; +} __usbrxplen_bits; + +/* USB - Transmit Packet Length Register */ +typedef struct { + __REG32 PKT_LNGHT :10; + __REG32 :22; +} __usbtxplen_bits; + +/* USB - Control Register */ +typedef struct { + __REG32 RD_EN : 1; + __REG32 WR_EN : 1; + __REG32 LOG_ENDPOINT : 4; + __REG32 :26; +} __usbctrl_bits; + +/* USB - Command Code Register */ +typedef struct { + __REG32 : 8; + __REG32 CMD_PHASE : 8; + __REG32 CMD_CODE : 8; + __REG32 : 8; +} __usbcmdcode_bits; + +/* USB - Command Data Register */ +typedef struct { + __REG32 CMD_DATA : 8; + __REG32 :24; +} __usbcmddata_bits; + +/* USB - DMA Interrupt Status Register */ +/* USB - DMA Interrupt Enable Register */ +typedef struct { + __REG32 EOT : 1; + __REG32 NDDR : 1; + __REG32 ERR : 1; + __REG32 :29; +} __usbdmaintst_bits; + +/* UART interrupt enable register */ +typedef struct{ +__REG32 RDAIE : 1; +__REG32 THREIE : 1; +__REG32 RXLSIE : 1; +__REG32 : 5; +__REG32 ABTOINTEN : 1; +__REG32 ABEOINTEN : 1; +__REG32 :22; +} __uartier0_bits; + +/* UART1 interrupt enable register */ +typedef struct{ +__REG32 RDAIE : 1; +__REG32 THREIE : 1; +__REG32 RXLSIE : 1; +__REG32 RXMSIE : 1; +__REG32 : 3; +__REG32 CTSIE : 1; +__REG32 ABTOINTEN : 1; +__REG32 ABEOINTEN : 1; +__REG32 :22; +} __uartier1_bits; + +/* UART Transmit Enable Register */ +typedef struct{ +__REG8 : 7; +__REG8 TXEN : 1; +} __uartter_bits; + +/* UART line status register */ +typedef struct{ +__REG8 DR : 1; +__REG8 OE : 1; +__REG8 PE : 1; +__REG8 FE : 1; +__REG8 BI : 1; +__REG8 THRE : 1; +__REG8 TEMT : 1; +__REG8 RXFE : 1; +} __uartlsr_bits; + +/* UART line control register */ +typedef struct{ +__REG8 WLS : 2; +__REG8 SBS : 1; +__REG8 PE : 1; +__REG8 PS : 2; +__REG8 BC : 1; +__REG8 DLAB : 1; +} __uartlcr_bits; + +/* UART interrupt identification register and fifo control register */ +typedef union { + //UxIIR + struct { +__REG32 IP : 1; +__REG32 IID : 3; +__REG32 : 2; +__REG32 IIRFE : 2; +__REG32 ABEOINT: 1; +__REG32 ABTOINT: 1; +__REG32 :22; + }; + //UxFCR + struct { +__REG32 FCRFE : 1; +__REG32 RFR : 1; +__REG32 TFR : 1; +__REG32 : 3; +__REG32 RTLS : 2; +__REG32 :24; + }; +} __uartfcriir_bits; + +/* UART modem control register */ +typedef struct{ +__REG8 DTR : 1; +__REG8 RTS : 1; +__REG8 : 2; +__REG8 LMS : 1; +__REG8 : 1; +__REG8 RTSEN : 1; +__REG8 CTSEN : 1; +} __uartmcr_bits; + +/* UART modem status register */ +typedef union{ + //UxMSR + struct { +__REG8 DCTS : 1; +__REG8 DDSR : 1; +__REG8 TERI : 1; +__REG8 DDCD : 1; +__REG8 CTS : 1; +__REG8 DSR : 1; +__REG8 RI : 1; +__REG8 DCD : 1; + }; + //UxMSR + struct { +__REG8 MSR0 : 1; +__REG8 MSR1 : 1; +__REG8 MSR2 : 1; +__REG8 MSR3 : 1; +__REG8 MSR4 : 1; +__REG8 MSR5 : 1; +__REG8 MSR6 : 1; +__REG8 MSR7 : 1; + }; +} __uartmsr_bits; + +/* UART Auto-baud Control Register */ +typedef struct{ +__REG32 START : 1; +__REG32 MODE : 1; +__REG32 AUTORESTART : 1; +__REG32 : 5; +__REG32 ABEOINTCLR : 1; +__REG32 ABTOINTCLR : 1; +__REG32 :22; +} __uartacr_bits; + +/* IrDA Control Register for UART3 Only */ +typedef struct{ +__REG32 IRDAEN : 1; +__REG32 IRDAINV : 1; +__REG32 FIXPULSEEN : 1; +__REG32 PULSEDIV : 3; +__REG32 :26; +} __uarticr_bits; + +/* UART Fractional Divider Register */ +typedef struct{ +__REG32 DIVADDVAL : 4; +__REG32 MULVAL : 4; +__REG32 :24; +} __uartfdr_bits; + +/* SPI control register */ +typedef struct{ +__REG32 : 2; +__REG32 BITENABLE : 1; +__REG32 CPHA : 1; +__REG32 CPOL : 1; +__REG32 MSTR : 1; +__REG32 LSBF : 1; +__REG32 SPIE : 1; +__REG32 BITS : 4; +__REG32 :20; +} __spcr_bits; + +/* SPI status register */ +typedef struct{ +__REG32 : 3; +__REG32 ABRT : 1; +__REG32 MODF : 1; +__REG32 ROVR : 1; +__REG32 WCOL : 1; +__REG32 SPIF : 1; +__REG32 :24; +} __spsr_bits; + +/* SPI clock counter register */ +typedef struct{ +__REG32 COUNTER : 8; +__REG32 :24; +} __spccr_bits; + +/* SPI interrupt register */ +typedef struct{ +__REG32 SPIINT : 1; +__REG32 :31; +} __spint_bits; + +/* SPI Test control register */ +typedef struct{ +__REG8 : 1; +__REG8 TEST : 7; +} __sptcr_bits; + +/* SPI Test Status Register */ +typedef struct{ +__REG8 : 3; +__REG8 ABRT : 1; +__REG8 MODF : 1; +__REG8 ROVR : 1; +__REG8 WCOL : 1; +__REG8 SPIF : 1; +} __sptsr_bits; + +/* SSP Control Register 0 */ +typedef struct{ +__REG32 DSS : 4; +__REG32 FRF : 2; +__REG32 SPO : 1; +__REG32 SPH : 1; +__REG32 SCR : 8; +__REG32 :16; +} __sspcr0_bits; + +/* SSP Control Register 1 */ +typedef struct{ +__REG32 LBM : 1; +__REG32 SSE : 1; +__REG32 MS : 1; +__REG32 SOD : 1; +__REG32 :28; +} __sspcr1_bits; + +/* SSP Data Register */ +typedef struct{ +__REG32 DATA :16; +__REG32 :16; +} __sspdr_bits; + +/* SSP Status Register */ +typedef struct{ +__REG32 TFE : 1; +__REG32 TNF : 1; +__REG32 RNE : 1; +__REG32 RFF : 1; +__REG32 BSY : 1; +__REG32 :27; +} __sspsr_bits; + +/* SSP Clock Prescale Register */ +typedef struct{ +__REG32 CPSDVSR : 8; +__REG32 :24; +} __sspcpsr_bits; + +/* SSP Interrupt Mask Set/Clear Register */ +typedef struct{ +__REG32 RORIM : 1; +__REG32 RTIM : 1; +__REG32 RXIM : 1; +__REG32 TXIM : 1; +__REG32 :28; +} __sspimsc_bits; + +/* SSP Raw Interrupt Status Register */ +typedef struct{ +__REG32 RORRIS : 1; +__REG32 RTRIS : 1; +__REG32 RXRIS : 1; +__REG32 TXRIS : 1; +__REG32 :28; +} __sspris_bits; + +/* SSP Masked Interrupt Status Register */ +typedef struct{ +__REG32 RORMIS : 1; +__REG32 RTMIS : 1; +__REG32 RXMIS : 1; +__REG32 TXMIS : 1; +__REG32 :28; +} __sspmis_bits; + +/* SSP Interrupt Clear Register */ +typedef struct{ +__REG32 RORIC : 1; +__REG32 RTIC : 1; +__REG32 :30; +} __sspicr_bits; + +/* SSP DMA Control Register */ +typedef struct{ +__REG32 RXDMAE : 1; +__REG32 TXDMAE : 1; +__REG32 :30; +} __sspdmacr_bits; + +/* SD/MMC Power control register */ +typedef struct{ +__REG32 CTRL : 2; +__REG32 : 4; +__REG32 OPENDRAIN : 1; +__REG32 ROD : 1; +__REG32 :24; +} __mcipower_bits; + +/* SD/MMC Clock control register */ +typedef struct{ +__REG32 CLKDIV : 8; +__REG32 ENABLE : 1; +__REG32 PWRSAVE : 1; +__REG32 BYPASS : 1; +__REG32 WIDEBUS : 1; +__REG32 :20; +} __mciclock_bits; + +/* SD/MMC Command register */ +typedef struct{ +__REG32 CMDINDEX : 6; +__REG32 RESPONSE : 1; +__REG32 LONGRSP : 1; +__REG32 INTERRUPT : 1; +__REG32 PENDING : 1; +__REG32 ENABLE : 1; +__REG32 :21; +} __mcicommand_bits; + +/* SD/MMC Command response register */ +typedef struct{ +__REG32 RESPCMD : 6; +__REG32 :26; +} __mcirespcmd_bits; + +/* SD/MMC Data control register */ +typedef struct{ +__REG32 ENABLE : 1; +__REG32 DIRECTION : 1; +__REG32 MODE : 1; +__REG32 DMAENABLE : 1; +__REG32 BLOCKSIZE : 4; +__REG32 :24; +} __mcidatactrl_bits; + +/* SD/MMC Status register */ +typedef struct{ +__REG32 CMDCRCFAIL : 1; +__REG32 DATACRCFAIL : 1; +__REG32 CMDTIMEOUT : 1; +__REG32 DATATIMEOUT : 1; +__REG32 TXUNDERRUN : 1; +__REG32 RXOVERRUN : 1; +__REG32 CMDRESPEND : 1; +__REG32 CMDSENT : 1; +__REG32 DATAEND : 1; +__REG32 STARTBITERR : 1; +__REG32 DATABLOCKEND : 1; +__REG32 CMDACTIVE : 1; +__REG32 TXACTIVE : 1; +__REG32 RXACTIVE : 1; +__REG32 TXFIFOHALFEMPTY : 1; +__REG32 RXFIFOHALFFULL : 1; +__REG32 TXFIFOFULL : 1; +__REG32 RXFIFOFULL : 1; +__REG32 TXFIFOEMPTY : 1; +__REG32 RXFIFOEMPTY : 1; +__REG32 TXDATAAVLBL : 1; +__REG32 RXDATAAVLBL : 1; +__REG32 :10; +} __mcistatus_bits; + +/* SD/MMC Clear register */ +typedef struct{ +__REG32 CMDCRCFAILCLR : 1; +__REG32 DATACRCFAILCLR : 1; +__REG32 CMDTIMEOUTCLR : 1; +__REG32 DATATIMEOUTCLR : 1; +__REG32 TXUNDERRUNCLR : 1; +__REG32 RXOVERRUNCLR : 1; +__REG32 CMDRESPENDCLR : 1; +__REG32 CMDSENTCLR : 1; +__REG32 DATAENDCLR : 1; +__REG32 STARTBITERRCLR : 1; +__REG32 DATABLOCKENDCLR : 1; +__REG32 :21; +} __mciclear_bits; + +/* SD/MMC FIFO counter register */ +typedef struct{ +__REG32 DATACOUNT :15; +__REG32 :17; +} __mcififocnt_bits; + +/* I2C control set register */ +typedef struct{ +__REG32 : 2; +__REG32 AA : 1; +__REG32 SI : 1; +__REG32 STO : 1; +__REG32 STA : 1; +__REG32 I2EN : 1; +__REG32 :25; +} __i2conset_bits; + +/* I2C control clear register */ +typedef struct{ +__REG32 : 2; +__REG32 AAC : 1; +__REG32 SIC : 1; +__REG32 : 1; +__REG32 STAC : 1; +__REG32 I2ENC : 1; +__REG32 :25; +} __i2conclr_bits; + +/* I2C status register */ +typedef struct{ +__REG32 STATUS : 8; +__REG32 :24; +} __i2stat_bits; + +/* I2C data register */ +typedef struct{ +__REG32 DATA : 8; +__REG32 :24; +} __i2dat_bits; + +/* I2C slave address register */ +typedef struct{ +__REG32 GC : 1; +__REG32 ADDR : 7; +__REG32 :24; +} __i2adr_bits; + +/* I2C SCL High Duty Cycle register */ +typedef struct{ +__REG32 SCLH :16; +__REG32 :16; +} __i2sch_bits; + +/* I2C scl duty cycle register */ +typedef struct{ +__REG32 SCLL :16; +__REG32 :16; +} __i2scl_bits; + +/* I2S Digital Audio Output Registes */ +typedef struct{ +__REG32 WORS_WIDTH : 2; +__REG32 MONO : 1; +__REG32 STOP : 1; +__REG32 RESET : 1; +__REG32 WS_SEL : 1; +__REG32 WS_HALFPERIOD : 9; +__REG32 MUTE : 1; +__REG32 :16; +} __i2sdao_bits; + +/* I2S Digital Audio Input Register */ +typedef struct{ +__REG32 WORS_WIDTH : 2; +__REG32 MONO : 1; +__REG32 STOP : 1; +__REG32 RESET : 1; +__REG32 WS_SEL : 1; +__REG32 WS_HALFPERIOD : 9; +__REG32 :17; +} __i2sdai_bits; + +/* I2S Status Feedback Register */ +typedef struct{ +__REG32 IRQ : 1; +__REG32 DMAREQ1 : 1; +__REG32 DMAREQ2 : 1; +__REG32 : 5; +__REG32 RX_LEVEL : 8; +__REG32 TX_LEVEL : 8; +__REG32 : 8; +} __i2sstate_bits; + +/* I2S DMA Configuration Register */ +typedef struct{ +__REG32 RX_DMA_EN : 1; +__REG32 TX_DMA_EN : 1; +__REG32 : 6; +__REG32 RX_DEPTH_DMA : 8; +__REG32 TX_DEPTH_DMA : 8; +__REG32 : 8; +} __i2sdma_bits; + +/* I2S Interrupt Request Control register */ +typedef struct{ +__REG32 RX_IRQ_EN : 1; +__REG32 TX_IRQ_EN : 1; +__REG32 : 6; +__REG32 RX_DEPTH_IRQ : 8; +__REG32 TX_DEPTH_IRQ : 8; +__REG32 : 8; +} __i2sirq_bits; + +/* I2S Transmit Clock Rate Register */ +typedef struct{ +__REG32 TX_RATE :10; +__REG32 :22; +} __i2stxrate_bits; + +/* I2S Receive Clock Rate Register */ +typedef struct{ +__REG32 RX_RATE :10; +__REG32 :22; +} __i2srxrate_bits; + +/* TIMER interrupt register */ +typedef struct{ +__REG32 MR0INT : 1; +__REG32 MR1INT : 1; +__REG32 MR2INT : 1; +__REG32 MR3INT : 1; +__REG32 CR0INT : 1; +__REG32 CR1INT : 1; +__REG32 CR2INT : 1; +__REG32 CR3INT : 1; +__REG32 :24; +} __ir_bits; + +/* TIMER control register */ +typedef struct{ +__REG32 CE : 1; +__REG32 CR : 1; +__REG32 :30; +} __tcr_bits; + +/* TIMER count control register */ +typedef struct{ +__REG32 CTM : 2; //Counter/Timer Mode +__REG32 CIS : 2; //Count Input Select +__REG32 :28; +} __ctcr_bits; + +/* TIMER match control register */ +typedef struct{ +__REG32 MR0I : 1; +__REG32 MR0R : 1; +__REG32 MR0S : 1; +__REG32 MR1I : 1; +__REG32 MR1R : 1; +__REG32 MR1S : 1; +__REG32 MR2I : 1; +__REG32 MR2R : 1; +__REG32 MR2S : 1; +__REG32 MR3I : 1; +__REG32 MR3R : 1; +__REG32 MR3S : 1; +__REG32 :20; +} __mcr_bits; + +/* TIMER capture control register */ +typedef struct{ +__REG32 CAP0RE : 1; +__REG32 CAP0FE : 1; +__REG32 CAP0I : 1; +__REG32 CAP1RE : 1; +__REG32 CAP1FE : 1; +__REG32 CAP1I : 1; +__REG32 CAP2RE : 1; +__REG32 CAP2FE : 1; +__REG32 CAP2I : 1; +__REG32 CAP3RE : 1; +__REG32 CAP3FE : 1; +__REG32 CAP3I : 1; +__REG32 :20; +} __ccr_bits; + +/* TIMER external match register */ +typedef struct{ +__REG32 EM0 : 1; +__REG32 EM1 : 1; +__REG32 EM2 : 1; +__REG32 EM3 : 1; +__REG32 EMC0 : 2; +__REG32 EMC1 : 2; +__REG32 EMC2 : 2; +__REG32 EMC3 : 2; +__REG32 :20; +} __emr_bits; + +/* Watchdog mode register */ +typedef struct{ +__REG32 WDEN : 1; +__REG32 WDRESET : 1; +__REG32 WDTOF : 1; +__REG32 WDINT : 1; +__REG32 :28; +} __wdmod_bits; + +/* Watchdog feed register */ +typedef struct{ +__REG32 FEED : 8; +__REG32 :24; +} __wdfeed_bits; + +/* Watchdog feed register */ +typedef struct{ +__REG32 WDSEL : 2; +__REG32 :30; +} __wdclksel_bits; + +/* A/D Control Register */ +typedef struct{ +__REG32 SEL : 8; +__REG32 CLKDIV : 8; +__REG32 BURST : 1; +__REG32 CLKS : 3; +__REG32 : 1; +__REG32 PDN : 1; +__REG32 : 2; +__REG32 START : 3; +__REG32 EDGE : 1; +__REG32 : 4; +} __adcr_bits; + +/* A/D Global Data Register */ +typedef struct{ +__REG32 : 6; +__REG32 RESULT :10; +__REG32 : 8; +__REG32 CHN : 3; +__REG32 : 3; +__REG32 OVERUN : 1; +__REG32 DONE : 1; +} __adgdr_bits; + +/* A/D Status Register */ +typedef struct{ +__REG32 DONE0 : 1; +__REG32 DONE1 : 1; +__REG32 DONE2 : 1; +__REG32 DONE3 : 1; +__REG32 DONE4 : 1; +__REG32 DONE5 : 1; +__REG32 : 2; +__REG32 OVERRUN0 : 1; +__REG32 OVERRUN1 : 1; +__REG32 OVERRUN2 : 1; +__REG32 OVERRUN3 : 1; +__REG32 OVERRUN4 : 1; +__REG32 OVERRUN5 : 1; +__REG32 : 2; +__REG32 ADINT : 1; +__REG32 :15; +} __adstat_bits; + +/* A/D Intrrupt Enable Register */ +typedef struct{ +__REG32 ADINTEN0 : 1; +__REG32 ADINTEN1 : 1; +__REG32 ADINTEN2 : 1; +__REG32 ADINTEN3 : 1; +__REG32 ADINTEN4 : 1; +__REG32 ADINTEN5 : 1; +__REG32 : 2; +__REG32 ADGINTEN : 1; +__REG32 :23; +} __adinten_bits; + +/* A/D Data Register */ +typedef struct{ +__REG32 : 6; +__REG32 RESULT :10; +__REG32 :14; +__REG32 OVERUN : 1; +__REG32 DONE : 1; +} __addr_bits; + +/* D/A Converter Register */ +typedef struct{ +__REG32 : 6; +__REG32 VALUE :10; +__REG32 BIAS : 1; +__REG32 :15; +} __dacr_bits; + +/* PWM interrupt register */ +typedef struct{ +__REG32 PWMMR0I : 1; +__REG32 PWMMR1I : 1; +__REG32 PWMMR2I : 1; +__REG32 PWMMR3I : 1; +__REG32 : 4; +__REG32 PWMMR4I : 1; +__REG32 PWMMR5I : 1; +__REG32 PWMMR6I : 1; +__REG32 :21; +} __pwmir_bits; + +/* PWM1 timer control register */ +typedef struct{ +__REG32 CE : 1; +__REG32 CR : 1; +__REG32 : 1; +__REG32 PWMEN : 1; +__REG32 :28; +} __pwmtcr1_bits; + +/* PWM Count Control Register */ +typedef struct{ +__REG32 CM : 2; +__REG32 CIS : 2; +__REG32 :28; +} __pwmctcr_bits; + +/* PWM match control register */ +typedef struct{ +__REG32 PWMMR0I : 1; +__REG32 PWMMR0R : 1; +__REG32 PWMMR0S : 1; +__REG32 PWMMR1I : 1; +__REG32 PWMMR1R : 1; +__REG32 PWMMR1S : 1; +__REG32 PWMMR2I : 1; +__REG32 PWMMR2R : 1; +__REG32 PWMMR2S : 1; +__REG32 PWMMR3I : 1; +__REG32 PWMMR3R : 1; +__REG32 PWMMR3S : 1; +__REG32 PWMMR4I : 1; +__REG32 PWMMR4R : 1; +__REG32 PWMMR4S : 1; +__REG32 PWMMR5I : 1; +__REG32 PWMMR5R : 1; +__REG32 PWMMR5S : 1; +__REG32 PWMMR6I : 1; +__REG32 PWMMR6R : 1; +__REG32 PWMMR6S : 1; +__REG32 :11; +} __pwmmcr_bits; + +/* PWM Capture Control Register */ +typedef struct{ +__REG32 CAP0RE : 1; +__REG32 CAP0FE : 1; +__REG32 CAP0INT : 1; +__REG32 CAP1RE : 1; +__REG32 CAP1FE : 1; +__REG32 CAP1INT : 1; +__REG32 CAP2RE : 1; +__REG32 CAP2FE : 1; +__REG32 CAP2INT : 1; +__REG32 CAP3RE : 1; +__REG32 CAP3FE : 1; +__REG32 CAP3INT : 1; +__REG32 :20; +} __pwmccr_bits; + +/* PWM control register */ +typedef struct{ +__REG32 : 2; +__REG32 PWMSEL2 : 1; +__REG32 PWMSEL3 : 1; +__REG32 PWMSEL4 : 1; +__REG32 PWMSEL5 : 1; +__REG32 PWMSEL6 : 1; +__REG32 : 2; +__REG32 PWMENA1 : 1; +__REG32 PWMENA2 : 1; +__REG32 PWMENA3 : 1; +__REG32 PWMENA4 : 1; +__REG32 PWMENA5 : 1; +__REG32 PWMENA6 : 1; +__REG32 :17; +} __pwmpcr_bits; + +/* PWM latch enable register */ +typedef struct{ +__REG32 EM0L : 1; +__REG32 EM1L : 1; +__REG32 EM2L : 1; +__REG32 EM3L : 1; +__REG32 EM4L : 1; +__REG32 EM5L : 1; +__REG32 EM6L : 1; +__REG32 :25; +} __pwmler_bits; + +/* RTC interrupt location register */ +typedef struct{ +__REG32 RTCCIF : 1; +__REG32 RTCALF : 1; +__REG32 RTSSF : 1; +__REG32 :29; +} __ilr_bits; + +/* RTC clock tick counter register */ +typedef struct{ +__REG32 COUNTER :15; +__REG32 :17; +} __ctc_bits; + +/* RTC clock control register */ +typedef struct{ +__REG32 CLKEN : 1; +__REG32 CTCRST : 1; +__REG32 CTTEST : 2; +__REG32 CLKSRC : 1; +__REG32 :27; +} __rtcccr_bits; + +/* RTC counter increment interrupt register */ +typedef struct{ +__REG32 IMSEC : 1; +__REG32 IMMIN : 1; +__REG32 IMHOUR : 1; +__REG32 IMDOM : 1; +__REG32 IMDOW : 1; +__REG32 IMDOY : 1; +__REG32 IMMON : 1; +__REG32 IMYEAR : 1; +__REG32 :24; +} __ciir_bits; + +/* RTC Counter Increment Select Mask Register */ +typedef struct{ +__REG32 SUBSECSEL : 3; +__REG32 : 4; +__REG32 SUBSECENA : 1; +__REG32 :24; +} __ciss_bits; + +/* RTC alarm mask register */ +typedef struct{ +__REG32 AMRSEC : 1; +__REG32 AMRMIN : 1; +__REG32 AMRHOUR : 1; +__REG32 AMRDOM : 1; +__REG32 AMRDOW : 1; +__REG32 AMRDOY : 1; +__REG32 AMRMON : 1; +__REG32 AMRYEAR : 1; +__REG32 :24; +} __amr_bits; + +/* RTC consolidated time register 0 */ +typedef struct{ +__REG32 SEC : 6; +__REG32 : 2; +__REG32 MIN : 6; +__REG32 : 2; +__REG32 HOUR : 5; +__REG32 : 3; +__REG32 DOW : 3; +__REG32 : 5; +} __ctime0_bits; + +/* RTC consolidated time register 1 */ +typedef struct{ +__REG32 DOM : 5; +__REG32 : 3; +__REG32 MON : 4; +__REG32 : 4; +__REG32 YEAR :12; +__REG32 : 4; +} __ctime1_bits; + +/* RTC consolidated time register 2 */ +typedef struct{ +__REG32 DOY :12; +__REG32 :20; +} __ctime2_bits; + +/* RTC second register */ +typedef struct{ +__REG32 SEC : 6; +__REG32 :26; +} __sec_bits; + +/* RTC minute register */ +typedef struct{ +__REG32 MIN : 6; +__REG32 :26; +} __min_bits; + +/* RTC hour register */ +typedef struct{ +__REG32 HOUR : 5; +__REG32 :27; +} __hour_bits; + +/* RTC day of month register */ +typedef struct{ +__REG32 DOM : 5; +__REG32 :27; +} __dom_bits; + +/* RTC day of week register */ +typedef struct{ +__REG32 DOW : 3; +__REG32 :29; +} __dow_bits; + +/* RTC day of year register */ +typedef struct{ +__REG32 DOY : 9; +__REG32 :23; +} __doy_bits; + +/* RTC month register */ +typedef struct{ +__REG32 MON : 4; +__REG32 :28; +} __month_bits; + +/* RTC year register */ +typedef struct{ +__REG32 YEAR :12; +__REG32 :20; +} __year_bits; + +/* RTC prescaler value, integer portion register */ +typedef struct{ +__REG32 VALUE :13; +__REG32 :19; +} __preint_bits; + +/* RTC prescaler value, fractional portion register */ +typedef struct{ +__REG32 VALUE :15; +__REG32 :17; +} __prefrac_bits; + +/* DMA Interrupt Status Register */ +typedef struct{ +__REG32 INTSTATUS0 : 1; +__REG32 INTSTATUS1 : 1; +__REG32 :30; +} __dmacintstatus_bits; + +/* DMA Interrupt Terminal Count Request Status Register */ +typedef struct{ +__REG32 INTTCSTATUS0 : 1; +__REG32 INTTCSTATUS1 : 1; +__REG32 :30; +} __dmacinttcstatus_bits; + +/* DMA Interrupt Terminal Count Request Clear Register */ +typedef struct{ +__REG32 INTTCCLEAR0 : 1; +__REG32 INTTCCLEAR1 : 1; +__REG32 :30; +} __dmacinttcclear_bits; + +/* DMA Interrupt Error Status Register */ +typedef struct{ +__REG32 INTERRORSTATUS0 : 1; +__REG32 INTERRORSTATUS1 : 1; +__REG32 :30; +} __dmacinterrstat_bits; + +/* DMA Interrupt Error Clear Register */ +typedef struct{ +__REG32 INTERRCLR0 : 1; +__REG32 INTERRCLR1 : 1; +__REG32 :30; +} __dmacinterrclr_bits; + +/* DMA Raw Interrupt Terminal Count Status Register */ +typedef struct{ +__REG32 RAWINTTCSTATUS0 : 1; +__REG32 RAWINTTCSTATUS1 : 1; +__REG32 :30; +} __dmacrawinttcstatus_bits; + +/* DMA Raw Error Interrupt Status Register */ +typedef struct{ +__REG32 RAWINTERRORSTATUS0 : 1; +__REG32 RAWINTERRORSTATUS1 : 1; +__REG32 :30; +} __dmacrawinterrorstatus_bits; + +/* DMA Enabled Channel Register */ +typedef struct{ +__REG32 ENABLEDCHANNELS0 : 1; +__REG32 ENABLEDCHANNELS1 : 1; +__REG32 :30; +} __dmacenbldchns_bits; + +/* DMA Software Burst Request Register */ +typedef struct{ +__REG32 SOFTBREQSSP0TX : 1; +__REG32 SOFTBREQSSP0RX : 1; +__REG32 SOFTBREQSSP1TX : 1; +__REG32 SOFTBREQSSP1RX : 1; +__REG32 SOFTBREQSDMMC : 1; +__REG32 :27; +} __dmacsoftbreq_bits; + +/* DMA Software Single Request Register */ +typedef struct{ +__REG32 SOFTREQSSP0TX : 1; +__REG32 SOFTREQSSP0RX : 1; +__REG32 SOFTREQSSP1TX : 1; +__REG32 SOFTREQSSP1RX : 1; +__REG32 SOFTREQSDMMC : 1; +__REG32 SOFTSREQI2S0 : 1; +__REG32 SOFTSREQI2S1 : 1; +__REG32 :25; +} __dmacsoftsreq_bits; + +/* DMA Software Last Burst Request Register */ +typedef struct{ +__REG32 : 4; +__REG32 SOFTLBREQSDMMC : 1; +__REG32 :27; +} __dmacsoftlbreq_bits; + +/* DMA Software Last Single Request Register */ +typedef struct{ +__REG32 : 4; +__REG32 SOFTLSREQSDMMC : 1; +__REG32 :27; +} __dmacsoftlsreq_bits; + +/* DMA Synchronization Register */ +typedef struct{ +__REG32 DMACSYNC :16; +__REG32 :16; +} __dmacsync_bits; + +/* DMA Configuration Register */ +typedef struct{ +__REG32 E : 1; +__REG32 M : 1; +__REG32 :30; +} __dmacconfig_bits; + +/* DMA Software Burst Request Register */ +typedef struct{ +__REG32 : 2; +__REG32 LLI :30; +} __dma_lli_bits; + +/* DMA Channel Control Registers */ +typedef struct{ +__REG32 TRANSFERSIZE :12; +__REG32 SBSIZE : 3; +__REG32 DBSIZE : 3; +__REG32 SWIDTH : 3; +__REG32 DWIDTH : 3; +__REG32 : 2; +__REG32 SI : 1; +__REG32 DI : 1; +__REG32 PROT1 : 1; +__REG32 PROT2 : 1; +__REG32 PROT3 : 1; +__REG32 I : 1; +} __dma_ctrl_bits; + +/* DMA Channel Configuration Registers */ +typedef struct{ +__REG32 E : 1; +__REG32 SRCPERIPHERAL : 4; +__REG32 : 1; +__REG32 DESTPERIPHERAL : 4; +__REG32 : 1; +__REG32 FLOWCNTRL : 3; +__REG32 IE : 1; +__REG32 ITC : 1; +__REG32 L : 1; +__REG32 A : 1; +__REG32 H : 1; +__REG32 :13; +} __dma_cfg_bits; + +#endif /* __IAR_SYSTEMS_ICC__ */ + +/* Declarations common to compiler and assembler **************************/ + +/*************************************************************************** + ** + ** System control block + ** + ***************************************************************************/ +__IO_REG32_BIT(MEMMAP, 0xE01FC040,__READ_WRITE ,__memmap_bits); +__IO_REG32_BIT(RSIR, 0xE01FC180,__READ_WRITE ,__rsir_bits); +#define RSID RSIR +#define RSID_bit RSIR_bit +__IO_REG32_BIT(EXTINT, 0xE01FC140,__READ_WRITE ,__extint_bits); +__IO_REG32_BIT(EXTMODE, 0xE01FC148,__READ_WRITE ,__extmode_bits); +__IO_REG32_BIT(EXTPOLAR, 0xE01FC14C,__READ_WRITE ,__extpolar_bits); +__IO_REG32_BIT(SCS, 0xE01FC1A0,__READ_WRITE ,__scs_bits); +__IO_REG32( CSPR, 0xE01FC184,__WRITE); +__IO_REG32_BIT(PLLCON, 0xE01FC080,__READ_WRITE ,__pllcon_bits); +__IO_REG32_BIT(PLLCFG, 0xE01FC084,__READ_WRITE ,__pllcfg_bits); +__IO_REG32_BIT(PLLSTAT, 0xE01FC088,__READ ,__pllstat_bits); +__IO_REG32_BIT(PLLFEED, 0xE01FC08C,__WRITE ,__pllfeed_bits); +__IO_REG32_BIT(CCLKCFG, 0xE01FC104,__READ_WRITE ,__cclkcfg_bits); +__IO_REG32_BIT(USBCLKCFG, 0xE01FC108,__READ_WRITE ,__usbclkcfg_bits); +__IO_REG32_BIT(CLKSRCSEL, 0xE01FC10C,__READ_WRITE ,__clksrcsel_bits); +__IO_REG32_BIT(IRCTRIM, 0xE01FC1A4,__READ_WRITE ,__irctrim_bits); +__IO_REG32_BIT(PCLKSEL0, 0xE01FC1A8,__READ_WRITE ,__pclksel0_bits); +__IO_REG32_BIT(PCLKSEL1, 0xE01FC1AC,__READ_WRITE ,__pclksel1_bits); +__IO_REG32_BIT(PCON, 0xE01FC0C0,__READ_WRITE ,__pcon_bits); +__IO_REG32_BIT(PCONP, 0xE01FC0C4,__READ_WRITE ,__pconp_bits); +__IO_REG32_BIT(INTWAKE, 0xE01FC144,__READ_WRITE ,__intwake_bits); + +/*************************************************************************** + ** + ** AHB + ** + ***************************************************************************/ +__IO_REG32_BIT(AHBCFG1, 0xE01FC188,__READ_WRITE ,__ahbcfg1_bits); +__IO_REG32_BIT(AHBCFG2, 0xE01FC18C,__READ_WRITE ,__ahbcfg2_bits); + +/*************************************************************************** + ** + ** MAM + ** + ***************************************************************************/ +__IO_REG32_BIT(MAMCR, 0xE01FC000,__READ_WRITE ,__mamcr_bits); +__IO_REG32_BIT(MAMTIM, 0xE01FC004,__READ_WRITE ,__mamtim_bits); + +/*************************************************************************** + ** + ** VIC + ** + ***************************************************************************/ +__IO_REG32_BIT(VICIRQSTATUS, 0xFFFFF000,__READ ,__vicint_bits); +__IO_REG32_BIT(VICFIQSTATUS, 0xFFFFF004,__READ ,__vicint_bits); +__IO_REG32_BIT(VICRAWINTR, 0xFFFFF008,__READ ,__vicint_bits); +__IO_REG32_BIT(VICINTSELECT, 0xFFFFF00C,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICINTENABLE, 0xFFFFF010,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICINTENCLEAR, 0xFFFFF014,__WRITE ,__vicint_bits); +__IO_REG32_BIT(VICSOFTINT, 0xFFFFF018,__READ_WRITE ,__vicint_bits); +__IO_REG32_BIT(VICSOFTINTCLEAR, 0xFFFFF01C,__WRITE ,__vicint_bits); +__IO_REG32_BIT(VICPROTECTION, 0xFFFFF020,__READ_WRITE ,__vicprotection_bits); +__IO_REG32_BIT(VICSWPRIORITYMASK, 0xFFFFF024,__READ_WRITE ,__vicswprmask_bits); +__IO_REG32( VICVECTADDR0, 0xFFFFF100,__READ_WRITE); +__IO_REG32( VICVECTADDR1, 0xFFFFF104,__READ_WRITE); +__IO_REG32( VICVECTADDR2, 0xFFFFF108,__READ_WRITE); +__IO_REG32( VICVECTADDR3, 0xFFFFF10C,__READ_WRITE); +__IO_REG32( VICVECTADDR4, 0xFFFFF110,__READ_WRITE); +__IO_REG32( VICVECTADDR5, 0xFFFFF114,__READ_WRITE); +__IO_REG32( VICVECTADDR6, 0xFFFFF118,__READ_WRITE); +__IO_REG32( VICVECTADDR7, 0xFFFFF11C,__READ_WRITE); +__IO_REG32( VICVECTADDR8, 0xFFFFF120,__READ_WRITE); +__IO_REG32( VICVECTADDR9, 0xFFFFF124,__READ_WRITE); +__IO_REG32( VICVECTADDR10, 0xFFFFF128,__READ_WRITE); +__IO_REG32( VICVECTADDR11, 0xFFFFF12C,__READ_WRITE); +__IO_REG32( VICVECTADDR12, 0xFFFFF130,__READ_WRITE); +__IO_REG32( VICVECTADDR13, 0xFFFFF134,__READ_WRITE); +__IO_REG32( VICVECTADDR14, 0xFFFFF138,__READ_WRITE); +__IO_REG32( VICVECTADDR15, 0xFFFFF13C,__READ_WRITE); +__IO_REG32( VICVECTADDR16, 0xFFFFF140,__READ_WRITE); +__IO_REG32( VICVECTADDR17, 0xFFFFF144,__READ_WRITE); +__IO_REG32( VICVECTADDR18, 0xFFFFF148,__READ_WRITE); +__IO_REG32( VICVECTADDR19, 0xFFFFF14C,__READ_WRITE); +__IO_REG32( VICVECTADDR20, 0xFFFFF150,__READ_WRITE); +__IO_REG32( VICVECTADDR21, 0xFFFFF154,__READ_WRITE); +__IO_REG32( VICVECTADDR22, 0xFFFFF158,__READ_WRITE); +__IO_REG32( VICVECTADDR23, 0xFFFFF15C,__READ_WRITE); +__IO_REG32( VICVECTADDR24, 0xFFFFF160,__READ_WRITE); +__IO_REG32( VICVECTADDR25, 0xFFFFF164,__READ_WRITE); +__IO_REG32( VICVECTADDR26, 0xFFFFF168,__READ_WRITE); +__IO_REG32( VICVECTADDR27, 0xFFFFF16C,__READ_WRITE); +__IO_REG32( VICVECTADDR28, 0xFFFFF170,__READ_WRITE); +__IO_REG32( VICVECTADDR29, 0xFFFFF174,__READ_WRITE); +__IO_REG32( VICVECTADDR30, 0xFFFFF178,__READ_WRITE); +__IO_REG32( VICVECTADDR31, 0xFFFFF17C,__READ_WRITE); +__IO_REG32_BIT(VICVECTPRIORITY0, 0xFFFFF200,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY1, 0xFFFFF204,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY2, 0xFFFFF208,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY3, 0xFFFFF20C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY4, 0xFFFFF210,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY5, 0xFFFFF214,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY6, 0xFFFFF218,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY7, 0xFFFFF21C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY8, 0xFFFFF220,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY9, 0xFFFFF224,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY10, 0xFFFFF228,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY11, 0xFFFFF22C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY12, 0xFFFFF230,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY13, 0xFFFFF234,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY14, 0xFFFFF238,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY15, 0xFFFFF23C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY16, 0xFFFFF240,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY17, 0xFFFFF244,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY18, 0xFFFFF248,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY19, 0xFFFFF24C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY20, 0xFFFFF250,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY21, 0xFFFFF254,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY22, 0xFFFFF258,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY23, 0xFFFFF25C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY24, 0xFFFFF260,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY25, 0xFFFFF264,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY26, 0xFFFFF268,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY27, 0xFFFFF26C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY28, 0xFFFFF270,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY29, 0xFFFFF274,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY30, 0xFFFFF278,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32_BIT(VICVECTPRIORITY31, 0xFFFFF27C,__READ_WRITE ,__vicvectpr_bits); +__IO_REG32( VICADDRESS, 0xFFFFFF00,__READ_WRITE); + +/*************************************************************************** + ** + ** Pin connect block + ** + ***************************************************************************/ +__IO_REG32_BIT(PINSEL0, 0xE002C000,__READ_WRITE ,__pinsel0_bits); +__IO_REG32_BIT(PINSEL1, 0xE002C004,__READ_WRITE ,__pinsel1_bits); +__IO_REG32_BIT(PINSEL2, 0xE002C008,__READ_WRITE ,__pinsel2_bits); +__IO_REG32_BIT(PINSEL3, 0xE002C00C,__READ_WRITE ,__pinsel3_bits); +__IO_REG32_BIT(PINSEL4, 0xE002C010,__READ_WRITE ,__pinsel4_bits); +__IO_REG32_BIT(PINSEL5, 0xE002C014,__READ_WRITE ,__pinsel5_bits); +__IO_REG32_BIT(PINSEL6, 0xE002C018,__READ_WRITE ,__pinsel6_bits); +__IO_REG32_BIT(PINSEL7, 0xE002C01C,__READ_WRITE ,__pinsel7_bits); +__IO_REG32_BIT(PINSEL8, 0xE002C020,__READ_WRITE ,__pinsel8_bits); +__IO_REG32_BIT(PINSEL9, 0xE002C024,__READ_WRITE ,__pinsel9_bits); +__IO_REG32_BIT(PINSEL10, 0xE002C028,__READ_WRITE ,__pinsel10_bits); +__IO_REG32_BIT(PINMODE0, 0xE002C040,__READ_WRITE ,__pinsel0_bits); +__IO_REG32_BIT(PINMODE1, 0xE002C044,__READ_WRITE ,__pinsel1_bits); +__IO_REG32_BIT(PINMODE2, 0xE002C048,__READ_WRITE ,__pinsel2_bits); +__IO_REG32_BIT(PINMODE3, 0xE002C04C,__READ_WRITE ,__pinsel3_bits); +__IO_REG32_BIT(PINMODE4, 0xE002C050,__READ_WRITE ,__pinsel4_bits); +__IO_REG32_BIT(PINMODE5, 0xE002C054,__READ_WRITE ,__pinsel5_bits); +__IO_REG32_BIT(PINMODE6, 0xE002C058,__READ_WRITE ,__pinsel6_bits); +__IO_REG32_BIT(PINMODE7, 0xE002C05C,__READ_WRITE ,__pinsel7_bits); +__IO_REG32_BIT(PINMODE8, 0xE002C060,__READ_WRITE ,__pinsel8_bits); +__IO_REG32_BIT(PINMODE9, 0xE002C064,__READ_WRITE ,__pinsel9_bits); + +/*************************************************************************** + ** + ** GPIO + ** + ***************************************************************************/ +__IO_REG32_BIT(IO0PIN, 0xE0028000,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0SET, 0xE0028004,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0DIR, 0xE0028008,__READ_WRITE,__gpio0_bits); +__IO_REG32_BIT(IO0CLR, 0xE002800C,__WRITE ,__gpio0_bits); +__IO_REG32_BIT(FIO0DIR, 0x3FFFC000,__READ_WRITE,__fgpio0_bits); +#define FIO0DIR0 FIO0DIR_bit.__byte0 +#define FIO0DIR0_bit FIO0DIR_bit.__byte0_bit +#define FIO0DIR1 FIO0DIR_bit.__byte1 +#define FIO0DIR1_bit FIO0DIR_bit.__byte1_bit +#define FIO0DIR2 FIO0DIR_bit.__byte2 +#define FIO0DIR2_bit FIO0DIR_bit.__byte2_bit +#define FIO0DIR3 FIO0DIR_bit.__byte3 +#define FIO0DIR3_bit FIO0DIR_bit.__byte3_bit +#define FIO0DIRL FIO0DIR_bit.__shortl +#define FIO0DIRL_bit FIO0DIR_bit.__shortl_bit +#define FIO0DIRU FIO0DIR_bit.__shortu +#define FIO0DIRU_bit FIO0DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO0MASK, 0x3FFFC010,__READ_WRITE,__fgpio0_bits); +#define FIO0MASK0 FIO0MASK_bit.__byte0 +#define FIO0MASK0_bit FIO0MASK_bit.__byte0_bit +#define FIO0MASK1 FIO0MASK_bit.__byte1 +#define FIO0MASK1_bit FIO0MASK_bit.__byte1_bit +#define FIO0MASK2 FIO0MASK_bit.__byte2 +#define FIO0MASK2_bit FIO0MASK_bit.__byte2_bit +#define FIO0MASK3 FIO0MASK_bit.__byte3 +#define FIO0MASK3_bit FIO0MASK_bit.__byte3_bit +#define FIO0MASKL FIO0MASK_bit.__shortl +#define FIO0MASKL_bit FIO0MASK_bit.__shortl_bit +#define FIO0MASKU FIO0MASK_bit.__shortu +#define FIO0MASKU_bit FIO0MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO0PIN, 0x3FFFC014,__READ_WRITE,__fgpio0_bits); +#define FIO0PIN0 FIO0PIN_bit.__byte0 +#define FIO0PIN0_bit FIO0PIN_bit.__byte0_bit +#define FIO0PIN1 FIO0PIN_bit.__byte1 +#define FIO0PIN1_bit FIO0PIN_bit.__byte1_bit +#define FIO0PIN2 FIO0PIN_bit.__byte2 +#define FIO0PIN2_bit FIO0PIN_bit.__byte2_bit +#define FIO0PIN3 FIO0PIN_bit.__byte3 +#define FIO0PIN3_bit FIO0PIN_bit.__byte3_bit +#define FIO0PINL FIO0PIN_bit.__shortl +#define FIO0PINL_bit FIO0PIN_bit.__shortl_bit +#define FIO0PINU FIO0PIN_bit.__shortu +#define FIO0PINU_bit FIO0PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO0SET, 0x3FFFC018,__READ_WRITE,__fgpio0_bits); +#define FIO0SET0 FIO0SET_bit.__byte0 +#define FIO0SET0_bit FIO0SET_bit.__byte0_bit +#define FIO0SET1 FIO0SET_bit.__byte1 +#define FIO0SET1_bit FIO0SET_bit.__byte1_bit +#define FIO0SET2 FIO0SET_bit.__byte2 +#define FIO0SET2_bit FIO0SET_bit.__byte2_bit +#define FIO0SET3 FIO0SET_bit.__byte3 +#define FIO0SET3_bit FIO0SET_bit.__byte3_bit +#define FIO0SETL FIO0SET_bit.__shortl +#define FIO0SETL_bit FIO0SET_bit.__shortl_bit +#define FIO0SETU FIO0SET_bit.__shortu +#define FIO0SETU_bit FIO0SET_bit.__shortu_bit +__IO_REG32_BIT(FIO0CLR, 0x3FFFC01C,__WRITE ,__fgpio0_bits); +#define FIO0CLR0 FIO0CLR_bit.__byte0 +#define FIO0CLR0_bit FIO0CLR_bit.__byte0_bit +#define FIO0CLR1 FIO0CLR_bit.__byte1 +#define FIO0CLR1_bit FIO0CLR_bit.__byte1_bit +#define FIO0CLR2 FIO0CLR_bit.__byte2 +#define FIO0CLR2_bit FIO0CLR_bit.__byte2_bit +#define FIO0CLR3 FIO0CLR_bit.__byte3 +#define FIO0CLR3_bit FIO0CLR_bit.__byte3_bit +#define FIO0CLRL FIO0CLR_bit.__shortl +#define FIO0CLRL_bit FIO0CLR_bit.__shortl_bit +#define FIO0CLRU FIO0CLR_bit.__shortu +#define FIO0CLRU_bit FIO0CLR_bit.__shortu_bit +__IO_REG32_BIT(IO1PIN, 0xE0028010,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1SET, 0xE0028014,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1DIR, 0xE0028018,__READ_WRITE,__gpio1_bits); +__IO_REG32_BIT(IO1CLR, 0xE002801C,__WRITE ,__gpio1_bits); +__IO_REG32_BIT(FIO1DIR, 0x3FFFC020,__READ_WRITE,__fgpio1_bits); +#define FIO1DIR0 FIO1DIR_bit.__byte0 +#define FIO1DIR0_bit FIO1DIR_bit.__byte0_bit +#define FIO1DIR1 FIO1DIR_bit.__byte1 +#define FIO1DIR1_bit FIO1DIR_bit.__byte1_bit +#define FIO1DIR2 FIO1DIR_bit.__byte2 +#define FIO1DIR2_bit FIO1DIR_bit.__byte2_bit +#define FIO1DIR3 FIO1DIR_bit.__byte3 +#define FIO1DIR3_bit FIO1DIR_bit.__byte3_bit +#define FIO1DIRL FIO1DIR_bit.__shortl +#define FIO1DIRL_bit FIO1DIR_bit.__shortl_bit +#define FIO1DIRU FIO1DIR_bit.__shortu +#define FIO1DIRU_bit FIO1DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO1MASK, 0x3FFFC030,__READ_WRITE,__fgpio1_bits); +#define FIO1MASK0 FIO1MASK_bit.__byte0 +#define FIO1MASK0_bit FIO1MASK_bit.__byte0_bit +#define FIO1MASK1 FIO1MASK_bit.__byte1 +#define FIO1MASK1_bit FIO1MASK_bit.__byte1_bit +#define FIO1MASK2 FIO1MASK_bit.__byte2 +#define FIO1MASK2_bit FIO1MASK_bit.__byte2_bit +#define FIO1MASK3 FIO1MASK_bit.__byte3 +#define FIO1MASK3_bit FIO1MASK_bit.__byte3_bit +#define FIO1MASKL FIO1MASK_bit.__shortl +#define FIO1MASKL_bit FIO1MASK_bit.__shortl_bit +#define FIO1MASKU FIO1MASK_bit.__shortu +#define FIO1MASKU_bit FIO1MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO1PIN, 0x3FFFC034,__READ_WRITE,__fgpio1_bits); +#define FIO1PIN0 FIO1PIN_bit.__byte0 +#define FIO1PIN0_bit FIO1PIN_bit.__byte0_bit +#define FIO1PIN1 FIO1PIN_bit.__byte1 +#define FIO1PIN1_bit FIO1PIN_bit.__byte1_bit +#define FIO1PIN2 FIO1PIN_bit.__byte2 +#define FIO1PIN2_bit FIO1PIN_bit.__byte2_bit +#define FIO1PIN3 FIO1PIN_bit.__byte3 +#define FIO1PIN3_bit FIO1PIN_bit.__byte3_bit +#define FIO1PINL FIO1PIN_bit.__shortl +#define FIO1PINL_bit FIO1PIN_bit.__shortl_bit +#define FIO1PINU FIO1PIN_bit.__shortu +#define FIO1PINU_bit FIO1PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO1SET, 0x3FFFC038,__READ_WRITE,__fgpio1_bits); +#define FIO1SET0 FIO1SET_bit.__byte0 +#define FIO1SET0_bit FIO1SET_bit.__byte0_bit +#define FIO1SET1 FIO1SET_bit.__byte1 +#define FIO1SET1_bit FIO1SET_bit.__byte1_bit +#define FIO1SET2 FIO1SET_bit.__byte2 +#define FIO1SET2_bit FIO1SET_bit.__byte2_bit +#define FIO1SET3 FIO1SET_bit.__byte3 +#define FIO1SET3_bit FIO1SET_bit.__byte3_bit +#define FIO1SETL FIO1SET_bit.__shortl +#define FIO1SETL_bit FIO1SET_bit.__shortl_bit +#define FIO1SETU FIO1SET_bit.__shortu +#define FIO1SETU_bit FIO1SET_bit.__shortu_bit +__IO_REG32_BIT(FIO1CLR, 0x3FFFC03C,__WRITE ,__fgpio1_bits); +#define FIO1CLR0 FIO1CLR_bit.__byte0 +#define FIO1CLR0_bit FIO1CLR_bit.__byte0_bit +#define FIO1CLR1 FIO1CLR_bit.__byte1 +#define FIO1CLR1_bit FIO1CLR_bit.__byte1_bit +#define FIO1CLR2 FIO1CLR_bit.__byte2 +#define FIO1CLR2_bit FIO1CLR_bit.__byte2_bit +#define FIO1CLR3 FIO1CLR_bit.__byte3 +#define FIO1CLR3_bit FIO1CLR_bit.__byte3_bit +#define FIO1CLRL FIO1CLR_bit.__shortl +#define FIO1CLRL_bit FIO1CLR_bit.__shortl_bit +#define FIO1CLRU FIO1CLR_bit.__shortu +#define FIO1CLRU_bit FIO1CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO2DIR, 0x3FFFC040,__READ_WRITE,__fgpio2_bits); +#define FIO2DIR0 FIO2DIR_bit.__byte0 +#define FIO2DIR0_bit FIO2DIR_bit.__byte0_bit +#define FIO2DIR1 FIO2DIR_bit.__byte1 +#define FIO2DIR1_bit FIO2DIR_bit.__byte1_bit +#define FIO2DIR2 FIO2DIR_bit.__byte2 +#define FIO2DIR2_bit FIO2DIR_bit.__byte2_bit +#define FIO2DIR3 FIO2DIR_bit.__byte3 +#define FIO2DIR3_bit FIO2DIR_bit.__byte3_bit +#define FIO2DIRL FIO2DIR_bit.__shortl +#define FIO2DIRL_bit FIO2DIR_bit.__shortl_bit +#define FIO2DIRU FIO2DIR_bit.__shortu +#define FIO2DIRU_bit FIO2DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO2MASK, 0x3FFFC050,__READ_WRITE,__fgpio2_bits); +#define FIO2MASK0 FIO2MASK_bit.__byte0 +#define FIO2MASK0_bit FIO2MASK_bit.__byte0_bit +#define FIO2MASK1 FIO2MASK_bit.__byte1 +#define FIO2MASK1_bit FIO2MASK_bit.__byte1_bit +#define FIO2MASK2 FIO2MASK_bit.__byte2 +#define FIO2MASK2_bit FIO2MASK_bit.__byte2_bit +#define FIO2MASK3 FIO2MASK_bit.__byte3 +#define FIO2MASK3_bit FIO2MASK_bit.__byte3_bit +#define FIO2MASKL FIO2MASK_bit.__shortl +#define FIO2MASKL_bit FIO2MASK_bit.__shortl_bit +#define FIO2MASKU FIO2MASK_bit.__shortu +#define FIO2MASKU_bit FIO2MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO2PIN, 0x3FFFC054,__READ_WRITE,__fgpio2_bits); +#define FIO2PIN0 FIO2PIN_bit.__byte0 +#define FIO2PIN0_bit FIO2PIN_bit.__byte0_bit +#define FIO2PIN1 FIO2PIN_bit.__byte1 +#define FIO2PIN1_bit FIO2PIN_bit.__byte1_bit +#define FIO2PIN2 FIO2PIN_bit.__byte2 +#define FIO2PIN2_bit FIO2PIN_bit.__byte2_bit +#define FIO2PIN3 FIO2PIN_bit.__byte3 +#define FIO2PIN3_bit FIO2PIN_bit.__byte3_bit +#define FIO2PINL FIO2PIN_bit.__shortl +#define FIO2PINL_bit FIO2PIN_bit.__shortl_bit +#define FIO2PINU FIO2PIN_bit.__shortu +#define FIO2PINU_bit FIO2PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO2SET, 0x3FFFC058,__READ_WRITE,__fgpio2_bits); +#define FIO2SET0 FIO2SET_bit.__byte0 +#define FIO2SET0_bit FIO2SET_bit.__byte0_bit +#define FIO2SET1 FIO2SET_bit.__byte1 +#define FIO2SET1_bit FIO2SET_bit.__byte1_bit +#define FIO2SET2 FIO2SET_bit.__byte2 +#define FIO2SET2_bit FIO2SET_bit.__byte2_bit +#define FIO2SET3 FIO2SET_bit.__byte3 +#define FIO2SET3_bit FIO2SET_bit.__byte3_bit +#define FIO2SETL FIO2SET_bit.__shortl +#define FIO2SETL_bit FIO2SET_bit.__shortl_bit +#define FIO2SETU FIO2SET_bit.__shortu +#define FIO2SETU_bit FIO2SET_bit.__shortu_bit +__IO_REG32_BIT(FIO2CLR, 0x3FFFC05C,__WRITE ,__fgpio2_bits); +#define FIO2CLR0 FIO2CLR_bit.__byte0 +#define FIO2CLR0_bit FIO2CLR_bit.__byte0_bit +#define FIO2CLR1 FIO2CLR_bit.__byte1 +#define FIO2CLR1_bit FIO2CLR_bit.__byte1_bit +#define FIO2CLR2 FIO2CLR_bit.__byte2 +#define FIO2CLR2_bit FIO2CLR_bit.__byte2_bit +#define FIO2CLR3 FIO2CLR_bit.__byte3 +#define FIO2CLR3_bit FIO2CLR_bit.__byte3_bit +#define FIO2CLRL FIO2CLR_bit.__shortl +#define FIO2CLRL_bit FIO2CLR_bit.__shortl_bit +#define FIO2CLRU FIO2CLR_bit.__shortu +#define FIO2CLRU_bit FIO2CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO3DIR, 0x3FFFC060,__READ_WRITE,__fgpio3_bits); +#define FIO3DIR0 FIO3DIR_bit.__byte0 +#define FIO3DIR0_bit FIO3DIR_bit.__byte0_bit +#define FIO3DIR1 FIO3DIR_bit.__byte1 +#define FIO3DIR1_bit FIO3DIR_bit.__byte1_bit +#define FIO3DIR2 FIO3DIR_bit.__byte2 +#define FIO3DIR2_bit FIO3DIR_bit.__byte2_bit +#define FIO3DIR3 FIO3DIR_bit.__byte3 +#define FIO3DIR3_bit FIO3DIR_bit.__byte3_bit +#define FIO3DIRL FIO3DIR_bit.__shortl +#define FIO3DIRL_bit FIO3DIR_bit.__shortl_bit +#define FIO3DIRU FIO3DIR_bit.__shortu +#define FIO3DIRU_bit FIO3DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO3MASK, 0x3FFFC070,__READ_WRITE,__fgpio3_bits); +#define FIO3MASK0 FIO3MASK_bit.__byte0 +#define FIO3MASK0_bit FIO3MASK_bit.__byte0_bit +#define FIO3MASK1 FIO3MASK_bit.__byte1 +#define FIO3MASK1_bit FIO3MASK_bit.__byte1_bit +#define FIO3MASK2 FIO3MASK_bit.__byte2 +#define FIO3MASK2_bit FIO3MASK_bit.__byte2_bit +#define FIO3MASK3 FIO3MASK_bit.__byte3 +#define FIO3MASK3_bit FIO3MASK_bit.__byte3_bit +#define FIO3MASKL FIO3MASK_bit.__shortl +#define FIO3MASKL_bit FIO3MASK_bit.__shortl_bit +#define FIO3MASKU FIO3MASK_bit.__shortu +#define FIO3MASKU_bit FIO3MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO3PIN, 0x3FFFC074,__READ_WRITE,__fgpio3_bits); +#define FIO3PIN0 FIO3PIN_bit.__byte0 +#define FIO3PIN0_bit FIO3PIN_bit.__byte0_bit +#define FIO3PIN1 FIO3PIN_bit.__byte1 +#define FIO3PIN1_bit FIO3PIN_bit.__byte1_bit +#define FIO3PIN2 FIO3PIN_bit.__byte2 +#define FIO3PIN2_bit FIO3PIN_bit.__byte2_bit +#define FIO3PIN3 FIO3PIN_bit.__byte3 +#define FIO3PIN3_bit FIO3PIN_bit.__byte3_bit +#define FIO3PINL FIO3PIN_bit.__shortl +#define FIO3PINL_bit FIO3PIN_bit.__shortl_bit +#define FIO3PINU FIO3PIN_bit.__shortu +#define FIO3PINU_bit FIO3PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO3SET, 0x3FFFC078,__READ_WRITE,__fgpio3_bits); +#define FIO3SET0 FIO3SET_bit.__byte0 +#define FIO3SET0_bit FIO3SET_bit.__byte0_bit +#define FIO3SET1 FIO3SET_bit.__byte1 +#define FIO3SET1_bit FIO3SET_bit.__byte1_bit +#define FIO3SET2 FIO3SET_bit.__byte2 +#define FIO3SET2_bit FIO3SET_bit.__byte2_bit +#define FIO3SET3 FIO3SET_bit.__byte3 +#define FIO3SET3_bit FIO3SET_bit.__byte3_bit +#define FIO3SETL FIO3SET_bit.__shortl +#define FIO3SETL_bit FIO3SET_bit.__shortl_bit +#define FIO3SETU FIO3SET_bit.__shortu +#define FIO3SETU_bit FIO3SET_bit.__shortu_bit +__IO_REG32_BIT(FIO3CLR, 0x3FFFC07C,__WRITE ,__fgpio3_bits); +#define FIO3CLR0 FIO3CLR_bit.__byte0 +#define FIO3CLR0_bit FIO3CLR_bit.__byte0_bit +#define FIO3CLR1 FIO3CLR_bit.__byte1 +#define FIO3CLR1_bit FIO3CLR_bit.__byte1_bit +#define FIO3CLR2 FIO3CLR_bit.__byte2 +#define FIO3CLR2_bit FIO3CLR_bit.__byte2_bit +#define FIO3CLR3 FIO3CLR_bit.__byte3 +#define FIO3CLR3_bit FIO3CLR_bit.__byte3_bit +#define FIO3CLRL FIO3CLR_bit.__shortl +#define FIO3CLRL_bit FIO3CLR_bit.__shortl_bit +#define FIO3CLRU FIO3CLR_bit.__shortu +#define FIO3CLRU_bit FIO3CLR_bit.__shortu_bit +__IO_REG32_BIT(FIO4DIR, 0x3FFFC080,__READ_WRITE,__fgpio4_bits); +#define FIO4DIR0 FIO4DIR_bit.__byte0 +#define FIO4DIR0_bit FIO4DIR_bit.__byte0_bit +#define FIO4DIR1 FIO4DIR_bit.__byte1 +#define FIO4DIR1_bit FIO4DIR_bit.__byte1_bit +#define FIO4DIR2 FIO4DIR_bit.__byte2 +#define FIO4DIR2_bit FIO4DIR_bit.__byte2_bit +#define FIO4DIR3 FIO4DIR_bit.__byte3 +#define FIO4DIR3_bit FIO4DIR_bit.__byte3_bit +#define FIO4DIRL FIO4DIR_bit.__shortl +#define FIO4DIRL_bit FIO4DIR_bit.__shortl_bit +#define FIO4DIRU FIO4DIR_bit.__shortu +#define FIO4DIRU_bit FIO4DIR_bit.__shortu_bit +__IO_REG32_BIT(FIO4MASK, 0x3FFFC090,__READ_WRITE,__fgpio4_bits); +#define FIO4MASK0 FIO4MASK_bit.__byte0 +#define FIO4MASK0_bit FIO4MASK_bit.__byte0_bit +#define FIO4MASK1 FIO4MASK_bit.__byte1 +#define FIO4MASK1_bit FIO4MASK_bit.__byte1_bit +#define FIO4MASK2 FIO4MASK_bit.__byte2 +#define FIO4MASK2_bit FIO4MASK_bit.__byte2_bit +#define FIO4MASK3 FIO4MASK_bit.__byte3 +#define FIO4MASK3_bit FIO4MASK_bit.__byte3_bit +#define FIO4MASKL FIO4MASK_bit.__shortl +#define FIO4MASKL_bit FIO4MASK_bit.__shortl_bit +#define FIO4MASKU FIO4MASK_bit.__shortu +#define FIO4MASKU_bit FIO4MASK_bit.__shortu_bit +__IO_REG32_BIT(FIO4PIN, 0x3FFFC094,__READ_WRITE,__fgpio4_bits); +#define FIO4PIN0 FIO4PIN_bit.__byte0 +#define FIO4PIN0_bit FIO4PIN_bit.__byte0_bit +#define FIO4PIN1 FIO4PIN_bit.__byte1 +#define FIO4PIN1_bit FIO4PIN_bit.__byte1_bit +#define FIO4PIN2 FIO4PIN_bit.__byte2 +#define FIO4PIN2_bit FIO4PIN_bit.__byte2_bit +#define FIO4PIN3 FIO4PIN_bit.__byte3 +#define FIO4PIN3_bit FIO4PIN_bit.__byte3_bit +#define FIO4PINL FIO4PIN_bit.__shortl +#define FIO4PINL_bit FIO4PIN_bit.__shortl_bit +#define FIO4PINU FIO4PIN_bit.__shortu +#define FIO4PINU_bit FIO4PIN_bit.__shortu_bit +__IO_REG32_BIT(FIO4SET, 0x3FFFC098,__READ_WRITE,__fgpio4_bits); +#define FIO4SET0 FIO4SET_bit.__byte0 +#define FIO4SET0_bit FIO4SET_bit.__byte0_bit +#define FIO4SET1 FIO4SET_bit.__byte1 +#define FIO4SET1_bit FIO4SET_bit.__byte1_bit +#define FIO4SET2 FIO4SET_bit.__byte2 +#define FIO4SET2_bit FIO4SET_bit.__byte2_bit +#define FIO4SET3 FIO4SET_bit.__byte3 +#define FIO4SET3_bit FIO4SET_bit.__byte3_bit +#define FIO4SETL FIO4SET_bit.__shortl +#define FIO4SETL_bit FIO4SET_bit.__shortl_bit +#define FIO4SETU FIO4SET_bit.__shortu +#define FIO4SETU_bit FIO4SET_bit.__shortu_bit +__IO_REG32_BIT(FIO4CLR, 0x3FFFC09C,__WRITE ,__fgpio4_bits); +#define FIO4CLR0 FIO4CLR_bit.__byte0 +#define FIO4CLR0_bit FIO4CLR_bit.__byte0_bit +#define FIO4CLR1 FIO4CLR_bit.__byte1 +#define FIO4CLR1_bit FIO4CLR_bit.__byte1_bit +#define FIO4CLR2 FIO4CLR_bit.__byte2 +#define FIO4CLR2_bit FIO4CLR_bit.__byte2_bit +#define FIO4CLR3 FIO4CLR_bit.__byte3 +#define FIO4CLR3_bit FIO4CLR_bit.__byte3_bit +#define FIO4CLRL FIO4CLR_bit.__shortl +#define FIO4CLRL_bit FIO4CLR_bit.__shortl_bit +#define FIO4CLRU FIO4CLR_bit.__shortu +#define FIO4CLRU_bit FIO4CLR_bit.__shortu_bit +__IO_REG32_BIT(IO0INTENR, 0xE0028090,__READ_WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO0INTENF, 0xE0028094,__READ_WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO0INTSTATR, 0xE0028084,__READ ,__gpio0_bits); +__IO_REG32_BIT(IO0INTSTATF, 0xE0028088,__READ ,__gpio0_bits); +__IO_REG32_BIT(IO0INTCLR, 0xE002808C,__WRITE ,__gpio0_bits); +__IO_REG32_BIT(IO2INTENR, 0xE00280B0,__READ_WRITE ,__gpio2_bits); +__IO_REG32_BIT(IO2INTENF, 0xE00280B4,__READ_WRITE ,__gpio2_bits); +__IO_REG32_BIT(IO2INTSTATR, 0xE00280A4,__READ ,__gpio2_bits); +__IO_REG32_BIT(IO2INTSTATF, 0xE00280A8,__READ ,__gpio2_bits); +__IO_REG32_BIT(IO2INTCLR, 0xE00280AC,__WRITE ,__gpio2_bits); +__IO_REG32_BIT(IOINTSTATUS, 0xE0028080,__READ ,__iointst_bits); + +/*************************************************************************** + ** + ** ETHERNET + ** + ***************************************************************************/ +__IO_REG32_BIT(MAC1, 0xFFE00000,__READ_WRITE ,__mac1_bits); +__IO_REG32_BIT(MAC2, 0xFFE00004,__READ_WRITE ,__mac2_bits); +__IO_REG32_BIT(IPGT, 0xFFE00008,__READ_WRITE ,__ipgt_bits); +__IO_REG32_BIT(IPGR, 0xFFE0000C,__READ_WRITE ,__ipgr_bits); +__IO_REG32_BIT(CLRT, 0xFFE00010,__READ_WRITE ,__clrt_bits); +__IO_REG32_BIT(MAXF, 0xFFE00014,__READ_WRITE ,__maxf_bits); +__IO_REG32_BIT(SUPP, 0xFFE00018,__READ_WRITE ,__supp_bits); +__IO_REG32_BIT(TEST, 0xFFE0001C,__READ_WRITE ,__test_bits); +__IO_REG32_BIT(MCFG, 0xFFE00020,__READ_WRITE ,__mcfg_bits); +__IO_REG32_BIT(MCMD, 0xFFE00024,__READ_WRITE ,__mcmd_bits); +__IO_REG32_BIT(MADR, 0xFFE00028,__READ_WRITE ,__madr_bits); +__IO_REG32_BIT(MWTD, 0xFFE0002C,__WRITE ,__mwtd_bits); +__IO_REG32_BIT(MRDD, 0xFFE00030,__READ ,__mrdd_bits); +__IO_REG32_BIT(MIND, 0xFFE00034,__READ ,__mind_bits); +__IO_REG32_BIT(SA0, 0xFFE00040,__READ_WRITE ,__sa0_bits); +__IO_REG32_BIT(SA1, 0xFFE00044,__READ_WRITE ,__sa1_bits); +__IO_REG32_BIT(SA2, 0xFFE00048,__READ_WRITE ,__sa2_bits); +__IO_REG32_BIT(COMMAND, 0xFFE00100,__READ_WRITE ,__command_bits); +__IO_REG32_BIT(STATUS, 0xFFE00104,__READ ,__status_bits); +__IO_REG32( RXDESCRIPTOR, 0xFFE00108,__READ_WRITE ); +__IO_REG32( RXSTATUS, 0xFFE0010C,__READ_WRITE ); +__IO_REG32_BIT(RXDESCRIPTORNUMBER, 0xFFE00110,__READ_WRITE ,__rxdescrn_bits); +__IO_REG32_BIT(RXPRODUCEINDEX, 0xFFE00114,__READ ,__rxprodind_bits); +__IO_REG32_BIT(RXCONSUMEINDEX, 0xFFE00118,__READ_WRITE ,__rxcomind_bits); +__IO_REG32( TXDESCRIPTOR, 0xFFE0011C,__READ_WRITE ); +__IO_REG32( TXSTATUS, 0xFFE00120,__READ_WRITE ); +__IO_REG32_BIT(TXDESCRIPTORNUMBER, 0xFFE00124,__READ_WRITE ,__txdescrn_bits); +__IO_REG32_BIT(TXPRODUCEINDEX, 0xFFE00128,__READ_WRITE ,__txprodind_bits); +__IO_REG32_BIT(TXCONSUMEINDEX, 0xFFE0012C,__READ ,__txcomind_bits); +__IO_REG32_BIT(TSV0, 0xFFE00158,__READ ,__tsv0_bits); +__IO_REG32_BIT(TSV1, 0xFFE0015C,__READ ,__tsv1_bits); +__IO_REG32_BIT(RSV, 0xFFE00160,__READ ,__rsv_bits); +__IO_REG32_BIT(FLOWCONTROLCOUNTER, 0xFFE00170,__READ_WRITE ,__fwctrlcnt_bits); +__IO_REG32_BIT(FLOWCONTROLSTATUS, 0xFFE00174,__READ ,__fwctrlstat_bits); +__IO_REG32_BIT(RXFILTERCTRL, 0xFFE00200,__READ_WRITE ,__rxflctrl_bits); +__IO_REG32_BIT(RXFILTERWOLSTATUS, 0xFFE00204,__READ_WRITE ,__rxflwolstat_bits); +__IO_REG32_BIT(RXFILTERWOLCLEAR, 0xFFE00208,__READ_WRITE ,__rxflwolclr_bits); +__IO_REG32( HASHFILTERL, 0xFFE00210,__READ_WRITE ); +__IO_REG32( HASHFILTERH, 0xFFE00214,__READ_WRITE ); +__IO_REG32_BIT(INTSTATUS, 0xFFE00FE0,__READ ,__intstat_bits); +__IO_REG32_BIT(INTENABLE, 0xFFE00FE4,__READ_WRITE ,__intena_bits); +__IO_REG32_BIT(INTCLEAR, 0xFFE00FE8,__WRITE ,__intclr_bits); +__IO_REG32_BIT(INTSET, 0xFFE00FEC,__WRITE ,__intset_bits); +__IO_REG32_BIT(POWERDOWN, 0xFFE00FF4,__READ_WRITE ,__pwrdn_bits); + +/*************************************************************************** + ** + ** CAN + ** + ***************************************************************************/ +__IO_REG32_BIT(AFMR, 0xE003C000,__READ_WRITE ,__afmr_bits); +__IO_REG32( SFF_SA, 0xE003C004,__READ_WRITE); +__IO_REG32( SFF_GRP_SA, 0xE003C008,__READ_WRITE); +__IO_REG32( EFF_SA, 0xE003C00C,__READ_WRITE); +__IO_REG32( EFF_GRP_SA, 0xE003C010,__READ_WRITE); +__IO_REG32( ENDOFTABLE, 0xE003C014,__READ_WRITE); +__IO_REG32( LUTERRAD, 0xE003C018,__READ); +__IO_REG32_BIT(LUTERR, 0xE003C01C,__READ ,__luterr_bits); +__IO_REG32_BIT(FCANIE, 0xE003C020,__READ_WRITE ,__fcanie_bits); +__IO_REG32_BIT(FCANIC0, 0xE003C024,__READ_WRITE ,__fcanic0_bits); +__IO_REG32_BIT(FCANIC1, 0xE003C028,__READ_WRITE ,__fcanic1_bits); +__IO_REG32_BIT(CANTXSR, 0xE0040000,__READ ,__cantxsr_bits); +__IO_REG32_BIT(CANRXSR, 0xE0040004,__READ ,__canrxsr_bits); +__IO_REG32_BIT(CANMSR, 0xE0040008,__READ ,__canmsr_bits); +__IO_REG32_BIT(CAN1MOD, 0xE0044000,__READ_WRITE ,__canmod_bits); +__IO_REG32_BIT(CAN1CMR, 0xE0044004,__WRITE ,__cancmr_bits); +__IO_REG32_BIT(CAN1GSR, 0xE0044008,__READ_WRITE ,__cangsr_bits); +__IO_REG32_BIT(CAN1ICR, 0xE004400C,__READ ,__canicr_bits); +__IO_REG32_BIT(CAN1IER, 0xE0044010,__READ_WRITE ,__canier_bits); +__IO_REG32_BIT(CAN1BTR, 0xE0044014,__READ_WRITE ,__canbtr_bits); +__IO_REG32_BIT(CAN1EWL, 0xE0044018,__READ_WRITE ,__canewl_bits); +__IO_REG32_BIT(CAN1SR, 0xE004401C,__READ ,__cansr_bits); +__IO_REG32_BIT(CAN1RFS, 0xE0044020,__READ_WRITE ,__canrfs_bits); +__IO_REG32_BIT(CAN1RID, 0xE0044024,__READ_WRITE ,__canrid_bits); +__IO_REG32_BIT(CAN1RDA, 0xE0044028,__READ_WRITE ,__canrda_bits); +__IO_REG32_BIT(CAN1RDB, 0xE004402C,__READ_WRITE ,__canrdb_bits); +__IO_REG32_BIT(CAN1TFI1, 0xE0044030,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID1, 0xE0044034,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA1, 0xE0044038,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB1, 0xE004403C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN1TFI2, 0xE0044040,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID2, 0xE0044044,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA2, 0xE0044048,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB2, 0xE004404C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN1TFI3, 0xE0044050,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN1TID3, 0xE0044054,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN1TDA3, 0xE0044058,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN1TDB3, 0xE004405C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2MOD, 0xE0048000,__READ_WRITE ,__canmod_bits); +__IO_REG32_BIT(CAN2CMR, 0xE0048004,__WRITE ,__cancmr_bits); +__IO_REG32_BIT(CAN2GSR, 0xE0048008,__READ_WRITE ,__cangsr_bits); +__IO_REG32_BIT(CAN2ICR, 0xE004800C,__READ ,__canicr_bits); +__IO_REG32_BIT(CAN2IER, 0xE0048010,__READ_WRITE ,__canier_bits); +__IO_REG32_BIT(CAN2BTR, 0xE0048014,__READ_WRITE ,__canbtr_bits); +__IO_REG32_BIT(CAN2EWL, 0xE0048018,__READ_WRITE ,__canewl_bits); +__IO_REG32_BIT(CAN2SR, 0xE004801C,__READ ,__cansr_bits); +__IO_REG32_BIT(CAN2RFS, 0xE0048020,__READ_WRITE ,__canrfs_bits); +__IO_REG32_BIT(CAN2RID, 0xE0048024,__READ_WRITE ,__canrid_bits); +__IO_REG32_BIT(CAN2RDA, 0xE0048028,__READ_WRITE ,__canrda_bits); +__IO_REG32_BIT(CAN2RDB, 0xE004802C,__READ_WRITE ,__canrdb_bits); +__IO_REG32_BIT(CAN2TFI1, 0xE0048030,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID1, 0xE0048034,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA1, 0xE0048038,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB1, 0xE004803C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2TFI2, 0xE0048040,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID2, 0xE0048044,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA2, 0xE0048048,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB2, 0xE004804C,__READ_WRITE ,__cantdb_bits); +__IO_REG32_BIT(CAN2TFI3, 0xE0048050,__READ_WRITE ,__cantfi_bits); +__IO_REG32_BIT(CAN2TID3, 0xE0048054,__READ_WRITE ,__cantid_bits); +__IO_REG32_BIT(CAN2TDA3, 0xE0048058,__READ_WRITE ,__cantda_bits); +__IO_REG32_BIT(CAN2TDB3, 0xE004805C,__READ_WRITE ,__cantdb_bits); + +/*************************************************************************** + ** + ** USB + ** + ***************************************************************************/ +__IO_REG32_BIT(USBPORTSEL, 0xFFE0C110,__READ_WRITE ,__usbportsel_bits); +__IO_REG32_BIT(USBCLKCTRL, 0xFFE0CFF4,__READ_WRITE ,__usbclkctrl_bits); +__IO_REG32_BIT(USBCLKST, 0xFFE0CFF8,__READ ,__usbclkst_bits); +__IO_REG32_BIT(USBINTS, 0xE01FC1C0,__READ_WRITE ,__usbints_bits); +__IO_REG32_BIT(USBDEVINTST, 0xFFE0C200,__READ ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTEN, 0xFFE0C204,__READ_WRITE ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTCLR, 0xFFE0C208,__WRITE ,__usbdevintst_bits); +__IO_REG32_BIT(USBDEVINTSET, 0xFFE0C20C,__WRITE ,__usbdevintst_bits); +__IO_REG8_BIT( USBDEVINTPRI, 0xFFE0C22C,__WRITE ,__usbdevintpri_bits); +__IO_REG32_BIT(USBEPINTST, 0xFFE0C230,__READ ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTEN, 0xFFE0C234,__READ_WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTCLR, 0xFFE0C238,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTSET, 0xFFE0C23C,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBEPINTPRI, 0xFFE0C240,__WRITE ,__usbepintst_bits); +__IO_REG32_BIT(USBREEP, 0xFFE0C244,__READ_WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEPIN, 0xFFE0C248,__WRITE ,__usbepin_bits); +__IO_REG32_BIT(USBMAXPSIZE, 0xFFE0C24C,__READ_WRITE ,__usbmaxpsize_bits); +__IO_REG32( USBRXDATA, 0xFFE0C218,__READ); +__IO_REG32_BIT(USBRXPLEN, 0xFFE0C220,__READ ,__usbrxplen_bits); +__IO_REG32( TDATA, 0xFFE0C21C,__WRITE); +__IO_REG32_BIT(USBTXPLEN, 0xFFE0C224,__WRITE ,__usbtxplen_bits); +__IO_REG32_BIT(USBCTRL, 0xFFE0C228,__READ_WRITE ,__usbctrl_bits); +__IO_REG32_BIT(USBCMDCODE, 0xFFE0C210,__WRITE ,__usbcmdcode_bits); +__IO_REG32_BIT(USBCMDDATA, 0xFFE0C214,__READ ,__usbcmddata_bits); +__IO_REG32_BIT(USBDMARST, 0xFFE0C250,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBDMARCLR, 0xFFE0C254,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBDMARSET, 0xFFE0C258,__WRITE ,__usbreep_bits); +__IO_REG32( USBUDCAH, 0xFFE0C280,__READ_WRITE ); +__IO_REG32_BIT(USBEPDMAST, 0xFFE0C284,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBEPDMAEN, 0xFFE0C288,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEPDMADIS, 0xFFE0C28C,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBDMAINTST, 0xFFE0C290,__READ ,__usbdmaintst_bits); +__IO_REG32_BIT(USBDMAINTEN, 0xFFE0C294,__READ_WRITE ,__usbdmaintst_bits); +__IO_REG32_BIT(USBNDDRINTST, 0xFFE0C2AC,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBNDDRINTCLR, 0xFFE0C2B0,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBNDDRINTSET, 0xFFE0C2B4,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTST, 0xFFE0C2A0,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTCLR, 0xFFE0C2A4,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBEOTINTSET, 0xFFE0C2A8,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTST, 0xFFE0C2B8,__READ ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTCLR, 0xFFE0C2BC,__WRITE ,__usbreep_bits); +__IO_REG32_BIT(USBSYSERRINTSET, 0xFFE0C2C0,__WRITE ,__usbreep_bits); + +/*************************************************************************** + ** + ** UART0 + ** + ***************************************************************************/ +/* U0DLL, U0RBR and U0THR share the same address */ +__IO_REG8( U0RBRTHR, 0xE000C000,__READ_WRITE); +#define U0DLL U0RBRTHR +#define U0RBR U0RBRTHR +#define U0THR U0RBRTHR + +/* U0DLM and U0IER share the same address */ +__IO_REG32_BIT(U0IER, 0xE000C004,__READ_WRITE ,__uartier0_bits); +#define U0DLM U0IER + +/* U0FCR and U0IIR share the same address */ +__IO_REG32_BIT(U0FCR, 0xE000C008,__READ_WRITE ,__uartfcriir_bits); +#define U0IIR U0FCR +#define U0IIR_bit U0FCR_bit + +__IO_REG8_BIT( U0LCR, 0xE000C00C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U0LSR, 0xE000C014,__READ ,__uartlsr_bits); +__IO_REG8( U0SCR, 0xE000C01C,__READ_WRITE); +__IO_REG32_BIT(U0ACR, 0xE000C020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U0FDR, 0xE000C028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U0TER, 0xE000C030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART1 + ** + ***************************************************************************/ +/* U1DLL, U1RBR and U1THR share the same address */ +__IO_REG8( U1RBRTHR, 0xE0010000,__READ_WRITE); +#define U1DLL U1RBRTHR +#define U1RBR U1RBRTHR +#define U1THR U1RBRTHR + +/* U1DLM and U1IER share the same address */ +__IO_REG32_BIT(U1IER, 0xE0010004,__READ_WRITE ,__uartier1_bits); +#define U1DLM U1IER + +/* U1FCR and U1IIR share the same address */ +__IO_REG32_BIT(U1FCR, 0xE0010008,__READ_WRITE ,__uartfcriir_bits); +#define U1IIR U1FCR +#define U1IIR_bit U1FCR_bit + +__IO_REG8_BIT( U1LCR, 0xE001000C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U1MCR, 0xE0010010,__READ_WRITE ,__uartmcr_bits); +__IO_REG8_BIT( U1LSR, 0xE0010014,__READ ,__uartlsr_bits); +__IO_REG8_BIT( U1MSR, 0xE0010018,__READ ,__uartmsr_bits); +__IO_REG8( U1SCR, 0xE001001C,__READ_WRITE); +__IO_REG32_BIT(U1ACR, 0xE0010020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U1FDR, 0xE0010028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U1TER, 0xE0010030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART2 + ** + ***************************************************************************/ +/* U2DLL, U2RBR and U2THR share the same address */ +__IO_REG8( U2RBRTHR, 0xE0078000,__READ_WRITE); +#define U2DLL U2RBRTHR +#define U2RBR U2RBRTHR +#define U2THR U2RBRTHR + +/* U2DLM and U2IER share the same address */ +__IO_REG32_BIT(U2IER, 0xE0078004,__READ_WRITE ,__uartier0_bits); +#define U2DLM U2IER + +/* U2FCR and U2IIR share the same address */ +__IO_REG32_BIT(U2FCR, 0xE0078008,__READ_WRITE ,__uartfcriir_bits); +#define U2IIR U2FCR +#define U2IIR_bit U2FCR_bit + +__IO_REG8_BIT( U2LCR, 0xE007800C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U2LSR, 0xE0078014,__READ ,__uartlsr_bits); +__IO_REG8( U2SCR, 0xE007801C,__READ_WRITE); +__IO_REG32_BIT(U2ACR, 0xE0078020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U2FDR, 0xE0078028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U2TER, 0xE0078030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** UART3 + ** + ***************************************************************************/ +/* U3DLL, U3RBR and U3THR share the same address */ +__IO_REG8( U3RBRTHR, 0xE007C000,__READ_WRITE); +#define U3DLL U3RBRTHR +#define U3RBR U3RBRTHR +#define U3THR U3RBRTHR + +/* U3DLM and U3IER share the same address */ +__IO_REG32_BIT(U3IER, 0xE007C004,__READ_WRITE ,__uartier0_bits); +#define U3DLM U3IER + +/* U3FCR and U3IIR share the same address */ +__IO_REG32_BIT(U3FCR, 0xE007C008,__READ_WRITE ,__uartfcriir_bits); +#define U3IIR U3FCR +#define U3IIR_bit U3FCR_bit + +__IO_REG8_BIT( U3LCR, 0xE007C00C,__READ_WRITE ,__uartlcr_bits); +__IO_REG8_BIT( U3LSR, 0xE007C014,__READ ,__uartlsr_bits); +__IO_REG8( U3SCR, 0xE007C01C,__READ_WRITE); +__IO_REG32_BIT(U3ACR, 0xE007C020,__READ_WRITE ,__uartacr_bits); +__IO_REG32_BIT(U3ICR, 0xE007C024,__READ_WRITE ,__uarticr_bits); +__IO_REG32_BIT(U3FDR, 0xE007C028,__READ_WRITE ,__uartfdr_bits); +__IO_REG8_BIT( U3TER, 0xE007C030,__READ_WRITE ,__uartter_bits); + +/*************************************************************************** + ** + ** SPI + ** + ***************************************************************************/ +__IO_REG32_BIT(S0SPCR, 0xE0020000,__READ_WRITE ,__spcr_bits); +__IO_REG32_BIT(S0SPSR, 0xE0020004,__READ ,__spsr_bits); +__IO_REG16( S0SPDR, 0xE0020008,__READ_WRITE); +__IO_REG32_BIT(S0SPCCR, 0xE002000C,__READ_WRITE ,__spccr_bits); +__IO_REG8_BIT( SPTCR, 0xE0020010,__READ_WRITE ,__sptcr_bits); +__IO_REG8_BIT( SPTSR, 0xE0020014,__READ_WRITE ,__sptsr_bits); +__IO_REG32_BIT(S0SPINT, 0xE002001C,__READ_WRITE ,__spint_bits); + +/*************************************************************************** + ** + ** SSP0 + ** + ***************************************************************************/ +__IO_REG32_BIT(SSP0CR0, 0xE0068000,__READ_WRITE ,__sspcr0_bits); +__IO_REG32_BIT(SSP0CR1, 0xE0068004,__READ_WRITE ,__sspcr1_bits); +__IO_REG32_BIT(SSP0DR, 0xE0068008,__READ_WRITE ,__sspdr_bits); +__IO_REG32_BIT(SSP0SR, 0xE006800C,__READ ,__sspsr_bits); +__IO_REG32_BIT(SSP0CPSR, 0xE0068010,__READ_WRITE ,__sspcpsr_bits); +__IO_REG32_BIT(SSP0IMSC, 0xE0068014,__READ_WRITE ,__sspimsc_bits); +__IO_REG32_BIT(SSP0RIS, 0xE0068018,__READ_WRITE ,__sspris_bits); +__IO_REG32_BIT(SSP0MIS, 0xE006801C,__READ_WRITE ,__sspmis_bits); +__IO_REG32_BIT(SSP0ICR, 0xE0068020,__READ_WRITE ,__sspicr_bits); +__IO_REG32_BIT(SSP0DMACR, 0xE0068024,__READ_WRITE ,__sspdmacr_bits); + +/*************************************************************************** + ** + ** SSP1 + ** + ***************************************************************************/ +__IO_REG32_BIT(SSP1CR0, 0xE0030000,__READ_WRITE ,__sspcr0_bits); +__IO_REG32_BIT(SSP1CR1, 0xE0030004,__READ_WRITE ,__sspcr1_bits); +__IO_REG32_BIT(SSP1DR, 0xE0030008,__READ_WRITE ,__sspdr_bits); +__IO_REG32_BIT(SSP1SR, 0xE003000C,__READ ,__sspsr_bits); +__IO_REG32_BIT(SSP1CPSR, 0xE0030010,__READ_WRITE ,__sspcpsr_bits); +__IO_REG32_BIT(SSP1IMSC, 0xE0030014,__READ_WRITE ,__sspimsc_bits); +__IO_REG32_BIT(SSP1RIS, 0xE0030018,__READ_WRITE ,__sspris_bits); +__IO_REG32_BIT(SSP1MIS, 0xE003001C,__READ_WRITE ,__sspmis_bits); +__IO_REG32_BIT(SSP1ICR, 0xE0030020,__READ_WRITE ,__sspicr_bits); +__IO_REG32_BIT(SSP1DMACR, 0xE0030024,__READ_WRITE ,__sspdmacr_bits); + +/*************************************************************************** + ** + ** SD/MMC + ** + ***************************************************************************/ +__IO_REG32_BIT(MCIPOWER, 0xE008C000,__READ_WRITE ,__mcipower_bits); +__IO_REG32_BIT(MCICLOCK, 0xE008C004,__READ_WRITE ,__mciclock_bits); +__IO_REG32( MCIARGUMENT, 0xE008C008,__READ_WRITE); +__IO_REG32_BIT(MCICOMMAND, 0xE008C00C,__READ_WRITE ,__mcicommand_bits); +__IO_REG32_BIT(MCIRESPCMD, 0xE008C010,__READ ,__mcirespcmd_bits); +__IO_REG32( MCIRESPONSE0, 0xE008C014,__READ); +__IO_REG32( MCIRESPONSE1, 0xE008C018,__READ); +__IO_REG32( MCIRESPONSE2, 0xE008C01C,__READ); +__IO_REG32( MCIRESPONSE3, 0xE008C020,__READ); +__IO_REG32( MCIDATATIMER, 0xE008C024,__READ_WRITE); +__IO_REG16( MCIDATALENGTH, 0xE008C028,__READ_WRITE); +__IO_REG32_BIT(MCIDATACTRL, 0xE008C02C,__READ_WRITE ,__mcidatactrl_bits); +__IO_REG16( MCIDATACNT, 0xE008C030,__READ); +__IO_REG32_BIT(MCISTATUS, 0xE008C034,__READ ,__mcistatus_bits); +__IO_REG32_BIT(MCICLEAR, 0xE008C038,__WRITE ,__mciclear_bits); +__IO_REG32_BIT(MCIMASK0, 0xE008C03C,__READ_WRITE ,__mcistatus_bits); +__IO_REG32_BIT(MCIMASK1, 0xE008C040,__READ_WRITE ,__mcistatus_bits); +__IO_REG32_BIT(MCIFIFOCNT, 0xE008C048,__READ ,__mcififocnt_bits); +__IO_REG32( MCIFIFO0, 0xE008C080,__READ_WRITE); +__IO_REG32( MCIFIFO1, 0xE008C084,__READ_WRITE); +__IO_REG32( MCIFIFO2, 0xE008C088,__READ_WRITE); +__IO_REG32( MCIFIFO3, 0xE008C08C,__READ_WRITE); +__IO_REG32( MCIFIFO4, 0xE008C090,__READ_WRITE); +__IO_REG32( MCIFIFO5, 0xE008C094,__READ_WRITE); +__IO_REG32( MCIFIFO6, 0xE008C098,__READ_WRITE); +__IO_REG32( MCIFIFO7, 0xE008C09C,__READ_WRITE); +__IO_REG32( MCIFIFO8, 0xE008C0A0,__READ_WRITE); +__IO_REG32( MCIFIFO9, 0xE008C0A4,__READ_WRITE); +__IO_REG32( MCIFIFO10, 0xE008C0A8,__READ_WRITE); +__IO_REG32( MCIFIFO11, 0xE008C0AC,__READ_WRITE); +__IO_REG32( MCIFIFO12, 0xE008C0B0,__READ_WRITE); +__IO_REG32( MCIFIFO13, 0xE008C0B4,__READ_WRITE); +__IO_REG32( MCIFIFO14, 0xE008C0B8,__READ_WRITE); +__IO_REG32( MCIFIFO15, 0xE008C0BC,__READ_WRITE); + +/*************************************************************************** + ** + ** I2C0 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C0CONSET, 0xE001C000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C0STAT, 0xE001C004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C0DAT, 0xE001C008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C0ADR, 0xE001C00C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C0SCLH, 0xE001C010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C0SCLL, 0xE001C014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C0CONCLR, 0xE001C018,__WRITE ,__i2conclr_bits); + +//The names of the registers above have been corrected according to the chip +//documentation. The defines below are aliases with the old names for backwards +//compatibility. +#define I20CONSET I2C0CONSET +#define I20STAT I2C0STAT +#define I20DAT I2C0DAT +#define I20ADR I2C0ADR +#define I20SCLH I2C0SCLH +#define I20SCLL I2C0SCLL +#define I20CONCLR I2C0CONCLR + +/*************************************************************************** + ** + ** I2C1 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C1CONSET, 0xE005C000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C1STAT, 0xE005C004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C1DAT, 0xE005C008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C1ADR, 0xE005C00C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C1SCLH, 0xE005C010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C1SCLL, 0xE005C014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C1CONCLR, 0xE005C018,__WRITE ,__i2conclr_bits); + +//The names of the registers above have been corrected according to the chip +//documentation. The defines below are aliases with the old names for backwards +//compatibility. +#define I21CONSET I2C1CONSET +#define I21STAT I2C1STAT +#define I21DAT I2C1DAT +#define I21ADR I2C1ADR +#define I21SCLH I2C1SCLH +#define I21SCLL I2C1SCLL +#define I21CONCLR I2C1CONCLR + +/*************************************************************************** + ** + ** I2C2 + ** + ***************************************************************************/ +__IO_REG32_BIT(I2C2CONSET, 0xE0080000,__READ_WRITE ,__i2conset_bits); +__IO_REG32_BIT(I2C2STAT, 0xE0080004,__READ ,__i2stat_bits); +__IO_REG32_BIT(I2C2DAT, 0xE0080008,__READ_WRITE ,__i2dat_bits); +__IO_REG32_BIT(I2C2ADR, 0xE008000C,__READ_WRITE ,__i2adr_bits); +__IO_REG32_BIT(I2C2SCLH, 0xE0080010,__READ_WRITE ,__i2sch_bits); +__IO_REG32_BIT(I2C2SCLL, 0xE0080014,__READ_WRITE ,__i2scl_bits); +__IO_REG32_BIT(I2C2CONCLR, 0xE0080018,__WRITE ,__i2conclr_bits); + +/*************************************************************************** + ** + ** I2S + ** + ***************************************************************************/ +__IO_REG32_BIT(I2SDAO, 0xE0088000,__READ_WRITE ,__i2sdao_bits); +__IO_REG32_BIT(I2SDAI, 0xE0088004,__READ_WRITE ,__i2sdai_bits); +__IO_REG32( I2STXFIFO, 0xE0088008,__WRITE); +__IO_REG32( I2SRXFIFO, 0xE008800C,__READ); +__IO_REG32_BIT(I2SSTATE, 0xE0088010,__READ ,__i2sstate_bits); +__IO_REG32_BIT(I2SDMA1, 0xE0088014,__READ_WRITE ,__i2sdma_bits); +__IO_REG32_BIT(I2SDMA2, 0xE0088018,__READ_WRITE ,__i2sdma_bits); +__IO_REG32_BIT(I2SIRQ, 0xE008801C,__READ_WRITE ,__i2sirq_bits); +__IO_REG32_BIT(I2STXRATE, 0xE0088020,__READ_WRITE ,__i2stxrate_bits); +__IO_REG32_BIT(I2SRXRATE, 0xE0088024,__READ_WRITE ,__i2srxrate_bits); + +/*************************************************************************** + ** + ** TIMER0 + ** + ***************************************************************************/ +__IO_REG32_BIT(T0IR, 0xE0004000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T0TCR, 0xE0004004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T0TC, 0xE0004008,__READ_WRITE); +__IO_REG32( T0PR, 0xE000400C,__READ_WRITE); +__IO_REG32( T0PC, 0xE0004010,__READ_WRITE); +__IO_REG32_BIT(T0MCR, 0xE0004014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T0MR0, 0xE0004018,__READ_WRITE); +__IO_REG32( T0MR1, 0xE000401C,__READ_WRITE); +__IO_REG32( T0MR2, 0xE0004020,__READ_WRITE); +__IO_REG32( T0MR3, 0xE0004024,__READ_WRITE); +__IO_REG32_BIT(T0CCR, 0xE0004028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T0CR0, 0xE000402C,__READ); +__IO_REG32( T0CR1, 0xE0004030,__READ); +__IO_REG32( T0CR2, 0xE0004034,__READ); +__IO_REG32( T0CR3, 0xE0004038,__READ); +__IO_REG32_BIT(T0EMR, 0xE000403C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T0CTCR, 0xE0004070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER1 + ** + ***************************************************************************/ +__IO_REG32_BIT(T1IR, 0xE0008000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T1TCR, 0xE0008004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T1TC, 0xE0008008,__READ_WRITE); +__IO_REG32( T1PR, 0xE000800C,__READ_WRITE); +__IO_REG32( T1PC, 0xE0008010,__READ_WRITE); +__IO_REG32_BIT(T1MCR, 0xE0008014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T1MR0, 0xE0008018,__READ_WRITE); +__IO_REG32( T1MR1, 0xE000801C,__READ_WRITE); +__IO_REG32( T1MR2, 0xE0008020,__READ_WRITE); +__IO_REG32( T1MR3, 0xE0008024,__READ_WRITE); +__IO_REG32_BIT(T1CCR, 0xE0008028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T1CR0, 0xE000802C,__READ); +__IO_REG32( T1CR1, 0xE0008030,__READ); +__IO_REG32( T1CR2, 0xE0008034,__READ); +__IO_REG32( T1CR3, 0xE0008038,__READ); +__IO_REG32_BIT(T1EMR, 0xE000803C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T1CTCR, 0xE0008070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER2 + ** + ***************************************************************************/ +__IO_REG32_BIT(T2IR, 0xE0070000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T2TCR, 0xE0070004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T2TC, 0xE0070008,__READ_WRITE); +__IO_REG32( T2PR, 0xE007000C,__READ_WRITE); +__IO_REG32( T2PC, 0xE0070010,__READ_WRITE); +__IO_REG32_BIT(T2MCR, 0xE0070014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T2MR0, 0xE0070018,__READ_WRITE); +__IO_REG32( T2MR1, 0xE007001C,__READ_WRITE); +__IO_REG32( T2MR2, 0xE0070020,__READ_WRITE); +__IO_REG32( T2MR3, 0xE0070024,__READ_WRITE); +__IO_REG32_BIT(T2CCR, 0xE0070028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T2CR0, 0xE007002C,__READ); +__IO_REG32( T2CR1, 0xE0070030,__READ); +__IO_REG32( T2CR2, 0xE0070034,__READ); +__IO_REG32( T2CR3, 0xE0070038,__READ); +__IO_REG32_BIT(T2EMR, 0xE007003C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T2CTCR, 0xE0070070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** TIMER3 + ** + ***************************************************************************/ +__IO_REG32_BIT(T3IR, 0xE0074000,__READ_WRITE ,__ir_bits); +__IO_REG32_BIT(T3TCR, 0xE0074004,__READ_WRITE ,__tcr_bits); +__IO_REG32( T3TC, 0xE0074008,__READ_WRITE); +__IO_REG32( T3PR, 0xE007400C,__READ_WRITE); +__IO_REG32( T3PC, 0xE0074010,__READ_WRITE); +__IO_REG32_BIT(T3MCR, 0xE0074014,__READ_WRITE ,__mcr_bits); +__IO_REG32( T3MR0, 0xE0074018,__READ_WRITE); +__IO_REG32( T3MR1, 0xE007401C,__READ_WRITE); +__IO_REG32( T3MR2, 0xE0074020,__READ_WRITE); +__IO_REG32( T3MR3, 0xE0074024,__READ_WRITE); +__IO_REG32_BIT(T3CCR, 0xE0074028,__READ_WRITE ,__ccr_bits); +__IO_REG32( T3CR0, 0xE007402C,__READ); +__IO_REG32( T3CR1, 0xE0074030,__READ); +__IO_REG32( T3CR2, 0xE0074034,__READ); +__IO_REG32( T3CR3, 0xE0074038,__READ); +__IO_REG32_BIT(T3EMR, 0xE007403C,__READ_WRITE ,__emr_bits); +__IO_REG32_BIT(T3CTCR, 0xE0074070,__READ_WRITE ,__ctcr_bits); + +/*************************************************************************** + ** + ** Watchdog + ** + ***************************************************************************/ +__IO_REG32_BIT(WDMOD, 0xE0000000,__READ_WRITE ,__wdmod_bits); +__IO_REG32( WDTC, 0xE0000004,__READ_WRITE); +__IO_REG32_BIT(WDFEED, 0xE0000008,__WRITE ,__wdfeed_bits); +__IO_REG32( WDTV, 0xE000000C,__READ); +__IO_REG32_BIT(WDCLKSEL, 0xE0000010,__READ_WRITE ,__wdclksel_bits); + +/*************************************************************************** + ** + ** A/D Converters + ** + ***************************************************************************/ +__IO_REG32_BIT(AD0CR, 0xE0034000,__READ_WRITE ,__adcr_bits); +__IO_REG32_BIT(AD0GDR, 0xE0034004,__READ_WRITE ,__adgdr_bits); +__IO_REG32_BIT(ADINTEN, 0xE003400C,__READ_WRITE ,__adinten_bits); +__IO_REG32_BIT(ADDR0, 0xE0034010,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR1, 0xE0034014,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR2, 0xE0034018,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR3, 0xE003401C,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR4, 0xE0034020,__READ ,__addr_bits); +__IO_REG32_BIT(ADDR5, 0xE0034024,__READ ,__addr_bits); +__IO_REG32_BIT(ADSTAT, 0xE0034030,__READ ,__adstat_bits); + +/*************************************************************************** + ** + ** D/A Converter + ** + ***************************************************************************/ +__IO_REG32_BIT(DACR, 0xE006C000,__READ_WRITE ,__dacr_bits); + +/*************************************************************************** + ** + ** PWM1 + ** + ***************************************************************************/ +__IO_REG32_BIT(PWM1IR, 0xE0018000,__READ_WRITE ,__pwmir_bits); +__IO_REG32_BIT(PWM1TCR, 0xE0018004,__READ_WRITE ,__pwmtcr1_bits); +__IO_REG32( PWM1TC, 0xE0018008,__READ_WRITE); +__IO_REG32( PWM1PR, 0xE001800C,__READ_WRITE); +__IO_REG32( PWM1PC, 0xE0018010,__READ_WRITE); +__IO_REG32_BIT(PWM1MCR, 0xE0018014,__READ_WRITE ,__pwmmcr_bits); +__IO_REG32( PWM1MR0, 0xE0018018,__READ_WRITE); +__IO_REG32( PWM1MR1, 0xE001801C,__READ_WRITE); +__IO_REG32( PWM1MR2, 0xE0018020,__READ_WRITE); +__IO_REG32( PWM1MR3, 0xE0018024,__READ_WRITE); +__IO_REG32_BIT(PWM1CCR, 0xE0018028,__READ_WRITE ,__pwmccr_bits); +__IO_REG32( PWM1CR0, 0xE001802C,__READ_WRITE); +__IO_REG32( PWM1CR1, 0xE0018030,__READ_WRITE); +__IO_REG32( PWM1CR2, 0xE0018034,__READ_WRITE); +__IO_REG32( PWM1CR3, 0xE0018038,__READ_WRITE); +__IO_REG32( PWM1EMR, 0xE001803C,__READ_WRITE); +__IO_REG32( PWM1MR4, 0xE0018040,__READ_WRITE); +__IO_REG32( PWM1MR5, 0xE0018044,__READ_WRITE); +__IO_REG32( PWM1MR6, 0xE0018048,__READ_WRITE); +__IO_REG32_BIT(PWM1PCR, 0xE001804C,__READ_WRITE ,__pwmpcr_bits); +__IO_REG32_BIT(PWM1LER, 0xE0018050,__READ_WRITE ,__pwmler_bits); +__IO_REG32_BIT(PWM1CTCR, 0xE0018070,__READ_WRITE ,__pwmctcr_bits); + +/*************************************************************************** + ** + ** RTC + ** + ***************************************************************************/ +__IO_REG32_BIT(ILR, 0xE0024000,__READ_WRITE ,__ilr_bits); +__IO_REG32_BIT(CTC, 0xE0024004,__READ ,__ctc_bits); +__IO_REG32_BIT(CCR, 0xE0024008,__READ_WRITE ,__rtcccr_bits); +__IO_REG32_BIT(CIIR, 0xE002400C,__READ_WRITE ,__ciir_bits); +__IO_REG32_BIT(AMR, 0xE0024010,__READ_WRITE ,__amr_bits); +__IO_REG32_BIT(CTIME0, 0xE0024014,__READ ,__ctime0_bits); +__IO_REG32_BIT(CTIME1, 0xE0024018,__READ ,__ctime1_bits); +__IO_REG32_BIT(CTIME2, 0xE002401C,__READ ,__ctime2_bits); +__IO_REG32_BIT(SEC, 0xE0024020,__READ_WRITE ,__sec_bits); +__IO_REG32_BIT(MIN, 0xE0024024,__READ_WRITE ,__min_bits); +__IO_REG32_BIT(HOUR, 0xE0024028,__READ_WRITE ,__hour_bits); +__IO_REG32_BIT(DOM, 0xE002402C,__READ_WRITE ,__dom_bits); +__IO_REG32_BIT(DOW, 0xE0024030,__READ_WRITE ,__dow_bits); +__IO_REG32_BIT(DOY, 0xE0024034,__READ_WRITE ,__doy_bits); +__IO_REG32_BIT(MONTH, 0xE0024038,__READ_WRITE ,__month_bits); +__IO_REG32_BIT(YEAR, 0xE002403C,__READ_WRITE ,__year_bits); +__IO_REG32_BIT(CISS, 0xE0024040,__READ_WRITE ,__ciss_bits); +__IO_REG32_BIT(ALSEC, 0xE0024060,__READ_WRITE ,__sec_bits); +__IO_REG32_BIT(ALMIN, 0xE0024064,__READ_WRITE ,__min_bits); +__IO_REG32_BIT(ALHOUR, 0xE0024068,__READ_WRITE ,__hour_bits); +__IO_REG32_BIT(ALDOM, 0xE002406C,__READ_WRITE ,__dom_bits); +__IO_REG32_BIT(ALDOW, 0xE0024070,__READ_WRITE ,__dow_bits); +__IO_REG32_BIT(ALDOY, 0xE0024074,__READ_WRITE ,__doy_bits); +__IO_REG32_BIT(ALMON, 0xE0024078,__READ_WRITE ,__month_bits); +__IO_REG32_BIT(ALYEAR, 0xE002407C,__READ_WRITE ,__year_bits); +__IO_REG32_BIT(PREINT, 0xE0024080,__READ_WRITE ,__preint_bits); +__IO_REG32_BIT(PREFRAC, 0xE0024084,__READ_WRITE ,__prefrac_bits); + +/*************************************************************************** + ** + ** DMA + ** + ***************************************************************************/ +__IO_REG32_BIT(DMACINTSTATUS, 0xFFE04000,__READ ,__dmacintstatus_bits); +__IO_REG32_BIT(DMACINTTCSTATUS, 0xFFE04004,__READ ,__dmacinttcstatus_bits); +__IO_REG32_BIT(DMACINTTCCLEAR, 0xFFE04008,__WRITE ,__dmacinttcclear_bits); +__IO_REG32_BIT(DMACINTERRSTAT, 0xFFE0400C,__READ ,__dmacinterrstat_bits); +__IO_REG32_BIT(DMACINTERRCLR, 0xFFE04010,__WRITE ,__dmacinterrclr_bits); +__IO_REG32_BIT(DMACRAWINTTCSTATUS, 0xFFE04014,__READ ,__dmacrawinttcstatus_bits); +__IO_REG32_BIT(DMACRAWINTERRORSTATUS, 0xFFE04018,__READ ,__dmacrawinterrorstatus_bits); +__IO_REG32_BIT(DMACENBLDCHNS, 0xFFE0401C,__READ ,__dmacenbldchns_bits); +__IO_REG32_BIT(DMACSOFTBREQ, 0xFFE04020,__READ_WRITE,__dmacsoftbreq_bits); +__IO_REG32_BIT(DMACSOFTSREQ, 0xFFE04024,__READ_WRITE,__dmacsoftsreq_bits); +__IO_REG32_BIT(DMACSOFTLBREQ, 0xFFE04028,__READ_WRITE,__dmacsoftlbreq_bits); +__IO_REG32_BIT(DMACSOFTLSREQ, 0xFFE0402C,__READ_WRITE,__dmacsoftlsreq_bits); +__IO_REG32_BIT(DMACCONFIGURATION, 0xFFE04030,__READ_WRITE,__dmacconfig_bits); +__IO_REG32_BIT(DMACSYNC, 0xFFE04034,__READ_WRITE,__dmacsync_bits); +__IO_REG32( DMACC0SRCADDR, 0xFFE04100,__READ_WRITE); +__IO_REG32( DMACC0DESTADDR, 0xFFE04104,__READ_WRITE); +__IO_REG32_BIT(DMACC0LLI, 0xFFE04108,__READ_WRITE,__dma_lli_bits); +__IO_REG32_BIT(DMACC0CONTROL, 0xFFE0410C,__READ_WRITE,__dma_ctrl_bits); +__IO_REG32_BIT(DMACC0CONFIGURATION, 0xFFE04110,__READ_WRITE,__dma_cfg_bits); +__IO_REG32( DMACC1SRCADDR, 0xFFE04120,__READ_WRITE); +__IO_REG32( DMACC1DESTADDR, 0xFFE04124,__READ_WRITE); +__IO_REG32_BIT(DMACC1LLI, 0xFFE04128,__READ_WRITE,__dma_lli_bits); +__IO_REG32_BIT(DMACC1CONTROL, 0xFFE0412C,__READ_WRITE,__dma_ctrl_bits); +__IO_REG32_BIT(DMACC1CONFIGURATION, 0xFFE04130,__READ_WRITE,__dma_cfg_bits); + +/*************************************************************************** + ** Assembler-specific declarations + ***************************************************************************/ + +#ifdef __IAR_SYSTEMS_ASM__ +#endif /* __IAR_SYSTEMS_ASM__ */ + +/*************************************************************************** + ** + ** Interrupt vector table + ** + ***************************************************************************/ +#define RESETV 0x00 /* Reset */ +#define UNDEFV 0x04 /* Undefined instruction */ +#define SWIV 0x08 /* Software interrupt */ +#define PABORTV 0x0C /* Prefetch abort */ +#define DABORTV 0x10 /* Data abort */ +#define IRQV 0x18 /* Normal interrupt */ +#define FIQV 0x1C /* Fast interrupt */ + +/*************************************************************************** + ** + ** DMA Controller peripheral devices lines + ** + ***************************************************************************/ +#define DMA_SSP0TX 0 /* SPI0 Tx */ +#define DMA_SSP0RX 1 /* SPI0 Rx */ +#define DMA_SSP1TX 2 /* SPI1 Tx */ +#define DMA_SSP1RX 3 /* SPI1 Rx */ +#define DMA_MMCSD 4 /* MMC/SD */ +#define DMA_I2S0 5 /* I2S Channel 0 */ +#define DMA_I2S1 6 /* I2S Channel 1 */ + +/*************************************************************************** + ** + ** VIC Interrupt channels + ** + ***************************************************************************/ +#define VIC_WDT 0 /* Watchdog */ +#define VIC_SW 1 /* Software interrupts */ +#define VIC_DEBUGRX 2 /* Embedded ICE, DbgCommRx */ +#define VIC_DEBUGTX 3 /* Embedded ICE, DbgCommTx */ +#define VIC_TIMER0 4 /* Timer 0 (Match 0-3 Capture 0-3) */ +#define VIC_TIMER1 5 /* Timer 1 (Match 0-3 Capture 0-3) */ +#define VIC_UART0 6 /* UART 0 (RLS, THRE, RDA, CTI) */ +#define VIC_UART1 7 /* UART 1 (RLS, THRE, RDA, CTI, MSI) */ +#define VIC_PWM1 8 /* PWM 01 (Match 0-6 Capture 0-3) */ +#define VIC_I2C0 9 /* I2C 0 (SI) */ +#define VIC_SPI 10 /* SPI 0, SSP 0 */ +#define VIC_SSP1 11 /* SSP 1 */ +#define VIC_PLL 12 /* PLL lock (PLOCK) */ +#define VIC_RTC 13 /* RTC (RTCCIF, RTCALF) */ +#define VIC_EINT0 14 /* External interrupt 0 (EINT0) */ +#define VIC_EINT1 15 /* External interrupt 1 (EINT1) */ +#define VIC_EINT2 16 /* External interrupt 2 (EINT2) */ +#define VIC_EINT3 17 /* External interrupt 3 (EINT3) */ +#define VIC_AD0 18 /* A/D converter 0 */ +#define VIC_I2C1 19 /* I2C 1 */ +#define VIC_BOD 20 /* Brown out detect */ +#define VIC_ETHERNET 21 /* Ethernet */ +#define VIC_USB 22 /* USB Low and High priority */ +#define VIC_CAN12 23 /* CAN1,2 Tx, Rx */ +#define VIC_MMC 24 /* SD/MMC */ +#define VIC_GP_DMA 25 /* DMA channel 0, DMA channel 1 */ +#define VIC_TIMER2 26 /* Timer 2 (Match 0-3 Capture 0-3) */ +#define VIC_TIMER3 27 /* Timer 3 (Match 0-3 Capture 0-3) */ +#define VIC_UART2 28 /* UART 2 (RLS, THRE, RDA, CTI) */ +#define VIC_UART3 29 /* UART 3 (RLS, THRE, RDA, CTI, MSI) */ +#define VIC_I2C2 30 /* I2C 0 (SI) */ +#define VIC_I2S 31 /* I2S Rx, Tx */ + +#endif /* __IOLPC2368_H */ diff --git a/OS/uc/cpu/cpu.h b/OS/uc/cpu/cpu.h new file mode 100644 index 0000000..a6ba9bd --- /dev/null +++ b/OS/uc/cpu/cpu.h @@ -0,0 +1,328 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/CPU in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/CPU. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM +* IAR C Compiler +* +* Filename : cpu.h +* Version : V1.17 +* Programmer(s) : ITJ +* JJL +* JDH +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_MODULE_PRESENT +#define CPU_CFG_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_def.h +* +* (b) \\\\cpu*.* +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\' directory & the +* specific CPU-compiler directory as additional include path directories. +********************************************************************************************************* +*/ + +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *pobj +* +* FnctName(pobj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef unsigned char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *); /* See Note #2b. */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size. */ + +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size. */ +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order. */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_DATA CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler allows in-line +* assembly AND will correctly modify the local stack pointer when interrupt status is +* pushed/popped onto the stack. +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (a) Save interrupt status into a local variable +* (b) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (c) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to +* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure +* 'CPU_SR' data type with the appropriate-sized CPU data type large enough to completely +* store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3). */ + + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +#define CPU_CRITICAL_ENTER() { cpu_sr = CPU_SR_Save(); } +#define CPU_CRITICAL_EXIT() { CPU_SR_Restore(cpu_sr); } + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SR CPU_SR_Save (void); +void CPU_SR_Restore(CPU_SR cpu_sr); + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_ADDR_SIZE +#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + +#ifndef CPU_CFG_DATA_SIZE +#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" + +#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \ + (CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32)) +#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]" +#error " [ || CPU_WORD_SIZE_16 16-bit alignment]" +#error " [ || CPU_WORD_SIZE_32 32-bit alignment]" +#endif + + + +#ifndef CPU_CFG_ENDIAN_TYPE +#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" + +#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \ + (CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE)) +#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_ENDIAN_TYPE_BIG ]" +#error " [ || CPU_ENDIAN_TYPE_LITTLE]" +#endif + + + + +#ifndef CPU_CFG_CRITICAL_METHOD +#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" + +#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \ + (CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL)) +#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' " +#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]" +#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]" +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of CPU cfg module inclusion. */ + diff --git a/OS/uc/cpu/cpu_a.s b/OS/uc/cpu/cpu_a.s new file mode 100644 index 0000000..8d97643 --- /dev/null +++ b/OS/uc/cpu/cpu_a.s @@ -0,0 +1,121 @@ +;******************************************************************************************************** +; uC/CPU +; CPU CONFIGURATION & PORT LAYER +; +; (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +; +; All rights reserved. Protected by international copyright laws. +; +; uC/CPU is provided in source form for FREE evaluation, for educational +; use or peaceful research. If you plan on using uC/CPU in a commercial +; product you need to contact Micrium to properly license its use in your +; product. We provide ALL the source code for your convenience and to +; help you experience uC/CPU. The fact that the source code is provided +; does NOT mean that you can use it without paying a licensing fee. +; +; Knowledge of the source code may NOT be used to develop a similar product. +; +; Please help us continue to provide the Embedded community with the finest +; software available. Your honesty is greatly appreciated. +;******************************************************************************************************** + +;******************************************************************************************************** +; +; CPU PORT FILE +; +; ARM +; IAR C Compiler +; +; Filename : cpu_a.s +; Version : V1.17 +; Programmer(s) : JJL +; JDH +; ITJ +;******************************************************************************************************** + + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + + PUBLIC CPU_SR_Save + PUBLIC CPU_SR_Restore + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +CPU_ARM_CTRL_INT_DIS EQU 0xC0 ; Disable both FIQ & IRQ + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + +;$PAGE +;******************************************************************************************************** +; CRITICAL SECTION FUNCTIONS +; +; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the +; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts +; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts). +; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register. +; +; Prototypes : CPU_SR CPU_SR_Save (void); +; void CPU_SR_Restore(CPU_SR cpu_sr); +; +; Note(s) : (1) These functions are used in general like this : +; +; void Task (void *p_arg) +; { +; /* Allocate storage for CPU status register */ +; #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +; CPU_SR cpu_sr; +; #endif +; +; : +; : +; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */ +; : +; : +; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */ +; : +; : +; } +; +; (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note : +; +; "Disabling Interrupts at Processor Level" +;******************************************************************************************************** + +CPU_SR_Save + MRS R0, CPSR + +CPU_SR_Save_Loop + ; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts + ORR R1, R0, #CPU_ARM_CTRL_INT_DIS + MSR CPSR_c, R1 + MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags + AND R1, R1, #CPU_ARM_CTRL_INT_DIS + CMP R1, #CPU_ARM_CTRL_INT_DIS + BNE CPU_SR_Save_Loop ; NOT properly DISABLED (try again) + BX LR ; DISABLED, return the original CPSR contents in R0 + + +CPU_SR_Restore ; See Note #2 + MSR CPSR_c, R0 + BX LR + + +;$PAGE +;******************************************************************************************************** +; CPU ASSEMBLY PORT FILE END +;******************************************************************************************************** + + END + diff --git a/OS/uc/cpu/cpu_def.h b/OS/uc/cpu/cpu_def.h new file mode 100644 index 0000000..8823af0 --- /dev/null +++ b/OS/uc/cpu/cpu_def.h @@ -0,0 +1,133 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/CPU in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/CPU. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION DEFINES +* +* Filename : cpu_def.h +* Version : V1.17 +* Programmer(s) : ITJ +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size See Note #1a +* +* (a) 64-bit word size NOT currently supported. +* +* (b) Ideally, CPU_WORD_SIZE #define's would be calculated at compile-time through use of +* the sizeof() operator. However, some compilers do NOT allow pre-processor directives +* to include run-time macro's -- e.g. 'sizeof()'. +* +* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order : +* +* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* ----------------------- CPU WORD SIZE ---------------------- */ +#define CPU_WORD_SIZE_08 1 /* 8-bit word size = sizeof(CPU_INT08x). */ +#define CPU_WORD_SIZE_16 2 /* 16-bit word size = sizeof(CPU_INT16x). */ +#define CPU_WORD_SIZE_32 4 /* 32-bit word size = sizeof(CPU_INT32x). */ +#define CPU_WORD_SIZE_64 8 /* 64-bit word size = sizeof(CPU_INT64x) [see Note #1a]. */ + + + /* ------------------- CPU WORD-ENDIAN ORDER ------------------ */ +#define CPU_ENDIAN_TYPE_NONE 0 /* */ +#define CPU_ENDIAN_TYPE_BIG 1 /* Big- endian word order (CPU words' most significant ... */ + /* ... octet @ lowest mem addr). */ +#define CPU_ENDIAN_TYPE_LITTLE 2 /* Little-endian word order (CPU words' least significant ... */ + /* ... octet @ lowest mem addr). */ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler allows in-line +* assembly AND will correctly modify the local stack pointer when interrupt status is +* pushed/popped onto the stack. +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (a) Save interrupt status into a local variable +* (b) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (c) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to +* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure +* 'CPU_SR' data type in 'cpu.h' with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* --------------- CPU CRITICAL SECTION METHODS --------------- */ +#define CPU_CRITICAL_METHOD_NONE 0 /* */ +#define CPU_CRITICAL_METHOD_INT_DIS_EN 1 /* DIS/EN ints. */ +#define CPU_CRITICAL_METHOD_STATUS_STK 2 /* Push/Pop int status onto stk. */ +#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3 /* Save/Restore int status to local var. */ + diff --git a/OS/uc/lib/lib_def.h b/OS/uc/lib/lib_def.h new file mode 100644 index 0000000..51c02c6 --- /dev/null +++ b/OS/uc/lib/lib_def.h @@ -0,0 +1,616 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CUSTOM LIBRARY MODULE +* +* Filename : lib_def.h +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_DEF_MODULE_PRESENT +#define LIB_DEF_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CUSTOM LIBRARY MODULE VERSION NUMBER +* +* Note(s) : (1) (a) The custom library module software version is denoted as follows : +* +* Vx.yy +* +* where +* V denotes 'Version' label +* x denotes major software version revision number +* yy denotes minor software version revision number +* +* (b) The software version label #define is formatted as follows : +* +* ver = x.yy * 100 +* +* where +* ver denotes software version number scaled as an integer value +* x.yy denotes software version number +********************************************************************************************************* +*/ + +#define LIB_VERSION 124u /* See Note #1. */ + + +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +********************************************************************************************************* +*/ + +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* STANDARD DEFINES +********************************************************************************************************* +*/ + + +#define DEF_DISABLED 0 +#define DEF_ENABLED 1 + +#define DEF_FALSE 0 +#define DEF_TRUE 1 + +#define DEF_NO 0 +#define DEF_YES 1 + +#define DEF_OFF 0 +#define DEF_ON 1 + +#define DEF_CLR 0 +#define DEF_SET 1 + +#define DEF_ACTIVE 0 +#define DEF_INACTIVE 1 + +#define DEF_FAIL 0 +#define DEF_OK 1 + + + /* -------------------- BIT DEFINES ------------------- */ +#define DEF_BIT_NONE 0x00 + +#define DEF_BIT_00 0x01 +#define DEF_BIT_01 0x02 +#define DEF_BIT_02 0x04 +#define DEF_BIT_03 0x08 +#define DEF_BIT_04 0x10 +#define DEF_BIT_05 0x20 +#define DEF_BIT_06 0x40 +#define DEF_BIT_07 0x80 + +#define DEF_BIT_08 0x0100 +#define DEF_BIT_09 0x0200 +#define DEF_BIT_10 0x0400 +#define DEF_BIT_11 0x0800 +#define DEF_BIT_12 0x1000 +#define DEF_BIT_13 0x2000 +#define DEF_BIT_14 0x4000 +#define DEF_BIT_15 0x8000 + +#define DEF_BIT_16 0x00010000 +#define DEF_BIT_17 0x00020000 +#define DEF_BIT_18 0x00040000 +#define DEF_BIT_19 0x00080000 +#define DEF_BIT_20 0x00100000 +#define DEF_BIT_21 0x00200000 +#define DEF_BIT_22 0x00400000 +#define DEF_BIT_23 0x00800000 + +#define DEF_BIT_24 0x01000000 +#define DEF_BIT_25 0x02000000 +#define DEF_BIT_26 0x04000000 +#define DEF_BIT_27 0x08000000 +#define DEF_BIT_28 0x10000000 +#define DEF_BIT_29 0x20000000 +#define DEF_BIT_30 0x40000000 +#define DEF_BIT_31 0x80000000 + + /* ------------------- OCTET DEFINES ------------------ */ +#define DEF_OCTET_NBR_BITS 8 +#define DEF_OCTET_MASK 0xFF + +#define DEF_NIBBLE_NBR_BITS 4 +#define DEF_NIBBLE_MASK 0x0F + + +/*$PAGE*/ + /* ------------------ INTEGER DEFINES ----------------- */ +#define DEF_INT_08_NBR_BITS 8 +#define DEF_INT_08_MASK 0xFF + +#define DEF_INT_08U_MIN_VAL 0u +#define DEF_INT_08U_MAX_VAL 255u + +#define DEF_INT_08S_MIN_VAL -128 +#define DEF_INT_08S_MAX_VAL 127 + +#define DEF_INT_08S_MIN_VAL_ONES_CPL -127 +#define DEF_INT_08S_MAX_VAL_ONES_CPL 127 + + +#define DEF_INT_16_NBR_BITS 16 +#define DEF_INT_16_MASK 0xFFFF + +#define DEF_INT_16U_MIN_VAL 0u +#define DEF_INT_16U_MAX_VAL 65535u + +#define DEF_INT_16S_MIN_VAL -32768 +#define DEF_INT_16S_MAX_VAL 32767 + +#define DEF_INT_16S_MIN_VAL_ONES_CPL -32767 +#define DEF_INT_16S_MAX_VAL_ONES_CPL 32767 + + +#define DEF_INT_32_NBR_BITS 32 +#define DEF_INT_32_MASK 0xFFFFFFFF + +#define DEF_INT_32U_MIN_VAL 0u +#define DEF_INT_32U_MAX_VAL 4294967295u + +#define DEF_INT_32S_MIN_VAL -2147483648 +#define DEF_INT_32S_MAX_VAL 2147483647 + +#define DEF_INT_32S_MIN_VAL_ONES_CPL -2147483647 +#define DEF_INT_32S_MAX_VAL_ONES_CPL 2147483647 + + +#define DEF_INT_64_NBR_BITS 64 +#define DEF_INT_64_MASK 0xFFFFFFFFFFFFFFFF + +#define DEF_INT_64U_MIN_VAL 0u +#define DEF_INT_64U_MAX_VAL 18446744073709551615u + +#define DEF_INT_64S_MIN_VAL -9223372036854775808 +#define DEF_INT_64S_MAX_VAL 9223372036854775807 + +#define DEF_INT_64S_MIN_VAL_ONES_CPL -9223372036854775807 +#define DEF_INT_64S_MAX_VAL_ONES_CPL 9223372036854775807 + + +/*$PAGE*/ + /* ---------------- CPU INTEGER DEFINES --------------- */ +#define DEF_INT_CPU_NBR_BITS (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) + + +#if (DEF_INT_CPU_NBR_BITS == DEF_INT_08_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_08_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_08U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_08U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_08S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_08S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_08S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_08S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_16_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_16_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_16U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_16U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_16S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_16S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_16S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_16S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_32_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_32_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_32U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_32U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_32S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_32S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_32S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_32S_MAX_VAL_ONES_CPL + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_64_NBR_BITS) + +#define DEF_INT_CPU_MASK DEF_INT_64_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_64U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_64U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_64S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_64S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_64S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_64S_MAX_VAL_ONES_CPL + + +#else + +#error "CPU_CFG_DATA_SIZE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ + /* ------------------- TIME DEFINES ------------------- */ +#define DEF_TIME_NBR_HR_PER_DAY 24uL + +#define DEF_TIME_NBR_MIN_PER_HR 60uL +#define DEF_TIME_NBR_MIN_PER_DAY (DEF_TIME_NBR_MIN_PER_HR * DEF_TIME_NBR_HR_PER_DAY) + +#define DEF_TIME_NBR_SEC_PER_MIN 60uL +#define DEF_TIME_NBR_SEC_PER_HR (DEF_TIME_NBR_SEC_PER_MIN * DEF_TIME_NBR_MIN_PER_HR) +#define DEF_TIME_NBR_SEC_PER_DAY (DEF_TIME_NBR_SEC_PER_HR * DEF_TIME_NBR_HR_PER_DAY) + +#define DEF_TIME_NBR_mS_PER_SEC 1000uL +#define DEF_TIME_NBR_uS_PER_SEC 1000000uL +#define DEF_TIME_NBR_nS_PER_SEC 1000000000uL + + +/*$PAGE*/ +/* +********************************************************************************************************* +* BIT MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_BIT() +* +* Description : Create bit mask with single, specified bit set. +* +* Argument(s) : bit Bit number of bit to set. +* +* Return(s) : Bit mask with single, specified bit set. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT(bit) (1u << (bit)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_MASK() +* +* Description : Shift a bit mask. +* +* Argument(s) : bit_mask Bit mask to shift. +* +* bit_shift Number of bit positions to left-shift bit mask. +* +* Return(s) : Shifted bit mask. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_MASK(bit_mask, bit_shift) ((bit_mask) << (bit_shift)) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD() +* +* Description : Create & shift a contiguous bit field. +* +* Argument(s) : bit_field Number of contiguous bits to set in the bit field. +* +* bit_shift Number of bit positions to left-shift bit field. +* +* Return(s) : Shifted bit field. +* +* Caller(s) : various. +* +* Note(s) : (1) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler environment +* (e.g. negative or greater-than-CPU-data-size values) MAY generate compiler warnings +* &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD(bit_field, bit_shift) ((((bit_field) >= DEF_INT_CPU_NBR_BITS) ? (DEF_INT_CPU_U_MAX_VAL) \ + : (DEF_BIT(bit_field) - 1)) \ + << (bit_shift)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_SET() +* +* Description : Set specified bit(s) in a value. +* +* Argument(s) : val Value to modify by setting specified bit(s). +* +* mask Mask of bits to set. +* +* Return(s) : Modified value with specified bit(s) set. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_SET(val, mask) { (val) |= (mask); } + + +/* +********************************************************************************************************* +* DEF_BIT_CLR() +* +* Description : Clear specified bit(s) in a value. +* +* Argument(s) : val Value to modify by clearing specified bit(s). +* +* mask Mask of bits to clear. +* +* Return(s) : Modified value with specified bit(s) clear. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_CLR(val, mask) { (val) &= ~(mask); } + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_IS_SET() +* +* Description : Determine if specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set. +* +* Return(s) : DEF_YES, if ALL specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET(val, mask) ((((val) & (mask)) == (mask)) ? (DEF_YES) : (DEF_NO )) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR() +* +* Description : Determine if specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear. +* +* Return(s) : DEF_YES, if ALL specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR(val, mask) (((val) & (mask)) ? (DEF_NO ) : (DEF_YES)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_BIT_IS_SET_ANY() +* +* Description : Determine if any specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set. +* +* Return(s) : DEF_YES, if ANY specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET_ANY(val, mask) (((val) & (mask)) ? (DEF_YES) : (DEF_NO )) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR_ANY() +* +* Description : Determine if any specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear. +* +* Return(s) : DEF_YES, if ANY specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR_ANY(val, mask) ((((val) & (mask)) != (mask)) ? (DEF_YES) : (DEF_NO )) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MATH MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_MIN() +* +* Description : Determine the minimum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Minimum of the two values. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MIN(a, b) (((a) < (b)) ? (a) : (b)) + + +/* +********************************************************************************************************* +* DEF_MAX() +* +* Description : Determine the maximum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Maximum of the two values. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEF_ABS() +* +* Description : Determine the absolute value of a value. +* +* Argument(s) : a Value to calculate absolute value. +* +* Return(s) : Absolute value of the value. +* +* Caller(s) : various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_ABS(a) (((a) < 0) ? (-(a)) : (a)) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib def module include. */ + diff --git a/OS/uc/lib/lib_mem.c b/OS/uc/lib/lib_mem.c new file mode 100644 index 0000000..c968758 --- /dev/null +++ b/OS/uc/lib/lib_mem.c @@ -0,0 +1,462 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* STANDARD MEMORY OPERATIONS +* +* Filename : lib_mem.c +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define LIB_MEM_MODULE +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Clr() +* +* Description : Clear data buffer (see Note #2). +* +* Argument(s) : pmem Pointer to memory buffer to clear. +* +* size Number of data buffer octets to clear. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null clears allowed (i.e. 0-octet size). +* +* See also 'Mem_Set() Note #1'. +* +* (2) Clear data by setting each data octet to 0. +********************************************************************************************************* +*/ + +void Mem_Clr (void *pmem, + CPU_SIZE_T size) +{ + Mem_Set((void *)pmem, + (CPU_INT08U)0, /* See Note #2. */ + (CPU_SIZE_T)size); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Set() +* +* Description : Fill data buffer with specified data octet. +* +* Argument(s) : pmem Pointer to memory buffer to fill with specified data octet. +* +* data_val Data fill octet value. +* +* size Number of data buffer octets to fill. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null sets allowed (i.e. 0-octet size). +* +* (2) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +********************************************************************************************************* +*/ + +void Mem_Set (void *pmem, + CPU_INT08U data_val, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN data_align; + CPU_ALIGN *pmem_align; + CPU_INT08U *pmem_08; + CPU_INT08U mem_align_modulo; + CPU_INT08U i; + + + if (size < 1) { /* See Note #1. */ + return; + } + if (pmem == (void *)0) { + return; + } + + + data_align = 0; + for (i = 0; i < sizeof(CPU_ALIGN); i++) { /* Fill each data_align octet with data val. */ + data_align <<= DEF_OCTET_NBR_BITS; + data_align |= (CPU_ALIGN)data_val; + } + + size_rem = (CPU_SIZE_T)size; + mem_align_modulo = (CPU_INT08U)((CPU_ADDR)pmem % sizeof(CPU_ALIGN)); /* See Note #3. */ + + pmem_08 = (CPU_INT08U *)pmem; + if (mem_align_modulo != 0) { /* If leading octets avail, ... */ + i = mem_align_modulo; + while ((size_rem > 0) && /* ... start mem buf fill with leading octets ... */ + (i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */ + *pmem_08++ = data_val; + size_rem -= sizeof(CPU_INT08U); + i++; + } + } + + pmem_align = (CPU_ALIGN *)pmem_08; /* See Note #2a. */ + while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem buf aligned on CPU_ALIGN word boundaries, */ + *pmem_align++ = data_align; /* ... fill mem buf with CPU_ALIGN-sized data. */ + size_rem -= sizeof(CPU_ALIGN); + } + + pmem_08 = (CPU_INT08U *)pmem_align; + while (size_rem > 0) { /* Finish mem buf fill with trailing octets. */ + *pmem_08++ = data_val; + size_rem -= sizeof(CPU_INT08U); + } +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Copy() +* +* Description : Copy data octets from one buffer to another buffer. +* +* Argument(s) : pdest Pointer to destination memory buffer. +* +* psrc Pointer to source memory buffer. +* +* size Number of data buffer octets to copy. +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Null copies allowed (i.e. 0-octet size). +* +* (2) Memory buffers NOT checked for overlapping. +* +* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if ((!defined(uC_CFG_OPTIMIZE_ASM_EN)) || \ + ((defined(uC_CFG_OPTIMIZE_ASM_EN)) && \ + (uC_CFG_OPTIMIZE_ASM_EN != DEF_ENABLED))) +void Mem_Copy (void *pdest, + void *psrc, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN *pmem_align_dest; + CPU_ALIGN *pmem_align_src; + CPU_INT08U *pmem_08_dest; + CPU_INT08U *pmem_08_src; + CPU_INT08U i; + CPU_INT08U mem_align_modulo_dest; + CPU_INT08U mem_align_modulo_src; + CPU_BOOLEAN mem_aligned; + + + if (size < 1) { /* See Note #1. */ + return; + } + if (pdest == (void *)0) { + return; + } + if (psrc == (void *)0) { + return; + } + + + size_rem = (CPU_SIZE_T )size; + + pmem_08_dest = (CPU_INT08U *)pdest; + pmem_08_src = (CPU_INT08U *)psrc; + /* See Note #4. */ + mem_align_modulo_dest = (CPU_INT08U )((CPU_ADDR)pmem_08_dest % sizeof(CPU_ALIGN)); + mem_align_modulo_src = (CPU_INT08U )((CPU_ADDR)pmem_08_src % sizeof(CPU_ALIGN)); + + mem_aligned = (mem_align_modulo_dest == mem_align_modulo_src) ? DEF_YES : DEF_NO; + + if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */ + /* ... optimize copy for mem buf alignment. */ + if (mem_align_modulo_dest != 0) { /* If leading octets avail, ... */ + i = mem_align_modulo_dest; + while ((size_rem > 0) && /* ... start mem buf copy with leading octets ... */ + (i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */ + *pmem_08_dest++ = *pmem_08_src++; + size_rem -= sizeof(CPU_INT08U); + i++; + } + } + + pmem_align_dest = (CPU_ALIGN *)pmem_08_dest; /* See Note #3a. */ + pmem_align_src = (CPU_ALIGN *)pmem_08_src; + while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem bufs aligned on CPU_ALIGN word boundaries, */ + *pmem_align_dest++ = *pmem_align_src++; /* ... copy psrc to pdest with CPU_ALIGN-sized words. */ + size_rem -= sizeof(CPU_ALIGN); + } + + pmem_08_dest = (CPU_INT08U *)pmem_align_dest; + pmem_08_src = (CPU_INT08U *)pmem_align_src; + } + + while (size_rem > 0) { /* For unaligned mem bufs or trailing octets, ... */ + *pmem_08_dest++ = *pmem_08_src++; /* ... copy psrc to pdest by octets. */ + size_rem -= sizeof(CPU_INT08U); + } +} +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Mem_Cmp() +* +* Description : Verify that ALL data octets in two memory buffers are identical in sequence. +* +* Argument(s) : p1_mem Pointer to first memory buffer. +* +* p2_mem Pointer to second memory buffer. +* +* size Number of data buffer octets to compare. +* +* Return(s) : DEF_YES, if 'size' number of data octets are identical in both memory buffers. +* +* DEF_NO, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Null compares allowed (i.e. 0-octet size); 'DEF_YES' returned to indicate identical +* null compare. +* +* (2) Many memory buffer comparisons vary ONLY in the least significant octets -- e.g. +* network address buffers. Consequently, memory buffer comparison is more efficient +* if the comparison starts from the end of the memory buffers which will abort sooner +* on dissimilar memory buffers that vary only in the least significant octets. +* +* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words. +* +* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on +* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses. +* +* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN' +* address boundary. +* +* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus, +* address values MUST be cast to an appropriately-sized integer value PRIOR to any +* mem_align_modulo arithmetic operation. +******************************************************************************************************** +*/ +/*$PAGE*/ +CPU_BOOLEAN Mem_Cmp (void *p1_mem, + void *p2_mem, + CPU_SIZE_T size) +{ + CPU_SIZE_T size_rem; + CPU_ALIGN *p1_mem_align; + CPU_ALIGN *p2_mem_align; + CPU_INT08U *p1_mem_08; + CPU_INT08U *p2_mem_08; + CPU_INT08U i; + CPU_INT08U mem_align_modulo_1; + CPU_INT08U mem_align_modulo_2; + CPU_BOOLEAN mem_aligned; + CPU_BOOLEAN mem_cmp; + + + if (size < 1) { /* See Note #1. */ + return (DEF_YES); + } + if (p1_mem == (void *)0) { + return (DEF_NO); + } + if (p2_mem == (void *)0) { + return (DEF_NO); + } + + + mem_cmp = DEF_YES; + size_rem = size; + /* Start @ end of mem bufs (see Note #2). */ + p1_mem_08 = (CPU_INT08U *)p1_mem + size; + p2_mem_08 = (CPU_INT08U *)p2_mem + size; + /* See Note #4. */ + mem_align_modulo_1 = (CPU_INT08U )((CPU_ADDR)p1_mem_08 % sizeof(CPU_ALIGN)); + mem_align_modulo_2 = (CPU_INT08U )((CPU_ADDR)p2_mem_08 % sizeof(CPU_ALIGN)); + + mem_aligned = (mem_align_modulo_1 == mem_align_modulo_2) ? DEF_YES : DEF_NO; + + if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */ + /* ... optimize cmp for mem buf alignment. */ + if (mem_align_modulo_1 != 0) { /* If trailing octets avail, ... */ + i = mem_align_modulo_1; + while ((mem_cmp == DEF_YES) && /* ... cmp mem bufs while identical & ... */ + (size_rem > 0) && /* ... start mem buf cmp with trailing octets ... */ + (i > 0)) { /* ... until next CPU_ALIGN word boundary. */ + p1_mem_08--; + p2_mem_08--; + if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_INT08U); + i--; + } + } + + if (mem_cmp == DEF_YES) { /* If cmp still identical, cmp aligned mem bufs. */ + p1_mem_align = (CPU_ALIGN *)p1_mem_08; /* See Note #3a. */ + p2_mem_align = (CPU_ALIGN *)p2_mem_08; + + while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical & ... */ + (size_rem >= sizeof(CPU_ALIGN))) { /* ... mem bufs aligned on CPU_ALIGN word boundaries. */ + p1_mem_align--; + p2_mem_align--; + if (*p1_mem_align != *p2_mem_align) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_ALIGN); + } + + p1_mem_08 = (CPU_INT08U *)p1_mem_align; + p2_mem_08 = (CPU_INT08U *)p2_mem_align; + } + } + + while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical ... */ + (size_rem > 0)) { /* ... for unaligned mem bufs or trailing octets. */ + p1_mem_08--; + p2_mem_08--; + if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */ + mem_cmp = DEF_NO; + } + size_rem -= sizeof(CPU_INT08U); + } + + return (mem_cmp); +} + diff --git a/OS/uc/lib/lib_mem.h b/OS/uc/lib/lib_mem.h new file mode 100644 index 0000000..b775e75 --- /dev/null +++ b/OS/uc/lib/lib_mem.h @@ -0,0 +1,615 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* STANDARD MEMORY OPERATIONS +* +* Filename : lib_mem.h +* Version : V1.24 +* Programmer(s) : ITJ +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_MEM_MODULE_PRESENT +#define LIB_MEM_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +* +* (3) NO compiler-supplied standard library functions SHOULD be used. +********************************************************************************************************* +*/ + +#include +#include +#include + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef LIB_MEM_MODULE +#define LIB_MEM_EXT +#else +#define LIB_MEM_EXT extern +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MEMORY DATA VALUE MACRO'S +* +* Note(s) : (1) (a) Some variables & variable buffers to pass & receive data values MUST start on appropriate +* CPU word-aligned addresses. This is required because most word-aligned processors are more +* efficient & may even REQUIRE that multi-octet words start on CPU word-aligned addresses. +* +* (1) For 16-bit word-aligned processors, this means that +* +* all 16- & 32-bit words MUST start on addresses that are multiples of 2 octets +* +* (2) For 32-bit word-aligned processors, this means that +* +* all 16-bit words MUST start on addresses that are multiples of 2 octets +* all 32-bit words MUST start on addresses that are multiples of 4 octets +* +* (b) However, some data values macro's appropriately access data values from any CPU addresses, +* word-aligned or not. Thus for processors that require data word alignment, data words can +* be accessed to/from any CPU address, word-aligned or not, without generating data-word- +* alignment exceptions/faults. +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_GET_xxx() +* +* Description : Decode data values from any CPU memory address. +* +* Argument(s) : addr Lowest CPU memory address of data value to decode (see Notes #2 & #3a). +* +* Return(s) : Decoded data value from CPU memory address (see Notes #1 & #3b). +* +* Caller(s) : various. +* +* Note(s) : (1) Decode data values based on the values' data-word order in CPU memory : +* +* MEM_VAL_GET_xxx_BIG() Decode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_GET_xxx_LITTLE() Decode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_GET_xxx() Decode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) (a) MEM_VAL_GET_xxx() macro's decode data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be decoded from any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +* +* (b) However, any variable to receive the returned data value MUST start on an appropriate CPU +* word-aligned address. +* +* See also 'MEMORY DATA VALUE MACRO'S Note #1'. +* +* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_COPY_GET_xxx() Note #4'. +* +* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ + +#define MEM_VAL_GET_INT08U_BIG(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + +#define MEM_VAL_GET_INT16U_BIG(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (0 * DEF_OCTET_NBR_BITS))) + +#define MEM_VAL_GET_INT32U_BIG(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (3 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (2 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (0 * DEF_OCTET_NBR_BITS))) + + + +#define MEM_VAL_GET_INT08U_LITTLE(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + +#define MEM_VAL_GET_INT16U_LITTLE(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS))) + +#define MEM_VAL_GET_INT32U_LITTLE(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (2 * DEF_OCTET_NBR_BITS)) + \ + (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (3 * DEF_OCTET_NBR_BITS))) + + + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + +#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_BIG(addr) +#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_BIG(addr) +#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_BIG(addr) + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + +#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_LITTLE(addr) +#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_LITTLE(addr) +#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_LITTLE(addr) + +#else /* See Note #5. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_SET_xxx() +* +* Description : Encode data values to any CPU memory address. +* +* Argument(s) : addr Lowest CPU memory address to encode data value (see Notes #2 & #3a). +* +* val Data value to encode (see Notes #1 & #3b). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Encode data values into CPU memory based on the values' data-word order : +* +* MEM_VAL_SET_xxx_BIG() Encode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_SET_xxx_LITTLE() Encode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_SET_xxx() Encode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) (a) MEM_VAL_SET_xxx() macro's encode data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be encoded to any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +* +* (b) However, 'val' data value to encode MUST start on an appropriate CPU word-aligned address. +* +* See also 'MEMORY DATA VALUE MACRO'S Note #1'. +* +* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_COPY_SET_xxx() Note #4'. +* +* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ + +#define MEM_VAL_SET_INT08U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT16U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT32U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); } + + + +#define MEM_VAL_SET_INT08U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT16U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); } + +#define MEM_VAL_SET_INT32U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \ + (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); } + + + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + +#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_BIG(addr, val) +#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_BIG(addr, val) +#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_BIG(addr, val) + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + +#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_LITTLE(addr, val) +#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_LITTLE(addr, val) +#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_LITTLE(addr, val) + +#else /* See Note #5. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_GET_xxx() +* +* Description : Copy & decode data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy/decode source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy/decode +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Copy/decode data values based on the values' data-word order : +* +* MEM_VAL_COPY_GET_xxx_BIG() Decode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_COPY_GET_xxx_LITTLE() Decode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_COPY_GET_xxx() Decode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_GET_xxx() macro's copy/decode data values without regard to CPU word-aligned +* addresses. Thus for processors that require data word alignment, data words can be copied/ +* decoded to/from any CPU address, word-aligned or not, without generating data-word-alignment +* exceptions/faults. +* +* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_GET_xxx() Note #4'. +* +* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets are +* inverse operations. +* +* See also 'MEM_VAL_COPY_SET_xxx() Note #5'. +* +* (6) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/ +* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration +* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order +* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is +* included as an extra precaution in case 'cpu.h' is incorrectly configured. +********************************************************************************************************* +*/ +/*$PAGE*/ + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) + + +#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + + +#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + + + +#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) + + + + +#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE) + + +#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + + + +#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + + +#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) + + + + +#else /* See Note #6. */ + +#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_SET_xxx() +* +* Description : Copy & encode data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy/encode source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy/encode +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) Copy/encode data values based on the values' data-word order : +* +* MEM_VAL_COPY_SET_xxx_BIG() Encode big- endian data values -- data words' most +* significant octet @ lowest memory address +* MEM_VAL_COPY_SET_xxx_LITTLE() Encode little-endian data values -- data words' least +* significant octet @ lowest memory address +* MEM_VAL_COPY_SET_xxx() Encode data values using CPU's native or configured +* data-word order +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_SET_xxx() macro's copy/encode data values without regard to CPU word-aligned +* addresses. Thus for processors that require data word alignment, data words can be copied/ +* encoded to/from any CPU address, word-aligned or not, without generating data-word-alignment +* exceptions/faults. +* +* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are +* also independent of CPU data-word-alignment & SHOULD be used whenever possible. +* +* See also 'MEM_VAL_SET_xxx() Note #4'. +* +* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets +* are inverse operations. +* +* See also 'MEM_VAL_COPY_GET_xxx() Note #5'. +********************************************************************************************************* +*/ + + /* See Note #5. */ +#define MEM_VAL_COPY_SET_INT08U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) + +#define MEM_VAL_COPY_SET_INT08U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) + + +#define MEM_VAL_COPY_SET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) +#define MEM_VAL_COPY_SET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MEM_VAL_COPY_xxx() +* +* Description : Copy data values from any CPU memory address to any CPU memory address. +* +* Argument(s) : addr_dest Lowest CPU memory address to copy source address's data value +* (see Notes #2 & #3). +* +* addr_src Lowest CPU memory address of data value to copy +* (see Notes #2 & #3). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) MEM_VAL_COPY_xxx() macro's copy data values based on CPU's native data-word order. +* +* See also 'cpu.h CPU WORD CONFIGURATION Note #2'. +* +* (2) CPU memory addresses/pointers NOT checked for NULL. +* +* (3) MEM_VAL_COPY_xxx() macro's copy data values without regard to CPU word-aligned addresses. +* Thus for processors that require data word alignment, data words can be copied to/from any +* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults. +********************************************************************************************************* +*/ + +#define MEM_VAL_COPY_08(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } + +#define MEM_VAL_COPY_16(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } + +#define MEM_VAL_COPY_32(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \ + (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \ + (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \ + (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } + + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +void Mem_Clr (void *pmem, + CPU_SIZE_T size); + +void Mem_Set (void *pmem, + CPU_INT08U data_val, + CPU_SIZE_T size); + +void Mem_Copy(void *pdest, + void *psrc, + CPU_SIZE_T size); + +CPU_BOOLEAN Mem_Cmp (void *p1_mem, + void *p2_mem, + CPU_SIZE_T size); + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib mem module include. */ + diff --git a/OS/uc/lib/lib_str.c b/OS/uc/lib/lib_str.c new file mode 100644 index 0000000..f0b4463 --- /dev/null +++ b/OS/uc/lib/lib_str.c @@ -0,0 +1,1248 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* ASCII STRING MANAGEMENT +* +* Filename : lib_str.c +* Version : V1.24 +* Programmer(s) : ITJ +* JDH +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* INCLUDE FILES +********************************************************************************************************* +*/ + +#define LIB_STR_MODULE +#include + + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL DEFINES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL TABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LOCAL CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Len() +* +* Description : Calculate length of a string. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* Return(s) : Length of string; number of characters in string before terminating NULL character. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String length calculation terminates when : +* +* (a) String pointer points to NULL. +* (1) String buffer overlaps with NULL address. +* (2) String length calculated for string up to but NOT beyond or including +* the NULL address. +* +* (b) Terminating NULL character found. +* (1) String length calculated for string up to but NOT including +* the NULL character. +********************************************************************************************************* +*/ + +CPU_SIZE_T Str_Len (CPU_CHAR *pstr) +{ + CPU_SIZE_T len; + + + len = 0; + while (( pstr != (CPU_CHAR *)0) && /* Calc str len until NULL ptr (see Note #2a) ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2b). */ + len++; + pstr++; + } + + return (len); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Copy() +* +* Description : Copy source string to destination string buffer. +* +* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1). +* +* psrc Pointer to source string to copy into destination string buffer. +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire source +* string size including the terminating NULL character. +* +* (2) String copy terminates when : +* +* (a) Destination/Source string pointer(s) are passed NULL pointers. +* (1) No string copy performed; NULL pointer returned. +* +* (b) Destination/Source string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Source string copied into destination string buffer up to but NOT beyond or +* including the NULL address; destination string buffer properly terminated +* with NULL character. +* +* (c) Source string's terminating NULL character found. +* (1) Entire source string copied into destination string buffer. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Copy (CPU_CHAR *pdest, + CPU_CHAR *psrc) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrc == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */ + ( psrc != (CPU_CHAR *)0) && + (*psrc != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2c). */ + *pstr = *psrc; + pstr++; + pstr_next++; + psrc++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Copy_N() +* +* Description : Copy source string to destination string buffer, up to a maximum number of characters. +* +* Argument(s) : pdest Pointer to destination string buffer to receive source string copy (see Note #1). +* +* psrc Pointer to source string to copy into destination string buffer. +* +* len_max Maximum number of characters to copy (see Note #2d). +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire source +* string size including the terminating NULL character. +* +* (2) String copy terminates when : +* +* (a) Destination/Source string pointer(s) are passed NULL pointers. +* (1) No string copy performed; NULL pointer returned. +* +* (b) Destination/Source string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Source string copied into destination string buffer up to but NOT beyond or +* including the NULL address; destination string buffer properly terminated +* with NULL character. +* +* (c) Source string's terminating NULL character found. +* (1) Entire source string copied into destination string buffer. +* +* (d) 'len_max' number of characters copied. +* (1) 'len_max' number of characters does NOT include the terminating NULL character. +* +* See also Note #1a. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest, + CPU_CHAR *psrc, + CPU_SIZE_T len_max) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + CPU_SIZE_T len_copy; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrc == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if copy len equals zero (see Note #2d). */ + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + pstr_next = pstr; + pstr_next++; + len_copy = 0; + + while (( pstr_next != (CPU_CHAR *)0) && /* Copy str until NULL ptr(s) (see Note #2b) ... */ + ( psrc != (CPU_CHAR *)0) && + (*psrc != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2c); ... */ + ( len_copy < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars copied (see Note #2d). */ + *pstr = *psrc; + pstr++; + pstr_next++; + psrc++; + len_copy++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2b2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cat() +* +* Description : Append concatenation string to destination string. +* +* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1). +* +* pstr_cat Pointer to concatenation string to append to destination string. +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated +* string size including the terminating NULL character. +* +* (2) String concatenation terminates when : +* +* (a) Destination/Concatenation string pointer(s) are passed NULL pointers. +* (1) No string concatenation performed; NULL pointer returned. +* +* (b) Destination string overlaps with NULL address. +* (1) No string concatenation performed; NULL pointer returned. +* +* (c) Destination/Concatenation string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Concatenation string appended into destination string buffer up to but NOT +* beyond or including the NULL address; destination string buffer properly +* terminated with NULL character. +* +* (d) Concatenation string's terminating NULL character found. +* (1) Entire concatenation string appended to destination string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Cat (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (pstr_cat == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */ + pstr++; + } + if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */ + ( pstr_cat != (CPU_CHAR *)0) && + (*pstr_cat != (CPU_CHAR )0)) { /* ... or NULL char found (see Note #2d). */ + *pstr = *pstr_cat; + pstr++; + pstr_next++; + pstr_cat++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cat_N() +* +* Description : Append concatenation string to destination string, up to a maximum number of characters. +* +* Argument(s) : pdest Pointer to destination string to append concatenation string (see Note #1). +* +* pstr_cat Pointer to concatenation string to append to destination string. +* +* len_max Maximum number of characters to concatenate (see Note #2e). +* +* Return(s) : Pointer to destination string, if NO errors (see Note #2). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) Destination string buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (a) Destination buffer size MUST be large enough to accommodate the entire concatenated +* string size including the terminating NULL character. +* +* (2) String concatenation terminates when : +* +* (a) Destination/Concatenation string pointer(s) are passed NULL pointers. +* (1) No string concatenation performed; NULL pointer returned. +* +* (b) Destination string overlaps with NULL address. +* (1) No string concatenation performed; NULL pointer returned. +* +* (c) Destination/Concatenation string pointer(s) points to NULL. +* (1) String buffer(s) overlap with NULL address. +* (2) Concatenation string appended into destination string buffer up to but NOT +* beyond or including the NULL address; destination string buffer properly +* terminated with NULL character. +* +* (d) Concatenation string's terminating NULL character found. +* (1) Entire concatenation string appended to destination string. +* +* (e) 'len_max' number of characters concatenated. +* (1) 'len_max' number of characters does NOT include the terminating NULL character. +* +* See also Note #1a. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat, + CPU_SIZE_T len_max) +{ + CPU_CHAR *pstr; + CPU_CHAR *pstr_next; + CPU_SIZE_T len_cat; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pdest == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (pstr_cat == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if cat len equals zero (see Note #2e). */ + return ((CPU_CHAR *)0); + } + + + pstr = pdest; + while (( pstr != (CPU_CHAR *)0) && /* Adv to end of cur dest str until NULL ptr ... */ + (*pstr != (CPU_CHAR )0)) { /* ... or NULL char found.. */ + pstr++; + } + if (pstr == (CPU_CHAR *)0) { /* If NULL str overrun, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + + pstr_next = pstr; + pstr_next++; + len_cat = 0; + + while (( pstr_next != (CPU_CHAR *)0) && /* Cat str until NULL ptr(s) (see Note #2c) ... */ + ( pstr_cat != (CPU_CHAR *)0) && + (*pstr_cat != (CPU_CHAR )0) && /* ... or NULL char found (see Note #2d); ... */ + ( len_cat < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars cat'd (see Note #2d). */ + *pstr = *pstr_cat; + pstr++; + pstr_next++; + pstr_cat++; + len_cat++; + } + + *pstr = (CPU_CHAR)0; /* Append NULL char (see Note #2c2). */ + + + return (pdest); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cmp() +* +* Description : Determine if two strings are identical. +* +* Argument(s) : p1_str Pointer to first string (see Note #1). +* +* p2_str Pointer to second string (see Note #1). +* +* Return(s) : 0, if strings are identical (see Notes #2a, #2e, & #2f). +* +* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d). +* +* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d). +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String comparison terminates when : +* +* (a) BOTH string pointer(s) are passed NULL pointers. +* (1) NULL strings identical; return 0. +* +* (b) 'p1_str' passed a NULL pointer. +* (1) Return negative value of character pointed to by 'p2_str'. +* +* (c) 'p2_str' passed a NULL pointer. +* (1) Return positive value of character pointed to by 'p1_str'. +* +* (d) Non-matching characters found. +* (1) Return signed-integer difference of the character pointed to by 'p2_str' +* from the character pointed to by 'p1_str'. +* +* (e) Terminating NULL character found in both strings. +* (1) Strings identical; return 0. +* (2) Only one NULL character test required in conditional since previous condition +* tested character equality. +* +* (f) BOTH strings point to NULL. +* (1) Strings overlap with NULL address. +* (2) Strings identical up to but NOT beyond or including the NULL address; return 0. +* +* (g) 'p1_str_next' points to NULL. +* (1) 'p1_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return negative value of character pointed to by 'p2_str_next'. +* +* (h) 'p2_str_next' points to NULL. +* (1) 'p2_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return positive value of character pointed to by 'p1_str_next'. +* +* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison +* return value, 'CPU_CHAR' native data type size MUST be 8-bit. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_INT16S Str_Cmp (CPU_CHAR *p1_str, + CPU_CHAR *p2_str) +{ + CPU_CHAR *p1_str_next; + CPU_CHAR *p2_str_next; + CPU_INT16S cmp_val; + + + if (p1_str == (CPU_CHAR *)0) { + if (p2_str == (CPU_CHAR *)0) { + return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */ + } + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str); + return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */ + } + if (p2_str == (CPU_CHAR *)0) { + cmp_val = (CPU_INT16S)(*p1_str); + return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */ + } + + + p1_str_next = p1_str; + p2_str_next = p2_str; + p1_str_next++; + p2_str_next++; + while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */ + (*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */ + ( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h). */ + ( p2_str_next != (CPU_CHAR *)0)) { + p1_str_next++; + p2_str_next++; + p1_str++; + p2_str++; + } + + + if (*p1_str != *p2_str) { /* If strs NOT identical, ... */ + cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */ + + } else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */ + cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */ + + } else { + if (p1_str_next == (CPU_CHAR *)0) { + if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */ + cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */ + } else { /* If p1_str_next NULL, ... */ + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */ + } + } else { /* If p2_str_next NULL, ... */ + cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */ + } + } + + + return (cmp_val); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Cmp_N() +* +* Description : Determine if two strings are identical for up to a maximum number of characters. +* +* Argument(s) : p1_str Pointer to first string (see Note #1). +* +* p2_str Pointer to second string (see Note #1). +* +* len_max Maximum number of characters to compare (see Notes #2i & #2j). +* +* Return(s) : 0, if strings are identical (see Notes #2a, #2e, #2f, #2i, & #2j). +* +* Negative value, if 'p1_str' is less than 'p2_str' (see Notes #2b, #2g, & #2d). +* +* Positive value, if 'p1_str' is greater than 'p2_str' (see Notes #2c, #2h, & #2d). +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String comparison terminates when : +* +* (a) BOTH string pointer(s) are passed NULL pointers. +* (1) NULL strings identical; return 0. +* +* (b) 'p1_str' passed a NULL pointer. +* (1) Return negative value of character pointed to by 'p2_str'. +* +* (c) 'p2_str' passed a NULL pointer. +* (1) Return positive value of character pointed to by 'p1_str'. +* +* (d) Non-matching characters found. +* (1) Return signed-integer difference of the character pointed to by 'p2_str' +* from the character pointed to by 'p1_str'. +* +* (e) Terminating NULL character found in both strings. +* (1) Strings identical; return 0. +* (2) Only one NULL character test required in conditional since previous condition +* tested character equality. +* +* (f) BOTH strings point to NULL. +* (1) Strings overlap with NULL address. +* (2) Strings identical up to but NOT beyond or including the NULL address; return 0. +* +* (g) 'p1_str_next' points to NULL. +* (1) 'p1_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return negative value of character pointed to by 'p2_str_next'. +* +* (h) 'p2_str_next' points to NULL. +* (1) 'p2_str' overlaps with NULL address. +* (2) Strings compared up to but NOT beyond or including the NULL address. +* (3) Return positive value of character pointed to by 'p1_str_next'. +* +* (i) 'len_max' passed a zero length. +* (1) Zero-length strings identical; return 0. +* +* (j) First 'len_max' number of characters identical. +* (1) Strings identical; return 0. +* +* (3) Since 16-bit signed arithmetic is performed to calculate a non-identical comparison +* return value, 'CPU_CHAR' native data type size MUST be 8-bit. +********************************************************************************************************* +*/ +/*$PAGE*/ +CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str, + CPU_CHAR *p2_str, + CPU_SIZE_T len_max) +{ + CPU_CHAR *p1_str_next; + CPU_CHAR *p2_str_next; + CPU_INT16S cmp_val; + CPU_SIZE_T cmp_len; + + + if (len_max == 0) { /* If cmp len equals zero, rtn 0 (see Note #2i). */ + return ((CPU_INT16S)0); + } + + if (p1_str == (CPU_CHAR *)0) { + if (p2_str == (CPU_CHAR *)0) { + return ((CPU_INT16S)0); /* If BOTH str ptrs NULL, rtn 0 (see Note #2a). */ + } + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str); + return (cmp_val); /* If p1_str NULL, rtn neg p2_str val (see Note #2b). */ + } + if (p2_str == (CPU_CHAR *)0) { + cmp_val = (CPU_INT16S)(*p1_str); + return (cmp_val); /* If p2_str NULL, rtn pos p1_str val (see Note #2c). */ + } + + + p1_str_next = p1_str; + p2_str_next = p2_str; + p1_str_next++; + p2_str_next++; + cmp_len = 0; + while ((*p1_str == *p2_str) && /* Cmp strs until non-matching char (see Note #2d) .. */ + (*p1_str != (CPU_CHAR )0) && /* .. or NULL char(s) (see Note #2e) .. */ + ( p1_str_next != (CPU_CHAR *)0) && /* .. or NULL ptr(s) found (see Notes #2f, #2g, & #2h); */ + ( p2_str_next != (CPU_CHAR *)0) && + ( cmp_len < (CPU_SIZE_T)len_max)) { /* .. or len nbr chars cmp'd (see Note #2j). */ + p1_str_next++; + p2_str_next++; + p1_str++; + p2_str++; + cmp_len++; + } + + + if (cmp_len == len_max) { /* If strs identical for len nbr of chars, */ + return ((CPU_INT16S)0); /* ... rtn 0 (see Note #2j). */ + } + + if (*p1_str != *p2_str) { /* If strs NOT identical, ... */ + cmp_val = (CPU_INT16S)(*p1_str) - (CPU_INT16S)(*p2_str); /* ... calc & rtn char diff (see Note #2d1). */ + + } else if (*p1_str == (CPU_CHAR)0) { /* If NULL char(s) found, ... */ + cmp_val = 0; /* ... strs identical; rtn 0 (see Note #2e). */ + + } else { + if (p1_str_next == (CPU_CHAR *)0) { + if (p2_str_next == (CPU_CHAR *)0) { /* If BOTH next str ptrs NULL, ... */ + cmp_val = (CPU_INT16S)0; /* ... rtn 0 (see Note #2f). */ + } else { /* If p1_str_next NULL, ... */ + cmp_val = (CPU_INT16S)0 - (CPU_INT16S)(*p2_str_next); /* ... rtn neg p2_str_next val (see Note #2g). */ + } + } else { /* If p2_str_next NULL, ... */ + cmp_val = (CPU_INT16S)(*p1_str_next); /* ... rtn pos p1_str_next val (see Note #2h). */ + } + } + + + return (cmp_val); +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char() +* +* Description : Search string for first occurrence of specific character. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* srch_char Search character. +* +* Return(s) : Pointer to first occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* +* (c) String's terminating NULL character found. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char (CPU_CHAR *pstr, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + pstr_next++; + while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */ + (*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */ + (*pstr != (CPU_CHAR )srch_char)) { /* ... or srch char found (see Note #2d). */ + pstr++; + pstr_next++; + } + + + if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char_N() +* +* Description : Search string for first occurrence of specific character, up to a maximum number of characters. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* len_max Maximum number of characters to search (see Notes #2e & #3). +* +* srch_char Search character. +* +* Return(s) : Pointer to first occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* +* (c) String's terminating NULL character found. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +* +* (e) 'len_max' number of characters searched. +* (1) 'len_max' number of characters does NOT include terminating NULL character. +* +* (3) Ideally, the 'len_max' parameter would be the last parameter in this function's +* paramter list for consistency with all other custom string library functions. +* However, the 'len_max' parameter is ordered to comply with the standard library +* function's parameter list. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char_N (CPU_CHAR *pstr, + CPU_SIZE_T len_max, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + CPU_SIZE_T len_srch; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + if (len_max == (CPU_SIZE_T)0) { /* Rtn NULL if srch len equals zero (see Note #2e). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + pstr_next++; + len_srch = 0; + while (( pstr_next != (CPU_CHAR *)0) && /* Srch str until NULL ptr(s) (see Note #2b) ... */ + (*pstr != (CPU_CHAR )0) && /* ... or NULL char (see Note #2c) ... */ + (*pstr != (CPU_CHAR )srch_char) && /* ... or srch char found (see Note #2d); ... */ + ( len_srch < (CPU_SIZE_T)len_max)) { /* ... or max nbr chars srch'd (see Note #2e). */ + pstr++; + pstr_next++; + len_srch++; + } + + + if (*pstr != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Char_Last() +* +* Description : Search string for last occurrence of specific character. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* srch_char Search character. +* +* Return(s) : Pointer to last occurrence of search character in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffer NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) String pointer points to NULL. +* (1) String overlaps with NULL address. +* (2) String searched up to but NOT beyond or including the NULL address. +* (3) NULL address boundary handled in Str_Len(). +* +* (c) String searched from end to beginning. +* (1) Search character NOT found in search string; NULL pointer returned. +* (2) Applicable ONLY IF search character is NOT the terminating NULL character. +* +* (d) Search character found. +* (1) Return pointer to first occurrence of search character in search string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Char_Last (CPU_CHAR *pstr, + CPU_CHAR srch_char) +{ + CPU_CHAR *pstr_next; + CPU_SIZE_T str_len; + + + if (pstr == (CPU_CHAR *)0) { /* Rtn NULL if srch str ptr NULL (see Note #2a). */ + return ((CPU_CHAR *)0); + } + + + pstr_next = pstr; + str_len = Str_Len(pstr); + pstr_next += str_len; + while (( pstr_next != pstr) && /* Srch str from end until beg (see Note #2c) ... */ + (*pstr_next != srch_char)) { /* ... until srch char found (see Note #2d). */ + pstr_next--; + } + + + if (*pstr_next != srch_char) { /* If srch char NOT found, str points to NULL; ... */ + return ((CPU_CHAR *)0); /* ... rtn NULL (see Notes #2b & #2c). */ + } + + return (pstr_next); /* Else rtn ptr to found srch char (see Note #2d). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_Str() +* +* Description : Search string for first occurence of a specific search string. +* +* Argument(s) : pstr Pointer to string (see Note #1). +* +* psrch_str Pointer to search string (see Note #1). +* +* Return(s) : Pointer to first occurrence of search string in string, if any. +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) String buffers NOT modified. +* +* (2) String search terminates when : +* +* (a) String pointer passed a NULL pointer. +* (1) No string search performed; NULL pointer returned. +* +* (b) Search string length greater than string length. +* (1) No string search performed; NULL pointer returned. +* +* (c) Search string length equal to zero. +* (1) NULL search string at end of string returned. +* +* (d) Entire string has been searched. +* (1) Maximum size of the search is defined as the subtraction of the +* search string length from the string length. +* (2) Search string not found; NULL pointer returned. +* +* (e) Search string found. +* (1) Search string found according to Str_Cmp_N() return value. +* (2) Return pointer to first occurrence of search string in string. +********************************************************************************************************* +*/ + +CPU_CHAR *Str_Str (CPU_CHAR *pstr, + CPU_CHAR *psrch_str) +{ + CPU_SIZE_T str_len; + CPU_SIZE_T srch_str_len; + CPU_SIZE_T srch_len; + CPU_SIZE_T srch_ix; + CPU_BOOLEAN srch_done; + CPU_INT16S srch_cmp; + CPU_CHAR *pstr_srch_ix; + + /* Rtn NULL if str ptr(s) NULL (see Note #2a). */ + if (pstr == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + if (psrch_str == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + str_len = Str_Len(pstr); + srch_str_len = Str_Len(psrch_str); + if (srch_str_len > str_len) { /* If srch str len > str len, rtn NULL (see Note #2b). */ + return ((CPU_CHAR *)0); + } + if (srch_str_len == 0) { /* If srch str len = 0, srch str equal NULL str; ... */ + pstr_srch_ix = (CPU_CHAR *)(pstr + str_len); /* ... rtn ptr to NULL str found in str (see Note #2c). */ + return (pstr_srch_ix); + } + + srch_len = str_len - srch_str_len; /* Determine srch len (see Note #2d1). */ + srch_ix = 0; + srch_done = DEF_NO; + while ((srch_done == DEF_NO) && (srch_ix <= srch_len)) { + pstr_srch_ix = (CPU_CHAR *)(pstr + srch_ix); + srch_cmp = Str_Cmp_N(pstr_srch_ix, psrch_str, srch_str_len); + srch_done = (srch_cmp == 0) ? DEF_YES : DEF_NO; + srch_ix++; + } + + + if (srch_cmp != 0) { /* If srch str NOT found, rtn NULL (see Note #2d). */ + return ((CPU_CHAR *)0); + } + + return (pstr_srch_ix); /* Rtn ptr to srch str found in str (see Note #2e). */ +} + + +/*$PAGE*/ +/* +********************************************************************************************************* +* Str_FmtNbr_32() +* +* Description : Format number into a multi-digit character string. +* +* Argument(s) : nbr Number to format (see Note #1). +* +* nbr_dig Number of integer digits to format (see Note #2). +* +* nbr_dp Number of decimal point digits to format. +* +* lead_zeros Prepend leading zeros option (DEF_YES/DEF_NO) [see Note #3]. +* +* nul NULL-character terminate option (DEF_YES/DEF_NO) [see Note #4]. +* +* pstr_fmt Pointer to character array to return formatted number string (see Note #5). +* +* Return(s) : Pointer to formatted string, if NO errors (see Note #6). +* +* Pointer to NULL, otherwise. +* +* Caller(s) : various. +* +* Note(s) : (1) (a) The maximum accuracy for 32-bit floating-point numbers : +* +* +* Maximum Accuracy log [Internal-Base ^ (Number-Internal-Base-Digits)] +* 32-bit Floating-point Number = ----------------------------------------------------- +* log [External-Base] +* +* log [2 ^ 24] +* = -------------- +* log [10] +* +* < 7.225 Base-10 Digits +* +* where +* Internal-Base Internal number base of floating- +* point numbers (i.e. 2) +* External-Base External number base of floating- +* point numbers (i.e. 10) +* Number-Internal-Base-Digits Number of internal number base +* significant digits (i.e. 24) +* +* (b) Some compilers' floating-point routines MAY further reduce the maximum accuracy. +* +* (c) If the total number of digits to format ('nbr_dig + nbr_dp') is greater than the +* maximum accuracy; digits following the first, significantly-accurate digits will +* be inaccurate. +* +* (2) (a) If the number of digits to format ('nbr_dig') is less than the number of significant +* integer digits of the number to format ('nbr'); then the most-significant digits of +* the formatted number will be truncated. +* +* Example : +* +* nbr = 23456.789 +* nbr_dig = 3 +* nbr_dp = 2 +* +* pstr_fmt = "456.78" +* +* (b) If number to format ('nbr') is negative but the most-significant digits of the +* formatted number are truncated (see Note #2a); the negative sign still prefixes +* the truncated formatted number. +* +* Example : +* +* nbr = -23456.789 +* nbr_dig = 3 +* nbr_dp = 2 +* +* pstr_fmt = "-456.78" +* +* (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit. +* The number of leading zeros is such that the total number integer digits is +* equal to the requested number of integer digits to format ('nbr_dig'). +* +* (b) (1) If leading zeros option DISABLED, ... +* (2) ... number of digits to format is non-zero, ... +* (3) ... & the integer value of the number to format is zero; ... +* (4) ... then one digit of '0' value is formatted. +* +* This is NOT a leading zero; but a single integer digit of '0' value. +* +* (4) (a) NULL-character terminate option DISABLED prevents overwriting previous character +* array formatting. +* +* (b) WARNING: Unless 'pstr_fmt' character array is pre-/post-terminated, NULL-character +* terminate option DISABLED will cause character string run-on. +*$PAGE* +* (5) (a) Format buffer size NOT validated; buffer overruns MUST be prevented by caller. +* +* (b) To prevent character buffer overrun : +* +* Character array size MUST be >= ('nbr_dig' + +* 'nbr_dp' + +* 1 negative sign + +* 1 decimal point + +* 1 'NUL' terminator) characters +* +* (6) String format terminates when : +* +* (a) Format string pointer is passed a NULL pointer. +* (1) No string format performed; NULL pointer returned. +* +* (b) Number successfully formatted into character string array. +********************************************************************************************************* +*/ + +#if (LIB_STR_CFG_FP_EN == DEF_ENABLED) +CPU_CHAR *Str_FmtNbr_32 (CPU_FP32 nbr, + CPU_INT08U nbr_dig, + CPU_INT08U nbr_dp, + CPU_BOOLEAN lead_zeros, + CPU_BOOLEAN nul, + CPU_CHAR *pstr_fmt) +{ + CPU_CHAR *pstr; + CPU_INT08U i; + CPU_INT32U dig_nbr; + CPU_INT32U dig_val; + CPU_FP32 dig_exp; + CPU_FP32 dp_exp; + + /* Rtn NULL if str ptr NULL (see Note #6a). */ + if (pstr_fmt == (CPU_CHAR *)0) { + return ((CPU_CHAR *)0); + } + + + pstr = pstr_fmt; + + if (nbr < 0.0) { /* If nbr neg, ... */ + if ((nbr_dig > 0) || /* ... & at least one dig ... */ + (nbr_dp > 0)) { /* ... or at least one dp; ... */ + nbr = -nbr; /* ... negate nbr & ... */ + *pstr++ = '-'; /* ... prefix with neg sign (see Note #2b). */ + } + } + + if (nbr_dig > 0) { + dig_exp = 1.0; + for (i = 1; i < nbr_dig; i++) { + dig_exp *= 10.0; + } + for (i = nbr_dig; i > 0; i--) { /* Fmt str for desired nbr digs. */ + dig_nbr = (CPU_INT32U)(nbr / dig_exp); + if ((dig_nbr > 0) || /* If dig nbr > 0, ... */ + (nbr_dig == 1) || /* ... OR exactly 1 dig to fmt, ... */ + (i == 1) || /* ... OR on one's dig to fmt, ... */ + (lead_zeros == DEF_YES)) { /* ... OR lead zeros opt ENABLED (see Note #3), ... */ + /* ... calc & fmt dig val. */ + dig_val = (CPU_INT32U)(dig_nbr % 10 ); + *pstr++ = (CPU_CHAR )(dig_val + '0'); + } + dig_exp /= 10.0; /* Shift to next least-significant dig. */ + } + } + + if (nbr_dp > 0) { + *pstr++ = '.'; /* Append dp prior to dp conversion. */ + dp_exp = 10.0; + for (i = 0; i < nbr_dp; i++) { /* Fmt str for desired nbr dp. */ + dig_nbr = (CPU_INT32U)(nbr * dp_exp ); + dig_val = (CPU_INT32U)(dig_nbr % 10 ); + *pstr++ = (CPU_CHAR )(dig_val + '0'); + dp_exp *= 10.0; /* Shift to next least-significant dp. */ + } + } + + if (nul != DEF_NO) { /* If NOT DISABLED, append NULL char (see Note #4). */ + *pstr = (CPU_CHAR)0; + } + + + return (pstr_fmt); +} +#endif + diff --git a/OS/uc/lib/lib_str.h b/OS/uc/lib/lib_str.h new file mode 100644 index 0000000..9ac9550 --- /dev/null +++ b/OS/uc/lib/lib_str.h @@ -0,0 +1,279 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form for FREE evaluation, for educational +* use or peaceful research. If you plan on using uC/LIB in a commercial +* product you need to contact Micrium to properly license its use in your +* product. We provide ALL the source code for your convenience and to +* help you experience uC/LIB. The fact that the source code is provided +* does NOT mean that you can use it without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* ASCII STRING MANAGEMENT +* +* Filename : lib_str.h +* Version : V1.24 +* Programmer(s) : ITJ +* JDH +********************************************************************************************************* +* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef LIB_STR_MODULE_PRESENT +#define LIB_STR_MODULE_PRESENT + + +/*$PAGE*/ +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The following common software files are located in the following directories : +* +* (a) \\lib*.* +* +* (b) (1) \\cpu_def.h +* +* (2) \\\\cpu*.* +* +* where +* directory path for custom library software +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include the '\\uC-LIB\', +* '\\' directory, & the specific CPU-compiler directory as +* additional include path directories. +* +* (3) NO compiler-supplied standard library functions SHOULD be used. +* +* #### The reference to standard library header files SHOULD be removed once all custom +* library functions are implemented WITHOUT reference to ANY standard library function(s). +* +* See also 'STANDARD LIBRARY MACRO'S Note #1'. +********************************************************************************************************* +*/ + +#include +#include +#include + + /* See Note #3. */ +#include +#include +#include +#include +#include + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef LIB_STR_MODULE +#define LIB_STR_EXT +#else +#define LIB_STR_EXT extern +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEFAULT CONFIGURATION +********************************************************************************************************* +*/ + +#ifndef LIB_STR_CFG_FP_EN +#define LIB_STR_CFG_FP_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define LIB_STR_NULL ((CPU_CHAR *)0) +#define LIB_STR_CMP_IDENTICAL 0 + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/*$PAGE*/ +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* STANDARD LIBRARY MACRO'S +* +* Note(s) : (1) NO compiler-supplied standard library functions SHOULD be used. +* +* #### The reference to standard memory functions SHOULD be removed once all custom library +* functions are implemented WITHOUT reference to ANY standard library function(s). +* +* See also 'INCLUDE FILES Note #3'. +********************************************************************************************************* +*/ + + /* See Note #1. */ +#define Str_IsAlpha(a) isalpha(a) +#define Str_IsDigit(a) isdigit(a) +#define Str_IsSpace(a) isspace(a) +#define Str_IsPrint(a) isprint(a) +#define Str_IsUpper(a) isupper(a) +#define Str_IsLower(a) islower(a) +#define Str_ToUpper(a) toupper(a) +#define Str_ToLower(a) tolower(a) + +#define Str_ToLong(a, b, c) strtol((char *)a, (char **)b, c) +#define Str_FmtPrint snprintf +#define Str_FmtScan sscanf + + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +CPU_SIZE_T Str_Len (CPU_CHAR *pstr); + + + +CPU_CHAR *Str_Copy (CPU_CHAR *pdest, + CPU_CHAR *psrc); + +CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest, + CPU_CHAR *psrc, + CPU_SIZE_T len_max); + + +CPU_CHAR *Str_Cat (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat); + +CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest, + CPU_CHAR *pstr_cat, + CPU_SIZE_T len_max); + + + +CPU_INT16S Str_Cmp (CPU_CHAR *p1_str, + CPU_CHAR *p2_str); + +CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str, + CPU_CHAR *p2_str, + CPU_SIZE_T len_max); + + +CPU_CHAR *Str_Char (CPU_CHAR *pstr, + CPU_CHAR srch_char); + +CPU_CHAR *Str_Char_N (CPU_CHAR *pstr, + CPU_SIZE_T len_max, + CPU_CHAR srch_char); + +CPU_CHAR *Str_Char_Last(CPU_CHAR *pstr, + CPU_CHAR srch_char); + + +CPU_CHAR *Str_Str (CPU_CHAR *pstr, + CPU_CHAR *srch_str); + + + +#if (LIB_STR_CFG_FP_EN == DEF_ENABLED) +CPU_CHAR *Str_FmtNbr_32(CPU_FP32 nbr, + CPU_INT08U nbr_dig, + CPU_INT08U nbr_dp, + CPU_BOOLEAN lead_zeros, + CPU_BOOLEAN nul, + CPU_CHAR *pstr_fmt); +#endif + + +/*$PAGE*/ +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + +#ifndef LIB_STR_CFG_FP_EN +#error "LIB_STR_CFG_FP_EN not #define'd in 'app_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " + +#elif ((LIB_STR_CFG_FP_EN != DEF_DISABLED) && \ + (LIB_STR_CFG_FP_EN != DEF_ENABLED )) +#error "LIB_STR_CFG_FP_EN illegally #define'd in 'app_cfg.h'" +#error " [MUST be DEF_DISABLED] " +#error " [ || DEF_ENABLED ] " +#endif + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of lib str module include. */ + diff --git a/OS/uc/os_ii/port/os_cpu.h b/OS/uc/os_ii/port/os_cpu.h new file mode 100644 index 0000000..a66cf6b --- /dev/null +++ b/OS/uc/os_ii/port/os_cpu.h @@ -0,0 +1,229 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_CPU.H +* Version : V1.82 +* By : Jean J. Labrosse +* Jean-Denis Hatier +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#ifndef OS_CPU_H +#define OS_CPU_H + + +#ifdef OS_CPU_GLOBALS +#define OS_CPU_EXT +#else +#define OS_CPU_EXT extern +#endif + +#ifndef OS_CPU_FPU_EN +#define OS_CPU_FPU_EN 0 /* HW floating point support disabled by default */ +#endif + +/* +********************************************************************************************************* +* INTERRUPT DISABLE TIME MEASUREMENT +********************************************************************************************************* +*/ + +#define OS_CPU_INT_DIS_MEAS_EN 0 + + +/* +********************************************************************************************************* +* EXCEPTION DEFINES +********************************************************************************************************* +*/ + + /* ARM exception IDs */ +#define OS_CPU_ARM_EXCEPT_RESET 0x00 +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01 +#define OS_CPU_ARM_EXCEPT_SWI 0x02 +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03 +#define OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04 +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05 +#define OS_CPU_ARM_EXCEPT_IRQ 0x06 +#define OS_CPU_ARM_EXCEPT_FIQ 0x07 +#define OS_CPU_ARM_EXCEPT_NBR 0x08 + + /* ARM exception vectors addresses */ +#define OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x00) +#define OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x00) + + /* ARM exception handlers addresses */ +#define OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x20) +#define OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x20) + + /* ARM "Jump To Self" assembled instruction */ +#define OS_CPU_ARM_INSTR_JUMP_TO_SELF 0xEAFFFFFE + /* ARM "Jump To Exception Handler" assembled instruction*/ +#define OS_CPU_ARM_INSTR_JUMP_TO_HANDLER 0xE59FF018 + + +/* +********************************************************************************************************* +* DATA TYPES +* (Compiler Specific) +********************************************************************************************************* +*/ + +typedef unsigned char BOOLEAN; +typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ +typedef signed char INT8S; /* Signed 8 bit quantity */ +typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ +typedef signed short INT16S; /* Signed 16 bit quantity */ +typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ +typedef signed int INT32S; /* Signed 32 bit quantity */ +typedef float FP32; /* Single precision floating point */ +typedef double FP64; /* Double precision floating point */ + +typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */ +typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ + +/* +********************************************************************************************************* +* ARM +* +* Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts +* will be enabled even if they were disabled before entering the critical section. +* NOT IMPLEMENTED +* +* Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if +* interrupts were disabled before entering the critical section, they will be disabled when +* leaving the critical section. +* NOT IMPLEMENTED +* +* Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you +* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then +* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to +* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' +* into the CPU's status register. +********************************************************************************************************* +*/ + +#define OS_CRITICAL_METHOD 3 + + +#if OS_CRITICAL_METHOD == 3 + +#if OS_CPU_INT_DIS_MEAS_EN > 0 + +#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save(); \ + OS_CPU_IntDisMeasStart();} +#define OS_EXIT_CRITICAL() {OS_CPU_IntDisMeasStop(); \ + OS_CPU_SR_Restore(cpu_sr);} + +#else + +#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();} +#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);} + +#endif + +#endif + +/* +********************************************************************************************************* +* ARM Miscellaneous +********************************************************************************************************* +*/ + +#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */ + +#define OS_TASK_SW() OSCtxSw() + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + /* Variables used to measure interrupt disable time */ +#if OS_CPU_INT_DIS_MEAS_EN > 0 +OS_CPU_EXT INT16U OS_CPU_IntDisMeasNestingCtr; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsEnter; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsExit; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsMax; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsDelta; +OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsOvrhd; +#endif + +/* +********************************************************************************************************* +* PROTOTYPES +********************************************************************************************************* +*/ + +#if OS_CRITICAL_METHOD == 3 +__arm OS_CPU_SR OS_CPU_SR_Save(void); /* See OS_CPU_A.ASM */ +__arm void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); +#endif + +__arm void OS_CPU_SR_INT_Dis(void); +__arm void OS_CPU_SR_INT_En(void); +__arm void OS_CPU_SR_FIQ_Dis(void); +__arm void OS_CPU_SR_FIQ_En(void); +__arm void OS_CPU_SR_IRQ_Dis(void); +__arm void OS_CPU_SR_IRQ_En(void); + +#if OS_CPU_FPU_EN > 0 + void OS_CPU_FP_Init(void); /* See OS_CPU_C.C */ +__arm void OS_CPU_FP_Restore(void *pblk); +__arm void OS_CPU_FP_Save(void *pblk); +#endif + +__arm void OSCtxSw(void); +__arm void OSIntCtxSw(void); +__arm void OSStartHighRdy(void); + + void OS_CPU_InitExceptVect(void); + +__arm void OS_CPU_ARM_ExceptResetHndlr(void); +__arm void OS_CPU_ARM_ExceptUndefInstrHndlr(void); +__arm void OS_CPU_ARM_ExceptSwiHndlr(void); +__arm void OS_CPU_ARM_ExceptPrefetchAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptDataAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptAddrAbortHndlr(void); +__arm void OS_CPU_ARM_ExceptIrqHndlr(void); +__arm void OS_CPU_ARM_ExceptFiqHndlr(void); + + void OS_CPU_ExceptHndlr(INT32U except_type); + +#if OS_CPU_INT_DIS_MEAS_EN > 0 + void OS_CPU_IntDisMeasInit(void); + void OS_CPU_IntDisMeasStart(void); + void OS_CPU_IntDisMeasStop(void); + INT16U OS_CPU_IntDisMeasTmrRd(void); +#endif + +#if OS_CPU_ARM_DCC_EN > 0 + void OSDCC_Handler(void); +#endif + +#endif diff --git a/OS/uc/os_ii/port/os_cpu_a.asm b/OS/uc/os_ii/port/os_cpu_a.asm new file mode 100644 index 0000000..52f5bfb --- /dev/null +++ b/OS/uc/os_ii/port/os_cpu_a.asm @@ -0,0 +1,577 @@ +; +;******************************************************************************************************** +; uC/OS-II +; The Real-Time Kernel +; +; +; (c) Copyright 1992-2007, Micrium, Weston, FL +; All Rights Reserved +; +; Generic ARM Port +; +; File : OS_CPU_A.ASM +; Version : V1.82 +; By : Jean J. Labrosse +; Jean-Denis Hatier +; +; For : ARM7 or ARM9 +; Mode : ARM or Thumb +; Toolchain : IAR's EWARM V4.11a and higher +;******************************************************************************************************** +; + +;******************************************************************************************************** +; PUBLIC FUNCTIONS +;******************************************************************************************************** + ; External references. + EXTERN OSRunning + EXTERN OSPrioCur + EXTERN OSPrioHighRdy + EXTERN OSTCBCur + EXTERN OSTCBHighRdy + EXTERN OSIntNesting + EXTERN OSIntExit + EXTERN OSTaskSwHook + + ; Functions declared in this file. + PUBLIC OS_CPU_SR_Save + PUBLIC OS_CPU_SR_Restore + PUBLIC OSStartHighRdy + PUBLIC OSCtxSw + PUBLIC OSIntCtxSw + + ; Functions related to exception handling. + PUBLIC OS_CPU_ARM_ExceptResetHndlr + PUBLIC OS_CPU_ARM_ExceptUndefInstrHndlr + PUBLIC OS_CPU_ARM_ExceptSwiHndlr + PUBLIC OS_CPU_ARM_ExceptPrefetchAbortHndlr + PUBLIC OS_CPU_ARM_ExceptDataAbortHndlr + PUBLIC OS_CPU_ARM_ExceptAddrAbortHndlr + PUBLIC OS_CPU_ARM_ExceptIrqHndlr + PUBLIC OS_CPU_ARM_ExceptFiqHndlr + + EXTERN OS_CPU_ExceptHndlr + + +;******************************************************************************************************** +; EQUATES +;******************************************************************************************************** + +OS_CPU_ARM_CONTROL_INT_DIS EQU 0xC0 ; Disable both FIQ and IRQ. +OS_CPU_ARM_CONTROL_FIQ_DIS EQU 0x40 ; Disable FIQ. +OS_CPU_ARM_CONTROL_IRQ_DIS EQU 0x80 ; Disable IRQ. +OS_CPU_ARM_CONTROL_THUMB EQU 0x20 ; Set THUMB mode. +OS_CPU_ARM_CONTROL_ARM EQU 0x00 ; Set ARM mode. + +OS_CPU_ARM_MODE_MASK EQU 0x1F +OS_CPU_ARM_MODE_USR EQU 0x10 +OS_CPU_ARM_MODE_FIQ EQU 0x11 +OS_CPU_ARM_MODE_IRQ EQU 0x12 +OS_CPU_ARM_MODE_SVC EQU 0x13 +OS_CPU_ARM_MODE_ABT EQU 0x17 +OS_CPU_ARM_MODE_UND EQU 0x1B +OS_CPU_ARM_MODE_SYS EQU 0x1F + +OS_CPU_ARM_EXCEPT_RESET EQU 0x00 +OS_CPU_ARM_EXCEPT_UNDEF_INSTR EQU 0x01 +OS_CPU_ARM_EXCEPT_SWI EQU 0x02 +OS_CPU_ARM_EXCEPT_PREFETCH_ABORT EQU 0x03 +OS_CPU_ARM_EXCEPT_DATA_ABORT EQU 0x04 +OS_CPU_ARM_EXCEPT_ADDR_ABORT EQU 0x05 +OS_CPU_ARM_EXCEPT_IRQ EQU 0x06 +OS_CPU_ARM_EXCEPT_FIQ EQU 0x07 + + +;******************************************************************************************************** +; CODE GENERATION DIRECTIVES +;******************************************************************************************************** + + RSEG CODE:CODE:NOROOT(2) + CODE32 + + + +;********************************************************************************************************* +; CRITICAL SECTION METHOD 3 FUNCTIONS +; +; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you +; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then +; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to +; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' +; into the CPU's status register. +; +; Prototypes : OS_CPU_SR OS_CPU_SR_Save (void); +; void OS_CPU_SR_Restore (OS_CPU_SR os_cpu_sr); +; +; +; Note(s) : (1) These functions are used in general like this: +; +; void Task (void *p_arg) +; { +; /* Allocate storage for CPU status register. */ +; #if (OS_CRITICAL_METHOD == 3) +; OS_CPU_SR os_cpu_sr; +; #endif +; +; : +; : +; OS_ENTER_CRITICAL(); /* os_cpu_sr = OS_CPU_SR_Save(); */ +; : +; : +; OS_EXIT_CRITICAL(); /* OS_CPU_SR_Restore(cpu_sr); */ +; : +; : +; } +;********************************************************************************************************* + +OS_CPU_SR_Save + MRS R0, CPSR + ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts. + MSR CPSR_c, R1 + BX LR ; Disabled, return the original CPSR contents in R0. + + +OS_CPU_SR_Restore + MSR CPSR_c, R0 + BX LR + + +;********************************************************************************************************* +; START MULTITASKING +; void OSStartHighRdy(void) +; +; Note(s) : 1) OSStartHighRdy() MUST: +; a) Call OSTaskSwHook() then, +; b) Set OSRunning to TRUE, +; c) Switch to the highest priority task. +;********************************************************************************************************* + +OSStartHighRdy + + ; Change to SVC mode. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_Running ; OSRunning = TRUE; + MOV R1, #1 + STRB R1, [R0] + + ; SWITCH TO HIGHEST PRIORITY TASK: + LDR R0, ?OS_TCBHighRdy ; Get highest priority task TCB address, + LDR R0, [R0] ; Get stack pointer, + LDR SP, [R0] ; Switch to the new stack, + + LDR R0, [SP], #4 ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;********************************************************************************************************* +; PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw() +; +; Note(s) : 1) OSCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED. +; +; 2) The pseudo-code for OSCtxSw() is: +; a) Save the current task's context onto the current task's stack, +; b) OSTCBCur->OSTCBStkPtr = SP; +; c) OSTaskSwHook(); +; d) OSPrioCur = OSPrioHighRdy; +; e) OSTCBCur = OSTCBHighRdy; +; f) SP = OSTCBHighRdy->OSTCBStkPtr; +; g) Restore the new task's context from the new task's stack, +; h) Return to new task's code. +; +; 3) Upon entry: +; OSTCBCur points to the OS_TCB of the task to suspend, +; OSTCBHighRdy points to the OS_TCB of the task to resume. +;********************************************************************************************************* + +OSCtxSw + ; SAVE CURRENT TASK'S CONTEXT: + STMFD SP!, {LR} ; Push return address, + STMFD SP!, {LR} + STMFD SP!, {R0-R12} ; Push registers, + MRS R0, CPSR ; Push current CPSR, + TST LR, #1 ; See if called from Thumb mode, + ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, set the T-bit. + STMFD SP!, {R0} + + LDR R0, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP; + LDR R1, [R0] + STR SP, [R1] + + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy; + LDR R1, ?OS_PrioHighRdy + LDRB R2, [R1] + STRB R2, [R0] + + LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy; + LDR R1, ?OS_TCBHighRdy + LDR R2, [R1] + STR R2, [R0] + + LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr; + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;********************************************************************************************************* +; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw() +; +; Note(s) : 1) OSIntCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED. +; +; 2) The pseudo-code for OSCtxSw() is: +; a) OSTaskSwHook(); +; b) OSPrioCur = OSPrioHighRdy; +; c) OSTCBCur = OSTCBHighRdy; +; d) SP = OSTCBHighRdy->OSTCBStkPtr; +; e) Restore the new task's context from the new task's stack, +; f) Return to new task's code. +; +; 3) Upon entry: +; OSTCBCur points to the OS_TCB of the task to suspend, +; OSTCBHighRdy points to the OS_TCB of the task to resume. +;********************************************************************************************************* + +OSIntCtxSw + LDR R0, ?OS_TaskSwHook ; OSTaskSwHook(); + MOV LR, PC + BX R0 + + LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy; + LDR R1, ?OS_PrioHighRdy + LDRB R2, [R1] + STRB R2, [R0] + + LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy; + LDR R1, ?OS_TCBHighRdy + LDR R2, [R1] + STR R2, [R0] + + LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr; + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;******************************************************************************************************** +; RESET EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptResetHndlr + ; LR offset to return from this exception: 0. + ; (there is no way to return from a RESET exception). + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_RESET ; Set exception ID to OS_CPU_ARM_EXCEPT_RESET. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; UNDEFINED INSTRUCTION EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptUndefInstrHndlr + ; LR offset to return from this exception: 0. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_UNDEF_INSTR ; Set exception ID to OS_CPU_ARM_EXCEPT_UNDEF_INSTR. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; SOFTWARE INTERRUPT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptSwiHndlr + ; LR offset to return from this exception: 0. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_SWI ; Set exception ID to OS_CPU_ARM_EXCEPT_SWI. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; PREFETCH ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptPrefetchAbortHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_PREFETCH_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_PREFETCH_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; DATA ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptDataAbortHndlr + SUB LR, LR, #8 ; LR offset to return from this exception: -8. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_DATA_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_DATA_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; ADDRESS ABORT EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptAddrAbortHndlr + SUB LR, LR, #8 ; LR offset to return from this exception: -8. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_ADDR_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_ADDR_ABORT. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; INTERRUPT REQUEST EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptIrqHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_IRQ ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; FAST INTERRUPT REQUEST EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptFiqHndlr + SUB LR, LR, #4 ; LR offset to return from this exception: -4. + STMFD SP!, {R0-R12, LR} ; Push working registers. + MOV R3, LR ; Save link register. + MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ. + B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler. + + +;******************************************************************************************************** +; GLOBAL EXCEPTION HANDLER +; +; Register Usage: R0 Exception Type +; R1 Exception's SPSR +; R2 Old CPU mode +; R3 Return PC +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr + MRS R1, SPSR ; Save CPSR (i.e. exception's SPSR). + + ; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION: + ; SPSR.Mode = SVC : task, + ; SPSR.Mode = FIQ, IRQ, ABT, UND : other exceptions, + ; SPSR.Mode = USR : *unsupported state*. + AND R2, R1, #OS_CPU_ARM_MODE_MASK + CMP R2, #OS_CPU_ARM_MODE_SVC + BNE OS_CPU_ARM_ExceptHndlr_BreakExcept + + +;******************************************************************************************************** +; EXCEPTION HANDLER: TASK INTERRUPTED +; +; Register Usage: R0 Exception Type +; R1 Exception's SPSR +; R2 Exception's CPSR +; R3 Return PC +; R4 Exception's SP +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr_BreakTask + MRS R2, CPSR ; Save exception's CPSR. + MOV R4, SP ; Save exception's stack pointer. + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; SAVE TASK'S CONTEXT ONTO TASK'S STACK: + STMFD SP!, {R3} ; Push task's PC, + STMFD SP!, {LR} ; Push task's LR, + STMFD SP!, {R5-R12} ; Push task's R12-R5, + LDMFD R4!, {R5-R9} ; Move task's R4-R0 from exception stack to task's stack. + STMFD SP!, {R5-R9} + STMFD SP!, {R1} ; Push task's CPSR (i.e. exception SPSR). + + ; if (OSRunning == 1) + LDR R1, ?OS_Running + LDRB R1, [R1] + CMP R1, #1 + BNE OS_CPU_ARM_ExceptHndlr_BreakTask_1 + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting++; + LDRB R4, [R3] + ADD R4, R4, #1 + STRB R4, [R3] + + LDR R3, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP; + LDR R4, [R3] + STR SP, [R4] + +OS_CPU_ARM_ExceptHndlr_BreakTask_1 + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; EXECUTE EXCEPTION HANDLER: + LDR R1, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0); + MOV LR, PC + BX R1 + + ; Adjust exception stack pointer. This is needed because + ; exception stack is not used when restoring task context. + ADD SP, SP, #(14 * 4) + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; Call OSIntExit(). This call MAY never return if a ready + ; task with higher priority than the interrupted one is + ; found. + LDR R0, ?OS_IntExit + MOV LR, PC + BX R0 + + ; RESTORE NEW TASK'S CONTEXT: + LDMFD SP!, {R0} ; Pop new task's CPSR, + MSR SPSR_cxsf, R0 + + LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context. + + +;******************************************************************************************************** +; EXCEPTION HANDLER: EXCEPTION INTERRUPTED +; +; Register Usage: R0 Exception Type +; R1 +; R2 +; R3 +;******************************************************************************************************** + +OS_CPU_ARM_ExceptHndlr_BreakExcept + MRS R2, CPSR ; Save exception's CPSR. + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting++; + LDRB R4, [R3] + ADD R4, R4, #1 + STRB R4, [R3] + + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; EXECUTE EXCEPTION HANDLER: + LDR R3, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0); + MOV LR, PC + BX R3 + + ; Change to SVC mode & disable interruptions. + MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC) + + ; HANDLE NESTING COUNTER: + LDR R3, ?OS_IntNesting ; OSIntNesting--; + LDRB R4, [R3] + SUB R4, R4, #1 + STRB R4, [R3] + + MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE. + + ; RESTORE OLD CONTEXT: + LDMFD SP!, {R0-R12, PC}^ ; Pull working registers and return from exception. + + +;********************************************************************************************************* +; POINTERS TO VARIABLES +;********************************************************************************************************* + + DATA + +?OS_Running: + DC32 OSRunning + +?OS_PrioCur: + DC32 OSPrioCur + +?OS_PrioHighRdy: + DC32 OSPrioHighRdy + +?OS_TCBCur: + DC32 OSTCBCur + +?OS_TCBHighRdy: + DC32 OSTCBHighRdy + +?OS_IntNesting: + DC32 OSIntNesting + +?OS_TaskSwHook: + DC32 OSTaskSwHook + +?OS_IntExit: + DC32 OSIntExit + +?OS_CPU_ExceptHndlr: + DC32 OS_CPU_ExceptHndlr + + + END diff --git a/OS/uc/os_ii/port/os_cpu_c.c b/OS/uc/os_ii/port/os_cpu_c.c new file mode 100644 index 0000000..ae07b00 --- /dev/null +++ b/OS/uc/os_ii/port/os_cpu_c.c @@ -0,0 +1,523 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_CPU_C.C +* Version : V1.82 +* By : Jean J. Labrosse +* Jean-Denis Hatier +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#define OS_CPU_GLOBALS +#include + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOCAL CONSTANTS +* +* Note(s) : 1) ARM_MODE_ARM is the CPSR bit mask for ARM Mode +* 2) ARM_MODE_THUMB is the CPSR bit mask for THUMB Mode +* 3) ARM_SVC_MODE_THUMB is the CPSR bit mask for SVC MODE + THUMB Mode +* 4) ARM_SVC_MODE_ARM is the CPSR bit mask for SVC MODE + ARM Mode + 5) OS_NTASKS_FP establishes the number of tasks capable of supporting floating-point. One +* task is removed for the idle task because it doesn't do floating-point at all. +* 6) OS_FP_STORAGE_SIZE currently allocates 1024 bytes of storage in order to accomodate +* thirty-two, single precision 32 bit, or sixteen double precision 64 bit VFP registers. +********************************************************************************************************* +*/ + +#define ARM_MODE_ARM 0x00000000 +#define ARM_MODE_THUMB 0x00000020 + +#define ARM_SVC_MODE_THUMB (0x00000013L + ARM_MODE_THUMB) +#define ARM_SVC_MODE_ARM (0x00000013L + ARM_MODE_ARM) + +#define OS_NTASKS_FP (OS_MAX_TASKS + OS_N_SYS_TASKS - 1) +#define OS_FP_STORAGE_SIZE 128L + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +#if OS_TMR_EN > 0 +static INT16U OSTmrCtr; +#endif + +#if OS_CPU_FPU_EN > 0 +static OS_MEM *OSFPPartPtr; /* Pointer to memory partition for storing FPU registers */ +static INT32U OSFPPart[OS_NTASKS_FP][OS_FP_STORAGE_SIZE / sizeof(INT32U)]; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE FP SUPPORT +* +* Description: This function initializes the memory partition used to save FPU registers +* during a context switch. This function MUST be called AFTER calling +* OSInit(). OS_CPU_FPU_EN must be defined > 0 in order to compile FPU support into the +* build. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) Tasks that are to use FP support MUST be created with OSTaskCreateExt(). +* 2) For the ARM VFP, 1024 bytes are required to save the VFP context. +* The INT32U data type is used to ensure that storage is aligned on a 32-bit boundary. +* 3) If you need to perform floating point operations from within the OSStatTaskHook(), +* then you must change the 'Options' attribute for OSTaskCreatExt() when creating +* the statistics task. This only applies if OS_TaskStat() was created with OSTaskCreateExt(). +********************************************************************************************************* +*/ + +#if OS_CPU_FPU_EN > 0 +void OS_CPU_FP_Init (void) +{ + INT8U err; +#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN + OS_TCB *ptcb; + void *pblk; +#endif + + + OSFPPartPtr = OSMemCreate(&OSFPPart[0][0], OS_NTASKS_FP, OS_FP_STORAGE_SIZE, &err); + +#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN /* CHANGE 'OPTIONS' for OS_TaskStat() */ + ptcb = OSTCBPrioTbl[OS_TASK_STAT_PRIO]; + ptcb->OSTCBOpt |= OS_TASK_OPT_SAVE_FP; /* Allow floating-point support for Statistic task */ + pblk = OSMemGet(OSFPPartPtr, &err); /* Get storage for VFP registers */ + if (pblk != (void *)0) { /* Did we get a memory block? */ + ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } +#endif +} +#endif + +/* +********************************************************************************************************* +* OS INITIALIZATION HOOK +* (BEGINNING) +* +* Description: This function is called by OSInit() at the beginning of OSInit(). +* +* Arguments : none +* +* Note(s) : 1) Interrupts should be disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSInitHookBegin (void) +{ +#if OS_TMR_EN > 0 + OSTmrCtr = 0; +#endif +} +#endif + +/* +********************************************************************************************************* +* OS INITIALIZATION HOOK +* (END) +* +* Description: This function is called by OSInit() at the end of OSInit(). +* +* Arguments : none +* +* Note(s) : 1) Interrupts should be disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSInitHookEnd (void) +{ +#if OS_CPU_INT_DIS_MEAS_EN > 0 + OS_CPU_IntDisMeasInit(); +#endif + +#if OS_CPU_FPU_EN > 0 + OS_CPU_FP_Init(); /* Initialize support for VFP register save / restore */ +#endif +} +#endif + +/* +********************************************************************************************************* +* TASK CREATION HOOK +* +* Description: This function is called when a task is created. +* +* Arguments : ptcb is a pointer to the task control block of the task being created. +* +* Note(s) : 1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 +void OSTaskCreateHook (OS_TCB *ptcb) +{ +#if OS_CPU_FPU_EN > 0 + INT8U err; + void *pblk; +#endif + + +#if OS_CPU_FPU_EN > 0 + if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task needs FP support */ + pblk = OSMemGet(OSFPPartPtr, &err); /* Yes, Get storage for VFP registers */ + if (pblk != (void *)0) { /* Did we get a memory block? */ + ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskCreateHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + + +/* +********************************************************************************************************* +* TASK DELETION HOOK +* +* Description: This function is called when a task is deleted. +* +* Arguments : ptcb is a pointer to the task control block of the task being deleted. +* +* Note(s) : 1) Interrupts are disabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 +void OSTaskDelHook (OS_TCB *ptcb) +{ +#if OS_CPU_FPU_EN > 0 + if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task had FP support */ + if (ptcb->OSTCBExtPtr != (void *)0) { /* Yes, OSTCBExtPtr must not be NULL */ + OSMemPut(OSFPPartPtr, ptcb->OSTCBExtPtr); /* Return memory block to free pool */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskDelHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + +/* +********************************************************************************************************* +* IDLE TASK HOOK +* +* Description: This function is called by the idle task. This hook has been added to allow you to do +* such things as STOP the CPU to conserve power. +* +* Arguments : none +* +* Note(s) : 1) Interrupts are enabled during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251 +void OSTaskIdleHook (void) +{ +#if OS_CPU_ARM_DCC_EN > 0 + OSDCC_Handler(); +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskIdleHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* STATISTIC TASK HOOK +* +* Description: This function is called every second by uC/OS-II's statistics task. This allows your +* application to add functionality to the statistics task. +* +* Arguments : none +********************************************************************************************************* +*/ + +#if OS_CPU_HOOKS_EN > 0 +void OSTaskStatHook (void) +{ +#if OS_APP_HOOKS_EN > 0 + App_TaskStatHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* INITIALIZE A TASK'S STACK +* +* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the +* stack frame of the task being created. This function is highly processor specific. +* +* Arguments : task is a pointer to the task code +* +* p_arg is a pointer to a user supplied data area that will be passed to the task +* when the task first executes. +* +* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to +* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then +* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if +* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address +* of the stack. +* +* opt specifies options that can be used to alter the behavior of OSTaskStkInit(). +* (see uCOS_II.H for OS_TASK_OPT_xxx). +* +* Returns : Always returns the location of the new top-of-stack' once the processor registers have +* been placed on the stack in the proper order. +* +* Note(s) : 1) Interrupts are enabled when your task starts executing. +* 2) All tasks run in SVC mode. +********************************************************************************************************* +*/ + +OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) +{ + OS_STK *stk; + INT32U task_addr; + + + opt = opt; /* 'opt' is not used, prevent warning */ + stk = ptos; /* Load stack pointer */ + task_addr = (INT32U)task & ~1; /* Mask off lower bit in case task is thumb mode */ + *(stk) = (INT32U)task_addr; /* Entry Point */ + *(--stk) = (INT32U)0x14141414L; /* R14 (LR) */ + *(--stk) = (INT32U)0x12121212L; /* R12 */ + *(--stk) = (INT32U)0x11111111L; /* R11 */ + *(--stk) = (INT32U)0x10101010L; /* R10 */ + *(--stk) = (INT32U)0x09090909L; /* R9 */ + *(--stk) = (INT32U)0x08080808L; /* R8 */ + *(--stk) = (INT32U)0x07070707L; /* R7 */ + *(--stk) = (INT32U)0x06060606L; /* R6 */ + *(--stk) = (INT32U)0x05050505L; /* R5 */ + *(--stk) = (INT32U)0x04040404L; /* R4 */ + *(--stk) = (INT32U)0x03030303L; /* R3 */ + *(--stk) = (INT32U)0x02020202L; /* R2 */ + *(--stk) = (INT32U)0x01010101L; /* R1 */ + *(--stk) = (INT32U)p_arg; /* R0 : argument */ + if ((INT32U)task & 0x01) { /* See if task runs in Thumb or ARM mode */ + *(--stk) = (INT32U)ARM_SVC_MODE_THUMB; /* CPSR (Enable both IRQ and FIQ interrupts, THUMB-mode) */ + } else { + *(--stk) = (INT32U)ARM_SVC_MODE_ARM; /* CPSR (Enable both IRQ and FIQ interrupts, ARM-mode) */ + } + + return (stk); +} + +/* +********************************************************************************************************* +* TASK SWITCH HOOK +* +* Description: This function is called when a task switch is performed. This allows you to perform other +* operations during a context switch. +* +* Arguments : none +* +* Note(s) : 1) Interrupts are disabled during this call. +* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that +* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the +* task being switched out (i.e. the preempted task). +********************************************************************************************************* +*/ +#if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0) +void OSTaskSwHook (void) +{ +#if OS_CPU_FPU_EN > 0 + void *pblk; +#endif + +#if OS_CPU_FPU_EN > 0 /* Save VFP context of preempted task */ + if (OSRunning == OS_TRUE) { /* Don't save on OSStart()! */ + if (OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task used FP */ + pblk = OSTCBCur->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */ + if (pblk != (void *)0) { /* Make sure we have storage */ + OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */ + } + } + } + /* Restore VFP context of new task */ + if (OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if new task uses FP */ + pblk = OSTCBHighRdy->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */ + if (pblk != (void *)0) { /* Make sure we have storage */ + OS_CPU_FP_Restore(pblk); /* Get contents of VFP registers */ + } + } +#endif + +#if OS_APP_HOOKS_EN > 0 + App_TaskSwHook(); +#endif +} +#endif + +/* +********************************************************************************************************* +* OS_TCBInit() HOOK +* +* Description: This function is called by OS_TCBInit() after setting up most of the TCB. +* +* Arguments : ptcb is a pointer to the TCB of the task being created. +* +* Note(s) : 1) Interrupts may or may not be ENABLED during this call. +********************************************************************************************************* +*/ +#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203 +void OSTCBInitHook (OS_TCB *ptcb) +{ +#if OS_APP_HOOKS_EN > 0 + App_TCBInitHook(ptcb); +#else + (void)ptcb; /* Prevent compiler warning */ +#endif +} +#endif + + +/* +********************************************************************************************************* +* TICK HOOK +* +* Description: This function is called every tick. +* +* Arguments : none +* +* Note(s) : 1) Interrupts may or may not be ENABLED during this call. +********************************************************************************************************* +*/ +#if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0) +void OSTimeTickHook (void) +{ +#if OS_APP_HOOKS_EN > 0 + App_TimeTickHook(); +#endif + +#if OS_TMR_EN > 0 + OSTmrCtr++; + if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) { + OSTmrCtr = 0; + OSTmrSignal(); + } +#endif + +#if OS_CPU_ARM_DCC_EN > 0 + OSDCC_Handler(); +#endif +} +#endif + + +/* +********************************************************************************************************* +* INTERRUPT DISABLE TIME MEASUREMENT, START +********************************************************************************************************* +*/ + +#if OS_CPU_INT_DIS_MEAS_EN > 0 +void OS_CPU_IntDisMeasInit (void) +{ + OS_CPU_IntDisMeasNestingCtr = 0; + OS_CPU_IntDisMeasCntsEnter = 0; + OS_CPU_IntDisMeasCntsExit = 0; + OS_CPU_IntDisMeasCntsMax = 0; + OS_CPU_IntDisMeasCntsDelta = 0; + OS_CPU_IntDisMeasCntsOvrhd = 0; + OS_CPU_IntDisMeasStart(); /* Measure the overhead of the functions */ + OS_CPU_IntDisMeasStop(); + OS_CPU_IntDisMeasCntsOvrhd = OS_CPU_IntDisMeasCntsDelta; +} + + +void OS_CPU_IntDisMeasStart (void) +{ + OS_CPU_IntDisMeasNestingCtr++; + if (OS_CPU_IntDisMeasNestingCtr == 1) { /* Only measure at the first nested level */ + OS_CPU_IntDisMeasCntsEnter = OS_CPU_IntDisMeasTmrRd(); + } +} + + +void OS_CPU_IntDisMeasStop (void) +{ + OS_CPU_IntDisMeasNestingCtr--; /* Decrement nesting ctr */ + if (OS_CPU_IntDisMeasNestingCtr == 0) { + OS_CPU_IntDisMeasCntsExit = OS_CPU_IntDisMeasTmrRd(); + OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsExit - OS_CPU_IntDisMeasCntsEnter; + if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsOvrhd) { /* Ensure overhead < delta */ + OS_CPU_IntDisMeasCntsDelta -= OS_CPU_IntDisMeasCntsOvrhd; + } else { + OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsOvrhd; + } + if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsMax) { /* Track MAXIMUM */ + OS_CPU_IntDisMeasCntsMax = OS_CPU_IntDisMeasCntsDelta; + } + } +} +#endif + + +/* +********************************************************************************************************* +* INITIALIZE EXCEPTION VECTORS +* +* Description : This function initialize exception vectors to the default handlers. +* +* Arguments : None. +********************************************************************************************************* +*/ + +void OS_CPU_InitExceptVect (void) +{ +/* + (*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptResetHndlr; +*/ + + (*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptUndefInstrHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptSwiHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptPrefetchAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptDataAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptAddrAbortHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptIrqHndlr; + + (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; + (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptFiqHndlr; +} diff --git a/OS/uc/os_ii/port/os_dbg.c b/OS/uc/os_ii/port/os_dbg.c new file mode 100644 index 0000000..744d0a4 --- /dev/null +++ b/OS/uc/os_ii/port/os_dbg.c @@ -0,0 +1,292 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* DEBUGGER CONSTANTS +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* +* File : OS_DBG.C +* Version : V1.82 +* By : Jean J. Labrosse +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.11a and higher +********************************************************************************************************* +*/ + +#include + + /* The following #define tells the IAR compiler to 'not' optimize these ... */ + /* ... 'const' out since they are not used elsewhere. */ +#define OS_COMPILER_OPT __root + +/* +********************************************************************************************************* +* DEBUG DATA +********************************************************************************************************* +*/ + +OS_COMPILER_OPT INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */ + +#if OS_DEBUG_EN > 0 + +OS_COMPILER_OPT INT32U const OSEndiannessTest = 0x12345678L; /* Variable to test CPU endianness */ + +OS_COMPILER_OPT INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */ +OS_COMPILER_OPT INT16U const OSEventNameSize = OS_EVENT_NAME_SIZE; /* Size (in bytes) of event names */ +OS_COMPILER_OPT INT16U const OSEventEn = OS_EVENT_EN; +#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0) +OS_COMPILER_OPT INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */ +OS_COMPILER_OPT INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */ +#else +OS_COMPILER_OPT INT16U const OSEventSize = 0; +OS_COMPILER_OPT INT16U const OSEventTblSize = 0; +#endif + +OS_COMPILER_OPT INT16U const OSFlagEn = OS_FLAG_EN; +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +OS_COMPILER_OPT INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */ +OS_COMPILER_OPT INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */ +OS_COMPILER_OPT INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */ +#else +OS_COMPILER_OPT INT16U const OSFlagGrpSize = 0; +OS_COMPILER_OPT INT16U const OSFlagNodeSize = 0; +OS_COMPILER_OPT INT16U const OSFlagWidth = 0; +#endif +OS_COMPILER_OPT INT16U const OSFlagMax = OS_MAX_FLAGS; +OS_COMPILER_OPT INT16U const OSFlagNameSize = OS_FLAG_NAME_SIZE; /* Size (in bytes) of flag names */ + +OS_COMPILER_OPT INT16U const OSLowestPrio = OS_LOWEST_PRIO; + +OS_COMPILER_OPT INT16U const OSMboxEn = OS_MBOX_EN; + +OS_COMPILER_OPT INT16U const OSMemEn = OS_MEM_EN; +OS_COMPILER_OPT INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */ +OS_COMPILER_OPT INT16U const OSMemNameSize = OS_MEM_NAME_SIZE; /* Size (in bytes) of partition names */ +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +OS_COMPILER_OPT INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */ +OS_COMPILER_OPT INT16U const OSMemTblSize = sizeof(OSMemTbl); +#else +OS_COMPILER_OPT INT16U const OSMemSize = 0; +OS_COMPILER_OPT INT16U const OSMemTblSize = 0; +#endif +OS_COMPILER_OPT INT16U const OSMutexEn = OS_MUTEX_EN; + +OS_COMPILER_OPT INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */ + +OS_COMPILER_OPT INT16U const OSQEn = OS_Q_EN; +OS_COMPILER_OPT INT16U const OSQMax = OS_MAX_QS; /* Number of queues */ +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +OS_COMPILER_OPT INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */ +#else +OS_COMPILER_OPT INT16U const OSQSize = 0; +#endif + +OS_COMPILER_OPT INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */ + +OS_COMPILER_OPT INT16U const OSSemEn = OS_SEM_EN; + +OS_COMPILER_OPT INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */ + +OS_COMPILER_OPT INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN; +OS_COMPILER_OPT INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN; +OS_COMPILER_OPT INT16U const OSTaskDelEn = OS_TASK_DEL_EN; +OS_COMPILER_OPT INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE; +OS_COMPILER_OPT INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN; +OS_COMPILER_OPT INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */ +OS_COMPILER_OPT INT16U const OSTaskNameSize = OS_TASK_NAME_SIZE; /* Size (in bytes) of task names */ +OS_COMPILER_OPT INT16U const OSTaskStatEn = OS_TASK_STAT_EN; +OS_COMPILER_OPT INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE; +OS_COMPILER_OPT INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN; +OS_COMPILER_OPT INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN; + +OS_COMPILER_OPT INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1; /* Number of entries in OSTCBPrioTbl[] */ +OS_COMPILER_OPT INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */ +OS_COMPILER_OPT INT16U const OSTicksPerSec = OS_TICKS_PER_SEC; +OS_COMPILER_OPT INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN; +OS_COMPILER_OPT INT16U const OSVersionNbr = OS_VERSION; + +OS_COMPILER_OPT INT16U const OSTmrEn = OS_TMR_EN; +OS_COMPILER_OPT INT16U const OSTmrCfgMax = OS_TMR_CFG_MAX; +OS_COMPILER_OPT INT16U const OSTmrCfgNameSize = OS_TMR_CFG_NAME_SIZE; +OS_COMPILER_OPT INT16U const OSTmrCfgWheelSize = OS_TMR_CFG_WHEEL_SIZE; +OS_COMPILER_OPT INT16U const OSTmrCfgTicksPerSec = OS_TMR_CFG_TICKS_PER_SEC; + +#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0) +OS_COMPILER_OPT INT16U const OSTmrSize = sizeof(OS_TMR); +OS_COMPILER_OPT INT16U const OSTmrTblSize = sizeof(OSTmrTbl); +OS_COMPILER_OPT INT16U const OSTmrWheelSize = sizeof(OS_TMR_WHEEL); +OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = sizeof(OSTmrWheelTbl); +#else +OS_COMPILER_OPT INT16U const OSTmrSize = 0; +OS_COMPILER_OPT INT16U const OSTmrTblSize = 0; +OS_COMPILER_OPT INT16U const OSTmrWheelSize = 0; +OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = 0; +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* DEBUG DATA +* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II +********************************************************************************************************* +*/ +#if OS_DEBUG_EN > 0 + +OS_COMPILER_OPT INT16U const OSDataSize = sizeof(OSCtxSwCtr) +#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0) + + sizeof(OSEventFreeList) + + sizeof(OSEventTbl) +#endif +#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + + sizeof(OSFlagTbl) + + sizeof(OSFlagFreeList) +#endif +#if OS_TASK_STAT_EN > 0 + + sizeof(OSCPUUsage) + + sizeof(OSIdleCtrMax) + + sizeof(OSIdleCtrRun) + + sizeof(OSStatRdy) + + sizeof(OSTaskStatStk) +#endif +#if OS_TICK_STEP_EN > 0 + + sizeof(OSTickStepState) +#endif +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + + sizeof(OSMemFreeList) + + sizeof(OSMemTbl) +#endif +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + + sizeof(OSQFreeList) + + sizeof(OSQTbl) +#endif +#if OS_TIME_GET_SET_EN > 0 + + sizeof(OSTime) +#endif +#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0) + + sizeof(OSTmrFree) + + sizeof(OSTmrUsed) + + sizeof(OSTmrTime) + + sizeof(OSTmrSem) + + sizeof(OSTmrSemSignal) + + sizeof(OSTmrFreeList) + + sizeof(OSTmrTbl) + + sizeof(OSTmrWheelTbl) +#endif + + sizeof(OSIntNesting) + + sizeof(OSLockNesting) + + sizeof(OSPrioCur) + + sizeof(OSPrioHighRdy) + + sizeof(OSRdyGrp) + + sizeof(OSRdyTbl) + + sizeof(OSRunning) + + sizeof(OSTaskCtr) + + sizeof(OSIdleCtr) + + sizeof(OSTaskIdleStk) + + sizeof(OSTCBCur) + + sizeof(OSTCBFreeList) + + sizeof(OSTCBHighRdy) + + sizeof(OSTCBList) + + sizeof(OSTCBPrioTbl) + + sizeof(OSTCBTbl); + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* OS DEBUG INITIALIZAZTION +* +* Description: This function is used to make sure that debug variables that are unused in the application +* are not optimized away. This function might not be necessary for all compilers. In this +* case, you should simply DELETE the code in this function while still leaving the declaration +* of the function itself. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out +* the 'const' variables which are declared in this file. +********************************************************************************************************* +*/ + +#if OS_VERSION >= 270 && OS_DEBUG_EN > 0 +void OSDebugInit (void) +{ + void *ptemp; + + + ptemp = (void *)&OSDebugEn; + + ptemp = (void *)&OSEndiannessTest; + + ptemp = (void *)&OSEventMax; + ptemp = (void *)&OSEventNameSize; + ptemp = (void *)&OSEventEn; + ptemp = (void *)&OSEventSize; + ptemp = (void *)&OSEventTblSize; + + ptemp = (void *)&OSFlagEn; + ptemp = (void *)&OSFlagGrpSize; + ptemp = (void *)&OSFlagNodeSize; + ptemp = (void *)&OSFlagWidth; + ptemp = (void *)&OSFlagMax; + ptemp = (void *)&OSFlagNameSize; + + ptemp = (void *)&OSLowestPrio; + + ptemp = (void *)&OSMboxEn; + + ptemp = (void *)&OSMemEn; + ptemp = (void *)&OSMemMax; + ptemp = (void *)&OSMemNameSize; + ptemp = (void *)&OSMemSize; + ptemp = (void *)&OSMemTblSize; + + ptemp = (void *)&OSMutexEn; + + ptemp = (void *)&OSPtrSize; + + ptemp = (void *)&OSQEn; + ptemp = (void *)&OSQMax; + ptemp = (void *)&OSQSize; + + ptemp = (void *)&OSRdyTblSize; + + ptemp = (void *)&OSSemEn; + + ptemp = (void *)&OSStkWidth; + + ptemp = (void *)&OSTaskCreateEn; + ptemp = (void *)&OSTaskCreateExtEn; + ptemp = (void *)&OSTaskDelEn; + ptemp = (void *)&OSTaskIdleStkSize; + ptemp = (void *)&OSTaskProfileEn; + ptemp = (void *)&OSTaskMax; + ptemp = (void *)&OSTaskNameSize; + ptemp = (void *)&OSTaskStatEn; + ptemp = (void *)&OSTaskStatStkSize; + ptemp = (void *)&OSTaskStatStkChkEn; + ptemp = (void *)&OSTaskSwHookEn; + + ptemp = (void *)&OSTCBPrioTblMax; + ptemp = (void *)&OSTCBSize; + + ptemp = (void *)&OSTicksPerSec; + ptemp = (void *)&OSTimeTickHookEn; + + ptemp = (void *)&OSVersionNbr; + + ptemp = (void *)&OSDataSize; + + ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */ +} +#endif diff --git a/OS/uc/os_ii/port/os_dcc.c b/OS/uc/os_ii/port/os_dcc.c new file mode 100644 index 0000000..8a4d84c --- /dev/null +++ b/OS/uc/os_ii/port/os_dcc.c @@ -0,0 +1,220 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* +* (c) Copyright 1992-2007, Micrium, Weston, FL +* All Rights Reserved +* +* Generic ARM Port +* DCC Communication +* +* File : OS_DCC.C +* Version : V1.82 +* +* For : ARM7 or ARM9 +* Mode : ARM or Thumb +* Toolchain : IAR's EWARM V4.40a and higher +********************************************************************************************************* +*/ + +#include + /* This directive suppresses warnings for non-... */ +#pragma diag_suppress=Pe940 /* ...void functions with no return values. */ + +#if OS_CPU_ARM_DCC_EN > 0 + +/* +********************************************************************************************************* +* CONSTANTS +********************************************************************************************************* +*/ + +#define OS_DCC_OP_READ_U32 0x01000000 +#define OS_DCC_OP_READ_U16 0x02000000 +#define OS_DCC_OP_READ_U8 0x04000000 +#define OS_DCC_OP_GET_CAPS 0x08000000 +#define OS_DCC_OP_WRITE_U32 0x10000000 +#define OS_DCC_OP_WRITE_U16 0x20000000 +#define OS_DCC_OP_WRITE_U8 0x40000000 +#define OS_DCC_OP_ODD_ADDR 0x80000000 +#define OS_DCC_OP_COMMAND 0x00000001 + +#define OS_DCC_COMM_CTRL_RD 0x00000001 +#define OS_DCC_COMM_CTRL_WR 0x00000002 + +#define OS_DCC_SIGNATURE 0x91CA0000 +#define OS_DCC_CONFIG 0x00000077 + +/* +********************************************************************************************************* +* LOCAL VARIABLES +********************************************************************************************************* +*/ + +static INT32U OSDCC_Cmd; +static INT32U OSDCC_Addr; +static INT32U OSDCC_ItemCnt; +static INT32U OSDCC_Data; + +/* +********************************************************************************************************* +* OSDCC_ReadCtrl() +* +* Description: This function retrieves data from the comms control register. +* +* Arguments : none +* +* Returns : The contents of the comms control register +* +* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents +* of the comms control register in R0. Thus, the function does not contain an +* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the +* top of this file, is used to suppress the warning that normally results from non- +* void functions lacking return statements. +********************************************************************************************************* +*/ + +static __arm INT32U OSDCC_ReadCtrl (void) +{ + __asm("mrc P14,0,R0,C0,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Read() +* +* Description: This function retrieves data from the comms data read register. +* +* Arguments : none +* +* Returns : The contents of the comms data read register +* +* Notes : 1) This function uses a coprocessor register transfer instruction to place the contents +* of the comms data read register in R0. Thus, the function does not contain an +* explicit return statement. "#pragma diag_suppress=Pe940", which appears at the +* top of this file, is used to suppress the warning that normally results from non- +* void functions lacking return statements. +********************************************************************************************************* +*/ + +static __arm INT32U OSDCC_Read (void) +{ + __asm("mrc P14,0,R0,C1,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Write() +* +* Description: This function places data in the comms data write register. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static __arm void OSDCC_Write (INT32U data) +{ + __asm("mcr P14,0,R0,C1,C0"); +} + +/* +********************************************************************************************************* +* OSDCC_Handler() +* +* Description: This function reads commands from the DCC comms data read register. Data may be +* transferred to or from memory based on those commands. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function should be called periodically. If OS_CPU_ARM_DCC_EN is '1', this +* function will be called from both the idle task hook and the tick interrupt hook. +********************************************************************************************************* +*/ + +void OSDCC_Handler (void) +{ + INT32U reg_val; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + OS_ENTER_CRITICAL(); /* Disable interrupts */ + + /* Check for the presence of new data */ + if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_RD) != 0) { + reg_val = OSDCC_Read(); /* Read the new data */ + + if ((reg_val & OS_DCC_OP_COMMAND) != 0) { /* Determine whether a command has been received */ + OSDCC_Cmd = reg_val; + /* Check for an odd address in the next operation */ + if ((OSDCC_Cmd & OS_DCC_OP_ODD_ADDR) != 0) { + OSDCC_Addr |= 1; + } + /* If data will be read, adjust OSDCC_ItemCnt */ + if ((OSDCC_Cmd & (OS_DCC_OP_READ_U32 | OS_DCC_OP_READ_U16 | OS_DCC_OP_READ_U8 + | OS_DCC_OP_GET_CAPS)) != 0) { + OSDCC_ItemCnt = (OSDCC_Cmd >> 2) & 0xffff; + } else { /* Data will be written; initialize OSDCC_Data */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) { + OSDCC_Data |= (OSDCC_Cmd << 14) & 0xffff0000; + } else { + OSDCC_Data = (OSDCC_Cmd >> 2) & 0xffff; + } + /* Write a single byte */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U8) != 0) { + *(INT8U *)OSDCC_Addr = OSDCC_Data; + OSDCC_Addr += 1; + } + /* Write two bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U16) != 0) { + *(INT16U *)OSDCC_Addr = OSDCC_Data; + OSDCC_Addr += 2; + } + /* Write four bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_WRITE_U32) != 0) { + *(INT32U *)OSDCC_Addr =OSDCC_Data; + OSDCC_Addr += 4; + } + } + OS_EXIT_CRITICAL(); + return; + } + OSDCC_Addr = reg_val; /* An address was received; OSDCC_Addr is updated */ + } + /* Determine whether data must be read */ + if (OSDCC_ItemCnt != 0) { + /* Confirm that the comms data write register... */ + /* ...is free from the processor point of view */ + if ((OSDCC_ReadCtrl() & OS_DCC_COMM_CTRL_WR) == 0) { + reg_val = (OS_DCC_CONFIG | OS_DCC_SIGNATURE); + /* Read a single byte */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U8) != 0) { + reg_val = *(INT8U *)OSDCC_Addr; + OSDCC_Addr += 1; + } + /* Read two bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U16) != 0) { + reg_val = *(INT16U *)OSDCC_Addr; + OSDCC_Addr += 2; + } + /* Read four bytes */ + if ((OSDCC_Cmd & OS_DCC_OP_READ_U32) != 0) { + reg_val = *(INT32U *)OSDCC_Addr; + OSDCC_Addr += 4; + } + + OSDCC_Write(reg_val); /* Place data in the comms data write register */ + OSDCC_ItemCnt--; /* Decrement the number of items to be read */ + } + } + OS_EXIT_CRITICAL(); +} + +#endif diff --git a/OS/uc/os_ii/source/os_core.c b/OS/uc/os_ii/source/os_core.c new file mode 100644 index 0000000..7da138c --- /dev/null +++ b/OS/uc/os_ii/source/os_core.c @@ -0,0 +1,1632 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* CORE FUNCTIONS +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_CORE.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#define OS_GLOBALS +#include +#endif + +/* +********************************************************************************************************* +* PRIORITY RESOLUTION TABLE +* +* Note: Index into table is bit pattern to resolve highest priority +* Indexed value corresponds to highest priority bit position (i.e. 0..7) +********************************************************************************************************* +*/ + +INT8U const OSUnMapTbl[256] = { + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */ + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */ + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */ + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */ + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */ + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */ +}; + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_InitEventList(void); + +static void OS_InitMisc(void); + +static void OS_InitRdyList(void); + +static void OS_InitTaskIdle(void); + +#if OS_TASK_STAT_EN > 0 +static void OS_InitTaskStat(void); +#endif + +static void OS_InitTCBList(void); + +static void OS_SchedNew(void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function is used to obtain the name assigned to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, the actual +* type is irrelevant. +* +* pname is a pointer to an ASCII string that will receive the name of the semaphore, +* mutex, mailbox or queue. The string must be able to hold at least +* OS_EVENT_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* +* Returns : The length of the string or 0 if the 'pevent' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +INT8U OSEventNameGet (OS_EVENT *pevent, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + len = OS_StrCopy(pname, pevent->OSEventName); /* Copy name from OS_EVENT */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function assigns a name to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, it doesn't +* matter the actual type. +* +* pname is a pointer to an ASCII string that will be used as the name of the semaphore, +* mutex, mailbox or queue. The string must be able to hold at least +* OS_EVENT_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +void OSEventNameSet (OS_EVENT *pevent, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return; + } + OS_ENTER_CRITICAL(); + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_EVENT_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pevent->OSEventName, pname); /* Yes, copy name to the event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* +* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to +* creating any uC/OS-II object and, prior to calling OSStart(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSInit (void) +{ + OSInitHookBegin(); /* Call port specific initialization code */ + + OS_InitMisc(); /* Initialize miscellaneous variables */ + + OS_InitRdyList(); /* Initialize the Ready List */ + + OS_InitTCBList(); /* Initialize the free list of OS_TCBs */ + + OS_InitEventList(); /* Initialize the free list of OS_EVENTs */ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + OS_FlagInit(); /* Initialize the event flag structures */ +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + OS_MemInit(); /* Initialize the memory manager */ +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + OS_QInit(); /* Initialize the message queue structures */ +#endif + + OS_InitTaskIdle(); /* Create the Idle Task */ +#if OS_TASK_STAT_EN > 0 + OS_InitTaskStat(); /* Create the Statistic Task */ +#endif + +#if OS_TMR_EN > 0 + OSTmr_Init(); /* Initialize the Timer Manager */ +#endif + + OSInitHookEnd(); /* Call port specific init. code */ + +#if OS_DEBUG_EN > 0 + OSDebugInit(); +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ENTER ISR +* +* Description: This function is used to notify uC/OS-II that you are about to service an interrupt +* service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus +* only perform rescheduling at the last nested ISR. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function should be called ith interrupts already disabled +* 2) Your ISR can directly increment OSIntNesting without calling this function because +* OSIntNesting has been declared 'global'. +* 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly. +* 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 5) You are allowed to nest interrupts up to 255 levels deep. +* 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because +* OSIntEnter() is always called with interrupts disabled. +********************************************************************************************************* +*/ + +void OSIntEnter (void) +{ + if (OSRunning == OS_TRUE) { + if (OSIntNesting < 255u) { + OSIntNesting++; /* Increment ISR nesting level */ + } + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* EXIT ISR +* +* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When +* the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether +* a new, high-priority task, is ready to run. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OSIntExit (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */ + OSIntNesting--; + } + if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */ + if (OSLockNesting == 0) { /* ... and not locked. */ + OS_SchedNew(); + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; +#if OS_TASK_PROFILE_EN > 0 + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Keep track of the number of ctx switches */ + OSIntCtxSw(); /* Perform interrupt level ctx switch */ + } + } + } + OS_EXIT_CRITICAL(); + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* PREVENT SCHEDULING +* +* Description: This function is used to prevent rescheduling to take place. This allows your application +* to prevent context switches until you are ready to permit context switching. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedLock (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0) { /* Can't call from an ISR */ + if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */ + OSLockNesting++; /* Increment lock nesting level */ + } + } + OS_EXIT_CRITICAL(); + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ENABLE SCHEDULING +* +* Description: This function is used to re-allow rescheduling. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedUnlock (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSLockNesting > 0) { /* Do not decrement if already 0 */ + OSLockNesting--; /* Decrement lock nesting level */ + if (OSLockNesting == 0) { /* See if scheduler is enabled and ... */ + if (OSIntNesting == 0) { /* ... not in an ISR */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* See if a HPT is ready */ + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* START MULTITASKING +* +* Description: This function is used to start the multitasking process which lets uC/OS-II manages the +* task that you have created. Before you can call OSStart(), you MUST have called OSInit() +* and you MUST have created at least one task. +* +* Arguments : none +* +* Returns : none +* +* Note : OSStartHighRdy() MUST: +* a) Call OSTaskSwHook() then, +* b) Set OSRunning to OS_TRUE. +* c) Load the context of the task pointed to by OSTCBHighRdy. +* d_ Execute the task. +********************************************************************************************************* +*/ + +void OSStart (void) +{ + if (OSRunning == OS_FALSE) { + OS_SchedNew(); /* Find highest priority's task priority number */ + OSPrioCur = OSPrioHighRdy; + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ + OSTCBCur = OSTCBHighRdy; + OSStartHighRdy(); /* Execute target specific code to start task */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS INITIALIZATION +* +* Description: This function is called by your application to establish CPU usage by first determining +* how high a 32-bit counter would count to in 1 second if no other tasks were to execute +* during that time. CPU usage is then determined by a low priority task which keeps track +* of this 32-bit counter every second but this time, with other tasks running. CPU usage is +* determined by: +* +* OSIdleCtr +* CPU Usage (%) = 100 * (1 - ------------) +* OSIdleCtrMax +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +void OSStatInit (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OSTimeDly(2); /* Synchronize with clock tick */ + OS_ENTER_CRITICAL(); + OSIdleCtr = 0L; /* Clear idle counter */ + OS_EXIT_CRITICAL(); + OSTimeDly(OS_TICKS_PER_SEC / 10); /* Determine MAX. idle counter value for 1/10 second */ + OS_ENTER_CRITICAL(); + OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1/10 second */ + OSStatRdy = OS_TRUE; + OS_EXIT_CRITICAL(); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* PROCESS SYSTEM TICK +* +* Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known +* as a 'clock tick'). This function should be called by the ticker ISR but, can also be +* called by a high priority task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSTimeTick (void) +{ + OS_TCB *ptcb; +#if OS_TICK_STEP_EN > 0 + BOOLEAN step; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_TIME_TICK_HOOK_EN > 0 + OSTimeTickHook(); /* Call user definable hook */ +#endif +#if OS_TIME_GET_SET_EN > 0 + OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */ + OSTime++; + OS_EXIT_CRITICAL(); +#endif + if (OSRunning == OS_TRUE) { +#if OS_TICK_STEP_EN > 0 + switch (OSTickStepState) { /* Determine whether we need to process a tick */ + case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */ + step = OS_TRUE; + break; + + case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */ + step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */ + break; + + case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */ + step = OS_TRUE; /* ... step command from uC/OS-View */ + OSTickStepState = OS_TICK_STEP_WAIT; + break; + + default: /* Invalid case, correct situation */ + step = OS_TRUE; + OSTickStepState = OS_TICK_STEP_DIS; + break; + } + if (step == OS_FALSE) { /* Return if waiting for step command */ + return; + } +#endif + ptcb = OSTCBList; /* Point at first TCB in TCB list */ + while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */ + OS_ENTER_CRITICAL(); + if (ptcb->OSTCBDly != 0) { /* No, Delayed or waiting for event with TO */ + if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */ + /* Check for timeout */ + if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_PEND_ANY; /* Yes, Clear status flag */ + ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ + } else { + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + } + + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } + } + } + ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */ + OS_EXIT_CRITICAL(); + } + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET VERSION +* +* Description: This function is used to return the version number of uC/OS-II. The returned value +* corresponds to uC/OS-II's version number multiplied by 100. In other words, version 2.00 +* would be returned as 200. +* +* Arguments : none +* +* Returns : the version number of uC/OS-II multiplied by 100. +********************************************************************************************************* +*/ + +INT16U OSVersion (void) +{ + return (OS_VERSION); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DUMMY FUNCTION +* +* Description: This function doesn't do anything. It is called by OSTaskDel(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0 +void OS_Dummy (void) +{ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY TO RUN BASED ON EVENT OCCURING +* +* Description: This function is called by other uC/OS-II services and is used to ready a task that was +* waiting for an event to occur. +* +* Arguments : pevent is a pointer to the event control block corresponding to the event. +* +* pmsg is a pointer to a message. This pointer is used by message oriented services +* such as MAILBOXEs and QUEUEs. The pointer is not used when called by other +* service functions. +* +* msk is a mask that is used to clear the status byte of the TCB. For example, +* OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc. +* +* pend_stat is used to indicate the readied task's pending status: +* +* OS_STAT_PEND_OK Task ready due to a post (or delete), not a timeout or +* an abort. +* OS_STAT_PEND_ABORT Task ready due to an abort. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *pmsg, INT8U msk, INT8U pend_stat) +{ + OS_TCB *ptcb; + INT8U x; + INT8U y; + INT8U prio; +#if OS_LOWEST_PRIO <= 63 + INT8U bitx; + INT8U bity; +#else + INT16U bitx; + INT16U bity; + INT16U *ptbl; +#endif + + +#if OS_LOWEST_PRIO <= 63 + y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message */ + bity = (INT8U)(1 << y); + x = OSUnMapTbl[pevent->OSEventTbl[y]]; + bitx = (INT8U)(1 << x); + prio = (INT8U)((y << 3) + x); /* Find priority of task getting the msg */ +#else + if ((pevent->OSEventGrp & 0xFF) != 0) { /* Find HPT waiting for message */ + y = OSUnMapTbl[pevent->OSEventGrp & 0xFF]; + } else { + y = OSUnMapTbl[(pevent->OSEventGrp >> 8) & 0xFF] + 8; + } + bity = (INT16U)(1 << y); + ptbl = &pevent->OSEventTbl[y]; + if ((*ptbl & 0xFF) != 0) { + x = OSUnMapTbl[*ptbl & 0xFF]; + } else { + x = OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8; + } + bitx = (INT16U)(1 << x); + prio = (INT8U)((y << 4) + x); /* Find priority of task getting the msg */ +#endif + + pevent->OSEventTbl[y] &= ~bitx; /* Remove this task from the waiting list */ + if (pevent->OSEventTbl[y] == 0) { + pevent->OSEventGrp &= ~bity; /* Clr group bit if this was only task pending */ + } + ptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB */ + ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from readying task */ + ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Unlink ECB from this task */ +#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) + ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task */ +#else + pmsg = pmsg; /* Prevent compiler warning if not used */ +#endif + ptcb->OSTCBStatPend = pend_stat; /* Set pend status of post or abort */ + ptcb->OSTCBStat &= ~msk; /* Clear bit associated with event type */ + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is ready (could be susp'd) */ + OSRdyGrp |= bity; /* Put task in the ready to run list */ + OSRdyTbl[y] |= bitx; + } + return (prio); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK WAIT FOR EVENT TO OCCUR +* +* Description: This function is called by other uC/OS-II services to suspend a task because an event has +* not occurred. +* +* Arguments : pevent is a pointer to the event control block for which the task will be waiting for. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventTaskWait (OS_EVENT *pevent) +{ + INT8U y; + + + OSTCBCur->OSTCBEventPtr = pevent; /* Store pointer to event control block in TCB */ + y = OSTCBCur->OSTCBY; /* Task no longer ready */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; /* Clear event grp bit if this was only task pending */ + } + pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list */ + pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY TO RUN BASED ON EVENT TIMEOUT OR ABORT +* +* Description: This function is called by other uC/OS-II services to make a task ready to run because a +* timeout or abort occurred. +* +* Arguments : pevent is a pointer to the event control block which is readying a task. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventTOAbort (OS_EVENT *pevent) +{ + INT8U y; + + + y = OSTCBCur->OSTCBY; + pevent->OSEventTbl[y] &= ~OSTCBCur->OSTCBBitX; /* Remove task from wait list */ + if (pevent->OSEventTbl[y] == 0x00) { + pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; + } + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ + OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set status to ready */ + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST +* +* Description: This function is called by other uC/OS-II services to initialize the event wait list. +* +* Arguments : pevent is a pointer to the event control block allocated to the event. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if OS_EVENT_EN +void OS_EventWaitListInit (OS_EVENT *pevent) +{ +#if OS_LOWEST_PRIO <= 63 + INT8U *ptbl; +#else + INT16U *ptbl; +#endif + INT8U i; + + + pevent->OSEventGrp = 0; /* No task waiting on event */ + ptbl = &pevent->OSEventTbl[0]; + + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *ptbl++ = 0; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF EVENT CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of event control blocks. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitEventList (void) +{ +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +#if (OS_MAX_EVENTS > 1) + INT16U i; + OS_EVENT *pevent1; + OS_EVENT *pevent2; + + + OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table */ + pevent1 = &OSEventTbl[0]; + pevent2 = &OSEventTbl[1]; + for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */ + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = pevent2; +#if OS_EVENT_NAME_SIZE > 1 + pevent1->OSEventName[0] = '?'; /* Unknown name */ + pevent1->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent1++; + pevent2++; + } + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_SIZE > 1 + pevent1->OSEventName[0] = '?'; + pevent1->OSEventName[1] = OS_ASCII_NUL; +#endif + OSEventFreeList = &OSEventTbl[0]; +#else + OSEventFreeList = &OSEventTbl[0]; /* Only have ONE event control block */ + OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED; + OSEventFreeList->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_SIZE > 1 + OSEventFreeList->OSEventName[0] = '?'; /* Unknown name */ + OSEventFreeList->OSEventName[1] = OS_ASCII_NUL; +#endif +#endif +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE MISCELLANEOUS VARIABLES +* +* Description: This function is called by OSInit() to initialize miscellaneous variables. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitMisc (void) +{ +#if OS_TIME_GET_SET_EN > 0 + OSTime = 0L; /* Clear the 32-bit system clock */ +#endif + + OSIntNesting = 0; /* Clear the interrupt nesting counter */ + OSLockNesting = 0; /* Clear the scheduling lock counter */ + + OSTaskCtr = 0; /* Clear the number of tasks */ + + OSRunning = OS_FALSE; /* Indicate that multitasking not started */ + + OSCtxSwCtr = 0; /* Clear the context switch counter */ + OSIdleCtr = 0L; /* Clear the 32-bit idle counter */ + +#if OS_TASK_STAT_EN > 0 + OSIdleCtrRun = 0L; + OSIdleCtrMax = 0L; + OSStatRdy = OS_FALSE; /* Statistic task is not ready */ +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE READY LIST +* +* Description: This function is called by OSInit() to initialize the Ready List. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitRdyList (void) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *prdytbl; +#else + INT16U *prdytbl; +#endif + + + OSRdyGrp = 0; /* Clear the ready list */ + prdytbl = &OSRdyTbl[0]; + for (i = 0; i < OS_RDY_TBL_SIZE; i++) { + *prdytbl++ = 0; + } + + OSPrioCur = 0; + OSPrioHighRdy = 0; + + OSTCBHighRdy = (OS_TCB *)0; + OSTCBCur = (OS_TCB *)0; +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE IDLE TASK +* +* Description: This function creates the Idle Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTaskIdle (void) +{ +#if OS_TASK_NAME_SIZE > 7 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[0], /* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], + OS_TASK_IDLE_PRIO); + #else + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[0], + OS_TASK_IDLE_PRIO); + #endif +#endif + +#if OS_TASK_NAME_SIZE > 14 + OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"uC/OS-II Idle", &err); +#else +#if OS_TASK_NAME_SIZE > 7 + OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)"OS-Idle", &err); +#endif +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE STATISTIC TASK +* +* Description: This function creates the Statistic Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +static void OS_InitTaskStat (void) +{ +#if OS_TASK_NAME_SIZE > 7 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #else + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #else + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #endif +#endif + +#if OS_TASK_NAME_SIZE > 14 + OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err); +#else +#if OS_TASK_NAME_SIZE > 7 + OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err); +#endif +#endif +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TASK CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TCBs. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTCBList (void) +{ + INT8U i; + OS_TCB *ptcb1; + OS_TCB *ptcb2; + + + OS_MemClr((INT8U *)&OSTCBTbl[0], sizeof(OSTCBTbl)); /* Clear all the TCBs */ + OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl)); /* Clear the priority table */ + ptcb1 = &OSTCBTbl[0]; + ptcb2 = &OSTCBTbl[1]; + for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { /* Init. list of free TCBs */ + ptcb1->OSTCBNext = ptcb2; +#if OS_TASK_NAME_SIZE > 1 + ptcb1->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + ptcb1++; + ptcb2++; + } + ptcb1->OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */ +#if OS_TASK_NAME_SIZE > 1 + ptcb1->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + OSTCBList = (OS_TCB *)0; /* TCB lists initializations */ + OSTCBFreeList = &OSTCBTbl[0]; +} +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR A SECTION OF MEMORY +* +* Description: This function is called by other uC/OS-II services to clear a contiguous block of RAM. +* +* Arguments : pdest is the start of the RAM to clear (i.e. write 0x00 to) +* +* size is the number of bytes to clear. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Note that we can only clear up to 64K bytes of RAM. This is not an issue because none +* of the uses of this function gets close to this limit. +* 3) The clear is done one byte at a time since this will work on any processor irrespective +* of the alignment of the destination. +********************************************************************************************************* +*/ + +void OS_MemClr (INT8U *pdest, INT16U size) +{ + while (size > 0) { + *pdest++ = (INT8U)0; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* COPY A BLOCK OF MEMORY +* +* Description: This function is called by other uC/OS-II services to copy a block of memory from one +* location to another. +* +* Arguments : pdest is a pointer to the 'destination' memory block +* +* psrc is a pointer to the 'source' memory block +* +* size is the number of bytes to copy. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. There is +* no provision to handle overlapping memory copy. However, that's not a problem since this +* is not a situation that will happen. +* 2) Note that we can only copy up to 64K bytes of RAM +* 3) The copy is done one byte at a time since this will work on any processor irrespective +* of the alignment of the source and destination. +********************************************************************************************************* +*/ + +void OS_MemCopy (INT8U *pdest, INT8U *psrc, INT16U size) +{ + while (size > 0) { + *pdest++ = *psrc++; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* SCHEDULER +* +* Description: This function is called by other uC/OS-II services to determine whether a new, high +* priority task has been made ready to run. This function is invoked by TASK level code +* and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling). +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OS_Sched (void) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0) { /* Schedule only if all ISRs done and ... */ + if (OSLockNesting == 0) { /* ... scheduler is not locked */ + OS_SchedNew(); + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; +#if OS_TASK_PROFILE_EN > 0 + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Increment context switch counter */ + OS_TASK_SW(); /* Perform a context switch */ + } + } + } + OS_EXIT_CRITICAL(); +} + + +/* +********************************************************************************************************* +* FIND HIGHEST PRIORITY TASK READY TO RUN +* +* Description: This function is called by other uC/OS-II services to determine the highest priority task +* that is ready to run. The global variable 'OSPrioHighRdy' is changed accordingly. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Interrupts are assumed to be disabled when this function is called. +********************************************************************************************************* +*/ + +static void OS_SchedNew (void) +{ +#if OS_LOWEST_PRIO <= 63 /* See if we support up to 64 tasks */ + INT8U y; + + + y = OSUnMapTbl[OSRdyGrp]; + OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); +#else /* We support up to 256 tasks */ + INT8U y; + INT16U *ptbl; + + + if ((OSRdyGrp & 0xFF) != 0) { + y = OSUnMapTbl[OSRdyGrp & 0xFF]; + } else { + y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8; + } + ptbl = &OSRdyTbl[y]; + if ((*ptbl & 0xFF) != 0) { + OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]); + } else { + OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8); + } +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* COPY AN ASCII STRING +* +* Description: This function is called by other uC/OS-II services to copy an ASCII string from a 'source' +* string to a 'destination' string. +* +* Arguments : pdest is a pointer to the string that will be receiving the copy. Note that there MUST +* be sufficient space in the destination storage area to receive this string. +* +* psrc is a pointer to the source string. The source string MUST NOT be greater than +* 254 characters. +* +* Returns : The size of the string (excluding the NUL terminating character) +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) || (OS_TMR_CFG_NAME_SIZE > 1) +INT8U OS_StrCopy (INT8U *pdest, INT8U *psrc) +{ + INT8U len; + + + len = 0; + while (*psrc != OS_ASCII_NUL) { + *pdest++ = *psrc++; + len++; + } + *pdest = OS_ASCII_NUL; + return (len); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* DETERMINE THE LENGTH OF AN ASCII STRING +* +* Description: This function is called by other uC/OS-II services to determine the size of an ASCII string +* (excluding the NUL character). +* +* Arguments : psrc is a pointer to the string for which we need to know the size. +* +* Returns : The size of the string (excluding the NUL terminating character) +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) The string to check must be less than 255 characters long. +********************************************************************************************************* +*/ + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) || (OS_TMR_CFG_NAME_SIZE > 1) +INT8U OS_StrLen (INT8U *psrc) +{ + INT8U len; + + + len = 0; + while (*psrc != OS_ASCII_NUL) { + psrc++; + len++; + } + return (len); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* IDLE TASK +* +* Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks +* executes because they are ALL waiting for event(s) to occur. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be +* enabled for at least a few instructions. On some processors (ex. Philips XA), enabling +* and then disabling interrupts didn't allow the processor enough time to have interrupts +* enabled before they were disabled again. uC/OS-II would thus never recognize +* interrupts. +* 2) This hook has been added to allow you to do such things as STOP the CPU to conserve +* power. +********************************************************************************************************* +*/ + +void OS_TaskIdle (void *p_arg) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + (void)p_arg; /* Prevent compiler warning for not using 'parg' */ + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtr++; + OS_EXIT_CRITICAL(); + OSTaskIdleHook(); /* Call user definable HOOK */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS TASK +* +* Description: This task is internal to uC/OS-II and is used to compute some statistics about the +* multitasking environment. Specifically, OS_TaskStat() computes the CPU usage. +* CPU usage is determined by: +* +* OSIdleCtr +* OSCPUUsage = 100 * (1 - ------------) (units are in %) +* OSIdleCtrMax +* +* Arguments : parg this pointer is not used at this time. +* +* Returns : none +* +* Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the +* next higher priority, OS_TASK_IDLE_PRIO-1. +* 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0. +* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the +* maximum value for the idle counter. +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0 +void OS_TaskStat (void *p_arg) +{ + INT32U run; + INT32U max; + INT8S usage; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + p_arg = p_arg; /* Prevent compiler warning for not using 'parg' */ + while (OSStatRdy == OS_FALSE) { + OSTimeDly(2 * OS_TICKS_PER_SEC / 10); /* Wait until statistic task is ready */ + } + max = OSIdleCtrMax / 100L; + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */ + run = OSIdleCtr; + OSIdleCtr = 0L; /* Reset the idle counter for the next second */ + OS_EXIT_CRITICAL(); + if (max > 0L) { + usage = (INT8S)(100L - run / max); + if (usage >= 0) { /* Make sure we don't have a negative percentage */ + OSCPUUsage = usage; + } else { + OSCPUUsage = 0; + } + } else { + OSCPUUsage = 0; + max = OSIdleCtrMax / 100L; + } + OSTaskStatHook(); /* Invoke user definable hook */ +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) + OS_TaskStatStkChk(); /* Check the stacks for each task */ +#endif + OSTimeDly(OS_TICKS_PER_SEC / 10); /* Accumulate OSIdleCtr for the next 1/10 second */ + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK ALL TASK STACKS +* +* Description: This function is called by OS_TaskStat() to check the stacks of each active task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) +void OS_TaskStatStkChk (void) +{ + OS_TCB *ptcb; + OS_STK_DATA stk_data; + INT8U err; + INT8U prio; + + + for (prio = 0; prio <= OS_TASK_IDLE_PRIO; prio++) { + err = OSTaskStkChk(prio, &stk_data); + if (err == OS_ERR_NONE) { + ptcb = OSTCBPrioTbl[prio]; + if (ptcb != (OS_TCB *)0) { /* Make sure task 'ptcb' is ... */ + if (ptcb != OS_TCB_RESERVED) { /* ... still valid. */ +#if OS_TASK_PROFILE_EN > 0 + #if OS_STK_GROWTH == 1 + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom + ptcb->OSTCBStkSize; + #else + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom - ptcb->OSTCBStkSize; + #endif + ptcb->OSTCBStkUsed = stk_data.OSUsed; /* Store the number of bytes used */ +#endif + } + } + } + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE TCB +* +* Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when +* a task is created (see OSTaskCreate() and OSTaskCreateExt()). +* +* Arguments : prio is the priority of the task being created +* +* ptos is a pointer to the task's top-of-stack assuming that the CPU registers +* have been placed on the stack. Note that the top-of-stack corresponds to a +* 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory +* location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU +* specific. +* +* pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by +* 'OSTaskCreate()'. +* +* id is the task's ID (0..65535) +* +* stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us +* then, 'stk_size' contains the number of bytes for the stack. If the stack +* units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack +* units are established by the #define constant OS_STK which is CPU +* specific. 'stk_size' is 0 if called by 'OSTaskCreate()'. +* +* pext is a pointer to a user supplied memory area that is used to extend the task +* control block. This allows you to store the contents of floating-point +* registers, MMU registers or anything else you could find useful during a +* context switch. You can even assign a name to each task and store this name +* in this TCB extension. A NULL pointer is passed if called by OSTaskCreate(). +* +* opt options as passed to 'OSTaskCreateExt()' or, +* 0 if called from 'OSTaskCreate()'. +* +* Returns : OS_ERR_NONE if the call was successful +* OS_ERR_TASK_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot +* be created. +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */ + if (ptcb != (OS_TCB *)0) { + OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */ + OS_EXIT_CRITICAL(); + ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */ + ptcb->OSTCBPrio = prio; /* Load task priority into TCB */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ + ptcb->OSTCBDly = 0; /* Task is not delayed */ + +#if OS_TASK_CREATE_EXT_EN > 0 + ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */ + ptcb->OSTCBStkSize = stk_size; /* Store stack size */ + ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */ + ptcb->OSTCBOpt = opt; /* Store task options */ + ptcb->OSTCBId = id; /* Store task ID */ +#else + pext = pext; /* Prevent compiler warning if not used */ + stk_size = stk_size; + pbos = pbos; + opt = opt; + id = id; +#endif + +#if OS_TASK_DEL_EN > 0 + ptcb->OSTCBDelReq = OS_ERR_NONE; +#endif + +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)(prio >> 3); /* Pre-compute X, Y, BitX and BitY */ + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBX = (INT8U)(prio & 0x07); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((prio >> 4) & 0xFF);/* Pre-compute X, Y, BitX and BitY */ + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBX = (INT8U)(prio & 0x0F); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + +#if OS_EVENT_EN + ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0) + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; /* Task is not pending on an event flag */ +#endif + +#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) + ptcb->OSTCBMsg = (void *)0; /* No message received */ +#endif + +#if OS_TASK_PROFILE_EN > 0 + ptcb->OSTCBCtxSwCtr = 0L; /* Initialize profiling variables */ + ptcb->OSTCBCyclesStart = 0L; + ptcb->OSTCBCyclesTot = 0L; + ptcb->OSTCBStkBase = (OS_STK *)0; + ptcb->OSTCBStkUsed = 0L; +#endif + +#if OS_TASK_NAME_SIZE > 1 + ptcb->OSTCBTaskName[0] = '?'; /* Unknown name at task creation */ + ptcb->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + + OSTCBInitHook(ptcb); + + OSTaskCreateHook(ptcb); /* Call user defined hook */ + + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = ptcb; + ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */ + ptcb->OSTCBPrev = (OS_TCB *)0; + if (OSTCBList != (OS_TCB *)0) { + OSTCBList->OSTCBPrev = ptcb; + } + OSTCBList = ptcb; + OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OSTaskCtr++; /* Increment the #tasks counter */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NO_MORE_TCB); +} diff --git a/OS/uc/os_ii/source/os_flag.c b/OS/uc/os_ii/source/os_flag.c new file mode 100644 index 0000000..e4445ae --- /dev/null +++ b/OS/uc/os_ii/source/os_flag.c @@ -0,0 +1,1174 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* EVENT FLAG MANAGEMENT +* +* (c) Copyright 2001-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_FLAG.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +/* +********************************************************************************************************* +* LOCAL PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_FlagBlock(OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout); +static BOOLEAN OS_FlagTaskRdy(OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy); + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP +* +* Description: This function is called to check the status of a combination of bits to be set or cleared +* in an event flag group. Your application can check for ANY bit to be set/cleared or ALL +* bits to be set/cleared. +* +* This call does not block if the desired flags are not present. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE No error +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag +* group handle. +* OS_ERR_FLAG_NOT_RDY The desired flags you are waiting for are not +* available. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task or ISR +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +#if OS_FLAG_ACCEPT_EN > 0 +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *perr) +{ + OS_FLAGS flags_rdy; + INT8U result; + BOOLEAN consume; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= ~OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + *perr = OS_ERR_NONE; /* Assume NO error until proven otherwise. */ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + break; + } + return (flags_rdy); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE AN EVENT FLAG +* +* Description: This function is called to create an event flag group. +* +* Arguments : flags Contains the initial value to store in the event flag group. +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an +* ISR. +* OS_ERR_FLAG_GRP_DEPLETED if there are no more event flag groups +* +* Returns : A pointer to an event flag group or a NULL pointer if no more groups are available. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *perr) +{ + OS_FLAG_GRP *pgrp; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAG_GRP *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */ + return ((OS_FLAG_GRP *)0); + } + OS_ENTER_CRITICAL(); + pgrp = OSFlagFreeList; /* Get next free event flag */ + if (pgrp != (OS_FLAG_GRP *)0) { /* See if we have event flag groups available */ + /* Adjust free list */ + OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList; + pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* Set to event flag group type */ + pgrp->OSFlagFlags = flags; /* Set to desired initial value */ + pgrp->OSFlagWaitList = (void *)0; /* Clear list of tasks waiting on flags */ +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_GRP_DEPLETED; + } + return (pgrp); /* Return pointer to event flag group */ +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE AN EVENT FLAG GROUP +* +* Description: This function deletes an event flag group and readies all tasks pending on the event flag +* group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the event flag group even if tasks are +* waiting. In this case, all the tasks pending will be +* readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the event flag group was +* deleted +* OS_ERR_DEL_ISR If you attempted to delete the event flag group from +* an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag +* group. +* +* Returns : pgrp upon error +* (OS_EVENT *)0 if the event flag group was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend(). +* 2) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the event flag group. +********************************************************************************************************* +*/ + +#if OS_FLAG_DEL_EN > 0 +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_FLAG_NODE *pnode; + OS_FLAG_GRP *pgrp_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pgrp); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return (pgrp); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pgrp); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event group type */ + *perr = OS_ERR_EVENT_TYPE; + return (pgrp); + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagWaitList != (void *)0) { /* See if any tasks waiting on event flags */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete group if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; /* Unknown name */ + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pgrp_return = pgrp; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the event flag group */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Ready ALL tasks waiting for flags */ + (void)OS_FlagTaskRdy(pnode, (OS_FLAGS)0); + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + } +#if OS_FLAG_NAME_SIZE > 1 + pgrp->OSFlagName[0] = '?'; /* Unknown name */ + pgrp->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pgrp_return = pgrp; + break; + } + return (pgrp_return); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF AN EVENT FLAG GROUP +* +* Description: This function is used to obtain the name assigned to an event flag group +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is a pointer to an ASCII string that will receive the name of the event flag +* group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_GET_ISR if you called this function from an ISR +* +* Returns : The length of the string or 0 if the 'pgrp' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_SIZE > 1 +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + len = OS_StrCopy(pname, pgrp->OSFlagName); /* Copy name from OS_FLAG_GRP */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO AN EVENT FLAG GROUP +* +* Description: This function assigns a name to an event flag group. +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is a pointer to an ASCII string that will be used as the name of the event flag +* group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_SIZE > 1 +void OSFlagNameSet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return; + } + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_FLAG_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pgrp->OSFlagName, pname); /* Yes, copy name from OS_FLAG_GRP */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* WAIT ON AN EVENT FLAG GROUP +* +* Description: This function is called to wait for a combination of bits to be set in an event flag +* group. Your application can wait for ANY bit to be set or ALL bits to be set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set or ANY of the bits to be set. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will wait for ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will wait for ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_CLR_ANY You will wait for ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ANY You will wait for ANY bit in 'mask' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* timeout is an optional timeout (in clock ticks) that your task will wait for the +* desired bit combination. If you specify 0, however, your task will wait +* forever at the specified event flag group or, until a message arrives. +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The desired bits have been set within the specified +* 'timeout'. +* OS_ERR_PEND_ISR If you tried to PEND from an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_TIMEOUT The bit(s) have not been set in the specified +* 'timeout'. +* OS_ERR_PEND_ABORT The wait on the flag was aborted. +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task ONLY +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *perr) +{ + OS_FLAG_NODE node; + OS_FLAGS flags_rdy; + INT8U result; + INT8U pend_stat; + BOOLEAN consume; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((OS_FLAGS)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((OS_FLAGS)0); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= ~(INT8U)OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + return (flags_rdy); + } +/*$PAGE*/ + OS_Sched(); /* Find next HPT ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* Have we timed-out or aborted? */ + pend_stat = OSTCBCur->OSTCBStatPend; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OS_FlagUnlink(&node); + OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Yes, make task ready-to-run */ + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that we timed-out waiting */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted waiting */ + break; + } + return (flags_rdy); + } + flags_rdy = OSTCBCur->OSTCBFlagsRdy; + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: + case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */ + pgrp->OSFlagFlags &= ~flags_rdy; + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: + case OS_FLAG_WAIT_CLR_ANY: /* Set ONLY the flags we got */ + pgrp->OSFlagFlags |= flags_rdy; + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; /* Event(s) must have occurred */ + return (flags_rdy); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET FLAGS WHO CAUSED TASK TO BECOME READY +* +* Description: This function is called to obtain the flags that caused the task to become ready to run. +* In other words, this function allows you to tell "Who done it!". +* +* Arguments : None +* +* Returns : The flags that caused the task to be ready. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPendGetFlagsRdy (void) +{ + OS_FLAGS flags; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + flags = OSTCBCur->OSTCBFlagsRdy; + OS_EXIT_CRITICAL(); + return (flags); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST EVENT FLAG BIT(S) +* +* Description: This function is called to set or clear some bits in an event flag group. The bits to +* set or clear are specified by a 'bit mask'. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags If 'opt' (see below) is OS_FLAG_SET, each bit that is set in 'flags' will +* set the corresponding bit in the event flag group. e.g. to set bits 0, 4 +* and 5 you would set 'flags' to: +* +* 0x31 (note, bit 0 is least significant bit) +* +* If 'opt' (see below) is OS_FLAG_CLR, each bit that is set in 'flags' will +* CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0, +* 4 and 5 you would specify 'flags' as: +* +* 0x31 (note, bit 0 is least significant bit) +* +* opt indicates whether the flags will be: +* set (OS_FLAG_SET) or +* cleared (OS_FLAG_CLR) +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_INVALID_OPT You specified an invalid option +* +* Returns : the new value of the event flags bits that are still set. +* +* Called From: Task or ISR +* +* WARNING(s) : 1) The execution time of this function depends on the number of tasks waiting on the event +* flag group. +* 2) The amount of time interrupts are DISABLED depends on the number of tasks waiting on +* the event flag group. +********************************************************************************************************* +*/ +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *perr) +{ + OS_FLAG_NODE *pnode; + BOOLEAN sched; + OS_FLAGS flags_cur; + OS_FLAGS flags_rdy; + BOOLEAN rdy; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (opt) { + case OS_FLAG_CLR: + pgrp->OSFlagFlags &= ~flags; /* Clear the flags specified in the group */ + break; + + case OS_FLAG_SET: + pgrp->OSFlagFlags |= flags; /* Set the flags specified in the group */ + break; + + default: + OS_EXIT_CRITICAL(); /* INVALID option */ + *perr = OS_ERR_FLAG_INVALID_OPT; + return ((OS_FLAGS)0); + } + sched = OS_FALSE; /* Indicate that we don't need rescheduling */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Go through all tasks waiting on event flag(s) */ + switch (pnode->OSFlagNodeWaitType) { + case OS_FLAG_WAIT_SET_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_SET_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0 + case OS_FLAG_WAIT_CLR_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_CLR_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)(~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */ + } + OS_EXIT_CRITICAL(); + if (sched == OS_TRUE) { + OS_Sched(); + } + OS_ENTER_CRITICAL(); + flags_cur = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags_cur); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY EVENT FLAG +* +* Description: This function is used to check the value of the event flag group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* perr is a pointer to an error code returned to the called: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* +* Returns : The current value of the event flag group. +* +* Called From: Task or ISR +********************************************************************************************************* +*/ + +#if OS_FLAG_QUERY_EN > 0 +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *perr) +{ + OS_FLAGS flags; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_FLAGS)0); + } + if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + OS_ENTER_CRITICAL(); + flags = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags); /* Return the current value of the event flags */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS +* +* Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired +* event flag bit(s) are set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'mask' to be set (1) +* +* timeout is the desired amount of time that the task will wait for the event flag +* bit(s) to be set. +* +* Returns : none +* +* Called by : OSFlagPend() OS_FLAG.C +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static void OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout) +{ + OS_FLAG_NODE *pnode_next; + INT8U y; + + + OSTCBCur->OSTCBStat |= OS_STAT_FLAG; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store timeout in task's TCB */ +#if OS_TASK_DEL_EN > 0 + OSTCBCur->OSTCBFlagNode = pnode; /* TCB to link to node */ +#endif + pnode->OSFlagNodeFlags = flags; /* Save the flags that we need to wait for */ + pnode->OSFlagNodeWaitType = wait_type; /* Save the type of wait we are doing */ + pnode->OSFlagNodeTCB = (void *)OSTCBCur; /* Link to task's TCB */ + pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */ + pnode->OSFlagNodePrev = (void *)0; + pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* Link to Event Flag Group */ + pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + if (pnode_next != (void *)0) { /* Is this the first NODE to insert? */ + pnode_next->OSFlagNodePrev = pnode; /* No, link in doubly linked list */ + } + pgrp->OSFlagWaitList = (void *)pnode; + + y = OSTCBCur->OSTCBY; /* Suspend current task until flag(s) received */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0x00) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE THE EVENT FLAG MODULE +* +* Description: This function is called by uC/OS-II to initialize the event flag module. Your application +* MUST NOT call this function. In other words, this function is internal to uC/OS-II. +* +* Arguments : none +* +* Returns : none +* +* WARNING : You MUST NOT call this function from your code. This is an INTERNAL function to uC/OS-II. +********************************************************************************************************* +*/ + +void OS_FlagInit (void) +{ +#if OS_MAX_FLAGS == 1 + OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */ + OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED; + OSFlagFreeList->OSFlagWaitList = (void *)0; + OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0; +#if OS_FLAG_NAME_SIZE > 1 + OSFlagFreeList->OSFlagName[0] = '?'; + OSFlagFreeList->OSFlagName[1] = OS_ASCII_NUL; +#endif +#endif + +#if OS_MAX_FLAGS >= 2 + INT16U i; + OS_FLAG_GRP *pgrp1; + OS_FLAG_GRP *pgrp2; + + + OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); /* Clear the flag group table */ + pgrp1 = &OSFlagTbl[0]; + pgrp2 = &OSFlagTbl[1]; + for (i = 0; i < (OS_MAX_FLAGS - 1); i++) { /* Init. list of free EVENT FLAGS */ + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)pgrp2; +#if OS_FLAG_NAME_SIZE > 1 + pgrp1->OSFlagName[0] = '?'; /* Unknown name */ + pgrp1->OSFlagName[1] = OS_ASCII_NUL; +#endif + pgrp1++; + pgrp2++; + } + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)0; +#if OS_FLAG_NAME_SIZE > 1 + pgrp1->OSFlagName[0] = '?'; /* Unknown name */ + pgrp1->OSFlagName[1] = OS_ASCII_NUL; +#endif + OSFlagFreeList = &OSFlagTbl[0]; +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED +* +* Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the +* desired event flag bits have been set. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags_rdy contains the bit pattern of the event flags that cause the task to become +* ready-to-run. +* +* Returns : OS_TRUE If the task has been placed in the ready list and thus needs scheduling +* OS_FALSE The task is still not ready to run and thus scheduling is not necessary +* +* Called by : OSFlagsPost() OS_FLAG.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy) +{ + OS_TCB *ptcb; + BOOLEAN sched; + + + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* Point to TCB of waiting task */ + ptcb->OSTCBDly = 0; + ptcb->OSTCBFlagsRdy = flags_rdy; + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_FLAG; + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Task now ready? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* Put task into ready list */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + sched = OS_TRUE; + } else { + sched = OS_FALSE; + } + OS_FlagUnlink(pnode); + return (sched); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* UNLINK EVENT FLAG NODE FROM WAITING LIST +* +* Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a +* list of tasks waiting for the event flag. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* Returns : none +* +* Called by : OS_FlagTaskRdy() OS_FLAG.C +* OSFlagPend() OS_FLAG.C +* OSTaskDel() OS_TASK.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_FlagUnlink (OS_FLAG_NODE *pnode) +{ +#if OS_TASK_DEL_EN > 0 + OS_TCB *ptcb; +#endif + OS_FLAG_GRP *pgrp; + OS_FLAG_NODE *pnode_prev; + OS_FLAG_NODE *pnode_next; + + + pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev; + pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */ + pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp; + pgrp->OSFlagWaitList = (void *)pnode_next; /* Update list for new 1st node */ + if (pnode_next != (OS_FLAG_NODE *)0) { + pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* Link new 1st node PREV to NULL */ + } + } else { /* No, A node somewhere in the list */ + pnode_prev->OSFlagNodeNext = pnode_next; /* Link around the node to unlink */ + if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */ + pnode_next->OSFlagNodePrev = pnode_prev; /* No, Link around current node */ + } + } +#if OS_TASK_DEL_EN > 0 + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; +#endif +} +#endif diff --git a/OS/uc/os_ii/source/os_mbox.c b/OS/uc/os_ii/source/os_mbox.c new file mode 100644 index 0000000..fa4dcdc --- /dev/null +++ b/OS/uc/os_ii/source/os_mbox.c @@ -0,0 +1,626 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MESSAGE MAILBOX MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_MBOX.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if OS_MBOX_EN > 0 +/* +********************************************************************************************************* +* ACCEPT MESSAGE FROM MAILBOX +* +* Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(), +* OSMboxAccept() does not suspend the calling task if a message is not available. +* +* Arguments : pevent is a pointer to the event control block +* +* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared +* so the next time OSMboxAccept() is called, the mailbox will be empty. +* == (void *)0 if the mailbox is empty or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass the proper event pointer. +********************************************************************************************************* +*/ + +#if OS_MBOX_ACCEPT_EN > 0 +void *OSMboxAccept (OS_EVENT *pevent) +{ + void *pmsg; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pmsg = pevent->OSEventPtr; + pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ + OS_EXIT_CRITICAL(); + return (pmsg); /* Return the message received (or NULL) */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MESSAGE MAILBOX +* +* Description: This function creates a message mailbox if free event control blocks are available. +* +* Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If +* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox +* will be considered empty. +* +* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created mailbox +* == (OS_EVENT *)0 if no event control blocks were available +********************************************************************************************************* +*/ + +OS_EVENT *OSMboxCreate (void *pmsg) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { + pevent->OSEventType = OS_EVENT_TYPE_MBOX; + pevent->OSEventCnt = 0; + pevent->OSEventPtr = pmsg; /* Deposit message in event control block */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); + } + return (pevent); /* Return pointer to event control block */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MAIBOX +* +* Description: This function deletes a mailbox and readies all tasks pending on the mailbox. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mailbox. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the mailbox was deleted +* OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the mailbox was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the mailbox MUST check the return code of OSMboxPend(). +* 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted! +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the mailbox. +* 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in +* applications where the mailbox is used for mutual exclusion because the resource(s) +* will no longer be guarded by the mailbox. +********************************************************************************************************* +*/ + +#if OS_MBOX_DEL_EN > 0 +OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mailbox */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the mailbox */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mailbox */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON MAILBOX FOR A MESSAGE +* +* Description: This function waits for a message to be sent to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for a message to arrive at the mailbox up to the amount of time +* specified by this argument. If you specify 0, however, your task will wait +* forever at the specified mailbox or, until a message arrives. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the mailbox was aborted. +* OS_ERR_EVENT_TYPE Invalid event type +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : != (void *)0 is a pointer to the message received +* == (void *)0 if no message was received or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass the proper pointer to the event control block. +********************************************************************************************************* +*/ + +void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + void *pmsg; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((void *)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pmsg = pevent->OSEventPtr; + if (pmsg != (void *)0) { /* See if there is already a message */ + pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return the message received (or NULL) */ + } + OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we weren't given the message */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); /* Timed out, Make task ready */ + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that a timeout occured */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return ((void *)0); /* Return a NULL message */ + } + pmsg = OSTCBCur->OSTCBMsg; + OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */ + OSTCBCur->OSTCBStat = OS_STAT_RDY; + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return the message received */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A MESSAGE MAILBOX +* +* Description: This function aborts & readies any tasks currently waiting on a mailbox. This function +* should be used to fault-abort the wait on the mailbox, rather than to normally signal +* the mailbox via OSMboxPost() or OSMboxPostOpt(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* mailbox +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* mailbox +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the mailbox. +* OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the mailbox +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the mailbox, or upon error. +* > 0 if one or more tasks waiting on the mailbox are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_MBOX_PEND_ABORT_EN > 0 +INT8U OSMboxPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on mailbox? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on mailbox */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on mailbox */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on mailbox */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A MAILBOX +* +* Description: This function sends a message to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one +* message at a time and thus, the message MUST be consumed before you +* are allowed to send another one. +* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer +* +* Note(s) : 1) HPT means Highest Priority Task +********************************************************************************************************* +*/ + +#if OS_MBOX_POST_EN > 0 +INT8U OSMboxPost (OS_EVENT *pevent, void *pmsg) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ + return (OS_ERR_POST_NULL_PTR); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ + /* Ready HPT waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MBOX_FULL); + } + pevent->OSEventPtr = pmsg; /* Place message in mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A MAILBOX +* +* Description: This function sends a message to a mailbox +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. +* +* opt determines the type of POST performed: +* OS_POST_OPT_NONE POST to a single waiting task +* (Identical to OSMboxPost()) +* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox +* +* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one +* message at a time and thus, the message MUST be consumed before you +* are allowed to send another one. +* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer +* +* Note(s) : 1) HPT means Highest Priority Task +* +* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the +* interrupt disable time is proportional to the number of tasks waiting on the mailbox. +********************************************************************************************************* +*/ + +#if OS_MBOX_POST_OPT_EN > 0 +INT8U OSMboxPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ + return (OS_ERR_POST_NULL_PTR); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ + if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ + while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on mailbox */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + } + } else { /* No, Post to HPT waiting on mbox */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); + } + OS_EXIT_CRITICAL(); + if ((opt & OS_POST_OPT_NO_SCHED) == 0) { /* See if scheduler needs to be invoked */ + OS_Sched(); /* Find HPT ready to run */ + } + return (OS_ERR_NONE); + } + if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MBOX_FULL); + } + pevent->OSEventPtr = pmsg; /* Place message in mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MESSAGE MAILBOX +* +* Description: This function obtains information about a message mailbox. +* +* Arguments : pevent is a pointer to the event control block associated with the desired mailbox +* +* p_mbox_data is a pointer to a structure that will contain information about the message +* mailbox. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_MBOX_QUERY_EN > 0 +INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *p_mbox_data) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_mbox_data == (OS_MBOX_DATA *)0) { /* Validate 'p_mbox_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_mbox_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_mbox_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + p_mbox_data->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_MBOX_QUERY_EN */ +#endif /* OS_MBOX_EN */ diff --git a/OS/uc/os_ii/source/os_mem.c b/OS/uc/os_ii/source/os_mem.c new file mode 100644 index 0000000..96eecd4 --- /dev/null +++ b/OS/uc/os_ii/source/os_mem.c @@ -0,0 +1,434 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MEMORY MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_MEM.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +/* +********************************************************************************************************* +* CREATE A MEMORY PARTITION +* +* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II. +* +* Arguments : addr is the starting address of the memory partition +* +* nblks is the number of memory blocks to create from the partition. +* +* blksize is the size (in bytes) of each block in the memory partition. +* +* perr is a pointer to a variable containing an error message which will be set by +* this function to either: +* +* OS_ERR_NONE if the memory partition has been created correctly. +* OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory +* storage of the partition or, the block does not align +* on a pointer boundary +* OS_ERR_MEM_INVALID_PART no free partitions available +* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2) +* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size +* - must be greater than the size of a pointer +* - must be able to hold an integral number of pointers +* Returns : != (OS_MEM *)0 is the partition was created +* == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no +* free partition is available. +********************************************************************************************************* +*/ + +OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *perr) +{ + OS_MEM *pmem; + INT8U *pblk; + void **plink; + INT32U i; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_MEM *)0); + } + if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/ + *perr = OS_ERR_MEM_INVALID_ADDR; + return ((OS_MEM *)0); + } + if (((INT32U)addr & (sizeof(void *) - 1)) != 0){ /* Must be pointer size aligned */ + *perr = OS_ERR_MEM_INVALID_ADDR; + return ((OS_MEM *)0); + } + if (nblks < 2) { /* Must have at least 2 blocks per partition */ + *perr = OS_ERR_MEM_INVALID_BLKS; + return ((OS_MEM *)0); + } + if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */ + *perr = OS_ERR_MEM_INVALID_SIZE; + return ((OS_MEM *)0); + } +#endif + OS_ENTER_CRITICAL(); + pmem = OSMemFreeList; /* Get next free memory partition */ + if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */ + OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; + } + OS_EXIT_CRITICAL(); + if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */ + *perr = OS_ERR_MEM_INVALID_PART; + return ((OS_MEM *)0); + } + plink = (void **)addr; /* Create linked list of free memory blocks */ + pblk = (INT8U *)((INT32U)addr + blksize); + for (i = 0; i < (nblks - 1); i++) { + *plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */ + plink = (void **)pblk; /* Position to NEXT block */ + pblk = (INT8U *)((INT32U)pblk + blksize); /* Point to the FOLLOWING block */ + } + *plink = (void *)0; /* Last memory block points to NULL */ + pmem->OSMemAddr = addr; /* Store start address of memory partition */ + pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */ + pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */ + pmem->OSMemNBlks = nblks; + pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */ + *perr = OS_ERR_NONE; + return (pmem); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET A MEMORY BLOCK +* +* Description : Get a memory block from a partition +* +* Arguments : pmem is a pointer to the memory partition control block +* +* perr is a pointer to a variable containing an error message which will be set by this +* function to either: +* +* OS_ERR_NONE if the memory partition has been created correctly. +* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* +* Returns : A pointer to a memory block if no error is detected +* A pointer to NULL if an error is detected +********************************************************************************************************* +*/ + +void *OSMemGet (OS_MEM *pmem, INT8U *perr) +{ + void *pblk; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return ((void *)0); + } +#endif + OS_ENTER_CRITICAL(); + if (pmem->OSMemNFree > 0) { /* See if there are any free memory blocks */ + pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */ + pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */ + pmem->OSMemNFree--; /* One less memory block in this partition */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; /* No error */ + return (pblk); /* Return memory block to caller */ + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */ + return ((void *)0); /* Return NULL pointer to caller */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A MEMORY PARTITION +* +* Description: This function is used to obtain the name assigned to a memory partition. +* +* Arguments : pmem is a pointer to the memory partition +* +* pname is a pointer to an ASCII string that will receive the name of the memory partition. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_NAME_GET_ISR You called this function from an ISR +* +* Returns : The length of the string or 0 if 'pmem' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_MEM_NAME_SIZE > 1 +INT8U OSMemNameGet (OS_MEM *pmem, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return (0); + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + len = OS_StrCopy(pname, pmem->OSMemName); /* Copy name from OS_MEM */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A MEMORY PARTITION +* +* Description: This function assigns a name to a memory partition. +* +* Arguments : pmem is a pointer to the memory partition +* +* pname is a pointer to an ASCII string that contains the name of the memory partition. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the name was copied to 'pname' +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_MEM_NAME_SIZE > 1 +void OSMemNameSet (OS_MEM *pmem, INT8U *pname, INT8U *perr) +{ + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ + *perr = OS_ERR_MEM_INVALID_PMEM; + return; + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + len = OS_StrLen(pname); /* Can we fit the string in the storage area? */ + if (len > (OS_MEM_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_MEM_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(pmem->OSMemName, pname); /* Yes, copy name to the memory partition header */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* RELEASE A MEMORY BLOCK +* +* Description : Returns a memory block to a partition +* +* Arguments : pmem is a pointer to the memory partition control block +* +* pblk is a pointer to the memory block being released. +* +* Returns : OS_ERR_NONE if the memory block was inserted into the partition +* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory +* partition (You freed more blocks than you allocated!) +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release. +********************************************************************************************************* +*/ + +INT8U OSMemPut (OS_MEM *pmem, void *pblk) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + return (OS_ERR_MEM_INVALID_PMEM); + } + if (pblk == (void *)0) { /* Must release a valid block */ + return (OS_ERR_MEM_INVALID_PBLK); + } +#endif + OS_ENTER_CRITICAL(); + if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */ + OS_EXIT_CRITICAL(); + return (OS_ERR_MEM_FULL); + } + *(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */ + pmem->OSMemFreeList = pblk; + pmem->OSMemNFree++; /* One more memory block in this partition */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); /* Notify caller that memory block was released */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY MEMORY PARTITION +* +* Description : This function is used to determine the number of free memory blocks and the number of +* used memory blocks from a memory partition. +* +* Arguments : pmem is a pointer to the memory partition control block +* +* p_mem_data is a pointer to a structure that will contain information about the memory +* partition. +* +* Returns : OS_ERR_NONE if no errors were found. +* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' +* OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient. +********************************************************************************************************* +*/ + +#if OS_MEM_QUERY_EN > 0 +INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *p_mem_data) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ + return (OS_ERR_MEM_INVALID_PMEM); + } + if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */ + return (OS_ERR_MEM_INVALID_PDATA); + } +#endif + OS_ENTER_CRITICAL(); + p_mem_data->OSAddr = pmem->OSMemAddr; + p_mem_data->OSFreeList = pmem->OSMemFreeList; + p_mem_data->OSBlkSize = pmem->OSMemBlkSize; + p_mem_data->OSNBlks = pmem->OSMemNBlks; + p_mem_data->OSNFree = pmem->OSMemNFree; + OS_EXIT_CRITICAL(); + p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree; + return (OS_ERR_NONE); +} +#endif /* OS_MEM_QUERY_EN */ +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE MEMORY PARTITION MANAGER +* +* Description : This function is called by uC/OS-II to initialize the memory partition manager. Your +* application MUST NOT call this function. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_MemInit (void) +{ +#if OS_MAX_MEM_PART == 1 + OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ + OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */ +#if OS_MEM_NAME_SIZE > 1 + OSMemFreeList->OSMemName[0] = '?'; /* Unknown name */ + OSMemFreeList->OSMemName[1] = OS_ASCII_NUL; +#endif +#endif + +#if OS_MAX_MEM_PART >= 2 + OS_MEM *pmem; + INT16U i; + + + OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ + pmem = &OSMemTbl[0]; /* Point to memory control block (MCB) */ + for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { /* Init. list of free memory partitions */ + pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions */ +#if OS_MEM_NAME_SIZE > 1 + pmem->OSMemName[0] = '?'; /* Unknown name */ + pmem->OSMemName[1] = OS_ASCII_NUL; +#endif + pmem++; + } + pmem->OSMemFreeList = (void *)0; /* Initialize last node */ +#if OS_MEM_NAME_SIZE > 1 + pmem->OSMemName[0] = '?'; /* Unknown name */ + pmem->OSMemName[1] = OS_ASCII_NUL; +#endif + + OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */ +#endif +} +#endif /* OS_MEM_EN */ diff --git a/OS/uc/os_ii/source/os_mutex.c b/OS/uc/os_ii/source/os_mutex.c new file mode 100644 index 0000000..68e2fd0 --- /dev/null +++ b/OS/uc/os_ii/source/os_mutex.c @@ -0,0 +1,711 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_MUTEX.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + + +#if OS_MUTEX_EN > 0 +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + +#define OS_MUTEX_KEEP_LOWER_8 (INT16U)0x00FFu +#define OS_MUTEX_KEEP_UPPER_8 (INT16U)0xFF00u + +#define OS_MUTEX_AVAILABLE (INT16U)0x00FFu + +/* +********************************************************************************************************* +* LOCAL CONSTANTS +********************************************************************************************************* +*/ + +static void OSMutex_RdyAtPrio(OS_TCB *ptcb, INT8U prio); + +/*$PAGE*/ +/* +********************************************************************************************************* +* ACCEPT MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function checks the mutual exclusion semaphore to see if a resource is available. +* Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is +* not available or the event did not occur. +* +* Arguments : pevent is a pointer to the event control block +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_EVENT_TYPE if 'pevent' is not a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR if you called this function from an ISR +* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +* +* Returns : == OS_TRUE if the resource is available, the mutual exclusion semaphore is acquired +* == OS_FALSE a) if the resource is not available +* b) you didn't pass a pointer to a mutual exclusion semaphore +* c) you called this function from an ISR +* +* Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are +* intended to be used by tasks only. +********************************************************************************************************* +*/ + +#if OS_MUTEX_ACCEPT_EN > 0 +BOOLEAN OSMutexAccept (OS_EVENT *pevent, INT8U *perr) +{ + INT8U pip; /* Priority Inheritance Priority (PIP) */ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (OS_FALSE); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (OS_FALSE); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* Make sure it's not called from an ISR */ + *perr = OS_ERR_PEND_ISR; + return (OS_FALSE); + } + OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */ + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */ + if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */ + pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */ + pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */ + if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + *perr = OS_ERR_PIP_LOWER; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } + return (OS_TRUE); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (OS_FALSE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function creates a mutual exclusion semaphore. +* +* Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In +* other words, when the semaphore is acquired and a higher priority task +* attempts to obtain the semaphore then the priority of the task owning the +* semaphore is raised to this priority. It is assumed that you will specify +* a priority that is LOWER in value than ANY of the tasks competing for the +* mutex. +* +* perr is a pointer to an error code which will be returned to your application: +* OS_ERR_NONE if the call was successful. +* OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR +* OS_ERR_PRIO_EXIST if a task at the priority inheritance priority +* already exist. +* OS_ERR_PEVENT_NULL No more event control blocks available. +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the +* maximum allowed (i.e. > OS_LOWEST_PRIO) +* +* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created mutex. +* == (void *)0 if an error is detected. +* +* Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number +* of the task owning the mutex or 0xFF if no task owns the mutex. +* +* 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number +* to use to reduce priority inversion. +********************************************************************************************************* +*/ + +OS_EVENT *OSMutexCreate (INT8U prio, INT8U *perr) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((OS_EVENT *)0); + } + if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */ + *perr = OS_ERR_PRIO_INVALID; + return ((OS_EVENT *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */ + return ((OS_EVENT *)0); + } + OS_ENTER_CRITICAL(); + if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */ + OS_EXIT_CRITICAL(); /* Task already exist at priority ... */ + *perr = OS_ERR_PRIO_EXIST; /* ... inheritance priority */ + return ((OS_EVENT *)0); + } + OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */ + pevent = OSEventFreeList; /* Get next free event control block */ + if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */ + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */ + return (pevent); + } + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */ + OS_EXIT_CRITICAL(); + pevent->OSEventType = OS_EVENT_TYPE_MUTEX; + pevent->OSEventCnt = (INT16U)((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is avail. */ + pevent->OSEventPtr = (void *)0; /* No task owning the mutex */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); + *perr = OS_ERR_NONE; + return (pevent); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MUTEX +* +* Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it. +* +* Arguments : pevent is a pointer to the event control block associated with the desired mutex. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the mutex was deleted +* OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the mutex was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the mutex MUST check the return code of OSMutexPend(). +* +* 2) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the mutex. +* +* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the +* resource(s) will no longer be guarded by the mutex. +* +* 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there +* is one) is ready-to-run and is thus NOT pending on another kernel object or +* has delayed itself. In other words, if a task owns the mutex being deleted, +* that task will be made ready-to-run at its original priority. +********************************************************************************************************* +*/ + +#if OS_MUTEX_DEL_EN +OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; + INT8U pip; /* Priority inheritance priority */ + INT8U prio; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mutex */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pip = (INT8U)(pevent->OSEventCnt >> 8); + OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* ALWAYS DELETE THE MUTEX ---------------- */ + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP of mutex */ + prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original prio */ + ptcb = (OS_TCB *)pevent->OSEventPtr; + if (ptcb != (OS_TCB *)0) { /* See if any task owns the mutex */ + if (ptcb->OSTCBPrio == pip) { /* See if original prio was changed */ + OSMutex_RdyAtPrio(ptcb, prio); /* Yes, Restore the task's original prio */ + } + } + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mutex */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pip = (INT8U)(pevent->OSEventCnt >> 8); + OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function waits for a mutual exclusion semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mutex. +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for the resource up to the amount of time specified by this argument. +* If you specify 0, however, your task will wait forever at the specified +* mutex or, until the resource becomes available. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* OS_ERR_NONE The call was successful and your task owns the mutex +* OS_ERR_TIMEOUT The mutex was not available within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the mutex was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : none +* +* Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex. +* +* 2) You MUST NOT change the priority of the task that owns the mutex +********************************************************************************************************* +*/ +void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + INT8U pip; /* Priority Inheritance Priority (PIP) */ + INT8U mprio; /* Mutex owner priority */ + BOOLEAN rdy; /* Flag indicating task was ready */ + OS_TCB *ptcb; + OS_EVENT *pevent2; + INT8U y; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return; + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return; + } + OS_ENTER_CRITICAL(); + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */ + /* Is Mutex available? */ + if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */ + pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */ + pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */ + if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + *perr = OS_ERR_PIP_LOWER; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } + return; + } + mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* No, Get priority of mutex owner */ + ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */ + if (ptcb->OSTCBPrio > pip) { /* Need to promote prio of owner?*/ + if (mprio > OSTCBCur->OSTCBPrio) { + y = ptcb->OSTCBY; + if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0) { /* See if mutex owner is ready */ + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Yes, Remove owner from Rdy ...*/ + if (OSRdyTbl[y] == 0) { /* ... list at current prio */ + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + rdy = OS_TRUE; + } else { + pevent2 = ptcb->OSTCBEventPtr; + if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */ + if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { + pevent2->OSEventGrp &= ~ptcb->OSTCBBitY; + } + } + rdy = OS_FALSE; /* No */ + } + ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */ +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3); + ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07); + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((ptcb->OSTCBPrio >> 4) & 0xFF); + ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x0F); + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + if (rdy == OS_TRUE) { /* If task was ready at owner's priority ...*/ + OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } else { + pevent2 = ptcb->OSTCBEventPtr; + if (pevent2 != (OS_EVENT *)0) { /* Add to event wait list */ + pevent2->OSEventGrp |= ptcb->OSTCBBitY; + pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + } + } + OSTCBPrioTbl[pip] = ptcb; + } + } + OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend current task */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed out during the pend */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get mutex within TO */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted getting mutex */ + break; + } + return; + } + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +/*$PAGE*/ +/* +********************************************************************************************************* +* POST TO A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function signals a mutual exclusion semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* mutex. +* +* Returns : OS_ERR_NONE The call was successful and the mutex was signaled. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex +* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer +* OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes) +* OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX. +* OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is +* HIGHER (i.e. a lower number) than the PIP. This error +* indicates that you did not set the PIP higher (lower +* number) than ALL the tasks that compete for the Mutex. +* Unfortunately, this is something that could not be +* detected when the Mutex is created because we don't know +* what tasks will be using the Mutex. +********************************************************************************************************* +*/ + +INT8U OSMutexPost (OS_EVENT *pevent) +{ + INT8U pip; /* Priority inheritance priority */ + INT8U prio; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */ + } +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get priority inheritance priority of mutex */ + prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */ + if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NOT_MUTEX_OWNER); + } + if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */ + OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */ + } + OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */ + if (pevent->OSEventGrp != 0) { /* Any task waiting for the mutex? */ + /* Yes, Make HPT waiting for mutex ready */ + prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); + pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */ + pevent->OSEventCnt |= prio; + pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */ + if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */ + OS_EXIT_CRITICAL(); /* ... than current task! */ + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_PIP_LOWER); + } else { + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + } + pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */ + pevent->OSEventPtr = (void *)0; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MUTUAL EXCLUSION SEMAPHORE +* +* Description: This function obtains information about a mutex +* +* Arguments : pevent is a pointer to the event control block associated with the desired mutex +* +* p_mutex_data is a pointer to a structure that will contain information about the mutex +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_QUERY_ISR If you called this function from an ISR +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex. +********************************************************************************************************* +*/ + +#if OS_MUTEX_QUERY_EN > 0 +INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data) +{ + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */ + } +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8); + p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); + if (p_mutex_data->OSOwnerPrio == 0xFF) { + p_mutex_data->OSValue = OS_TRUE; + } else { + p_mutex_data->OSValue = OS_FALSE; + } + p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_mutex_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_MUTEX_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY +* +* Description: This function makes a task ready at the specified priority +* +* Arguments : ptcb is a pointer to OS_TCB of the task to make ready +* +* prio is the desired priority +* +* Returns : none +********************************************************************************************************* +*/ + +static void OSMutex_RdyAtPrio (OS_TCB *ptcb, INT8U prio) +{ + INT8U y; + + + y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */ + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + ptcb->OSTCBPrio = prio; +#if OS_LOWEST_PRIO <= 63 + ptcb->OSTCBY = (INT8U)((prio >> (INT8U)3) & (INT8U)0x07); + ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x07); + ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); +#else + ptcb->OSTCBY = (INT8U)((prio >> (INT8U)4) & (INT8U)0x0F); + ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x0F); + ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY); + ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX); +#endif + OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OSTCBPrioTbl[prio] = ptcb; +} + + +#endif /* OS_MUTEX_EN */ diff --git a/OS/uc/os_ii/source/os_q.c b/OS/uc/os_ii/source/os_q.c new file mode 100644 index 0000000..a93419b --- /dev/null +++ b/OS/uc/os_ii/source/os_q.c @@ -0,0 +1,865 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* MESSAGE QUEUE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_Q.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +/* +********************************************************************************************************* +* ACCEPT MESSAGE FROM QUEUE +* +* Description: This function checks the queue to see if a message is available. Unlike OSQPend(), +* OSQAccept() does not suspend the calling task if a message is not available. +* +* Arguments : pevent is a pointer to the event control block +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_Q_EMPTY The queue did not contain any messages +* +* Returns : != (void *)0 is the message in the queue if one is available. The message is removed +* from the so the next time OSQAccept() is called, the queue will contain +* one less entry. +* == (void *)0 if you received a NULL pointer message +* if the queue is empty or, +* if 'pevent' is a NULL pointer or, +* if you passed an invalid event type +* +* Note(s) : As of V2.60, you can now pass NULL pointers through queues. Because of this, the argument +* 'perr' has been added to the API to tell you about the outcome of the call. +********************************************************************************************************* +*/ + +#if OS_Q_ACCEPT_EN > 0 +void *OSQAccept (OS_EVENT *pevent, INT8U *perr) +{ + void *pmsg; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ + if (pq->OSQEntries > 0) { /* See if any messages in the queue */ + pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ + pq->OSQEntries--; /* Update the number of entries in the queue */ + if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ + pq->OSQOut = pq->OSQStart; + } + *perr = OS_ERR_NONE; + } else { + *perr = OS_ERR_Q_EMPTY; + pmsg = (void *)0; /* Queue is empty */ + } + OS_EXIT_CRITICAL(); + return (pmsg); /* Return message received (or NULL) */ +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A MESSAGE QUEUE +* +* Description: This function creates a message queue if free event control blocks are available. +* +* Arguments : start is a pointer to the base address of the message queue storage area. The +* storage area MUST be declared as an array of pointers to 'void' as follows +* +* void *MessageStorage[size] +* +* size is the number of elements in the storage area +* +* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the +* created queue +* == (OS_EVENT *)0 if no event control blocks were available or an error was detected +********************************************************************************************************* +*/ + +OS_EVENT *OSQCreate (void **start, INT16U size) +{ + OS_EVENT *pevent; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */ + OS_ENTER_CRITICAL(); + pq = OSQFreeList; /* Get a free queue control block */ + if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */ + OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/ + OS_EXIT_CRITICAL(); + pq->OSQStart = start; /* Initialize the queue */ + pq->OSQEnd = &start[size]; + pq->OSQIn = start; + pq->OSQOut = start; + pq->OSQSize = size; + pq->OSQEntries = 0; + pevent->OSEventType = OS_EVENT_TYPE_Q; + pevent->OSEventCnt = 0; + pevent->OSEventPtr = pq; +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); /* Initalize the wait list */ + } else { + pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */ + OSEventFreeList = pevent; + OS_EXIT_CRITICAL(); + pevent = (OS_EVENT *)0; + } + } + return (pevent); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A MESSAGE QUEUE +* +* Description: This function deletes a message queue and readies all tasks pending on the queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* queue. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the queue was deleted +* OS_ERR_DEL_ISR If you tried to delete the queue from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the queue +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the queue was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the queue MUST check the return code of OSQPend(). +* 2) OSQAccept() callers will not know that the intended queue has been deleted unless +* they check 'pevent' to see that it's a NULL pointer. +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the queue. +* 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in +* applications where the queue is used for mutual exclusion because the resource(s) +* will no longer be guarded by the queue. +* 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc() +* type call) then your application MUST release the memory storage by call the counterpart +* call of the dynamic allocation scheme used. If the queue storage was created statically +* then, the storage can be reused. +********************************************************************************************************* +*/ + +#if OS_Q_DEL_EN > 0 +OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on queue */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ + pq->OSQPtr = OSQFreeList; + OSQFreeList = pq; + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the queue */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for queue */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ + pq->OSQPtr = OSQFreeList; + OSQFreeList = pq; + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FLUSH QUEUE +* +* Description : This function is used to flush the contents of the message queue. +* +* Arguments : none +* +* Returns : OS_ERR_NONE upon success +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* WARNING : You should use this function with great care because, when to flush the queue, you LOOSE +* the references to what the queue entries are pointing to and thus, you could cause +* 'memory leaks'. In other words, the data you are pointing to that's being referenced +* by the queue entries should, most likely, need to be de-allocated (i.e. freed). +********************************************************************************************************* +*/ + +#if OS_Q_FLUSH_EN > 0 +INT8U OSQFlush (OS_EVENT *pevent) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } +#endif + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */ + pq->OSQIn = pq->OSQStart; + pq->OSQOut = pq->OSQStart; + pq->OSQEntries = 0; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON A QUEUE FOR A MESSAGE +* +* Description: This function waits for a message to be sent to a queue +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for a message to arrive at the queue up to the amount of time +* specified by this argument. If you specify 0, however, your task will wait +* forever at the specified queue or, until a message arrives. +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task received a +* message. +* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. +* OS_ERR_PEND_ABORT The wait on the queue was aborted. +* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked +* +* Returns : != (void *)0 is a pointer to the message received +* == (void *)0 if you received a NULL pointer message or, +* if no message was received or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass a pointer to a queue. +* +* Note(s) : As of V2.60, this function allows you to receive NULL pointer messages. +********************************************************************************************************* +*/ + +void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + void *pmsg; + OS_Q *pq; + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return ((void *)0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return ((void *)0); + } + if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((void *)0); + } +#endif + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((void *)0); + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((void *)0); + } + OS_ENTER_CRITICAL(); + pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ + if (pq->OSQEntries > 0) { /* See if any messages in the queue */ + pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ + pq->OSQEntries--; /* Update the number of entries in the queue */ + if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ + pq->OSQOut = pq->OSQStart; + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return message received */ + } + OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* Was task readied because timed-out or aborted?*/ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate a timeout occured */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return ((void *)0); /* No message received */ + } + pmsg = OSTCBCur->OSTCBMsg;/* No, Extract message from TCB (Put there by QPost) */ + OSTCBCur->OSTCBMsg = (void *)0; + OSTCBCur->OSTCBStat = OS_STAT_RDY; + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (pmsg); /* Return message received */ +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A MESSAGE QUEUE +* +* Description: This function aborts & readies any tasks currently waiting on a queue. This function +* should be used to fault-abort the wait on the queue, rather than to normally signal +* the queue via OSQPost(), OSQPostFront() or OSQPostOpt(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* queue +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* queue +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the queue. +* OS_ERR_PEND_ABORT At least one task waiting on the queue was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the queue +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the queue, or upon error. +* > 0 if one or more tasks waiting on the queue are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_Q_PEND_ABORT_EN > 0 +INT8U OSQPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on queue? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on queue */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on queue */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on queue */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A QUEUE +* +* Description: This function sends a message to a queue +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. +********************************************************************************************************* +*/ + +#if OS_Q_POST_EN > 0 +INT8U OSQPost (OS_EVENT *pevent, void *pmsg) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on queue */ + /* Ready highest priority task waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + *pq->OSQIn++ = pmsg; /* Insert message into queue */ + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ + pq->OSQIn = pq->OSQStart; + } + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO THE FRONT OF A QUEUE +* +* Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at +* the front instead of the end of the queue. Using OSQPostFront() allows you to send +* 'priority' messages. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. +********************************************************************************************************* +*/ + +#if OS_Q_POST_FRONT_EN > 0 +INT8U OSQPostFront (OS_EVENT *pevent, void *pmsg) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task pending on queue */ + /* Ready highest priority task waiting on event */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find highest priority task ready to run */ + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */ + pq->OSQOut = pq->OSQEnd; + } + pq->OSQOut--; + *pq->OSQOut = pmsg; /* Insert message into queue */ + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* POST MESSAGE TO A QUEUE +* +* Description: This function sends a message to a queue. This call has been added to reduce code size +* since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the +* capability to broadcast a message to ALL tasks waiting on the message queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* pmsg is a pointer to the message to send. +* +* opt determines the type of POST performed: +* OS_POST_OPT_NONE POST to a single waiting task +* (Identical to OSQPost()) +* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue +* OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront()) +* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* +* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the +* interrupt disable time is proportional to the number of tasks waiting on the queue. +********************************************************************************************************* +*/ + +#if OS_Q_POST_OPT_EN > 0 +INT8U OSQPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) +{ + OS_Q *pq; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */ + if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ + while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on queue */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + } + } else { /* No, Post to HPT waiting on queue */ + (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); + } + OS_EXIT_CRITICAL(); + if ((opt & OS_POST_OPT_NO_SCHED) == 0) { /* See if scheduler needs to be invoked */ + OS_Sched(); /* Find highest priority task ready to run */ + } + return (OS_ERR_NONE); + } + pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ + if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ + OS_EXIT_CRITICAL(); + return (OS_ERR_Q_FULL); + } + if ((opt & OS_POST_OPT_FRONT) != 0x00) { /* Do we post to the FRONT of the queue? */ + if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */ + pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */ + } + pq->OSQOut--; + *pq->OSQOut = pmsg; /* Insert message into queue */ + } else { /* No, Post as FIFO */ + *pq->OSQIn++ = pmsg; /* Insert message into queue */ + if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ + pq->OSQIn = pq->OSQStart; + } + } + pq->OSQEntries++; /* Update the nbr of entries in the queue */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A MESSAGE QUEUE +* +* Description: This function obtains information about a message queue. +* +* Arguments : pevent is a pointer to the event control block associated with the desired queue +* +* p_q_data is a pointer to a structure that will contain information about the message +* queue. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer +* OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_Q_QUERY_EN > 0 +INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *p_q_data) +{ + OS_Q *pq; + INT8U i; +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_q_data == (OS_Q_DATA *)0) { /* Validate 'p_q_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_q_data->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_q_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + pq = (OS_Q *)pevent->OSEventPtr; + if (pq->OSQEntries > 0) { + p_q_data->OSMsg = *pq->OSQOut; /* Get next message to return if available */ + } else { + p_q_data->OSMsg = (void *)0; + } + p_q_data->OSNMsgs = pq->OSQEntries; + p_q_data->OSQSize = pq->OSQSize; + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_Q_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUEUE MODULE INITIALIZATION +* +* Description : This function is called by uC/OS-II to initialize the message queue module. Your +* application MUST NOT call this function. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_QInit (void) +{ +#if OS_MAX_QS == 1 + OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */ + OSQFreeList->OSQPtr = (OS_Q *)0; +#endif + +#if OS_MAX_QS >= 2 + INT16U i; + OS_Q *pq1; + OS_Q *pq2; + + + + OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); /* Clear the queue table */ + pq1 = &OSQTbl[0]; + pq2 = &OSQTbl[1]; + for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE control blocks */ + pq1->OSQPtr = pq2; + pq1++; + pq2++; + } + pq1->OSQPtr = (OS_Q *)0; + OSQFreeList = &OSQTbl[0]; +#endif +} +#endif /* OS_Q_EN */ diff --git a/OS/uc/os_ii/source/os_sem.c b/OS/uc/os_ii/source/os_sem.c new file mode 100644 index 0000000..369a22c --- /dev/null +++ b/OS/uc/os_ii/source/os_sem.c @@ -0,0 +1,629 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* SEMAPHORE MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_SEM.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +#if OS_SEM_EN > 0 +/*$PAGE*/ +/* +********************************************************************************************************* +* ACCEPT SEMAPHORE +* +* Description: This function checks the semaphore to see if a resource is available or, if an event +* occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the +* resource is not available or the event did not occur. +* +* Arguments : pevent is a pointer to the event control block +* +* Returns : > 0 if the resource is available or the event did not occur the semaphore is +* decremented to obtain the resource. +* == 0 if the resource is not available or the event did not occur or, +* if 'pevent' is a NULL pointer or, +* if you didn't pass a pointer to a semaphore +********************************************************************************************************* +*/ + +#if OS_SEM_ACCEPT_EN > 0 +INT16U OSSemAccept (OS_EVENT *pevent) +{ + INT16U cnt; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (0); + } + OS_ENTER_CRITICAL(); + cnt = pevent->OSEventCnt; + if (cnt > 0) { /* See if resource is available */ + pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */ + } + OS_EXIT_CRITICAL(); + return (cnt); /* Return semaphore count */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A SEMAPHORE +* +* Description: This function creates a semaphore. +* +* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is +* available (or no event has occurred). You initialize the semaphore to a +* non-zero value to specify how many resources are available (e.g. if you have +* 10 resources, you would initialize the semaphore to 10). +* +* Returns : != (void *)0 is a pointer to the event control block (OS_EVENT) associated with the +* created semaphore +* == (void *)0 if no event control blocks were available +********************************************************************************************************* +*/ + +OS_EVENT *OSSemCreate (INT16U cnt) +{ + OS_EVENT *pevent; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if called from ISR ... */ + return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ + } + OS_ENTER_CRITICAL(); + pevent = OSEventFreeList; /* Get next free event control block */ + if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ + OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; + } + OS_EXIT_CRITICAL(); + if (pevent != (OS_EVENT *)0) { /* Get an event control block */ + pevent->OSEventType = OS_EVENT_TYPE_SEM; + pevent->OSEventCnt = cnt; /* Set semaphore value */ + pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */ +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */ + } + return (pevent); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A SEMAPHORE +* +* Description: This function deletes a semaphore and readies all tasks pending on the semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting. +* In this case, all the tasks pending will be readied. +* +* perr is a pointer to an error code that can contain one of the following values: +* OS_ERR_NONE The call was successful and the semaphore was deleted +* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : pevent upon error +* (OS_EVENT *)0 if the semaphore was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the semaphore MUST check the return code of OSSemPend(). +* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless +* they check 'pevent' to see that it's a NULL pointer. +* 3) This call can potentially disable interrupts for a long time. The interrupt disable +* time is directly proportional to the number of tasks waiting on the semaphore. +* 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in +* applications where the semaphore is used for mutual exclusion because the resource(s) +* will no longer be guarded by the semaphore. +********************************************************************************************************* +*/ + +#if OS_SEM_DEL_EN > 0 +OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_EVENT *pevent_return; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (pevent); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (pevent); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (pevent); + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pevent); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on semaphore */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pevent_return = pevent; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the semaphore */ + while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); + } +#if OS_EVENT_NAME_SIZE > 1 + pevent->OSEventName[0] = '?'; /* Unknown name */ + pevent->OSEventName[1] = OS_ASCII_NUL; +#endif + pevent->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ + pevent->OSEventCnt = 0; + OSEventFreeList = pevent; /* Get next free event control block */ + OS_EXIT_CRITICAL(); + if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ + OS_Sched(); /* Find highest priority task ready to run */ + } + *perr = OS_ERR_NONE; + pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pevent_return = pevent; + break; + } + return (pevent_return); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON SEMAPHORE +* +* Description: This function waits for a semaphore. +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for the resource up to the amount of time specified by this argument. +* If you specify 0, however, your task will wait forever at the specified +* semaphore or, until the resource becomes available (or the event occurs). +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE The call was successful and your task owns the resource +* or, the event you are waiting for occurred. +* OS_ERR_TIMEOUT The semaphore was not received within the specified +* 'timeout'. +* OS_ERR_PEND_ABORT The wait on the semaphore was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEND_ISR If you called this function from an ISR and the result +* would lead to a suspension. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked +* +* Returns : none +********************************************************************************************************* +*/ + +void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) +{ + INT8U pend_stat; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + if (OSIntNesting > 0) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return; + } + if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return; + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */ + pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return; + } + /* Otherwise, must wait until event occurs */ + OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ + OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed-out or aborted */ + pend_stat = OSTCBCur->OSTCBStatPend; + OS_EventTOAbort(pevent); + OS_EXIT_CRITICAL(); + switch (pend_stat) { + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that didn't get event within TO */ + break; + + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ + break; + } + return; + } + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* ABORT WAITING ON A SEMAPHORE +* +* Description: This function aborts & readies any tasks currently waiting on a semaphore. This function +* should be used to fault-abort the wait on the semaphore, rather than to normally signal +* the semaphore via OSSemPost(). +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* opt determines the type of ABORT performed: +* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the +* semaphore +* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the +* semaphore +* +* perr is a pointer to where an error message will be deposited. Possible error +* messages are: +* +* OS_ERR_NONE No tasks were waiting on the semaphore. +* OS_ERR_PEND_ABORT At least one task waiting on the semaphore was readied +* and informed of the aborted wait; check return value +* for the number of tasks whose wait on the semaphore +* was aborted. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* +* Returns : == 0 if no tasks were waiting on the semaphore, or upon error. +* > 0 if one or more tasks waiting on the semaphore are now readied and informed. +********************************************************************************************************* +*/ + +#if OS_SEM_PEND_ABORT_EN > 0 +INT8U OSSemPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) +{ + INT8U nbr_tasks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return (0); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting on semaphore? */ + nbr_tasks = 0; + switch (opt) { + case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ + while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on semaphore */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); + nbr_tasks++; + } + break; + + case OS_PEND_OPT_NONE: /* No, ready HPT waiting on semaphore */ + default: + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); + nbr_tasks++; + break; + } + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + *perr = OS_ERR_PEND_ABORT; + return (nbr_tasks); + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (0); /* No tasks waiting on semaphore */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST TO A SEMAPHORE +* +* Description: This function signals a semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore. +* +* Returns : OS_ERR_NONE The call was successful and the semaphore was signaled. +* OS_ERR_SEM_OVF If the semaphore count exceeded its limit. In other words, you have +* signalled the semaphore more often than you waited on it with either +* OSSemAccept() or OSSemPend(). +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +********************************************************************************************************* +*/ + +INT8U OSSemPost (OS_EVENT *pevent) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore */ + /* Ready HPT waiting on event */ + (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find HPT ready to run */ + return (OS_ERR_NONE); + } + if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */ + pevent->OSEventCnt++; /* Increment semaphore count to register event */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ + return (OS_ERR_SEM_OVF); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A SEMAPHORE +* +* Description: This function obtains information about a semaphore +* +* Arguments : pevent is a pointer to the event control block associated with the desired +* semaphore +* +* p_sem_data is a pointer to a structure that will contain information about the +* semaphore. +* +* Returns : OS_ERR_NONE The call was successful and the message was sent +* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_PDATA_NULL If 'p_sem_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_SEM_QUERY_EN > 0 +INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *p_sem_data) +{ +#if OS_LOWEST_PRIO <= 63 + INT8U *psrc; + INT8U *pdest; +#else + INT16U *psrc; + INT16U *pdest; +#endif + INT8U i; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (OS_ERR_PEVENT_NULL); + } + if (p_sem_data == (OS_SEM_DATA *)0) { /* Validate 'p_sem_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (OS_ERR_EVENT_TYPE); + } + OS_ENTER_CRITICAL(); + p_sem_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ + psrc = &pevent->OSEventTbl[0]; + pdest = &p_sem_data->OSEventTbl[0]; + for (i = 0; i < OS_EVENT_TBL_SIZE; i++) { + *pdest++ = *psrc++; + } + p_sem_data->OSCnt = pevent->OSEventCnt; /* Get semaphore count */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif /* OS_SEM_QUERY_EN */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* SET SEMAPHORE +* +* Description: This function sets the semaphore count to the value specified as an argument. Typically, +* this value would be 0. +* +* You would typically use this function when a semaphore is used as a signaling mechanism +* and, you want to reset the count value. +* +* Arguments : pevent is a pointer to the event control block +* +* cnt is the new value for the semaphore count. You would pass 0 to reset the +* semaphore count. +* +* perr is a pointer to an error code returned by the function as follows: +* +* OS_ERR_NONE The call was successful and the semaphore value was set. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. +* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. +* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore. +********************************************************************************************************* +*/ + +#if OS_SEM_SET_EN > 0 +void OSSemSet (OS_EVENT *pevent, INT16U cnt, INT8U *perr) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + *perr = OS_ERR_PEVENT_NULL; + return; + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return; + } + OS_ENTER_CRITICAL(); + *perr = OS_ERR_NONE; + if (pevent->OSEventCnt > 0) { /* See if semaphore already has a count */ + pevent->OSEventCnt = cnt; /* Yes, set it to the new value specified. */ + } else { /* No */ + if (pevent->OSEventGrp == 0) { /* See if task(s) waiting? */ + pevent->OSEventCnt = cnt; /* No, OK to set the value */ + } else { + *perr = OS_ERR_TASK_WAITING; + } + } + OS_EXIT_CRITICAL(); +} +#endif + +// +INT16U OSSemCheck (OS_EVENT *pevent) +{ + INT16U cnt; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + +#if OS_ARG_CHK_EN > 0 + if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ + return (0); + } +#endif + if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ + return (0); + } + OS_ENTER_CRITICAL(); + cnt = pevent->OSEventCnt; + OS_EXIT_CRITICAL(); + return (cnt); /* Return semaphore count */ +} + +#endif /* OS_SEM_EN */ diff --git a/OS/uc/os_ii/source/os_task.c b/OS/uc/os_ii/source/os_task.c new file mode 100644 index 0000000..bd09677 --- /dev/null +++ b/OS/uc/os_ii/source/os_task.c @@ -0,0 +1,1070 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* TASK MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_TASK.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHANGE PRIORITY OF A TASK +* +* Description: This function allows you to change the priority of a task dynamically. Note that the new +* priority MUST be available. +* +* Arguments : oldp is the old priority +* +* newp is the new priority +* +* Returns : OS_ERR_NONE is the call was successful +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_PRIO_EXIST if the new priority already exist. +* OS_ERR_PRIO there is no task with the specified OLD priority (i.e. the OLD task does +* not exist. +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP. +********************************************************************************************************* +*/ + +#if OS_TASK_CHANGE_PRIO_EN > 0 +INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) +{ +#if OS_EVENT_EN + OS_EVENT *pevent; +#endif + OS_TCB *ptcb; + INT8U x; + INT8U y; +#if OS_LOWEST_PRIO <= 63 + INT8U bitx; + INT8U bity; +#else + INT16U bitx; + INT16U bity; +#endif + INT8U y_old; +#if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; /* Storage for CPU status register */ +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (oldprio >= OS_LOWEST_PRIO) { + if (oldprio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (newprio >= OS_LOWEST_PRIO) { + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); + } + if (oldprio == OS_PRIO_SELF) { /* See if changing self */ + oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ + } + ptcb = OSTCBPrioTbl[oldprio]; + if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Is task assigned to Mutex */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_TASK_NOT_EXIST); + } +#if OS_LOWEST_PRIO <= 63 + y = (INT8U)(newprio >> 3); /* Yes, compute new TCB fields */ + x = (INT8U)(newprio & 0x07); + bity = (INT8U)(1 << y); + bitx = (INT8U)(1 << x); +#else + y = (INT8U)((newprio >> 4) & 0x0F); + x = (INT8U)( newprio & 0x0F); + bity = (INT16U)(1 << y); + bitx = (INT16U)(1 << x); +#endif + + OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ + OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ + y_old = ptcb->OSTCBY; + if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0) { /* If task is ready make it not */ + OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y_old] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + OSRdyGrp |= bity; /* Make new priority ready to run */ + OSRdyTbl[y] |= bitx; + } +#if OS_EVENT_EN + pevent = ptcb->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { /* ... remove from event wait list */ + pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX; + if (pevent->OSEventTbl[y_old] == 0) { + pevent->OSEventGrp &= ~ptcb->OSTCBBitY; + } + pevent->OSEventGrp |= bity; /* Add new priority to wait list */ + pevent->OSEventTbl[y] |= bitx; + } +#endif + ptcb->OSTCBPrio = newprio; /* Set new task priority */ + ptcb->OSTCBY = y; + ptcb->OSTCBX = x; + ptcb->OSTCBBitY = bity; + ptcb->OSTCBBitX = bitx; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pstk' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EN > 0 +INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio) +{ + OS_STK *psp; + INT8U err; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + psp = OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK (Extended Version) +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. This function is similar to OSTaskCreate() except that it allows +* additional information about a task to be specified. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'ptos' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'ptos' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. 'ptos' MUST point to a valid 'free' data item. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* id is the task's ID (0..65535) +* +* pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* HIGHEST memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U, +* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to +* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if +* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries +* available on the stack. +* +* pext is a pointer to a user supplied memory location which is used as a TCB extension. +* For example, this user memory can hold the contents of floating-point registers +* during a context switch, the time each task takes to execute, the number of times +* the task has been switched-in, etc. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. Current choices are: +* +* OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task +* OS_TASK_OPT_STK_CLR Clear the stack when the task is created +* OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them +* during a context switch. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt) +{ + OS_STK *psp; + INT8U err; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + +#if OS_TASK_STAT_STK_CHK_EN > 0 + OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */ +#endif + + psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A TASK +* +* Description: This function allows you to delete a task. The calling task can delete itself by +* its own priority number. The deleted task is returned to the dormant state and can be +* re-activated by creating the deleted task again. +* +* Arguments : prio is the priority of the task to delete. Note that you can explicitely delete +* the current task without knowing its priority level by setting 'prio' to +* OS_PRIO_SELF. +* +* Returns : OS_ERR_NONE if the call is successful +* OS_ERR_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex PIP. +* OS_ERR_TASK_NOT_EXIST if the task you want to delete does not exist. +* OS_ERR_TASK_DEL_ISR if you tried to delete a task from an ISR +* +* Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task: +* a) by making it not ready +* b) by removing it from any wait lists +* c) by preventing OSTimeTick() from making the task ready to run. +* The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II. +* 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors, +* the next instruction following the enable interrupt instruction is ignored. +* 3) An ISR cannot delete a task. +* 4) The lock nesting counter is incremented because, for a brief instant, if the current +* task is being deleted, the current task would not be able to be rescheduled because it +* is removed from the ready list. Incrementing the nesting counter prevents another task +* from being schedule. This means that an ISR would return to the current task which is +* being deleted. The rest of the deletion would thus be able to be completed. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDel (INT8U prio) +{ +#if OS_EVENT_EN + OS_EVENT *pevent; +#endif +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + OS_FLAG_NODE *pnode; +#endif + OS_TCB *ptcb; + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if trying to delete from ISR */ + return (OS_ERR_TASK_DEL_ISR); + } + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */ + prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { /* Must not be assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + y = ptcb->OSTCBY; + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; + if (OSRdyTbl[y] == 0) { /* Make task not ready */ + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + +#if OS_EVENT_EN + pevent = ptcb->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */ + pevent->OSEventTbl[y] &= ~ptcb->OSTCBBitX; + if (pevent->OSEventTbl[y] == 0) { /* ... remove task from ... */ + pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */ + } + } +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + pnode = ptcb->OSTCBFlagNode; + if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */ + OS_FlagUnlink(pnode); /* Remove from wait list */ + } +#endif + + ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (OSLockNesting < 255u) { /* Make sure we don't context switch */ + OSLockNesting++; + } + OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */ + OS_Dummy(); /* ... Dummy ensures that INTs will be */ + OS_ENTER_CRITICAL(); /* ... disabled HERE! */ + if (OSLockNesting > 0) { /* Remove context switch lock */ + OSLockNesting--; + } + OSTaskDelHook(ptcb); /* Call user defined hook */ + OSTaskCtr--; /* One less task being managed */ + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */ + if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */ + ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; + OSTCBList = ptcb->OSTCBNext; + } else { + ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; + ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; + } + ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */ + OSTCBFreeList = ptcb; +#if OS_TASK_NAME_SIZE > 1 + ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */ + ptcb->OSTCBTaskName[1] = OS_ASCII_NUL; +#endif + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* REQUEST THAT A TASK DELETE ITSELF +* +* Description: This function is used to: +* a) notify a task to delete itself. +* b) to see if a task requested that the current task delete itself. +* This function is a little tricky to understand. Basically, you have a task that needs +* to be deleted however, this task has resources that it has allocated (memory buffers, +* semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these +* resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that +* the task needs to be deleted. Deleting of the task is however, deferred to the task to +* be deleted. For example, suppose that task #10 needs to be deleted. The requesting task +* example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls +* this function by specifying OS_PRIO_SELF and monitors the returned value. If the return +* value is OS_ERR_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like +* this: +* +* void Task(void *p_arg) +* { +* . +* . +* while (1) { +* OSTimeDly(1); +* if (OSTaskDelReq(OS_PRIO_SELF) == OS_ERR_TASK_DEL_REQ) { +* Release any owned resources; +* De-allocate any dynamic memory; +* OSTaskDel(OS_PRIO_SELF); +* } +* } +* } +* +* Arguments : prio is the priority of the task to request the delete from +* +* Returns : OS_ERR_NONE if the task exist and the request has been registered +* OS_ERR_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether +* the request has been executed. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex. +* OS_ERR_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL_REQ if a task (possibly another task) requested that the running task be +* deleted. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDelReq (INT8U prio) +{ + INT8U stat; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */ + OS_ENTER_CRITICAL(); /* ... this task to delete itself */ + stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */ + OS_EXIT_CRITICAL(); + return (stat); + } + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* Task must already be deleted */ + } + if (ptcb == OS_TCB_RESERVED) { /* Must NOT be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + ptcb->OSTCBDelReq = OS_ERR_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A TASK +* +* Description: This function is called to obtain the name of a task. +* +* Arguments : prio is the priority of the task that you want to obtain the name from. +* +* pname is a pointer to an ASCII string that will receive the name of the task. The +* string must be able to hold at least OS_TASK_NAME_SIZE characters. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_NAME_GET_ISR You called this function from an ISR +* +* +* Returns : The length of the string or 0 if the task does not exist. +********************************************************************************************************* +*/ + +#if OS_TASK_NAME_SIZE > 1 +INT8U OSTaskNameGet (INT8U prio, INT8U *pname, INT8U *perr) +{ + OS_TCB *ptcb; + INT8U len; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return (0); + } + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return (0); + } + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + return (0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if caller desires it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0); + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0); + } + len = OS_StrCopy(pname, ptcb->OSTCBTaskName); /* Yes, copy name from TCB */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A TASK +* +* Description: This function is used to set the name of a task. +* +* Arguments : prio is the priority of the task that you want the assign a name to. +* +* pname is a pointer to an ASCII string that contains the name of the task. The ASCII +* string must be NUL terminated. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_TASK_NAME_TOO_LONG if the name you are giving to the task exceeds the +* storage capacity of a task name as specified by +* OS_TASK_NAME_SIZE. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ +#if OS_TASK_NAME_SIZE > 1 +void OSTaskNameSet (INT8U prio, INT8U *pname, INT8U *perr) +{ + INT8U len; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate 'perr' */ + return; + } + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return; + } + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + return; + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + len = OS_StrLen(pname); /* Yes, Can we fit the string in the TCB? */ + if (len > (OS_TASK_NAME_SIZE - 1)) { /* No */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_NAME_TOO_LONG; + return; + } + (void)OS_StrCopy(ptcb->OSTCBTaskName, pname); /* Yes, copy to TCB */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* RESUME A SUSPENDED TASK +* +* Description: This function is called to resume a previously suspended task. This is the only call that +* will remove an explicit task suspension. +* +* Arguments : prio is the priority of the task to resume. +* +* Returns : OS_ERR_NONE if the requested task is resumed +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_RESUME_PRIO if the task to resume does not exist +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_TASK_NOT_SUSPENDED if the task to resume has not been suspended +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskResume (INT8U prio) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_RESUME_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */ + ptcb->OSTCBStat &= ~(INT8U)OS_STAT_SUSPEND; /* Remove suspension */ + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is now ready */ + if (ptcb->OSTCBDly == 0) { + OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + } else { + OS_EXIT_CRITICAL(); + } + } else { /* Must be pending on event */ + OS_EXIT_CRITICAL(); + } + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_SUSPENDED); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* STACK CHECKING +* +* Description: This function is called to check the amount of free memory left on the specified task's +* stack. +* +* Arguments : prio is the task priority +* +* p_stk_data is a pointer to a data structure of type OS_STK_DATA. +* +* Returns : OS_ERR_NONE upon success +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP +* OS_ERR_TASK_OPT if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created +* OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer +********************************************************************************************************* +*/ +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data) +{ + OS_TCB *ptcb; + OS_STK *pchk; + INT32U free; + INT32U size; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_stk_data == (OS_STK_DATA *)0) { /* Validate 'p_stk_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + p_stk_data->OSFree = 0; /* Assume failure, set to 0 size */ + p_stk_data->OSUsed = 0; + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if check for SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Make sure task exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_OPT); + } + free = 0; + size = ptcb->OSTCBStkSize; + pchk = ptcb->OSTCBStkBottom; + OS_EXIT_CRITICAL(); +#if OS_STK_GROWTH == 1 + while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */ + free++; + } +#else + while (*pchk-- == (OS_STK)0) { + free++; + } +#endif + p_stk_data->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */ + p_stk_data->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */ + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND A TASK +* +* Description: This function is called to suspend a task. The task can be the calling task if the +* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF. +* +* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the +* calling task will suspend itself and rescheduling will occur. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed. +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_SUSPEND_PRIO if the task to suspend does not exist +* OS_ERR_TASK_NOT_EXITS if the task is assigned to a Mutex PIP +* +* Note : You should use this function with great care. If you suspend a task that is waiting for +* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from +* running when the event arrives. +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskSuspend (INT8U prio) +{ + BOOLEAN self; + OS_TCB *ptcb; + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to suspend idle task */ + return (OS_ERR_TASK_SUSPEND_IDLE); + } + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + self = OS_TRUE; + } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */ + self = OS_TRUE; + } else { + self = OS_FALSE; /* No suspending another task */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_SUSPEND_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + y = ptcb->OSTCBY; + OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready */ + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~ptcb->OSTCBBitY; + } + ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */ + OS_EXIT_CRITICAL(); + if (self == OS_TRUE) { /* Context switch only if SELF */ + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A TASK +* +* Description: This function is called to obtain a copy of the desired task's TCB. +* +* Arguments : prio is the priority of the task to obtain information from. +* +* p_task_data is a pointer to where the desired task's OS_TCB will be stored. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_PRIO if the desired task has not been created +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_PDATA_NULL if 'p_task_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_TASK_QUERY_EN > 0 +INT8U OSTaskQuery (INT8U prio, OS_TCB *p_task_data) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + +#if OS_ARG_CHK_EN > 0 + if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_task_data == (OS_TCB *)0) { /* Validate 'p_task_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to query must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Task to query must not be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + /* Copy TCB into user storage area */ + OS_MemCopy((INT8U *)p_task_data, (INT8U *)ptcb, sizeof(OS_TCB)); + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR TASK STACK +* +* Description: This function is used to clear the stack of a task (i.e. write all zeros) +* +* Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the lowest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* highest memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* size is the number of 'stack elements' to clear. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. +* +* Returns : none +********************************************************************************************************* +*/ +#if OS_TASK_CREATE_EXT_EN > 0 +void OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt) +{ + if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000) { /* See if stack checking has been enabled */ + if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000) { /* See if stack needs to be cleared */ +#if OS_STK_GROWTH == 1 + while (size > 0) { /* Stack grows from HIGH to LOW memory */ + size--; + *pbos++ = (OS_STK)0; /* Clear from bottom of stack and up! */ + } +#else + while (size > 0) { /* Stack grows from LOW to HIGH memory */ + size--; + *pbos-- = (OS_STK)0; /* Clear from bottom of stack and down */ + } +#endif + } + } +} + +#endif diff --git a/OS/uc/os_ii/source/os_time.c b/OS/uc/os_ii/source/os_time.c new file mode 100644 index 0000000..24a309d --- /dev/null +++ b/OS/uc/os_ii/source/os_time.c @@ -0,0 +1,268 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* TIME MANAGEMENT +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : OS_TIME.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_MASTER_FILE +#include +#endif + +/* +********************************************************************************************************* +* DELAY TASK 'n' TICKS (n from 0 to 65535) +* +* Description: This function is called to delay execution of the currently running task until the +* specified number of system ticks expires. This, of course, directly equates to delaying +* the current task for some time to expire. No delay will result If the specified delay is +* 0. If the specified delay is greater than 0 then, a context switch will result. +* +* Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'. +* Note that by specifying 0, the task will not be delayed. +* +* Returns : none +********************************************************************************************************* +*/ + +void OSTimeDly (INT16U ticks) +{ + INT8U y; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + return; + } + if (ticks > 0) { /* 0 means no delay! */ + OS_ENTER_CRITICAL(); + y = OSTCBCur->OSTCBY; /* Delay current task */ + OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0) { + OSRdyGrp &= ~OSTCBCur->OSTCBBitY; + } + OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next task to run! */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* DELAY TASK FOR SPECIFIED TIME +* +* Description: This function is called to delay execution of the currently running task until some time +* expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and +* MILLISECONDS instead of ticks. +* +* Arguments : hours specifies the number of hours that the task will be delayed (max. is 255) +* minutes specifies the number of minutes (max. 59) +* seconds specifies the number of seconds (max. 59) +* milli specifies the number of milliseconds (max. 999) +* +* Returns : OS_ERR_NONE +* OS_ERR_TIME_INVALID_MINUTES +* OS_ERR_TIME_INVALID_SECONDS +* OS_ERR_TIME_INVALID_MS +* OS_ERR_TIME_ZERO_DLY +* OS_ERR_TIME_DLY_ISR +* +* Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do +* a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be +* set to 0. The actual delay is rounded to the nearest tick. +********************************************************************************************************* +*/ + +#if OS_TIME_DLY_HMSM_EN > 0 +INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U ms) +{ + INT32U ticks; + INT16U loops; + + + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + return (OS_ERR_TIME_DLY_ISR); + } +#if OS_ARG_CHK_EN > 0 + if (hours == 0) { + if (minutes == 0) { + if (seconds == 0) { + if (ms == 0) { + return (OS_ERR_TIME_ZERO_DLY); + } + } + } + } + if (minutes > 59) { + return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */ + } + if (seconds > 59) { + return (OS_ERR_TIME_INVALID_SECONDS); + } + if (ms > 999) { + return (OS_ERR_TIME_INVALID_MS); + } +#endif + /* Compute the total number of clock ticks required.. */ + /* .. (rounded to the nearest tick) */ + ticks = ((INT32U)hours * 3600L + (INT32U)minutes * 60L + (INT32U)seconds) * OS_TICKS_PER_SEC + + OS_TICKS_PER_SEC * ((INT32U)ms + 500L / OS_TICKS_PER_SEC) / 1000L; + loops = (INT16U)(ticks >> 16); /* Compute the integral number of 65536 tick delays */ + ticks = ticks & 0xFFFFL; /* Obtain the fractional number of ticks */ + OSTimeDly((INT16U)ticks); + while (loops > 0) { + OSTimeDly((INT16U)32768u); + OSTimeDly((INT16U)32768u); + loops--; + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* RESUME A DELAYED TASK +* +* Description: This function is used resume a task that has been delayed through a call to either +* OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a +* task that is waiting for an event with timeout. This would make the task look +* like a timeout occurred. +* +* Also, you cannot resume a task that has called OSTimeDlyHMSM() with a combined time that +* exceeds 65535 clock ticks. In other words, if the clock tick runs at 100 Hz then, you will +* not be able to resume a delayed task that called OSTimeDlyHMSM(0, 10, 55, 350) or higher: +* +* (10 Minutes * 60 + 55 Seconds + 0.35) * 100 ticks/second. +* +* Arguments : prio specifies the priority of the task to resume +* +* Returns : OS_ERR_NONE Task has been resumed +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire +* OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex. +********************************************************************************************************* +*/ + +#if OS_TIME_DLY_RESUME_EN > 0 +INT8U OSTimeDlyResume (INT8U prio) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + if (prio >= OS_LOWEST_PRIO) { + return (OS_ERR_PRIO_INVALID); + } + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */ + if (ptcb == (OS_TCB *)0) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ + } + if (ptcb == OS_TCB_RESERVED) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ + } + if (ptcb->OSTCBDly == 0) { /* See if task is delayed */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */ + } + + ptcb->OSTCBDly = 0; /* Clear the time delay */ + if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { + ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */ + ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ + } else { + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + } + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OS_EXIT_CRITICAL(); + OS_Sched(); /* See if this is new highest priority */ + } else { + OS_EXIT_CRITICAL(); /* Task may be suspended */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET CURRENT SYSTEM TIME +* +* Description: This function is used by your application to obtain the current value of the 32-bit +* counter which keeps track of the number of clock ticks. +* +* Arguments : none +* +* Returns : The current value of OSTime +********************************************************************************************************* +*/ + +#if OS_TIME_GET_SET_EN > 0 +INT32U OSTimeGet (void) +{ + INT32U ticks; +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + ticks = OSTime; + OS_EXIT_CRITICAL(); + return (ticks); +} +#endif + +/* +********************************************************************************************************* +* SET SYSTEM CLOCK +* +* Description: This function sets the 32-bit counter which keeps track of the number of clock ticks. +* +* Arguments : ticks specifies the new value that OSTime needs to take. +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TIME_GET_SET_EN > 0 +void OSTimeSet (INT32U ticks) +{ +#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; +#endif + + + + OS_ENTER_CRITICAL(); + OSTime = ticks; + OS_EXIT_CRITICAL(); +} +#endif diff --git a/OS/uc/os_ii/source/os_tmr.c b/OS/uc/os_ii/source/os_tmr.c new file mode 100644 index 0000000..efc59f8 --- /dev/null +++ b/OS/uc/os_ii/source/os_tmr.c @@ -0,0 +1,1116 @@ +/* +************************************************************************************************************************ +* uC/OS-III +* The Real-Time Kernel +* +* (c) Copyright 2005-2007, Micrium, Weston, FL +* All Rights Reserved +* +* TIMER MANAGEMENT +* +* File : OS_TMR.C +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +************************************************************************************************************************ +*/ + +#include + +/* +************************************************************************************************************************ +* NOTES +* +* 1) Your application MUST define the following #define constants: +* +* OS_TASK_TMR_PRIO The priority of the Timer management task +* OS_TASK_TMR_STK_SIZE The size of the Timer management task's stack +* +* 2) You must call OSTmrSignal() to notify the Timer management task that it's time to update the timers. +************************************************************************************************************************ +*/ + +/* +************************************************************************************************************************ +* CONSTANTS +************************************************************************************************************************ +*/ + +#define OS_TMR_LINK_DLY 0 +#define OS_TMR_LINK_PERIODIC 1 + +/* +************************************************************************************************************************ +* LOCAL PROTOTYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static OS_TMR *OSTmr_Alloc (void); +static void OSTmr_Free (OS_TMR *ptmr); +static void OSTmr_InitTask (void); +static void OSTmr_Link (OS_TMR *ptmr, INT8U type); +static void OSTmr_Unlink (OS_TMR *ptmr); +static void OSTmr_Lock (void); +static void OSTmr_Unlock (void); +static void OSTmr_Task (void *p_arg); +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* CREATE A TIMER +* +* Description: This function is called by your application code to create a timer. +* +* Arguments : dly Initial delay. +* If the timer is configured for ONE-SHOT mode, this is the timeout used +* If the timer is configured for PERIODIC mode, this is the first timeout to wait for +* before the timer starts entering periodic mode +* +* period The 'period' being repeated for the timer. +* If you specified 'OS_TMR_OPT_PERIODIC' as an option, when the timer expires, it will +* automatically restart with the same period. +* +* opt Specifies either: +* OS_TMR_OPT_ONE_SHOT The timer counts down only once +* OS_TMR_OPT_PERIODIC The timer counts down and then reloads itself +* +* callback Is a pointer to a callback function that will be called when the timer expires. The +* callback function must be declared as follows: +* +* void MyCallback (OS_TMR *ptmr, void *p_arg); +* +* callback_arg Is an argument (a pointer) that is passed to the callback function when it is called. +* +* pname Is a pointer to an ASCII string that is used to name the timer. Names are useful for +* debugging. The length of the ASCII string for the name can be as big as: +* +* OS_TMR_CFG_NAME_SIZE and should be found in OS_CFG.H +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID_DLY you specified an invalid delay +* OS_ERR_TMR_INVALID_PERIOD you specified an invalid period +* OS_ERR_TMR_INVALID_OPT you specified an invalid option +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_NON_AVAIL if there are no free timers from the timer pool +* OS_ERR_TMR_NAME_TOO_LONG if the timer name is too long to fit +* +* Returns : A pointer to an OS_TMR data structure. +* This is the 'handle' that your application will use to reference the timer created. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr) +{ + OS_TMR *ptmr; +#if OS_TMR_CFG_NAME_SIZE > 0 + INT8U len; +#endif + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return ((OS_TMR *)0); + } + switch (opt) { + case OS_TMR_OPT_PERIODIC: + if (period == 0) { + *perr = OS_ERR_TMR_INVALID_PERIOD; + return ((OS_TMR *)0); + } + break; + + case OS_TMR_OPT_ONE_SHOT: + if (dly == 0) { + *perr = OS_ERR_TMR_INVALID_DLY; + return ((OS_TMR *)0); + } + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + return ((OS_TMR *)0); + } +#endif + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return ((OS_TMR *)0); + } + OSTmr_Lock(); + ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */ + if (ptmr == (OS_TMR *)0) { + OSTmr_Unlock(); + *perr = OS_ERR_TMR_NON_AVAIL; + return ((OS_TMR *)0); + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; /* Indicate that timer is not running yet */ + ptmr->OSTmrDly = dly; + ptmr->OSTmrPeriod = period; + ptmr->OSTmrOpt = opt; + ptmr->OSTmrCallback = callback; + ptmr->OSTmrCallbackArg = callback_arg; +#if OS_TMR_CFG_NAME_SIZE > 0 + if (pname !=(INT8U *)0) { + len = OS_StrLen(pname); /* Copy timer name */ + if (len < OS_TMR_CFG_NAME_SIZE) { + (void)OS_StrCopy(ptmr->OSTmrName, pname); + } else { +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr->OSTmrName[0] = '#'; /* Invalid size specified */ + ptmr->OSTmrName[1] = OS_ASCII_NUL; +#endif + *perr = OS_ERR_TMR_NAME_TOO_LONG; + OSTmr_Unlock(); + return (ptmr); + } + } +#endif + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (ptmr); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* DELETE A TIMER +* +* Description: This function is called by your application code to delete a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop and delete. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE If the call was successful +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr) +{ +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */ + case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Already deleted */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET THE NAME OF A TIMER +* +* Description: This function is called to obtain the name of a timer. +* +* Arguments : ptmr Is a pointer to the timer to obtain the name for +* +* pdest Is a pointer to where the name of the timer will be placed. It is the caller's responsibility +* to ensure that he has sufficient storage in the destination, i.e. at least OS_TMR_CFG_NAME_SIZE +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE The call was successful +* OS_ERR_TMR_INVALID_DEST 'pdest' is a NULL pointer +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_NAME_GET_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The length of the string or 0 if the timer does not exist. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 && OS_TMR_CFG_NAME_SIZE > 0 +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U *pdest, + INT8U *perr) +{ + INT8U len; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (pdest == (INT8U *)0) { + *perr = OS_ERR_TMR_INVALID_DEST; + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + len = OS_StrCopy(pdest, ptmr->OSTmrName); + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (len); + + case OS_TMR_STATE_UNUSED: /* Timer is not allocated */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET HOW MUCH TIME IS LEFT BEFORE A TIMER EXPIRES +* +* Description: This function is called to get the number of ticks before a timer times out. +* +* Arguments : ptmr Is a pointer to the timer to obtain the remaining time from. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The time remaining for the timer to expire. The time represents 'timer' increments. In other words, if +* OSTmr_Task() is signaled every 1/10 of a second then the returned value represents the number of 1/10 of +* a second remaining before the timer expires. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT32U remain; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + remain = ptmr->OSTmrMatch - OSTmrTime; /* Determine how much time is left to timeout */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (remain); + + case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */ + switch (ptmr->OSTmrOpt) { + case OS_TMR_OPT_PERIODIC: + if (ptmr->OSTmrDly == 0) { + remain = ptmr->OSTmrPeriod; + } else { + remain = ptmr->OSTmrDly; + } + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + break; + + case OS_TMR_OPT_ONE_SHOT: + default: + remain = ptmr->OSTmrDly; + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + break; + } + return (remain); + + case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (0); + + case OS_TMR_STATE_UNUSED: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* FIND OUT WHAT STATE A TIMER IS IN +* +* Description: This function is called to determine what state the timer is in: +* +* OS_TMR_STATE_UNUSED the timer has not been created +* OS_TMR_STATE_STOPPED the timer has been created but has not been started or has been stopped +* OS_TMR_COMPLETED the timer is in ONE-SHOT mode and has completed it's timeout +* OS_TMR_RUNNING the timer is currently running +* +* Arguments : ptmr Is a pointer to the desired timer +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE if the timer is not in a valid state +* +* Returns : The current state of the timer (see description). +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT8U state; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { + return (0); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0); + } + OSTmr_Lock(); + state = ptmr->OSTmrState; + switch (state) { + case OS_TMR_STATE_UNUSED: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + case OS_TMR_STATE_RUNNING: + *perr = OS_ERR_NONE; + break; + + default: + *perr = OS_ERR_TMR_INVALID_STATE; + break; + } + OSTmr_Unlock(); + return (state); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* START A TIMER +* +* Description: This function is called by your application code to start a timer. +* +* Arguments : ptmr Is a pointer to an OS_TMR +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE if the timer was started +* OS_FALSE if an error was detected +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr) +{ +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: /* Restart the timer */ + OSTmr_Unlink(ptmr); /* ... Stop the timer */ + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Start the timer */ + case OS_TMR_STATE_COMPLETED: + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSTmr_Unlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer not created */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* STOP A TIMER +* +* Description: This function is called by your application code to stop a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop. +* +* opt Allows you to specify an option to this functions which can be: +* +* OS_TMR_OPT_NONE Do nothing special but stop the timer +* OS_TMR_OPT_CALLBACK Execute the callback function, pass it the callback argument +* specified when the timer was created. +* OS_TMR_OPT_CALLBACK_ARG Execute the callback function, pass it the callback argument +* specified in THIS function call +* +* callback_arg Is a pointer to a 'new' callback argument that can be passed to the callback function +* instead of the timer's callback argument. In other words, use 'callback_arg' passed in +* THIS function INSTEAD of ptmr->OSTmrCallbackArg +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_OPT if you specified an invalid option for 'opt' +* OS_ERR_TMR_STOPPED if the timer was already stopped +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* OS_ERR_TMR_NO_CALLBACK if the timer does not have a callback function defined +* +* Returns : OS_TRUE If we stopped the timer (if the timer is already stopped, we also return OS_TRUE) +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr) +{ + OS_TMR_CALLBACK pfnct; + + +#if OS_ARG_CHK_EN > 0 + if (perr == (INT8U *)0) { /* Validate arguments */ + return (OS_FALSE); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSTmr_Lock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + *perr = OS_ERR_NONE; + switch (opt) { + case OS_TMR_OPT_CALLBACK: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); /* Use callback arg when timer was created */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_CALLBACK_ARG: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, callback_arg); /* ... using the 'callback_arg' provided in call */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_NONE: + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + break; + } + OSTmr_Unlock(); + return (OS_TRUE); + + case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or ... */ + case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_STOPPED; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer was not created */ + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSTmr_Unlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* SIGNAL THAT IT'S TIME TO UPDATE THE TIMERS +* +* Description: This function is typically called by the ISR that occurs at the timer tick rate and is used to signal to +* OSTmr_Task() that it's time to update the timers. +* +* Arguments : none +* +* Returns : OS_ERR_NONE The call was successful and the timer task was signaled. +* OS_ERR_SEM_OVF If OSTmrSignal() was called more often than OSTmr_Task() can handle the timers. +* This would indicate that your system is heavily loaded. +* OS_ERR_EVENT_TYPE Unlikely you would get this error because the semaphore used for signaling is created +* by uC/OS-II. +* OS_ERR_PEVENT_NULL Again, unlikely you would ever get this error because the semaphore used for signaling +* is created by uC/OS-II. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +INT8U OSTmrSignal (void) +{ + INT8U err; + + + err = OSSemPost(OSTmrSemSignal); + return (err); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* ALLOCATE AND FREE A TIMER +* +* Description: This function is called to allocate a timer. +* +* Arguments : none +* +* Returns : a pointer to a timer if one is available +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static OS_TMR *OSTmr_Alloc (void) +{ + OS_TMR *ptmr; + + + if (OSTmrFreeList == (OS_TMR *)0) { + return ((OS_TMR *)0); + } + ptmr = (OS_TMR *)OSTmrFreeList; + OSTmrFreeList = (OS_TMR *)ptmr->OSTmrNext; + ptmr->OSTmrNext = (OS_TCB *)0; + ptmr->OSTmrPrev = (OS_TCB *)0; + OSTmrUsed++; + OSTmrFree--; + return (ptmr); +} +#endif + + +/* +************************************************************************************************************************ +* RETURN A TIMER TO THE FREE LIST +* +* Description: This function is called to return a timer object to the free list of timers. +* +* Arguments : ptmr is a pointer to the timer to free +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Free (OS_TMR *ptmr) +{ + ptmr->OSTmrState = OS_TMR_STATE_UNUSED; /* Clear timer object fields */ + ptmr->OSTmrOpt = OS_TMR_OPT_NONE; + ptmr->OSTmrPeriod = 0; + ptmr->OSTmrMatch = 0; + ptmr->OSTmrCallback = (OS_TMR_CALLBACK)0; + ptmr->OSTmrCallbackArg = (void *)0; +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr->OSTmrName[0] = '?'; /* Unknown name */ + ptmr->OSTmrName[1] = OS_ASCII_NUL; +#endif + + ptmr->OSTmrPrev = (OS_TCB *)0; /* Chain timer to free list */ + ptmr->OSTmrNext = OSTmrFreeList; + OSTmrFreeList = ptmr; + + OSTmrUsed--; /* Update timer object statistics */ + OSTmrFree++; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TIMERS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TMRs. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +void OSTmr_Init (void) +{ +#if OS_EVENT_NAME_SIZE > 10 + INT8U err; +#endif + INT16U i; + OS_TMR *ptmr1; + OS_TMR *ptmr2; + + + OS_MemClr((INT8U *)&OSTmrTbl[0], sizeof(OSTmrTbl)); /* Clear all the TMRs */ + OS_MemClr((INT8U *)&OSTmrWheelTbl[0], sizeof(OSTmrWheelTbl)); /* Clear the timer wheel */ + + ptmr1 = &OSTmrTbl[0]; + ptmr2 = &OSTmrTbl[1]; + for (i = 0; i < (OS_TMR_CFG_MAX - 1); i++) { /* Init. list of free TMRs */ + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)ptmr2; /* Link to next timer */ +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr1->OSTmrName[0] = '?'; /* Unknown name */ + ptmr1->OSTmrName[1] = OS_ASCII_NUL; +#endif + ptmr1++; + ptmr2++; + } + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)0; /* Last OS_TMR */ +#if OS_TMR_CFG_NAME_SIZE > 1 + ptmr1->OSTmrName[0] = '?'; /* Unknown name */ + ptmr1->OSTmrName[1] = OS_ASCII_NUL; +#endif + OSTmrTime = 0; + OSTmrUsed = 0; + OSTmrFree = OS_TMR_CFG_MAX; + OSTmrFreeList = &OSTmrTbl[0]; + OSTmrSem = OSSemCreate(1); + OSTmrSemSignal = OSSemCreate(0); + +#if OS_EVENT_NAME_SIZE > 18 + OSEventNameSet(OSTmrSem, (INT8U *)"uC/OS-II TmrLock", &err);/* Assign names to semaphores */ +#else +#if OS_EVENT_NAME_SIZE > 10 + OSEventNameSet(OSTmrSem, (INT8U *)"OS-TmrLock", &err); +#endif +#endif + +#if OS_EVENT_NAME_SIZE > 18 + OSEventNameSet(OSTmrSemSignal, (INT8U *)"uC/OS-II TmrSignal", &err); +#else +#if OS_EVENT_NAME_SIZE > 10 + OSEventNameSet(OSTmrSemSignal, (INT8U *)"OS-TmrSig", &err); +#endif +#endif + + OSTmr_InitTask(); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZE THE TIMER MANAGEMENT TASK +* +* Description: This function is called by OSTmrInit() to create the timer management task. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_InitTask (void) +{ +#if OS_TASK_NAME_SIZE > 6 + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0 + #if OS_STK_GROWTH == 1 + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[0], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1 + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], + OS_TASK_TMR_PRIO); + #else + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[0], + OS_TASK_TMR_PRIO); + #endif +#endif + +#if OS_TASK_NAME_SIZE > 12 + OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"uC/OS-II Tmr", &err); +#else +#if OS_TASK_NAME_SIZE > 6 + OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"OS-Tmr", &err); +#endif +#endif +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INSERT A TIMER INTO THE TIMER WHEEL +* +* Description: This function is called to insert the timer into the timer wheel. The timer is always inserted at the +* beginning of the list. +* +* Arguments : ptmr Is a pointer to the timer to insert. +* +* type Is either: +* OS_TMR_LINK_PERIODIC Means to re-insert the timer after a period expired +* OS_TMR_LINK_DLY Means to insert the timer the first time +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Link (OS_TMR *ptmr, INT8U type) +{ + OS_TMR *ptmr1; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + ptmr->OSTmrState = OS_TMR_STATE_RUNNING; + if (type == OS_TMR_LINK_PERIODIC) { /* Determine when timer will expire */ + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + if (ptmr->OSTmrDly == 0) { + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + ptmr->OSTmrMatch = ptmr->OSTmrDly + OSTmrTime; + } + } + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == (OS_TMR *)0) { /* Link into timer wheel */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (OS_TMR *)0; + pspoke->OSTmrEntries = 1; + } else { + ptmr1 = pspoke->OSTmrFirst; /* Point to first timer in the spoke */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (void *)ptmr1; + ptmr1->OSTmrPrev = (void *)ptmr; + pspoke->OSTmrEntries++; + } + ptmr->OSTmrPrev = (void *)0; /* Timer always inserted as first node in list */ +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* REMOVE A TIMER FROM THE TIMER WHEEL +* +* Description: This function is called to remove the timer from the timer wheel. +* +* Arguments : ptmr Is a pointer to the timer to remove. +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Unlink (OS_TMR *ptmr) +{ + OS_TMR *ptmr1; + OS_TMR *ptmr2; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == ptmr) { /* See if timer to remove is at the beginning of list */ + ptmr1 = (OS_TMR *)ptmr->OSTmrNext; + pspoke->OSTmrFirst = (void *)ptmr1; + if (ptmr1 != (OS_TMR *)0) { + ptmr1->OSTmrPrev = (void *)0; + } + } else { + ptmr1 = (OS_TMR *)ptmr->OSTmrPrev; /* Remove timer from somewhere in the list */ + ptmr2 = (OS_TMR *)ptmr->OSTmrNext; + ptmr1->OSTmrNext = ptmr2; + if (ptmr2 != (OS_TMR *)0) { + ptmr2->OSTmrPrev = (void *)ptmr1; + } + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; + ptmr->OSTmrNext = (void *)0; + ptmr->OSTmrPrev = (void *)0; + pspoke->OSTmrEntries--; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER MANAGER DATA STRUCTURE LOCKING MECHANISM +* +* Description: These functions are used to gain exclusive access to timer management data structures. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Lock (void) +{ + INT8U err; + + + OSSemPend(OSTmrSem, 0, &err); + (void)err; +} +#endif + + + +#if OS_TMR_EN > 0 +static void OSTmr_Unlock (void) +{ + (void)OSSemPost(OSTmrSem); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER MANAGEMENT TASK +* +* Description: This task is created by OSTmrInit(). +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +static void OSTmr_Task (void *p_arg) +{ + INT8U err; + OS_TMR *ptmr; + OS_TMR *ptmr_next; + OS_TMR_CALLBACK pfnct; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + (void)p_arg; /* Not using 'p_arg', prevent compiler warning */ + for (;;) { + OSSemPend(OSTmrSemSignal, 0, &err); /* Wait for signal indicating time to update timers */ + OSTmr_Lock(); + OSTmrTime++; /* Increment the current time */ + spoke = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE); /* Position on current timer wheel entry */ + pspoke = &OSTmrWheelTbl[spoke]; + ptmr = pspoke->OSTmrFirst; + while (ptmr != (OS_TMR *)0) { + ptmr_next = (OS_TMR *)ptmr->OSTmrNext; /* Point to next timer to update because current ... */ + /* ... timer could get unlinked from the wheel. */ + if (OSTmrTime == ptmr->OSTmrMatch) { /* Process each timer that expires */ + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); + } + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) { + OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC); /* Recalculate new position of timer in wheel */ + } else { + ptmr->OSTmrState = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ + } + } + ptmr = ptmr_next; + } + OSTmr_Unlock(); + } +} +#endif diff --git a/OS/uc/os_ii/source/ucos_ii.h b/OS/uc/os_ii/source/ucos_ii.h new file mode 100644 index 0000000..5ddfc92 --- /dev/null +++ b/OS/uc/os_ii/source/ucos_ii.h @@ -0,0 +1,1902 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL +* All Rights Reserved +* +* File : uCOS_II.H +* By : Jean J. Labrosse +* Version : V2.85 +* +* LICENSING TERMS: +* --------------- +* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. +* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license +* its use in your product. We provide ALL the source code for your convenience and to help you experience +* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a +* licensing fee. +********************************************************************************************************* +*/ + +#ifndef OS_uCOS_II_H +#define OS_uCOS_II_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* uC/OS-II VERSION NUMBER +********************************************************************************************************* +*/ + +#define OS_VERSION 285u /* Version of uC/OS-II (Vx.yy mult. by 100) */ + +/* +********************************************************************************************************* +* INCLUDE HEADER FILES +********************************************************************************************************* +*/ + +#include +#include +#include + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifdef OS_GLOBALS +#define OS_EXT +#else +#define OS_EXT extern +#endif + +#ifndef OS_FALSE +#define OS_FALSE 0u +#endif + +#ifndef OS_TRUE +#define OS_TRUE 1u +#endif + +#define OS_ASCII_NUL (INT8U)0 + +#define OS_PRIO_SELF 0xFFu /* Indicate SELF priority */ + +#if OS_TASK_STAT_EN > 0 +#define OS_N_SYS_TASKS 2u /* Number of system tasks */ +#else +#define OS_N_SYS_TASKS 1u +#endif + +#define OS_TASK_STAT_PRIO (OS_LOWEST_PRIO - 1) /* Statistic task priority */ +#define OS_TASK_IDLE_PRIO (OS_LOWEST_PRIO) /* IDLE task priority */ + +#if OS_LOWEST_PRIO <= 63 +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) /* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 8 + 1) /* Size of ready table */ +#else +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 16 + 1) /* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 16 + 1) /* Size of ready table */ +#endif + +#define OS_TASK_IDLE_ID 65535u /* ID numbers for Idle, Stat and Timer tasks */ +#define OS_TASK_STAT_ID 65534u +#define OS_TASK_TMR_ID 65533u + +#define OS_EVENT_EN (((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)) + +#define OS_TCB_RESERVED ((OS_TCB *)1) + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK STATUS (Bit definition for OSTCBStat) +********************************************************************************************************* +*/ +#define OS_STAT_RDY 0x00u /* Ready to run */ +#define OS_STAT_SEM 0x01u /* Pending on semaphore */ +#define OS_STAT_MBOX 0x02u /* Pending on mailbox */ +#define OS_STAT_Q 0x04u /* Pending on queue */ +#define OS_STAT_SUSPEND 0x08u /* Task is suspended */ +#define OS_STAT_MUTEX 0x10u /* Pending on mutual exclusion semaphore */ +#define OS_STAT_FLAG 0x20u /* Pending on event flag group */ + +#define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_FLAG) + +/* +********************************************************************************************************* +* TASK PEND STATUS (Status codes for OSTCBStatPend) +********************************************************************************************************* +*/ +#define OS_STAT_PEND_OK 0u /* Pending status OK, not pending, or pending complete */ +#define OS_STAT_PEND_TO 1u /* Pending timed out */ +#define OS_STAT_PEND_ABORT 2u /* Pending aborted */ + +/* +********************************************************************************************************* +* OS_EVENT types +********************************************************************************************************* +*/ +#define OS_EVENT_TYPE_UNUSED 0u +#define OS_EVENT_TYPE_MBOX 1u +#define OS_EVENT_TYPE_Q 2u +#define OS_EVENT_TYPE_SEM 3u +#define OS_EVENT_TYPE_MUTEX 4u +#define OS_EVENT_TYPE_FLAG 5u + +#define OS_TMR_TYPE 100u /* Used to identify Timers ... */ + /* ... (Must be different value than OS_EVENT_TYPE_xxx) */ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ +#define OS_FLAG_WAIT_CLR_ALL 0u /* Wait for ALL the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_AND 0u + +#define OS_FLAG_WAIT_CLR_ANY 1u /* Wait for ANY of the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_OR 1u + +#define OS_FLAG_WAIT_SET_ALL 2u /* Wait for ALL the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_AND 2u + +#define OS_FLAG_WAIT_SET_ANY 3u /* Wait for ANY of the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_OR 3u + + +#define OS_FLAG_CONSUME 0x80u /* Consume the flags if condition(s) satisfied */ + + +#define OS_FLAG_CLR 0u +#define OS_FLAG_SET 1u + +/* +********************************************************************************************************* +* Values for OSTickStepState +* +* Note(s): This feature is used by uC/OS-View. +********************************************************************************************************* +*/ + +#if OS_TICK_STEP_EN > 0 +#define OS_TICK_STEP_DIS 0u /* Stepping is disabled, tick runs as mormal */ +#define OS_TICK_STEP_WAIT 1u /* Waiting for uC/OS-View to set OSTickStepState to _ONCE */ +#define OS_TICK_STEP_ONCE 2u /* Process tick once and wait for next cmd from uC/OS-View */ +#endif + +/* +********************************************************************************************************* +* Possible values for 'opt' argument of OSSemDel(), OSMboxDel(), OSQDel() and OSMutexDel() +********************************************************************************************************* +*/ +#define OS_DEL_NO_PEND 0u +#define OS_DEL_ALWAYS 1u + +/* +********************************************************************************************************* +* OS???Pend() OPTIONS +* +* These #defines are used to establish the options for OS???PendAbort(). +********************************************************************************************************* +*/ +#define OS_PEND_OPT_NONE 0u /* NO option selected */ +#define OS_PEND_OPT_BROADCAST 1u /* Broadcast action to ALL tasks waiting */ + +/* +********************************************************************************************************* +* OS???PostOpt() OPTIONS +* +* These #defines are used to establish the options for OSMboxPostOpt() and OSQPostOpt(). +********************************************************************************************************* +*/ +#define OS_POST_OPT_NONE 0x00u /* NO option selected */ +#define OS_POST_OPT_BROADCAST 0x01u /* Broadcast message to ALL tasks waiting */ +#define OS_POST_OPT_FRONT 0x02u /* Post to highest priority task waiting */ +#define OS_POST_OPT_NO_SCHED 0x04u /* Do not call the scheduler if this option is selected */ + +/* +********************************************************************************************************* +* TASK OPTIONS (see OSTaskCreateExt()) +********************************************************************************************************* +*/ +#define OS_TASK_OPT_NONE 0x0000u /* NO option selected */ +#define OS_TASK_OPT_STK_CHK 0x0001u /* Enable stack checking for the task */ +#define OS_TASK_OPT_STK_CLR 0x0002u /* Clear the stack when the task is create */ +#define OS_TASK_OPT_SAVE_FP 0x0004u /* Save the contents of any floating-point registers */ + +/* +********************************************************************************************************* +* TIMER OPTIONS (see OSTmrStart() and OSTmrStop()) +********************************************************************************************************* +*/ +#define OS_TMR_OPT_NONE 0u /* No option selected */ + +#define OS_TMR_OPT_ONE_SHOT 1u /* Timer will not automatically restart when it expires */ +#define OS_TMR_OPT_PERIODIC 2u /* Timer will automatically restart when it expires */ + +#define OS_TMR_OPT_CALLBACK 3u /* OSTmrStop() option to call 'callback' w/ timer arg. */ +#define OS_TMR_OPT_CALLBACK_ARG 4u /* OSTmrStop() option to call 'callback' w/ new arg. */ + +/* +********************************************************************************************************* +* TIMER STATES +********************************************************************************************************* +*/ +#define OS_TMR_STATE_UNUSED 0u +#define OS_TMR_STATE_STOPPED 1u +#define OS_TMR_STATE_COMPLETED 2u +#define OS_TMR_STATE_RUNNING 3u + +/* +********************************************************************************************************* +* ERROR CODES +********************************************************************************************************* +*/ +#define OS_ERR_NONE 0u + +#define OS_ERR_EVENT_TYPE 1u +#define OS_ERR_PEND_ISR 2u +#define OS_ERR_POST_NULL_PTR 3u +#define OS_ERR_PEVENT_NULL 4u +#define OS_ERR_POST_ISR 5u +#define OS_ERR_QUERY_ISR 6u +#define OS_ERR_INVALID_OPT 7u +#define OS_ERR_PDATA_NULL 9u + +#define OS_ERR_TIMEOUT 10u +#define OS_ERR_EVENT_NAME_TOO_LONG 11u +#define OS_ERR_PNAME_NULL 12u +#define OS_ERR_PEND_LOCKED 13u +#define OS_ERR_PEND_ABORT 14u +#define OS_ERR_DEL_ISR 15u +#define OS_ERR_CREATE_ISR 16u +#define OS_ERR_NAME_GET_ISR 17u +#define OS_ERR_NAME_SET_ISR 18u + +#define OS_ERR_MBOX_FULL 20u + +#define OS_ERR_Q_FULL 30u +#define OS_ERR_Q_EMPTY 31u + +#define OS_ERR_PRIO_EXIST 40u +#define OS_ERR_PRIO 41u +#define OS_ERR_PRIO_INVALID 42u + +#define OS_ERR_SEM_OVF 50u + +#define OS_ERR_TASK_CREATE_ISR 60u +#define OS_ERR_TASK_DEL 61u +#define OS_ERR_TASK_DEL_IDLE 62u +#define OS_ERR_TASK_DEL_REQ 63u +#define OS_ERR_TASK_DEL_ISR 64u +#define OS_ERR_TASK_NAME_TOO_LONG 65u +#define OS_ERR_TASK_NO_MORE_TCB 66u +#define OS_ERR_TASK_NOT_EXIST 67u +#define OS_ERR_TASK_NOT_SUSPENDED 68u +#define OS_ERR_TASK_OPT 69u +#define OS_ERR_TASK_RESUME_PRIO 70u +#define OS_ERR_TASK_SUSPEND_IDLE 71u +#define OS_ERR_TASK_SUSPEND_PRIO 72u +#define OS_ERR_TASK_WAITING 73u + +#define OS_ERR_TIME_NOT_DLY 80u +#define OS_ERR_TIME_INVALID_MINUTES 81u +#define OS_ERR_TIME_INVALID_SECONDS 82u +#define OS_ERR_TIME_INVALID_MS 83u +#define OS_ERR_TIME_ZERO_DLY 84u +#define OS_ERR_TIME_DLY_ISR 85u + +#define OS_ERR_MEM_INVALID_PART 90u +#define OS_ERR_MEM_INVALID_BLKS 91u +#define OS_ERR_MEM_INVALID_SIZE 92u +#define OS_ERR_MEM_NO_FREE_BLKS 93u +#define OS_ERR_MEM_FULL 94u +#define OS_ERR_MEM_INVALID_PBLK 95u +#define OS_ERR_MEM_INVALID_PMEM 96u +#define OS_ERR_MEM_INVALID_PDATA 97u +#define OS_ERR_MEM_INVALID_ADDR 98u +#define OS_ERR_MEM_NAME_TOO_LONG 99u + +#define OS_ERR_NOT_MUTEX_OWNER 100u + +#define OS_ERR_FLAG_INVALID_PGRP 110u +#define OS_ERR_FLAG_WAIT_TYPE 111u +#define OS_ERR_FLAG_NOT_RDY 112u +#define OS_ERR_FLAG_INVALID_OPT 113u +#define OS_ERR_FLAG_GRP_DEPLETED 114u +#define OS_ERR_FLAG_NAME_TOO_LONG 115u + +#define OS_ERR_PIP_LOWER 120u + +#define OS_ERR_TMR_INVALID_DLY 130u +#define OS_ERR_TMR_INVALID_PERIOD 131u +#define OS_ERR_TMR_INVALID_OPT 132u +#define OS_ERR_TMR_INVALID_NAME 133u +#define OS_ERR_TMR_NON_AVAIL 134u +#define OS_ERR_TMR_INACTIVE 135u +#define OS_ERR_TMR_INVALID_DEST 136u +#define OS_ERR_TMR_INVALID_TYPE 137u +#define OS_ERR_TMR_INVALID 138u +#define OS_ERR_TMR_ISR 139u +#define OS_ERR_TMR_NAME_TOO_LONG 140u +#define OS_ERR_TMR_INVALID_STATE 141u +#define OS_ERR_TMR_STOPPED 142u +#define OS_ERR_TMR_NO_CALLBACK 143u + +/* +********************************************************************************************************* +* OLD ERROR CODE NAMES (< V2.84) +********************************************************************************************************* +*/ +#define OS_NO_ERR OS_ERR_NONE +#define OS_TIMEOUT OS_ERR_TIMEOUT +#define OS_TASK_NOT_EXIST OS_ERR_TASK_NOT_EXIST +#define OS_MBOX_FULL OS_ERR_MBOX_FULL +#define OS_Q_FULL OS_ERR_Q_FULL +#define OS_Q_EMPTY OS_ERR_Q_EMPTY +#define OS_PRIO_EXIST OS_ERR_PRIO_EXIST +#define OS_PRIO_ERR OS_ERR_PRIO +#define OS_PRIO_INVALID OS_ERR_PRIO_INVALID +#define OS_SEM_OVF OS_ERR_SEM_OVF +#define OS_TASK_DEL_ERR OS_ERR_TASK_DEL +#define OS_TASK_DEL_IDLE OS_ERR_TASK_DEL_IDLE +#define OS_TASK_DEL_REQ OS_ERR_TASK_DEL_REQ +#define OS_TASK_DEL_ISR OS_ERR_TASK_DEL_ISR +#define OS_NO_MORE_TCB OS_ERR_TASK_NO_MORE_TCB +#define OS_TIME_NOT_DLY OS_ERR_TIME_NOT_DLY +#define OS_TIME_INVALID_MINUTES OS_ERR_TIME_INVALID_MINUTES +#define OS_TIME_INVALID_SECONDS OS_ERR_TIME_INVALID_SECONDS +#define OS_TIME_INVALID_MS OS_ERR_TIME_INVALID_MS +#define OS_TIME_ZERO_DLY OS_ERR_TIME_ZERO_DLY +#define OS_TASK_SUSPEND_PRIO OS_ERR_TASK_SUSPEND_PRIO +#define OS_TASK_SUSPEND_IDLE OS_ERR_TASK_SUSPEND_IDLE +#define OS_TASK_RESUME_PRIO OS_ERR_TASK_RESUME_PRIO +#define OS_TASK_NOT_SUSPENDED OS_ERR_TASK_NOT_SUSPENDED +#define OS_MEM_INVALID_PART OS_ERR_MEM_INVALID_PART +#define OS_MEM_INVALID_BLKS OS_ERR_MEM_INVALID_BLKS +#define OS_MEM_INVALID_SIZE OS_ERR_MEM_INVALID_SIZE +#define OS_MEM_NO_FREE_BLKS OS_ERR_MEM_NO_FREE_BLKS +#define OS_MEM_FULL OS_ERR_MEM_FULL +#define OS_MEM_INVALID_PBLK OS_ERR_MEM_INVALID_PBLK +#define OS_MEM_INVALID_PMEM OS_ERR_MEM_INVALID_PMEM +#define OS_MEM_INVALID_PDATA OS_ERR_MEM_INVALID_PDATA +#define OS_MEM_INVALID_ADDR OS_ERR_MEM_INVALID_ADDR +#define OS_MEM_NAME_TOO_LONG OS_ERR_MEM_NAME_TOO_LONG +#define OS_TASK_OPT_ERR OS_ERR_TASK_OPT +#define OS_FLAG_INVALID_PGRP OS_ERR_FLAG_INVALID_PGRP +#define OS_FLAG_ERR_WAIT_TYPE OS_ERR_FLAG_WAIT_TYPE +#define OS_FLAG_ERR_NOT_RDY OS_ERR_FLAG_NOT_RDY +#define OS_FLAG_INVALID_OPT OS_ERR_FLAG_INVALID_OPT +#define OS_FLAG_GRP_DEPLETED OS_ERR_FLAG_GRP_DEPLETED + +/*$PAGE*/ +/* +********************************************************************************************************* +* EVENT CONTROL BLOCK +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +typedef struct os_event { + INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */ + void *OSEventPtr; /* Pointer to message or queue structure */ + INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ +#else + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ +#endif + +#if OS_EVENT_NAME_SIZE > 1 + INT8U OSEventName[OS_EVENT_NAME_SIZE]; +#endif +} OS_EVENT; +#endif + + +/* +********************************************************************************************************* +* EVENT FLAGS CONTROL BLOCK +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + +#if OS_FLAGS_NBITS == 8 /* Determine the size of OS_FLAGS (8, 16 or 32 bits) */ +typedef INT8U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 16 +typedef INT16U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 32 +typedef INT32U OS_FLAGS; +#endif + + +typedef struct os_flag_grp { /* Event Flag Group */ + INT8U OSFlagType; /* Should be set to OS_EVENT_TYPE_FLAG */ + void *OSFlagWaitList; /* Pointer to first NODE of task waiting on event flag */ + OS_FLAGS OSFlagFlags; /* 8, 16 or 32 bit flags */ +#if OS_FLAG_NAME_SIZE > 1 + INT8U OSFlagName[OS_FLAG_NAME_SIZE]; +#endif +} OS_FLAG_GRP; + + + +typedef struct os_flag_node { /* Event Flag Wait List Node */ + void *OSFlagNodeNext; /* Pointer to next NODE in wait list */ + void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */ + void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */ + void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */ + OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */ + INT8U OSFlagNodeWaitType; /* Type of wait: */ + /* OS_FLAG_WAIT_AND */ + /* OS_FLAG_WAIT_ALL */ + /* OS_FLAG_WAIT_OR */ + /* OS_FLAG_WAIT_ANY */ +} OS_FLAG_NODE; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE MAILBOX DATA +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0 +typedef struct os_mbox_data { + void *OSMsg; /* Pointer to message in mailbox */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_MBOX_DATA; +#endif + +/* +********************************************************************************************************* +* MEMORY PARTITION DATA STRUCTURES +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +typedef struct os_mem { /* MEMORY CONTROL BLOCK */ + void *OSMemAddr; /* Pointer to beginning of memory partition */ + void *OSMemFreeList; /* Pointer to list of free memory blocks */ + INT32U OSMemBlkSize; /* Size (in bytes) of each block of memory */ + INT32U OSMemNBlks; /* Total number of blocks in this partition */ + INT32U OSMemNFree; /* Number of memory blocks remaining in this partition */ +#if OS_MEM_NAME_SIZE > 1 + INT8U OSMemName[OS_MEM_NAME_SIZE]; /* Memory partition name */ +#endif +} OS_MEM; + + +typedef struct os_mem_data { + void *OSAddr; /* Pointer to the beginning address of the memory partition */ + void *OSFreeList; /* Pointer to the beginning of the free list of memory blocks */ + INT32U OSBlkSize; /* Size (in bytes) of each memory block */ + INT32U OSNBlks; /* Total number of blocks in the partition */ + INT32U OSNFree; /* Number of memory blocks free */ + INT32U OSNUsed; /* Number of memory blocks used */ +} OS_MEM_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0 +typedef struct os_mutex_data { +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif + BOOLEAN OSValue; /* Mutex value (OS_FALSE = used, OS_TRUE = available) */ + INT8U OSOwnerPrio; /* Mutex owner's task priority or 0xFF if no owner */ + INT8U OSMutexPIP; /* Priority Inheritance Priority or 0xFF if no owner */ +} OS_MUTEX_DATA; +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUE DATA +********************************************************************************************************* +*/ + +#if OS_Q_EN > 0 +typedef struct os_q { /* QUEUE CONTROL BLOCK */ + struct os_q *OSQPtr; /* Link to next queue control block in list of free blocks */ + void **OSQStart; /* Pointer to start of queue data */ + void **OSQEnd; /* Pointer to end of queue data */ + void **OSQIn; /* Pointer to where next message will be inserted in the Q */ + void **OSQOut; /* Pointer to where next message will be extracted from the Q */ + INT16U OSQSize; /* Size of queue (maximum number of entries) */ + INT16U OSQEntries; /* Current number of entries in the queue */ +} OS_Q; + + +typedef struct os_q_data { + void *OSMsg; /* Pointer to next message to be extracted from queue */ + INT16U OSNMsgs; /* Number of messages in message queue */ + INT16U OSQSize; /* Size of message queue */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_Q_DATA; +#endif + +/* +********************************************************************************************************* +* SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_SEM_EN > 0 +typedef struct os_sem_data { + INT16U OSCnt; /* Semaphore count */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT8U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#else + INT16U OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + INT16U OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +#endif +} OS_SEM_DATA; +#endif + +/* +********************************************************************************************************* +* TASK STACK DATA +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EXT_EN > 0 +typedef struct os_stk_data { + INT32U OSFree; /* Number of free bytes on the stack */ + INT32U OSUsed; /* Number of bytes used on the stack */ +} OS_STK_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK CONTROL BLOCK +********************************************************************************************************* +*/ + +typedef struct os_tcb { + OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */ + +#if OS_TASK_CREATE_EXT_EN > 0 + void *OSTCBExtPtr; /* Pointer to user definable data for TCB extension */ + OS_STK *OSTCBStkBottom; /* Pointer to bottom of stack */ + INT32U OSTCBStkSize; /* Size of task stack (in number of stack elements) */ + INT16U OSTCBOpt; /* Task options as passed by OSTaskCreateExt() */ + INT16U OSTCBId; /* Task ID (0..65535) */ +#endif + + struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list */ + struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list */ + +#if OS_EVENT_EN || (OS_FLAG_EN > 0) + OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */ +#endif + +#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) + void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +#if OS_TASK_DEL_EN > 0 + OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */ +#endif + OS_FLAGS OSTCBFlagsRdy; /* Event flags that made task ready to run */ +#endif + + INT16U OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */ + INT8U OSTCBStat; /* Task status */ + INT8U OSTCBStatPend; /* Task PEND status */ + INT8U OSTCBPrio; /* Task priority (0 == highest) */ + + INT8U OSTCBX; /* Bit position in group corresponding to task priority */ + INT8U OSTCBY; /* Index into ready table corresponding to task priority */ +#if OS_LOWEST_PRIO <= 63 + INT8U OSTCBBitX; /* Bit mask to access bit position in ready table */ + INT8U OSTCBBitY; /* Bit mask to access bit position in ready group */ +#else + INT16U OSTCBBitX; /* Bit mask to access bit position in ready table */ + INT16U OSTCBBitY; /* Bit mask to access bit position in ready group */ +#endif + +#if OS_TASK_DEL_EN > 0 + INT8U OSTCBDelReq; /* Indicates whether a task needs to delete itself */ +#endif + +#if OS_TASK_PROFILE_EN > 0 + INT32U OSTCBCtxSwCtr; /* Number of time the task was switched in */ + INT32U OSTCBCyclesTot; /* Total number of clock cycles the task has been running */ + INT32U OSTCBCyclesStart; /* Snapshot of cycle counter at start of task resumption */ + OS_STK *OSTCBStkBase; /* Pointer to the beginning of the task stack */ + INT32U OSTCBStkUsed; /* Number of bytes used from the stack */ +#endif + +#if OS_TASK_NAME_SIZE > 1 + INT8U OSTCBTaskName[OS_TASK_NAME_SIZE]; +#endif +} OS_TCB; + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER DATA TYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0 +typedef void (*OS_TMR_CALLBACK)(void *ptmr, void *parg); + + + +typedef struct os_tmr { + INT8U OSTmrType; /* Should be set to OS_TMR_TYPE */ + OS_TMR_CALLBACK OSTmrCallback; /* Function to call when timer expires */ + void *OSTmrCallbackArg; /* Argument to pass to function when timer expires */ + void *OSTmrNext; /* Double link list pointers */ + void *OSTmrPrev; + INT32U OSTmrMatch; /* Timer expires when OSTmrTime == OSTmrMatch */ + INT32U OSTmrDly; /* Delay time before periodic update starts */ + INT32U OSTmrPeriod; /* Period to repeat timer */ +#if OS_TMR_CFG_NAME_SIZE > 0 + INT8U OSTmrName[OS_TMR_CFG_NAME_SIZE]; /* Name to give the timer */ +#endif + INT8U OSTmrOpt; /* Options (see OS_TMR_OPT_xxx) */ + INT8U OSTmrState; /* Indicates the state of the timer: */ + /* OS_TMR_STATE_UNUSED */ + /* OS_TMR_STATE_RUNNING */ + /* OS_TMR_STATE_STOPPED */ +} OS_TMR; + + + +typedef struct os_tmr_wheel { + OS_TMR *OSTmrFirst; /* Pointer to first timer in linked list */ + INT16U OSTmrEntries; +} OS_TMR_WHEEL; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + +OS_EXT INT32U OSCtxSwCtr; /* Counter of number of context switches */ + +#if OS_EVENT_EN && (OS_MAX_EVENTS > 0) +OS_EXT OS_EVENT *OSEventFreeList; /* Pointer to list of free EVENT control blocks */ +OS_EXT OS_EVENT OSEventTbl[OS_MAX_EVENTS];/* Table of EVENT control blocks */ +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +OS_EXT OS_FLAG_GRP OSFlagTbl[OS_MAX_FLAGS]; /* Table containing event flag groups */ +OS_EXT OS_FLAG_GRP *OSFlagFreeList; /* Pointer to free list of event flag groups */ +#endif + +#if OS_TASK_STAT_EN > 0 +OS_EXT INT8S OSCPUUsage; /* Percentage of CPU used */ +OS_EXT INT32U OSIdleCtrMax; /* Max. value that idle ctr can take in 1 sec. */ +OS_EXT INT32U OSIdleCtrRun; /* Val. reached by idle ctr at run time in 1 sec. */ +OS_EXT BOOLEAN OSStatRdy; /* Flag indicating that the statistic task is rdy */ +OS_EXT OS_STK OSTaskStatStk[OS_TASK_STAT_STK_SIZE]; /* Statistics task stack */ +#endif + +OS_EXT INT8U OSIntNesting; /* Interrupt nesting level */ + +OS_EXT INT8U OSLockNesting; /* Multitasking lock nesting level */ + +OS_EXT INT8U OSPrioCur; /* Priority of current task */ +OS_EXT INT8U OSPrioHighRdy; /* Priority of highest priority task */ + +#if OS_LOWEST_PRIO <= 63 +OS_EXT INT8U OSRdyGrp; /* Ready list group */ +OS_EXT INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ +#else +OS_EXT INT16U OSRdyGrp; /* Ready list group */ +OS_EXT INT16U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ +#endif + +OS_EXT BOOLEAN OSRunning; /* Flag indicating that kernel is running */ + +OS_EXT INT8U OSTaskCtr; /* Number of tasks created */ + +OS_EXT volatile INT32U OSIdleCtr; /* Idle counter */ + +OS_EXT OS_STK OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE]; /* Idle task stack */ + + +OS_EXT OS_TCB *OSTCBCur; /* Pointer to currently running TCB */ +OS_EXT OS_TCB *OSTCBFreeList; /* Pointer to list of free TCBs */ +OS_EXT OS_TCB *OSTCBHighRdy; /* Pointer to highest priority TCB R-to-R */ +OS_EXT OS_TCB *OSTCBList; /* Pointer to doubly linked list of TCBs */ +OS_EXT OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];/* Table of pointers to created TCBs */ +OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]; /* Table of TCBs */ + +#if OS_TICK_STEP_EN > 0 +OS_EXT INT8U OSTickStepState; /* Indicates the state of the tick step feature */ +#endif + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +OS_EXT OS_MEM *OSMemFreeList; /* Pointer to free list of memory partitions */ +OS_EXT OS_MEM OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager */ +#endif + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) +OS_EXT OS_Q *OSQFreeList; /* Pointer to list of free QUEUE control blocks */ +OS_EXT OS_Q OSQTbl[OS_MAX_QS]; /* Table of QUEUE control blocks */ +#endif + +#if OS_TIME_GET_SET_EN > 0 +OS_EXT volatile INT32U OSTime; /* Current value of system time (in ticks) */ +#endif + +#if OS_TMR_EN > 0 +OS_EXT INT16U OSTmrFree; /* Number of free entries in the timer pool */ +OS_EXT INT16U OSTmrUsed; /* Number of timers used */ +OS_EXT INT32U OSTmrTime; /* Current timer time */ + +OS_EXT OS_EVENT *OSTmrSem; /* Sem. used to gain exclusive access to timers */ +OS_EXT OS_EVENT *OSTmrSemSignal; /* Sem. used to signal the update of timers */ + +OS_EXT OS_TMR OSTmrTbl[OS_TMR_CFG_MAX]; /* Table containing pool of timers */ +OS_EXT OS_TMR *OSTmrFreeList; /* Pointer to free list of timers */ +OS_EXT OS_STK OSTmrTaskStk[OS_TASK_TMR_STK_SIZE]; + +OS_EXT OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]; +#endif + +extern INT8U const OSUnMapTbl[256]; /* Priority->Index lookup table */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Independent Functions) +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1) +INT8U OSEventNameGet (OS_EVENT *pevent, + INT8U *pname, + INT8U *perr); + +void OSEventNameSet (OS_EVENT *pevent, + INT8U *pname, + INT8U *perr); +#endif + +/* +********************************************************************************************************* +* EVENT FLAGS MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) + +#if OS_FLAG_ACCEPT_EN > 0 +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT8U *perr); +#endif + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, + INT8U *perr); + +#if OS_FLAG_DEL_EN > 0 +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, + INT8U opt, + INT8U *perr); +#endif + +#if (OS_FLAG_EN > 0) && (OS_FLAG_NAME_SIZE > 1) +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, + INT8U *pname, + INT8U *perr); + +void OSFlagNameSet (OS_FLAG_GRP *pgrp, + INT8U *pname, + INT8U *perr); +#endif + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT16U timeout, + INT8U *perr); + +OS_FLAGS OSFlagPendGetFlagsRdy (void); +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U opt, + INT8U *perr); + +#if OS_FLAG_QUERY_EN > 0 +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, + INT8U *perr); +#endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOX MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0 + +#if OS_MBOX_ACCEPT_EN > 0 +void *OSMboxAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSMboxCreate (void *pmsg); + +#if OS_MBOX_DEL_EN > 0 +OS_EVENT *OSMboxDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void *OSMboxPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_MBOX_PEND_ABORT_EN > 0 +INT8U OSMboxPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_MBOX_POST_EN > 0 +INT8U OSMboxPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_MBOX_POST_OPT_EN > 0 +INT8U OSMboxPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_MBOX_QUERY_EN > 0 +INT8U OSMboxQuery (OS_EVENT *pevent, + OS_MBOX_DATA *p_mbox_data); +#endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) + +OS_MEM *OSMemCreate (void *addr, + INT32U nblks, + INT32U blksize, + INT8U *perr); + +void *OSMemGet (OS_MEM *pmem, + INT8U *perr); +#if OS_MEM_NAME_SIZE > 1 +INT8U OSMemNameGet (OS_MEM *pmem, + INT8U *pname, + INT8U *perr); + +void OSMemNameSet (OS_MEM *pmem, + INT8U *pname, + INT8U *perr); +#endif +INT8U OSMemPut (OS_MEM *pmem, + void *pblk); + +#if OS_MEM_QUERY_EN > 0 +INT8U OSMemQuery (OS_MEM *pmem, + OS_MEM_DATA *p_mem_data); +#endif + +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0 + +#if OS_MUTEX_ACCEPT_EN > 0 +BOOLEAN OSMutexAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSMutexCreate (INT8U prio, + INT8U *perr); + +#if OS_MUTEX_DEL_EN > 0 +OS_EVENT *OSMutexDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSMutexPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +INT8U OSMutexPost (OS_EVENT *pevent); + +#if OS_MUTEX_QUERY_EN > 0 +INT8U OSMutexQuery (OS_EVENT *pevent, + OS_MUTEX_DATA *p_mutex_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE QUEUE MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) + +#if OS_Q_ACCEPT_EN > 0 +void *OSQAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSQCreate (void **start, + INT16U size); + +#if OS_Q_DEL_EN > 0 +OS_EVENT *OSQDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_FLUSH_EN > 0 +INT8U OSQFlush (OS_EVENT *pevent); +#endif + +void *OSQPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_Q_PEND_ABORT_EN > 0 +INT8U OSQPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_POST_EN > 0 +INT8U OSQPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_FRONT_EN > 0 +INT8U OSQPostFront (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_OPT_EN > 0 +INT8U OSQPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_Q_QUERY_EN > 0 +INT8U OSQQuery (OS_EVENT *pevent, + OS_Q_DATA *p_q_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ +#if OS_SEM_EN > 0 + +#if OS_SEM_ACCEPT_EN > 0 +INT16U OSSemAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSSemCreate (INT16U cnt); + +#if OS_SEM_DEL_EN > 0 +OS_EVENT *OSSemDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSSemPend (OS_EVENT *pevent, + INT16U timeout, + INT8U *perr); + +#if OS_SEM_PEND_ABORT_EN > 0 +INT8U OSSemPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +INT8U OSSemPost (OS_EVENT *pevent); + +#if OS_SEM_QUERY_EN > 0 +INT8U OSSemQuery (OS_EVENT *pevent, + OS_SEM_DATA *p_sem_data); +#endif + +#if OS_SEM_SET_EN > 0 +void OSSemSet (OS_EVENT *pevent, + INT16U cnt, + INT8U *perr); +#endif + +INT16U OSSemCheck (OS_EVENT *pevent); + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ +#if OS_TASK_CHANGE_PRIO_EN > 0 +INT8U OSTaskChangePrio (INT8U oldprio, + INT8U newprio); +#endif + +#if OS_TASK_CREATE_EN > 0 +INT8U OSTaskCreate (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt); +#endif + +#if OS_TASK_DEL_EN > 0 +INT8U OSTaskDel (INT8U prio); +INT8U OSTaskDelReq (INT8U prio); +#endif + +#if OS_TASK_NAME_SIZE > 1 +INT8U OSTaskNameGet (INT8U prio, + INT8U *pname, + INT8U *perr); + +void OSTaskNameSet (INT8U prio, + INT8U *pname, + INT8U *perr); +#endif + +#if OS_TASK_SUSPEND_EN > 0 +INT8U OSTaskResume (INT8U prio); +INT8U OSTaskSuspend (INT8U prio); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +INT8U OSTaskStkChk (INT8U prio, + OS_STK_DATA *p_stk_data); +#endif + +#if OS_TASK_QUERY_EN > 0 +INT8U OSTaskQuery (INT8U prio, + OS_TCB *p_task_data); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +void OSTimeDly (INT16U ticks); + +#if OS_TIME_DLY_HMSM_EN > 0 +INT8U OSTimeDlyHMSM (INT8U hours, + INT8U minutes, + INT8U seconds, + INT16U milli); +#endif + +#if OS_TIME_DLY_RESUME_EN > 0 +INT8U OSTimeDlyResume (INT8U prio); +#endif + +#if OS_TIME_GET_SET_EN > 0 +INT32U OSTimeGet (void); +void OSTimeSet (INT32U ticks); +#endif + +void OSTimeTick (void); + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_TMR_EN > 0 +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr); + +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr); + +#if OS_TMR_CFG_NAME_SIZE > 0 +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U *pdest, + INT8U *perr); +#endif +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr); + +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr); + +INT8U OSTmrSignal (void); +#endif + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +void OSInit (void); + +void OSIntEnter (void); +void OSIntExit (void); + +#if OS_SCHED_LOCK_EN > 0 +void OSSchedLock (void); +void OSSchedUnlock (void); +#endif + +void OSStart (void); + +void OSStatInit (void); + +INT16U OSVersion (void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* INTERNAL FUNCTION PROTOTYPES +* (Your application MUST NOT call these functions) +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0 +void OS_Dummy (void); +#endif + +#if OS_EVENT_EN +INT8U OS_EventTaskRdy (OS_EVENT *pevent, + void *pmsg, + INT8U msk, + INT8U pend_stat); + +void OS_EventTaskWait (OS_EVENT *pevent); + +void OS_EventTOAbort (OS_EVENT *pevent); + +void OS_EventWaitListInit (OS_EVENT *pevent); +#endif + +#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) +void OS_FlagInit (void); +void OS_FlagUnlink (OS_FLAG_NODE *pnode); +#endif + +void OS_MemClr (INT8U *pdest, + INT16U size); + +void OS_MemCopy (INT8U *pdest, + INT8U *psrc, + INT16U size); + +#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) +void OS_MemInit (void); +#endif + +#if OS_Q_EN > 0 +void OS_QInit (void); +#endif + +void OS_Sched (void); + +#if (OS_EVENT_NAME_SIZE > 1) || (OS_FLAG_NAME_SIZE > 1) || (OS_MEM_NAME_SIZE > 1) || (OS_TASK_NAME_SIZE > 1) +INT8U OS_StrCopy (INT8U *pdest, + INT8U *psrc); + +INT8U OS_StrLen (INT8U *psrc); +#endif + +void OS_TaskIdle (void *p_arg); + +#if OS_TASK_STAT_EN > 0 +void OS_TaskStat (void *p_arg); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0 +void OS_TaskStkClr (OS_STK *pbos, + INT32U size, + INT16U opt); +#endif + +#if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0) +void OS_TaskStatStkChk (void); +#endif + +INT8U OS_TCBInit (INT8U prio, + OS_STK *ptos, + OS_STK *pbos, + INT16U id, + INT32U stk_size, + void *pext, + INT16U opt); + +#if OS_TMR_EN > 0 +void OSTmr_Init(void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Specific Functions) +********************************************************************************************************* +*/ + +#if OS_DEBUG_EN > 0 +void OSDebugInit (void); +#endif + +void OSInitHookBegin (void); +void OSInitHookEnd (void); + +void OSTaskCreateHook (OS_TCB *ptcb); +void OSTaskDelHook (OS_TCB *ptcb); + +void OSTaskIdleHook (void); + +void OSTaskStatHook (void); +OS_STK *OSTaskStkInit (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT16U opt); + +#if OS_TASK_SW_HOOK_EN > 0 +void OSTaskSwHook (void); +#endif + +void OSTCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0 +void OSTimeTickHook (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Application Specific Functions) +********************************************************************************************************* +*/ + +#if OS_APP_HOOKS_EN > 0 +void App_TaskCreateHook (OS_TCB *ptcb); +void App_TaskDelHook (OS_TCB *ptcb); +void App_TaskIdleHook (void); + +void App_TaskStatHook (void); + +#if OS_TASK_SW_HOOK_EN > 0 +void App_TaskSwHook (void); +#endif + +void App_TCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0 +void App_TimeTickHook (void); +#endif +#endif + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* IMPORTANT: These prototypes MUST be placed in OS_CPU.H +********************************************************************************************************* +*/ + +#if 0 +void OSStartHighRdy (void); +void OSIntCtxSw (void); +void OSCtxSw (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOOK FOR MISSING #define CONSTANTS +* +* This section is used to generate ERROR messages at compile time if certain #define constants are +* MISSING in OS_CFG.H. This allows you to quickly determine the source of the error. +* +* You SHOULD NOT change this section UNLESS you would like to add more comments as to the source of the +* compile time error. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ + +#ifndef OS_FLAG_EN +#error "OS_CFG.H, Missing OS_FLAG_EN: Enable (1) or Disable (0) code generation for Event Flags" +#else + #ifndef OS_MAX_FLAGS + #error "OS_CFG.H, Missing OS_MAX_FLAGS: Max. number of Event Flag Groups in your application" + #else + #if OS_MAX_FLAGS > 65500u + #error "OS_CFG.H, OS_MAX_FLAGS must be <= 65500" + #endif + #endif + + #ifndef OS_FLAGS_NBITS + #error "OS_CFG.H, Missing OS_FLAGS_NBITS: Determine #bits used for event flags, MUST be either 8, 16 or 32" + #endif + + #ifndef OS_FLAG_WAIT_CLR_EN + #error "OS_CFG.H, Missing OS_FLAG_WAIT_CLR_EN: Include code for Wait on Clear EVENT FLAGS" + #endif + + #ifndef OS_FLAG_ACCEPT_EN + #error "OS_CFG.H, Missing OS_FLAG_ACCEPT_EN: Include code for OSFlagAccept()" + #endif + + #ifndef OS_FLAG_DEL_EN + #error "OS_CFG.H, Missing OS_FLAG_DEL_EN: Include code for OSFlagDel()" + #endif + + #ifndef OS_FLAG_NAME_SIZE + #error "OS_CFG.H, Missing OS_FLAG_NAME_SIZE: Determines the size of flag group names" + #endif + + #ifndef OS_FLAG_QUERY_EN + #error "OS_CFG.H, Missing OS_FLAG_QUERY_EN: Include code for OSFlagQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOXES +********************************************************************************************************* +*/ + +#ifndef OS_MBOX_EN +#error "OS_CFG.H, Missing OS_MBOX_EN: Enable (1) or Disable (0) code generation for MAILBOXES" +#else + #ifndef OS_MBOX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MBOX_ACCEPT_EN: Include code for OSMboxAccept()" + #endif + + #ifndef OS_MBOX_DEL_EN + #error "OS_CFG.H, Missing OS_MBOX_DEL_EN: Include code for OSMboxDel()" + #endif + + #ifndef OS_MBOX_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_MBOX_PEND_ABORT_EN: Include code for OSMboxPendAbort()" + #endif + + #ifndef OS_MBOX_POST_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_EN: Include code for OSMboxPost()" + #endif + + #ifndef OS_MBOX_POST_OPT_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_OPT_EN: Include code for OSMboxPostOpt()" + #endif + + #ifndef OS_MBOX_QUERY_EN + #error "OS_CFG.H, Missing OS_MBOX_QUERY_EN: Include code for OSMboxQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MEM_EN +#error "OS_CFG.H, Missing OS_MEM_EN: Enable (1) or Disable (0) code generation for MEMORY MANAGER" +#else + #ifndef OS_MAX_MEM_PART + #error "OS_CFG.H, Missing OS_MAX_MEM_PART: Max. number of memory partitions" + #else + #if OS_MAX_MEM_PART > 65500u + #error "OS_CFG.H, OS_MAX_MEM_PART must be <= 65500" + #endif + #endif + + #ifndef OS_MEM_NAME_SIZE + #error "OS_CFG.H, Missing OS_MEM_NAME_SIZE: Determines the size of memory partition names" + #endif + + #ifndef OS_MEM_QUERY_EN + #error "OS_CFG.H, Missing OS_MEM_QUERY_EN: Include code for OSMemQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_MUTEX_EN +#error "OS_CFG.H, Missing OS_MUTEX_EN: Enable (1) or Disable (0) code generation for MUTEX" +#else + #ifndef OS_MUTEX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MUTEX_ACCEPT_EN: Include code for OSMutexAccept()" + #endif + + #ifndef OS_MUTEX_DEL_EN + #error "OS_CFG.H, Missing OS_MUTEX_DEL_EN: Include code for OSMutexDel()" + #endif + + #ifndef OS_MUTEX_QUERY_EN + #error "OS_CFG.H, Missing OS_MUTEX_QUERY_EN: Include code for OSMutexQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUES +********************************************************************************************************* +*/ + +#ifndef OS_Q_EN +#error "OS_CFG.H, Missing OS_Q_EN: Enable (1) or Disable (0) code generation for QUEUES" +#else + #ifndef OS_MAX_QS + #error "OS_CFG.H, Missing OS_MAX_QS: Max. number of queue control blocks" + #else + #if OS_MAX_QS > 65500u + #error "OS_CFG.H, OS_MAX_QS must be <= 65500" + #endif + #endif + + #ifndef OS_Q_ACCEPT_EN + #error "OS_CFG.H, Missing OS_Q_ACCEPT_EN: Include code for OSQAccept()" + #endif + + #ifndef OS_Q_DEL_EN + #error "OS_CFG.H, Missing OS_Q_DEL_EN: Include code for OSQDel()" + #endif + + #ifndef OS_Q_FLUSH_EN + #error "OS_CFG.H, Missing OS_Q_FLUSH_EN: Include code for OSQFlush()" + #endif + + #ifndef OS_Q_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_Q_PEND_ABORT_EN: Include code for OSQPendAbort()" + #endif + + #ifndef OS_Q_POST_EN + #error "OS_CFG.H, Missing OS_Q_POST_EN: Include code for OSQPost()" + #endif + + #ifndef OS_Q_POST_FRONT_EN + #error "OS_CFG.H, Missing OS_Q_POST_FRONT_EN: Include code for OSQPostFront()" + #endif + + #ifndef OS_Q_POST_OPT_EN + #error "OS_CFG.H, Missing OS_Q_POST_OPT_EN: Include code for OSQPostOpt()" + #endif + + #ifndef OS_Q_QUERY_EN + #error "OS_CFG.H, Missing OS_Q_QUERY_EN: Include code for OSQQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_SEM_EN +#error "OS_CFG.H, Missing OS_SEM_EN: Enable (1) or Disable (0) code generation for SEMAPHORES" +#else + #ifndef OS_SEM_ACCEPT_EN + #error "OS_CFG.H, Missing OS_SEM_ACCEPT_EN: Include code for OSSemAccept()" + #endif + + #ifndef OS_SEM_DEL_EN + #error "OS_CFG.H, Missing OS_SEM_DEL_EN: Include code for OSSemDel()" + #endif + + #ifndef OS_SEM_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_SEM_PEND_ABORT_EN: Include code for OSSemPendAbort()" + #endif + + #ifndef OS_SEM_QUERY_EN + #error "OS_CFG.H, Missing OS_SEM_QUERY_EN: Include code for OSSemQuery()" + #endif + + #ifndef OS_SEM_SET_EN + #error "OS_CFG.H, Missing OS_SEM_SET_EN: Include code for OSSemSet()" + #endif +#endif + +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MAX_TASKS +#error "OS_CFG.H, Missing OS_MAX_TASKS: Max. number of tasks in your application" +#else + #if OS_MAX_TASKS < 2 + #error "OS_CFG.H, OS_MAX_TASKS must be >= 2" + #endif + + #if OS_MAX_TASKS > ((OS_LOWEST_PRIO - OS_N_SYS_TASKS) + 1) + #error "OS_CFG.H, OS_MAX_TASKS must be <= OS_LOWEST_PRIO - OS_N_SYS_TASKS + 1" + #endif + +#endif + +#if OS_LOWEST_PRIO > 254 +#error "OS_CFG.H, OS_LOWEST_PRIO must be <= 254 in V2.8x and higher" +#endif + +#ifndef OS_TASK_IDLE_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_IDLE_STK_SIZE: Idle task stack size" +#endif + +#ifndef OS_TASK_STAT_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_EN: Enable (1) or Disable(0) the statistics task" +#endif + +#ifndef OS_TASK_STAT_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_SIZE: Statistics task stack size" +#endif + +#ifndef OS_TASK_STAT_STK_CHK_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_CHK_EN: Check task stacks from statistics task" +#endif + +#ifndef OS_TASK_CHANGE_PRIO_EN +#error "OS_CFG.H, Missing OS_TASK_CHANGE_PRIO_EN: Include code for OSTaskChangePrio()" +#endif + +#ifndef OS_TASK_CREATE_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EN: Include code for OSTaskCreate()" +#endif + +#ifndef OS_TASK_CREATE_EXT_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EXT_EN: Include code for OSTaskCreateExt()" +#endif + +#ifndef OS_TASK_DEL_EN +#error "OS_CFG.H, Missing OS_TASK_DEL_EN: Include code for OSTaskDel()" +#endif + +#ifndef OS_TASK_NAME_SIZE +#error "OS_CFG.H, Missing OS_TASK_NAME_SIZE: Determine the size of task names" +#endif + +#ifndef OS_TASK_SUSPEND_EN +#error "OS_CFG.H, Missing OS_TASK_SUSPEND_EN: Include code for OSTaskSuspend() and OSTaskResume()" +#endif + +#ifndef OS_TASK_QUERY_EN +#error "OS_CFG.H, Missing OS_TASK_QUERY_EN: Include code for OSTaskQuery()" +#endif + +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TICKS_PER_SEC +#error "OS_CFG.H, Missing OS_TICKS_PER_SEC: Sets the number of ticks in one second" +#endif + +#ifndef OS_TIME_DLY_HMSM_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_HMSM_EN: Include code for OSTimeDlyHMSM()" +#endif + +#ifndef OS_TIME_DLY_RESUME_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_RESUME_EN: Include code for OSTimeDlyResume()" +#endif + +#ifndef OS_TIME_GET_SET_EN +#error "OS_CFG.H, Missing OS_TIME_GET_SET_EN: Include code for OSTimeGet() and OSTimeSet()" +#endif + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TMR_EN +#error "OS_CFG.H, Missing OS_TMR_EN: When (1) enables code generation for Timer Management" +#elif OS_TMR_EN > 0 + #if OS_SEM_EN == 0 + #error "OS_CFG.H, Semaphore management is required (set OS_SEM_EN to 1) when enabling Timer Management." + #error " Timer management require TWO semaphores." + #endif + + #ifndef OS_TMR_CFG_MAX + #error "OS_CFG.H, Missing OS_TMR_CFG_MAX: Determines the total number of timers in an application (2 .. 65500)" + #else + #if OS_TMR_CFG_MAX < 2 + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + + #if OS_TMR_CFG_MAX > 65500 + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + #endif + + #ifndef OS_TMR_CFG_WHEEL_SIZE + #error "OS_CFG.H, Missing OS_TMR_CFG_WHEEL_SIZE: Sets the size of the timer wheel (1 .. 1023)" + #else + #if OS_TMR_CFG_WHEEL_SIZE < 2 + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + + #if OS_TMR_CFG_WHEEL_SIZE > 1024 + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + #endif + + #ifndef OS_TMR_CFG_NAME_SIZE + #error "OS_CFG.H, Missing OS_TMR_CFG_NAME_SIZE: Determines the number of characters used for Timer names" + #endif + + #ifndef OS_TMR_CFG_TICKS_PER_SEC + #error "OS_CFG.H, Missing OS_TMR_CFG_TICKS_PER_SEC: Determines the rate at which tiem timer management task will run (Hz)" + #endif + + #ifndef OS_TASK_TMR_STK_SIZE + #error "OS_CFG.H, Missing OS_TASK_TMR_STK_SIZE: Determines the size of the Timer Task's stack" + #endif +#endif + + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifndef OS_ARG_CHK_EN +#error "OS_CFG.H, Missing OS_ARG_CHK_EN: Enable (1) or Disable (0) argument checking" +#endif + + +#ifndef OS_CPU_HOOKS_EN +#error "OS_CFG.H, Missing OS_CPU_HOOKS_EN: uC/OS-II hooks are found in the processor port files when 1" +#endif + + +#ifndef OS_APP_HOOKS_EN +#error "OS_CFG.H, Missing OS_APP_HOOKS_EN: Application-defined hooks are called from the uC/OS-II hooks" +#endif + + +#ifndef OS_DEBUG_EN +#error "OS_CFG.H, Missing OS_DEBUG_EN: Allows you to include variables for debugging or not" +#endif + + +#ifndef OS_LOWEST_PRIO +#error "OS_CFG.H, Missing OS_LOWEST_PRIO: Defines the lowest priority that can be assigned" +#endif + + +#ifndef OS_MAX_EVENTS +#error "OS_CFG.H, Missing OS_MAX_EVENTS: Max. number of event control blocks in your application" +#else + #if OS_MAX_EVENTS > 65500u + #error "OS_CFG.H, OS_MAX_EVENTS must be <= 65500" + #endif +#endif + + +#ifndef OS_SCHED_LOCK_EN +#error "OS_CFG.H, Missing OS_SCHED_LOCK_EN: Include code for OSSchedLock() and OSSchedUnlock()" +#endif + + +#ifndef OS_TASK_PROFILE_EN +#error "OS_CFG.H, Missing OS_TASK_PROFILE_EN: Include data structure for run-time task profiling" +#endif + + +#ifndef OS_TASK_SW_HOOK_EN +#error "OS_CFG.H, Missing OS_TASK_SW_HOOK_EN: Allows you to include the code for OSTaskSwHook() or not" +#endif + + +#ifndef OS_TICK_STEP_EN +#error "OS_CFG.H, Missing OS_TICK_STEP_EN: Allows to 'step' one tick at a time with uC/OS-View" +#endif + + +#ifndef OS_TIME_TICK_HOOK_EN +#error "OS_CFG.H, Missing OS_TIME_TICK_HOOK_EN: Allows you to include the code for OSTimeTickHook() or not" +#endif + +/* +********************************************************************************************************* +* SAFETY CRITICAL USE +********************************************************************************************************* +*/ + +#ifdef SAFETY_CRITICAL_RELEASE + +#if OS_ARG_CHK_EN < 1 +#error "OS_CFG.H, OS_ARG_CHK_EN must be enabled for safety-critical release code" +#endif + +#if OS_APP_HOOKS_EN > 0 +#error "OS_CFG.H, OS_APP_HOOKS_EN must be disabled for safety-critical release code" +#endif + +#if OS_DEBUG_EN > 0 +#error "OS_CFG.H, OS_DEBUG_EN must be disabled for safety-critical release code" +#endif + +#ifdef CANTATA +#error "OS_CFG.H, CANTATA must be disabled for safety-critical release code" +#endif + +#ifdef OS_SCHED_LOCK_EN +#error "OS_CFG.H, OS_SCHED_LOCK_EN must be disabled for safety-critical release code" +#endif + +#ifdef VSC_VALIDATION_MODE +#error "OS_CFG.H, VSC_VALIDATION_MODE must be disabled for safety-critical release code" +#endif + +#if OS_TASK_STAT_EN > 0 +#error "OS_CFG.H, OS_TASK_STAT_EN must be disabled for safety-critical release code" +#endif + +#if OS_TICK_STEP_EN > 0 +#error "OS_CFG.H, OS_TICK_STEP_EN must be disabled for safety-critical release code" +#endif + +#if OS_FLAG_EN > 0 + #if OS_FLAG_DEL_EN > 0 + #error "OS_CFG.H, OS_FLAG_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MBOX_EN > 0 + #if OS_MBOX_DEL_EN > 0 + #error "OS_CFG.H, OS_MBOX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MUTEX_EN > 0 + #if OS_MUTEX_DEL_EN > 0 + #error "OS_CFG.H, OS_MUTEX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_Q_EN > 0 + #if OS_Q_DEL_EN > 0 + #error "OS_CFG.H, OS_Q_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_SEM_EN > 0 + #if OS_SEM_DEL_EN > 0 + #error "OS_CFG.H, OS_SEM_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_TASK_EN > 0 + #if OS_TASK_DEL_EN > 0 + #error "OS_CFG.H, OS_TASK_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_CRITICAL_METHOD != 3 +#error "OS_CPU.H, OS_CRITICAL_METHOD must be type 3 for safety-critical release code" +#endif + +#endif /* ------------------------ SAFETY_CRITICAL_RELEASE ------------------------ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/PROJECT/app/app_serv.c b/PROJECT/app/app_serv.c new file mode 100644 index 0000000..d744b19 --- /dev/null +++ b/PROJECT/app/app_serv.c @@ -0,0 +1,1186 @@ +#include +#include "app_serv.h" +#include "modem.h" +#include "validator.h" +#include "coin.h" +#include "time.h" +#include "fiscal.h" +#include "menu.h" +#include "data.h" +#include "mode.h" +#include "menudesc.h" +#include "datadesc.h" +#include "control.h" +#include "validator.h" +#include "CCRSProtocol.h" +#include "menu.h" +#include "journal.h" +#include "fr.h" +#include "CRC16.h" +#include "modem_task.h" + +// , F1 +//#define _DEBUG_MONEY + +CPU_INT32U SystemTime; +CPU_INT08U EnabledChannelsNum; +CPU_INT08U RecentChannel; +CPU_INT08U UserMenuState; + #define USER_STATE_FIRST_PAGE 0 + #define USER_STATE_ACCEPT_MONEY 1 + #define USER_STATE_SHOW_THANKS 2 +CPU_INT08U ThanksCtr; + +CPU_INT08U ChannelsState[CHANNELS_NUM]; + #define CHANNEL_STATE_EMPTY 0 + #define CHANNEL_STATE_PAUSE_BEFORE 1 + #define CHANNEL_STATE_WORK 2 + #define CHANNEL_STATE_PAUSE_AFTER 3 +CPU_INT32U ChannelsCounters[CHANNELS_NUM]; +CPU_INT32U ChannelsPayedTime[CHANNELS_NUM]; +CPU_INT32U ChannelsWaitDeffered[CHANNELS_NUM] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +extern CPU_INT32U BillNominals[24]; +CPU_INT32U incas_bill_nom_counter[24]; +CPU_INT32U incas_common_bill_counter; + +CPU_INT08U max_msg = 0; + +#define USER_QUERY_LEN 64 + +OS_STK UserTaskStk[USER_TASK_STK_SIZE]; +OS_EVENT *UserQuery = NULL; +void *UserTbl[USER_QUERY_LEN]; + +int GetUserEvent(int* event); +void UserPrintMoneyMenu(void); +void IncRecentChannel(void); +void DecRecentChannel(void); +void WorkServer(void); +void UserPrintThanksMenu(void); +void UserPrintFirstMenu(CPU_INT08U recentchannel); +void UserPrintErrorMenu(void); +CPU_INT32U GetChannelsTimeForFree(CPU_INT08U ch); +void LoadAcceptedMoney(void); +void SetAcceptedMoney(CPU_INT32U money); +void ClearAcceptedMoney(void); +CPU_INT32U GetAcceptedMoney(void); +void InitPass(void); +void UserPrintDeferredWaitMenu(int channel); + +static char incassation; +static char was_critical_error; +/*! + +*/ +void UserAppTask(void *p_arg) +{ + int event; + CPU_INT32U temp; + static CPU_INT08U fr_conn_ctr = 0; + + { + CPU_INT32U m=0; + GetData(&AcceptedMoneyDesc, &m, 0, DATA_FLAG_SYSTEM_INDEX); + if (m) + { + EnabledChannelsNum = 0; + for (CPU_INT08U i=0; i maxtime*60) + { + CoinDisable(); + } + else + { + CoinEnable(); + } + was_critical_error = 0; + } + } + else if (UserMenuState == USER_STATE_SHOW_THANKS) + { // "" + LED_off(); + CoinDisable(); + if (ThanksCtr) {UserPrintThanksMenu(); ThanksCtr--;} + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + else if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + LED_off(); + CoinDisable(); + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + break; + case EVENT_INCASSATION: + { + CPU_INT32U incas_sum = 0, temp; + for (CPU_INT32U i = 0; i < 24; i++) + { + CPU_INT32U val = 0; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + incas_sum += val*BillNominals[i]; + } + incassation = 1; + sprintf((char*)str_IncasMenu_3, " %u .", incas_sum); + // + GoToMenu(IncasMenuPanel); + // + SaveEventRecord(0, JOURNAL_EVENT_INCASSATION, incas_sum); + GetData(&BillCounterDesc, &incas_common_bill_counter, 0, DATA_FLAG_SYSTEM_INDEX); + for (CPU_INT32U i = 0; i < 24; i++) + { + GetData(&BillnomCountersDesc, &incas_bill_nom_counter[i], i, DATA_FLAG_DIRECT_INDEX); + } + + SetData(&IncasMoneyDesc, &incas_sum, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = GetTimeSec(); + SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + + temp = INCAS_SEND_FLAG; + SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + PostModemTask(MODEM_TASK_SEND_INCAS); + // + ClearBillnomCounter(); + } + break; + case EVENT_INCASSATION_FINISH: + incassation = 0; + GoToPreviousMenu(); + break; + case EVENT_MODE_CHANGE: + ReInitMenu(); + SaveEventRecord(0, JOURNAL_EVENT_CHANGE_MODE, GetMode()); + break; + case EVENT_COIN_INSERTED: + { + CPU_INT32U cpp = 1; + CPU_INT32U money, accmoney; + GetData(&CoinPerPulseDesc, &cpp, 0, DATA_FLAG_SYSTEM_INDEX); + money = cpp*GetResetCoinCount(); + accmoney = GetAcceptedMoney(); + accmoney += money; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_COIN, money); + + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if ((pricetime*accmoney*60)/price > maxtime*60) + { + CoinDisable(); + } + } + break; + case EVENT_BILL_ESCROW: + // + { + CPU_INT32U billnom_index; + CPU_INT32U billnom = GetResetBillCount(&billnom_index); + CPU_INT32U price=1, pricetime=0, maxtime = 0xffffffff, accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + accmoney = GetAcceptedMoney(); + if ((pricetime*(accmoney+billnom)*60)/price > maxtime*60) + { + max_msg = 3; + if (IsValidatorConnected()) if (!CC_CmdReturn(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + else + { + max_msg = 0; + if (IsValidatorConnected()) if (!CC_CmdPack(ADDR_FL)) SetErrorFlag(ERROR_VALIDATOR_CONN); + } + } + break; + case EVENT_BILL_STACKED: + // + { + CPU_INT32U billnom_index; + CPU_INT32U note,accmoney; + note = GetResetBillCount(&billnom_index); + accmoney = GetAcceptedMoney(); + accmoney += note; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + SaveEventRecord(RecentChannel, JOURNAL_EVENT_MONEY_NOTE, note); + IncBillnomCounter(billnom_index); + } + break; + + case EVENT_KEY_F1: + #ifdef _DEBUG_MONEY + { + CPU_INT32U accmoney; + accmoney = GetAcceptedMoney(); + accmoney += 10; + SetAcceptedMoney(accmoney); + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { + UserPrintMoneyMenu(); + RefreshMenu(); + } + } + #endif + break; + case EVENT_KEY_F2: + break; + case EVENT_KEY_F3: + break; + + case EVENT_KEY_LEFT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + DecRecentChannel(); + if (ChannelsWaitDeffered[RecentChannel] != 0) + { + UserPrintDeferredWaitMenu(RecentChannel); + RefreshMenu(); + } + else + { + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + break; + case EVENT_KEY_RIGHT: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + + if ((UserMenuState == USER_STATE_FIRST_PAGE) && (EnabledChannelsNum > 1)) + { + IncRecentChannel(); + if (ChannelsWaitDeffered[RecentChannel] != 0) + { + UserPrintDeferredWaitMenu(RecentChannel); + RefreshMenu(); + } + else + { + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + } + } + break; + case EVENT_KEY_DOWN: + break; + case EVENT_KEY_UP: + break; + + case EVENT_KEY_STOP: + if ((GetMode() != MODE_WORK) || (incassation)) break; + if (TstCriticalErrors()) {UserPrintErrorMenu(); RefreshMenu(); break;} + UserMenuState = USER_STATE_FIRST_PAGE; + UserPrintFirstMenu(RecentChannel); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + break; + case EVENT_KEY_DEFERRED_CH1: + case EVENT_KEY_DEFERRED_CH2: + case EVENT_KEY_DEFERRED_CH3: + case EVENT_KEY_DEFERRED_CH4: + case EVENT_KEY_DEFERRED_CH5: + case EVENT_KEY_DEFERRED_CH6: + case EVENT_KEY_DEFERRED_CH7: + case EVENT_KEY_DEFERRED_CH8: + case EVENT_KEY_DEFERRED_CH9: + case EVENT_KEY_DEFERRED_CH10: + if (ChannelsWaitDeffered[event - EVENT_KEY_DEFERRED_CH1] != 0) + { + // + ChannelsWaitDeffered[event - EVENT_KEY_DEFERRED_CH1] = 0; + ChannelOn(event - EVENT_KEY_DEFERRED_CH1); + ChannelsCounters[event - EVENT_KEY_DEFERRED_CH1] = ChannelsPayedTime[event - EVENT_KEY_DEFERRED_CH1]; + ChannelsState[event - EVENT_KEY_DEFERRED_CH1] = CHANNEL_STATE_WORK; + // + SaveEventRecord(event - EVENT_KEY_DEFERRED_CH1, JOURNAL_EVENT_START_SESSION, ChannelsPayedTime[event - EVENT_KEY_DEFERRED_CH1]); + // "" + if (IsFiscalConnected()) + { + UserPrintThanksMenu(); + RefreshMenu(); + UserMenuState = USER_STATE_SHOW_THANKS; + } + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + } + ThanksCtr = 3; + LED_off(); + } + break; + case EVENT_KEY_START: + case EVENT_KEY_USER_START: + if (incassation) break; + if (GetMode() != MODE_WORK) + { + if (!FlagForPrintReport) break; + if (GetCurrentMenu() == xReportMenuPanel) + { // X- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportNoClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_X, GetTimeSec()); + GoToPreviousMenu(); + } + } + else if (GetCurrentMenu() == zReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportClear(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec()); + GoToPreviousMenu(); + ClrFiscalErrorByCode(FR_ERROR_CODE_4e); + } + } + else if (GetCurrentMenu() == bufReportMenuPanel) + { // Z- + CPU_INT08U err; + if (IsFiscalConnected()) + { + FPend(); + FiscPrintDayReportsFromBuf(30, &err); + FPost(); + if (err) {SetFiscalErrorByCode(err);} + SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec()); + GoToPreviousMenu(); + } + } + break; + } + + if (TstCriticalErrors()) + { + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + + // -------------------------- + // + // -------------------------- + + if (EnabledChannelsNum == 0) break; + + if (UserMenuState == USER_STATE_FIRST_PAGE) + { // + if (IsChannelOn(RecentChannel)) break; + FPend(); + if ((CheckFiscalStatus() < 0) && (TstCriticalErrors())) + { + FPost(); + UserPrintErrorMenu(); + RefreshMenu(); + break; + } + FPost(); + UserMenuState = USER_STATE_ACCEPT_MONEY; + UserPrintMoneyMenu(); + RefreshMenu(); + if (IsValidatorConnected()) CC_CmdBillType(0xffffff, 0xffffffff, ADDR_FL); + CoinEnable(); + max_msg = 0; + break; + } + + + if (UserMenuState == USER_STATE_ACCEPT_MONEY) + { // + CPU_INT32U price=1, pricetime=0, mintime=0,accmoney; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + accmoney = GetAcceptedMoney(); + ChannelsPayedTime[RecentChannel] = (pricetime*accmoney*60)/price; + GetData(&MinWorkTimeDesc, &mintime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (ChannelsPayedTime[RecentChannel] >= mintime*60) + { // , + if (IsValidatorConnected()) CC_CmdBillType(0x000000, 0x000000, ADDR_FL); + // + if (IsFiscalConnected()) + { + if (PrintFiscalBill(accmoney, ChannelsPayedTime[RecentChannel]) == 0) + { + SaveEventRecord(RecentChannel, JOURNAL_EVENT_PRINT_BILL, GetTimeSec()); + } + else + { + // + + } + } + IncCounter(RecentChannel, ChannelsPayedTime[RecentChannel], accmoney); + SetAcceptedMoney(0); + // + + CPU_INT32U deferred = 0; + GetData(&DeferredStartDesc, &deferred, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (deferred) + { + ChannelsCounters[RecentChannel] = 0; + ChannelsState[RecentChannel] = CHANNEL_STATE_PAUSE_BEFORE; + ChannelsWaitDeffered[RecentChannel] = 1; + LED_off(); + UserMenuState = USER_STATE_FIRST_PAGE; + } + else + { + ChannelsWaitDeffered[RecentChannel] = 0; + GetData(&TimeOutBeforeDesc, &ChannelsCounters[RecentChannel], RecentChannel, DATA_FLAG_DIRECT_INDEX); + ChannelsState[RecentChannel] = CHANNEL_STATE_PAUSE_BEFORE; + // "" + if (IsFiscalConnected()) + { + UserPrintThanksMenu(); + RefreshMenu(); + UserMenuState = USER_STATE_SHOW_THANKS; + } + else + { + UserMenuState = USER_STATE_FIRST_PAGE; + } + ThanksCtr = 5; + } + } + else + { // + + + + } + break; + } + + + break; + + } + } + else + { + OSTimeDly(1); + } + } +} + +/*! + +*/ +void UserStartupFunc(void) +{ + // + InitMode(); + + // + CheckAllData(); + + // + CheckLongCounters(); + + // + LoadAcceptedMoney(); + + // + InitPass(); + + // + InitChannels(); + + // + PINSEL3_bit.P1_21 = 0x0; + PINMODE3_bit.P1_21 = 0; + FIO1DIR_bit.P1_21= 1; + FIO1MASK_bit.P1_21 = 0; + LED_off(); + + // + InitMenu(); + + OSTimeDly(1000); + + // + StartUpValidator(); + + OSTimeDly(10000); + InitFiscal(); + + // + InitRTC(); + + // + SaveEventRecord(0, JOURNAL_EVENT_DEVICE_ON, GetTimeSec()); + + CPU_INT32U enable; + GetData(&EnableModemDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + + // - + if (InitModem() != 0) + { + SetErrorFlag(ERROR_MODEM_CONN); + } + else + { + ClrErrorFlag(ERROR_MODEM_CONN); + } + + // + InitCoin(); + + // + if (UserQuery == NULL) + { + UserQuery = OSQCreate(&UserTbl[0], USER_QUERY_LEN); + OSTaskCreate(UserAppTask, (void *)0, (OS_STK *)&UserTaskStk[USER_TASK_STK_SIZE-1], USER_TASK_PRIO); + } + + SystemTime = GetTimeSec(); + + // , + if (GetMode() == MODE_WORK) {SetMenu(WORK_MENU);} + else SetMenu(SERVICE_MENU); +} + +int GetUserEvent(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(UserQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + + +void PostUserEvent(int event) +{ + OSQPost(UserQuery, (void *)event); +} + + +void InitUserMenu(void) +{ + for (RecentChannel=0; RecentChannel 1) + { + GetDataStr(&NameChannelDesc, (CPU_INT08U*)buf, channel, DATA_FLAG_DIRECT_INDEX); + sprintf(&buf[strlen(buf)], " %d", channel+1); + } + else + { + sprintf(buf, " "); + } + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + + if (EnabledChannelsNum > 1) + { + sprintf(buf, " ."); + } + else + { + sprintf(buf, " "); + } + PrintUserMenuStr(buf, 3); + } +} + +void UserPrintMoneyMenu(void) +{ + char buf[32]; + CPU_INT32U accmoney; + + sprintf(buf, " "); + PrintUserMenuStr(buf, 0); + accmoney = GetAcceptedMoney(); + sprintf(buf, " %d .", accmoney); + PrintUserMenuStr(buf, 1); + + CPU_INT32U price=1, pricetime=0, time=0; + GetRecentChannelPrice(RecentChannel, &price, &pricetime); + time = (pricetime*accmoney*60)/price; + sprintf(buf, " %d:%02d", time/60, time%60); + PrintUserMenuStr(buf, 2); + + if (max_msg) + { + --max_msg; + sprintf(buf, " .."); + } + else + { + CPU_INT32U mintime=0, maxtime=0; + GetData(&MinWorkTimeDesc, &mintime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + GetData(&MaxWorkTimeDesc, &maxtime, RecentChannel, DATA_FLAG_DIRECT_INDEX); + if (EnabledChannelsNum > 1) sprintf(buf, ".%d ", RecentChannel+1); + else sprintf(buf, ""); + if (time >= mintime*60) + { + LED_on(); + if (time >= maxtime*60) sprintf(&buf[strlen(buf)], "."); + else sprintf(&buf[strlen(buf)], "."); + } + else + { + LED_off(); + sprintf(&buf[strlen(buf)], "."); + } + } + PrintUserMenuStr(buf, 3); +} + +// +void UserPrintErrorMenu(void) +{ + char buf[32]; + + if (TstErrorFlag(ERROR_VALIDATOR_CONN) || TstCriticalValidatorErrors()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + if (TstErrorFlag(ERROR_VALIDATOR_CONN)) + { + sprintf(buf, " "); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + } + else if (TstErrorFlag(ERROR_FR_CONN)) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + PrintUserMenuStr(buf, 3); + } + else if (TstCriticalFiscalError()) + { + sprintf(buf, ""); + PrintUserMenuStr(buf, 0); + CPU_INT08U errcode = 0; + sprintf(buf, " "); + PrintUserMenuStr(buf, 1); + GetFirstCriticalFiscalError(&errcode); + GetDataItem(&JournalErrorNumberDesc0, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 2); + GetDataItem(&JournalErrorNumberDesc1, (CPU_INT08U*)buf, errcode); + PrintUserMenuStr(buf, 3); + } + /* + else if (!FReportTest()) + { + sprintf(buf, "b "); + PrintUserMenuStr(buf, 0); + sprintf(buf, ""); + PrintUserMenuStr(buf, 1); + sprintf(buf, ""); + PrintUserMenuStr(buf, 2); + sprintf(buf, ""); + PrintUserMenuStr(buf, 3); + } + */ +} + +// +int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time) +{ + TRTC_Data rtc; + + if (EnabledChannelsNum == 0) return -1; + + RTC_ReadTime(&rtc); + + // , + CPU_INT32U wend = 0; + CPU_INT08U iswend = 0; // + GetData(&WeekEndDesc, &wend, RecentChannel, DATA_FLAG_DIRECT_INDEX); + + switch (wend) + { + case WEEKEND_FRIDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day > 4)) iswend = 1; + break; + case WEEKEND_SATURDAY_SUNDAY: + if ((rtc.day == 0) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_SATURDAY: + if ((rtc.day == 5) || (rtc.day == 6)) iswend = 1; + break; + case WEEKEND_FRIDAY_MONDAY: + if ((rtc.day > 4) || (rtc.day < 2)) iswend = 1; + break; + default: + iswend = 0; + break; + } + + // + CPU_INT08U i; + for (i=0; i= start) && (rtc.hour < end)){break;} + } + + if (i >= PRICE_PERIODS_NUM) return -2; + + // + if (iswend) + { + GetData(&PriceTimeWeekendDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekendDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + else + { + GetData(&PriceTimeWeekdaysDesc, time, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + GetData(&PriceWeekdaysDesc, price, RecentChannel*PRICE_PERIODS_NUM+i, DATA_FLAG_DIRECT_INDEX); + } + + return 0; +} + + +void IncRecentChannel(void) +{ + CPU_INT08U i; + + for (i=RecentChannel+1; i=0; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {break;} + } + + if (i>=0) {RecentChannel = i; return;} + + for (i=CHANNELS_NUM-1; i>RecentChannel; i--) + { + CPU_INT32U en = 0; + GetData(&EnableChannelDesc, &en, i, DATA_FLAG_DIRECT_INDEX); + if (en) {RecentChannel = i; return;} + } + +} + + +void WorkServer(void) +{ + for (CPU_INT08U i=0; i +#include "control.h" +#include "data.h" +#include "datadesc.h" +#include +#include + +/* +P2.2 MK_P73 1 +P0.9 MK_P76 2 +P0.8 MK_P77 3 +P0.7 MK_P78 4 +P0.6 MK_P79 5 +P0.5 MK_P80 6 +P0.4 MK_P81 7 +P4.28 MK_P82 8 +P1.27 MK_P43 9 +P1.28 MK_P44 10 +*/ + +CPU_INT16U ChannelStatus; // + + + +// +void ChannelOn(CPU_INT08U ch) +{ + ChannelStatus |= (1L << ch); + switch (ch) + { + case 0: + FIO2SET_bit.P2_2 = 1; + break; + case 1: + FIO0SET_bit.P0_9 = 1; + break; + case 2: + FIO0SET_bit.P0_8 = 1; + break; + case 3: + FIO0SET_bit.P0_7 = 1; + break; + case 4: + FIO0SET_bit.P0_6 = 1; + break; + case 5: + FIO0SET_bit.P0_5 = 1; + break; + case 6: + FIO0SET_bit.P0_4 = 1; + break; + case 7: + FIO4SET_bit.P4_28 = 1; + break; + case 8: + FIO1SET_bit.P1_27 = 1; + break; + case 9: + FIO1SET_bit.P1_28 = 1; + break; + } +} + +// +void ChannelOff(CPU_INT08U ch) +{ + ChannelStatus &= ~(1L << ch); + switch (ch) + { + case 0: + FIO2CLR_bit.P2_2 = 1; + break; + case 1: + FIO0CLR_bit.P0_9 = 1; + break; + case 2: + FIO0CLR_bit.P0_8 = 1; + break; + case 3: + FIO0CLR_bit.P0_7 = 1; + break; + case 4: + FIO0CLR_bit.P0_6 = 1; + break; + case 5: + FIO0CLR_bit.P0_5 = 1; + break; + case 6: + FIO0CLR_bit.P0_4 = 1; + break; + case 7: + FIO4CLR_bit.P4_28 = 1; + break; + case 8: + FIO1CLR_bit.P1_27 = 1; + break; + case 9: + FIO1CLR_bit.P1_28 = 1; + break; + } +} + + + +// +void InitChannels(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + // 1 + PINSEL4_bit.P2_2 = 0x0; + PINMODE4_bit.P2_2 = 0; + FIO2DIR_bit.P2_2 = 1; + FIO2MASK_bit.P2_2 = 0; + FIO2CLR_bit.P2_2 = 1; + + // 2 + PINSEL0_bit.P0_9 = 0x0; + PINMODE0_bit.P0_9 = 0; + FIO0DIR_bit.P0_9 = 1; + FIO0MASK_bit.P0_9 = 0; + FIO0CLR_bit.P0_9 = 1; + + // 3 + PINSEL0_bit.P0_8 = 0x0; + PINMODE0_bit.P0_8 = 0; + FIO0DIR_bit.P0_8 = 1; + FIO0MASK_bit.P0_8 = 0; + FIO0CLR_bit.P0_8 = 1; + + // 4 + PINSEL0_bit.P0_7 = 0x0; + PINMODE0_bit.P0_7 = 0; + FIO0DIR_bit.P0_7 = 1; + FIO0MASK_bit.P0_7 = 0; + FIO0CLR_bit.P0_7 = 1; + + // 5 + PINSEL0_bit.P0_6 = 0x0; + PINMODE0_bit.P0_6 = 0; + FIO0DIR_bit.P0_6 = 1; + FIO0MASK_bit.P0_6 = 0; + FIO0CLR_bit.P0_6 = 1; + + // 6 + PINSEL0_bit.P0_5 = 0x0; + PINMODE0_bit.P0_5 = 0; + FIO0DIR_bit.P0_5 = 1; + FIO0MASK_bit.P0_5 = 0; + FIO0CLR_bit.P0_5 = 1; + + // 7 + PINSEL0_bit.P0_4 = 0x0; + PINMODE0_bit.P0_4 = 0; + FIO0DIR_bit.P0_4 = 1; + FIO0MASK_bit.P0_4 = 0; + FIO0CLR_bit.P0_4 = 1; + + // 8 + PINSEL9_bit.P4_28 = 0x0; + PINMODE9_bit.P4_28 = 0; + FIO4DIR_bit.P4_28 = 1; + FIO4MASK_bit.P4_28 = 0; + FIO4CLR_bit.P4_28 = 1; + + // 9 + PINSEL3_bit.P1_27 = 0x0; + PINMODE3_bit.P1_27 = 0; + FIO1DIR_bit.P1_27 = 1; + FIO1MASK_bit.P1_27 = 0; + FIO1CLR_bit.P1_27 = 1; + + // 10 + PINSEL3_bit.P1_28= 0x0; + PINMODE3_bit.P1_28 = 0; + FIO1DIR_bit.P1_28 = 1; + FIO1MASK_bit.P1_28 = 0; + FIO1CLR_bit.P1_28 = 1; + + OS_EXIT_CRITICAL(); +} + + diff --git a/PROJECT/app/control.h b/PROJECT/app/control.h new file mode 100644 index 0000000..fb5098f --- /dev/null +++ b/PROJECT/app/control.h @@ -0,0 +1,24 @@ +#ifndef _CONTROL_H_ +#define _CONTROL_H_ + +#define CHANNELS_NUM 10 + +#define CHANNEL_1 0 +#define CHANNEL_2 1 +#define CHANNEL_3 2 +#define CHANNEL_4 3 +#define CHANNEL_5 4 +#define CHANNEL_6 5 +#define CHANNEL_7 6 +#define CHANNEL_8 7 +#define CHANNEL_9 8 +#define CHANNEL_10 9 + + +extern void InitChannels(void); +extern void ChannelOn(CPU_INT08U ch); +extern void ChannelOff(CPU_INT08U ch); +extern int IsChannelOn(CPU_INT08U ch); + + +#endif //#ifndef _CONTROL_H_ diff --git a/PROJECT/app/journal.c b/PROJECT/app/journal.c new file mode 100644 index 0000000..c49496c --- /dev/null +++ b/PROJECT/app/journal.c @@ -0,0 +1,460 @@ +#include +#include +#include "journal.h" +#include "fram.h" +#include "fram_map.h" +#include "time.h" +#include "fr.h" +#include "crc16.h" +#include "mode.h" + +static CPU_INT32U GlobalErrorsFlags[8] = {0,0,0,0,0,0,0,0}; + +void SetErrorFlag(CPU_INT08U error) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + GlobalErrorsFlags[error/32] |= (1L << (error%32)); + OS_EXIT_CRITICAL(); +} + +void ClrErrorFlag(CPU_INT08U error) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + GlobalErrorsFlags[error/32] &= ~(1L << (error%32)); + OS_EXIT_CRITICAL(); +} + +int TstErrorFlag(CPU_INT08U error) +{ + CPU_INT32U temp = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + temp = GlobalErrorsFlags[error/32] & (1L << (error%32)); + OS_EXIT_CRITICAL(); + return temp; +} + +int TstCriticalErrors(void) +{ + CPU_INT32U errors = 0; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + CPU_INT32U ignore_fiscal = 0; + + GetData(&DisableFiscalErrorsDesc, &ignore_fiscal, 0, DATA_FLAG_SYSTEM_INDEX); + + OS_ENTER_CRITICAL(); + + if (!ignore_fiscal) + { + errors |= TstCriticalFiscalError(); + errors |= TstErrorFlag(ERROR_FR_CONN); + /* + if (!FReportTest()) + { // + errors |= 0x1; + } + */ + } + + errors |= TstErrorFlag(ERROR_VALIDATOR_CONN); + + OS_EXIT_CRITICAL(); + if (errors) return 1; + return 0; +} + + +int TstCriticalValidatorErrors(void) +{ + return 0; +} + +void ClrValidatorErrors(void) +{ + for (CPU_INT08U i=ERROR_VALIDATOR_FAILURE; i= maxtime) {maxtime = record.time; indm = i;} + } + + if (i >= ERROR_RECORDS_NUM) + { // - + ind = (indm+1)%ERROR_RECORDS_NUM; + } + + record.time = GetTimeSec(); + record.error = error; + WriteArrayFram(offsetof(TFramMap, ErrorRecords[0])+ind*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)&record); +} + +// +int GetErrorRecord(TErrorRecord* record, CPU_INT32U index) +{ + if (index >= ERROR_RECORDS_NUM) return -1; + + ReadArrayFram(offsetof(TFramMap, ErrorRecords[0])+index*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)record); + + return 0; +} + +// +int GetEventRecord(TEventRecord* record, CPU_INT32U index) +{ + if (index >= EVENT_RECORDS_NUM) return -1; + + ReadArrayFram(offsetof(TFramMap, EventRecords[0])+index*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)record); + + return 0; +} + +// +void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT32U data) +{ + TEventRecord record; + + // + CPU_INT32U i, ind=0, indm = 0, maxtime = 0; + for (i=0; i= maxtime) {maxtime = record.time; indm = i;} + } + + if (i >= ERROR_RECORDS_NUM) + { // - + ind = (indm+1)%ERROR_RECORDS_NUM; + } + + record.time = GetTimeSec(); + record.channel = channel; + record.event = event; + record.data = data; + WriteArrayFram(offsetof(TFramMap, EventRecords[0])+ind*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)&record); +} + + +void ClearErrorJournal(void) +{ + SetArrayFram(offsetof(TFramMap, ErrorRecords), sizeof(TErrorRecord)*ERROR_RECORDS_NUM, 0x00); +} + +void ClearEventJournal(void) +{ + SetArrayFram(offsetof(TFramMap, EventRecords), sizeof(TEventRecord)*EVENT_RECORDS_NUM, 0x00); +} + +void GetEventStr(char* str, char event) +{ + switch (event){ + case JOURNAL_EVENT_MONEY_NOTE: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_MONEY_COIN: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_START_SESSION: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_END_SESSION: + sprintf(str, ". "); + break; + case JOURNAL_EVENT_DEVICE_ON: + sprintf(str, ""); + break; + case JOURNAL_EVENT_PRINT_BILL: + sprintf(str, " "); + break; + case JOURNAL_EVENT_PRINT_Z: + sprintf(str, " Z-"); + break; + case JOURNAL_EVENT_PRINT_X: + sprintf(str, " X-"); + break; + case JOURNAL_EVENT_PRINT_BUF: + sprintf(str, " . ."); + break; + case JOURNAL_EVENT_CHANGE_MODE: + sprintf(str, " "); + break; + case JOURNAL_EVENT_INCASSATION: + sprintf(str, ""); + break; + case JOURNAL_EVENT_PASS_FAIL: + sprintf(str, " "); + break; + case JOURNAL_EVENT_EMAIL_FAIL: + sprintf(str, " .e-mail"); + break; + case JOURNAL_EVENT_EMAIL_OK: + sprintf(str, "E-mail ."); + break; + default: + sprintf(str, ""); + break; + } +} + +void GetEventStrEng(char* str, char event) +{ + switch (event){ + case JOURNAL_EVENT_MONEY_NOTE: + sprintf(str, " | Vnesena kupura "); + break; + case JOURNAL_EVENT_MONEY_COIN: + sprintf(str, " | Vneseny monety "); + break; + case JOURNAL_EVENT_START_SESSION: + sprintf(str, " | Nachalo seansa "); + break; + case JOURNAL_EVENT_END_SESSION: + sprintf(str, " | Kone seansa "); + break; + case JOURNAL_EVENT_DEVICE_ON: + sprintf(str, " | Vkluchenie "); + break; + case JOURNAL_EVENT_PRINT_BILL: + sprintf(str, " | Pechat' checka "); + break; + case JOURNAL_EVENT_PRINT_Z: + sprintf(str, " | Pechat' Z-otcheta "); + break; + case JOURNAL_EVENT_PRINT_X: + sprintf(str, " | Pechat' X-otcheta "); + break; + case JOURNAL_EVENT_PRINT_BUF: + sprintf(str, " | Pechat' otcheta iz bufera "); + break; + case JOURNAL_EVENT_CHANGE_MODE: + sprintf(str, " | Smena rejima "); + break; + case JOURNAL_EVENT_INCASSATION: + sprintf(str, " | Incassaciya "); + break; + case JOURNAL_EVENT_PASS_FAIL: + sprintf(str, " | Neverniy parol' "); + break; + case JOURNAL_EVENT_EMAIL_FAIL: + sprintf(str, " | Oshibka otpravki e-mail "); + break; + case JOURNAL_EVENT_EMAIL_OK: + sprintf(str, " | E-mail otpravleno uspeshno "); + break; + default: + sprintf(str, " | Net sobytiya "); + break; + } +} + +void PrintEventJournalRecordEng(char* str, TEventRecord *record) +{ + if (record->event) + { + TRTC_Data rtc_data; + + // + Sec2Date(&rtc_data, record->time); + sprintf(str, "| "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc_data); + // + GetEventStrEng(&str[strlen(str)], record->event); + + // + if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN)) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + sprintf(&str[strlen(str)], "%d rub.", record->data); + } + else if (record->event == JOURNAL_EVENT_START_SESSION) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + PrintSecToHourMinSec(&str[strlen(str)], record->data); + } + else if (record->event == JOURNAL_EVENT_END_SESSION) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_DEVICE_ON) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BILL) + { + sprintf(&str[strlen(str)], "kanal %d ", record->channel+1); + } + else if (record->event == JOURNAL_EVENT_PRINT_Z) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_X) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BUF) + { + sprintf(&str[strlen(str)], ""); + } + else if (record->event == JOURNAL_EVENT_CHANGE_MODE) + { + if (record->data == MODE_WORK) sprintf(&str[strlen(str)], "rabota"); + else sprintf(&str[strlen(str)], "nastroika"); + } + else if (record->event == JOURNAL_EVENT_INCASSATION) + { + sprintf(&str[strlen(str)], "%u rub.", record->data); + } + else if (record->event == JOURNAL_EVENT_PASS_FAIL) + { + sprintf(&str[strlen(str)], "%u", record->data); + } + else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL)) + { + sprintf(&str[strlen(str)], ""); + } + sprintf(&str[strlen(str)], "\r\n"); + } + else + { // + sprintf(str, "net zapisi\r\n"); + } +} + +void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money) +{ + CPU_INT32U r, t, m; + TCountersLong long_ctrs; + + // + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r); + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t); + ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m); + r++; + t+=time; + m+=money; + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r); + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t); + WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m); + + // + ReadArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r); + ReadArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t); + ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m); + r++; + t+=time; + m+=money; + WriteArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r); + WriteArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t); + WriteArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m); + + // + ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + long_ctrs.CounterChannelRunLong[ch]++; + long_ctrs.CounterChannelTimeLong[ch] += time; + long_ctrs.CounterChannelMoneyLong[ch] += money; + long_ctrs.CounterRunLong++; + long_ctrs.CounterTimeLong += time; + long_ctrs.CounterMoneyLong += money; + long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); +} + +CPU_INT32U GetShortMoney() +{ + CPU_INT32U money; + ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&money); + return money; +} + +void CheckLongCounters(void) +{ + TCountersLong long_ctrs; + CPU_INT16U crc; + ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + if (crc != long_ctrs.crc) + { + memset(&long_ctrs, 0, sizeof(TCountersLong)); + long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc)); + WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs); + /// + ClearCounters(); + ClearBillnomCounter(); + } +} + +void ClearCounters(void) +{ + SetArrayFram(offsetof(TFramMap, Counters), sizeof(CPU_INT32U)*(CHANNELS_NUM+1)*3, 0x00); +} + +/// +void IncBillnomCounter(CPU_INT32U index) +{ + CPU_INT32U counter; + if (index >= 24) return; + ReadArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter); + counter++; + WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter); + + ReadArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); + counter++; + WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); +} + +/// +void ClearBillnomCounter(void) +{ + CPU_INT32U counter = 0; + CPU_INT32U i; + + for (i = 0; i < 24; i++) + { + WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*i, sizeof(CPU_INT32U), (unsigned char*)&counter); + } + + WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter); +} + +// ( ) +void ErrorServer(void) +{ + static CPU_INT32U PrevFlags[8] = {0,0,0,0,0,0,0,0}; + + for (int i=0; i +#include "journal.h" +#include "modem.h" +#include "modem_task.h" +#include "data.h" +#include "datadesc.h" +#include "time.h" + +OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE]; +OS_EVENT *ModemQuery = NULL; +void *ModemTbl[MODEM_QUERY_LEN]; + +static int index; +static CPU_INT32U enable_journals; + +#define STAT_STR_NUM 17 + +static void GetChannelStatStr(char* str, int ch) +{ + CPU_INT32U val; + + GetData(&CounterChannelMoneyDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val); + + GetData(&CounterChannelRunDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %7d | ", val); + + GetData(&CounterChannelTimeDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); +} + +static void GetChannelStatStrLong(char* str, int ch) +{ + CPU_INT32U val; + + GetData(&CounterChannelMoneyLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val); + + GetData(&CounterChannelRunLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "| %7d | ", val); + + GetData(&CounterChannelTimeLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); +} + +extern CPU_INT32U BillNominals[24]; + +static int GetEmailStr(char *str) +{ + if (index < STAT_STR_NUM) + { + str[0] = 0; + if (index == 0) + { + // + TRTC_Data rtc; + RTC_ReadTime(&rtc); + sprintf(str, "Systemnoe vremya: "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc); + sprintf(&str[strlen(str)], "\r\n\r\n-------------------------------------------------------------\r\nStatistika obshaya. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n"); + } + else if (index == 1) + { + CPU_INT32U val; + // + sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n"); + + GetData(&CounterMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %16d ", val); + + GetData(&CounterRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %12d | ", val); + + GetData(&CounterTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); + } + else if (index == 2) + { + sprintf(&str[strlen(str)], "\r\n-------------------------------------------------------------\r\nStatistika obshaya. Dlinnye schetchiki\r\n-------------------------------------------------------------\r\n"); + } + else if (index == 3) + { + CPU_INT32U val; + // + sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n"); + + GetData(&CounterLongMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %16d ", val); + + GetData(&CounterLongRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(&str[strlen(str)], "| %12d | ", val); + + GetData(&CounterLongTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + PrintSecToHourMinSec(&str[strlen(str)], val); + + sprintf(&str[strlen(str)], "\r\n"); + + } + else if (index == 4) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n"); + } + else if (index == 5) + { + int i; + for (i = 0; i < 3; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 6) + { + int i; + for (i = 3; i < 6; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 7) + { + int i; + for (i = 6; i < 10; i++) + { + GetChannelStatStr(&str[strlen(str)], i); + } + } + else if (index == 8) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Dlinnye schetchiki.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n"); + } + else if (index == 9) + { + int i; + for (i = 0; i < 3; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 10) + { + int i; + for (i = 3; i < 6; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 11) + { + int i; + for (i = 6; i < 10; i++) + { + GetChannelStatStrLong(&str[strlen(str)], i); + } + } + else if (index == 12) + { + CPU_INT32U val; + // + sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n"); + GetData(&BillCounterDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX); + if (!val) + { + // + sprintf(&str[strlen(str)], "Kupuropriemnik pust.\r\n\r\n"); + index++; + index++; + } + else + { + sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n"); + } + } + else if (index == 13) + { + int i; + str[0] = 0; + for (i = 0; i < 6; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + val = strlen(str); + } + } + else if (index == 14) + { + int i; + str[0] = 0; + for (i = 6; i < 12; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 15) + { + int i; + str[0] = 0; + for (i = 12; i < 18; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 16) + { + int i; + str[0] = 0; + for (i = 18; i < 24; i++) + { + CPU_INT32U val; + GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX); + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + index++; + return 0; + } + else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM) + { + TEventRecord record; + + if (enable_journals == 0) return -1; + + GetEventRecord(&record, index-STAT_STR_NUM); + + + str[0] = 0; + if ((index-STAT_STR_NUM) == 0) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal sobytiy\r\n-------------------------------------------------------------\r\n"); + } + if (record.time == 0x00000000) + { + index++; + return 0; + } + PrintEventJournalRecordEng(&str[strlen(str)], &record); + index++; + return 0; + } + else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM+ERROR_RECORDS_NUM) + { + CPU_INT32U time = 0; + TRTC_Data rtc_data; + + str[0] = 0; + if ((index-(STAT_STR_NUM+EVENT_RECORDS_NUM)) == 0) + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal oshibok\r\n-------------------------------------------------------------\r\n"); + } + + GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + if (time == 0x00000000) + { + index++; + return 0; + } + + sprintf(&str[strlen(str)], "| "); + GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + Sec2Date(&rtc_data, time); + PrintRTCDateTimeString(&str[strlen(str)], &rtc_data); + + sprintf(&str[strlen(str)], " | "); + GetDataStr(&JournalErrorNumberDescEng, (CPU_INT08U*)&str[strlen(str)], index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX); + sprintf(&str[strlen(str)], "\r\n"); + index++; + return 0; + } + + return -1; +} + +/// e-mail +int SendStatistics(void) +{ + CPU_INT32U dev_id; + char theme[48]; + index = 0; + // + GetData(&EnableEmailJournalSendDesc, &enable_journals, 0, DATA_FLAG_SYSTEM_INDEX); + // id + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Report from solarium device id %d.", dev_id); + return ModemSendEmail(theme, GetEmailStr); +} + +// +static int GetModemTask(int* event) +{ + CPU_INT08U err = 0; + int evt = (int)OSQPend(ModemQuery, 1, &err); + if (err != 0) return 0; + *event = evt; + return 1; +} + +int GetTestText(char *str) +{ + if (index == 0) + { + index++; + sprintf(str, "Test message from solarium."); + return 0; + } + + return -1; +} +// +int SendTest(void) +{ + CPU_INT32U dev_id; + char theme[48]; + + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Test message. Device id %d.", dev_id); + + index = 0; + return ModemSendEmail(theme, GetTestText); +} + + +static CPU_INT32U incas_money; +static CPU_INT32U incas_time; + + +int GetIncasText(char *str) +{ + if (index == 0) + { + // + TRTC_Data rtc; + Sec2Date(&rtc, incas_time); + sprintf(str, "Vremya incassacii: "); + PrintRTCDateTimeString(&str[strlen(str)], &rtc); + sprintf(&str[strlen(str)], "\r\n\r\nSumma %d rub.\r\n", incas_money); + } + else if (index == 1) + { + CPU_INT32U val; + // + val = incas_common_bill_counter; + if (!val) + { + // + sprintf(&str[strlen(str)], "Kupuropriemnik byl pust.\r\n\r\n"); + index=100; + } + else + { + sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n"); + sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n"); + } + } + else if (index == 2) + { + int i; + str[0] = 0; + for (i = 0; i < 6; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + val = strlen(str); + } + } + else if (index == 3) + { + int i; + str[0] = 0; + for (i = 6; i < 12; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 4) + { + int i; + str[0] = 0; + for (i = 12; i < 18; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else if (index == 5) + { + int i; + str[0] = 0; + for (i = 18; i < 24; i++) + { + CPU_INT32U val; + val = incas_bill_nom_counter[i]; + if (val) + { + sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val); + } + } + } + else + { + return -1; + } + + index++; + return 0; +} + +// +int SendIncas(void) +{ + CPU_INT32U dev_id; + char theme[48]; + + GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX); + sprintf(theme, "Incassation. Device id %d.", dev_id); + + index = 0; + return ModemSendEmail(theme, GetIncasText); +} + + + +// +const int send_period_list[7] = {0, 1, 2, 4, 8, 12, 24}; +// +CPU_INT32U modem_status = 0; + +// , +int SamePeriod(CPU_INT32U time1, CPU_INT32U time2, CPU_INT08U period) +{ + TRTC_Data rtc1, rtc2; + CPU_INT08U hour1, hour2; + + Sec2Date(&rtc1, time1); + Sec2Date(&rtc2, time2); + + if ((rtc1.year != rtc2.year) || (rtc1.mon != rtc2.mon) || (rtc1.date != rtc2.date)) + { + // - + return 0; + } + + // time1 - + // + hour1 = rtc1.hour - (rtc1.hour % period); + // + hour2 = rtc2.hour - (rtc2.hour % period); + + if (hour1 != hour2) + { + return 0; + } + + return 1; +} + +#define MODEM_REPEAT_NUM 3 + +static CPU_INT32U last_stat_send_time; + +// +void ModemTask(void *p_arg) +{ + int task; + int send_res, send_ctr, repeat_ctr; + + while (1) + { + CPU_INT32U en = 0; + + OSTimeDly(100); + + if (!IsModemValid()) + { + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + if (en) + { + if (!IsModemConn()) + { + modem_status = 2; + } + else if (!IsModemConf()) + { + modem_status = 1; + } + + // + if (InitModem() != 0) + { + SetErrorFlag(ERROR_MODEM_CONN); + } + else + { + ClrErrorFlag(ERROR_MODEM_CONN); + } + } + else + { + modem_status = 0; + } + continue; + } + + modem_status = 0; + + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + if (!en) + { + ResetModemValid(); + continue; + } + + if (GetModemTask(&task)) + { + // + switch (task) + { + case MODEM_TASK_SEND_INCAS: + { + CPU_INT32U temp; + GetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + if (temp != INCAS_SEND_FLAG) + { + break; + } + GetData(&IncasMoneyDesc, &incas_money, 0, DATA_FLAG_SYSTEM_INDEX); + GetData(&IncasTimeDesc, &incas_time, 0, DATA_FLAG_SYSTEM_INDEX); + repeat_ctr = 0; + while (repeat_ctr < MODEM_REPEAT_NUM) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendIncas(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= MODEM_REPEAT_NUM) + { + // + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + // , , + PostModemTask(MODEM_TASK_SEND_INCAS); + } + else + { + temp = 0; + SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&IncasMoneyDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX); + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + } + } + break; + + case MODEM_TASK_SEND_STATISTICS: + repeat_ctr = 0; + while (repeat_ctr < MODEM_REPEAT_NUM) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendStatistics(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= MODEM_REPEAT_NUM) + { + // + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + // , , + // - , .. + //PostModemTask(MODEM_TASK_SEND_STATISTICS); + } + else + { + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + ClearCounters(); + SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + } + break; + + case MODEM_TASK_SEND_TEST_MSG: + repeat_ctr = 0; + while (repeat_ctr < 3) + { + send_ctr = 0; + while (send_ctr < 3) + { + send_res = SendTest(); + if (send_res == 0) break; + OSTimeDly(1000); + send_ctr++; + } + if (send_ctr < 3) + { + break; + } + else + { + // - + InitModem(); + } + repeat_ctr++; + } + if (repeat_ctr >= 3) + { + // , + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0); + } + else + { + SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0); + } + break; + + case MODEM_TASK_RECONNECT: + // + InitModem(); + break; + } + } + else + { + CPU_INT32U send_time, send_hour, send_minute; + CPU_INT32U last_send_time, sec; + TRTC_Data rtc_1, rtc_2; + + OSTimeDly(MODEM_TASK_DELAY); + // + GetData(&SystemTimeDesc, &sec, 0, DATA_FLAG_SYSTEM_INDEX); + + GetData(&StatSendHourMinDesc, &send_time, 0, DATA_FLAG_SYSTEM_INDEX); + send_hour = send_time / 60; + send_minute = send_time % 60; + + // + GetData(&LastEmailSendTime, &last_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + + Sec2Date(&rtc_1, sec); + Sec2Date(&rtc_2, last_send_time); + + // , + // 9.10 + if ((rtc_1.hour >= send_hour) && (rtc_1.min >= send_minute) && ((rtc_2.date != rtc_1.date) || (rtc_2.year != rtc_1.year) || (rtc_2.mon != rtc_1.mon))) + { + PostModemTask(MODEM_TASK_SEND_STATISTICS); + last_stat_send_time = sec; + //SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX); + // , + } + } + } +} + +// +void PostModemTask(int new_task) +{ + OSQPost(ModemQuery, (void *)new_task); +} diff --git a/PROJECT/app/modem_task.h b/PROJECT/app/modem_task.h new file mode 100644 index 0000000..f92913a --- /dev/null +++ b/PROJECT/app/modem_task.h @@ -0,0 +1,28 @@ +#ifndef _MODEM_TASK_H_ +#define _MODEM_TASK_H_ + +#include "app_serv.h" + +// +#define MODEM_QUERY_LEN 8 +// +#define MODEM_TASK_DELAY 10000 + +enum{ + MODEM_TASK_NONE = 0, + MODEM_TASK_SEND_STATISTICS, + MODEM_TASK_SEND_TEST_MSG, + MODEM_TASK_RECONNECT, + MODEM_TASK_SEND_INCAS, + +}; + +extern OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE]; +extern OS_EVENT *ModemQuery; +extern void *ModemTbl[MODEM_QUERY_LEN]; + + +extern void ModemTask(void *p_arg); +extern void PostModemTask(int new_task); + +#endif //#ifndef _MODEM_TASK_H_ diff --git a/PROJECT/data/data.c b/PROJECT/data/data.c new file mode 100644 index 0000000..f6f4af1 --- /dev/null +++ b/PROJECT/data/data.c @@ -0,0 +1,357 @@ +#include +#include "data.h" +#include "datadesc.h" +#include "fram.h" +#include "time.h" +#include +#include + + +// +int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + CPU_INT32U ofst = 0; + + // . + if (desc->IsArray) + { + if (flags == DATA_FLAG_DIRECT_INDEX) + { + ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index; + } + else + { + GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX); + ofst *= desc->ArrayOffset; + } + } + + // + if (desc->Location == DATA_LOC_RAM) + { + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + memcpy(&Val, (CPU_INT08U*)desc->Data+ofst, sizeof(CPU_INT32U)); + OS_EXIT_CRITICAL(); + } + else if (desc->Location == DATA_LOC_FRAM) + { + ReadArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val); + } + else return DATA_ERR; + + // + memcpy(buf, &Val, sizeof(CPU_INT32U)); + + return DATA_OK; +} + +// +int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + CPU_INT32U ofst = 0; + + if (desc->Desc == DATA_DESC_VIEW) return DATA_ERR; + + // + if (desc->RangeValue) + { + TVariant32 ValMin, ValMax; + TRangeValueULONG* RVal = desc->RangeValue; + + memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U)); + memcpy(&Val, buf, sizeof(CPU_INT32U)); + + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) return DATA_ERR; + } + else if (desc->Type == DATA_TYPE_TIME) + { + + } + else if (desc->Type == DATA_TYPE_HOUR_MIN) + { + if (Val.Val32U >= 24*60) return DATA_ERR; + } + else return DATA_ERR; + } + else + { + memcpy(&Val, buf, sizeof(CPU_INT32U)); + } + // . + if (desc->IsArray) + { + if (flags == DATA_FLAG_DIRECT_INDEX) + { + ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index; + } + else + { + GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX); + ofst *= desc->ArrayOffset; + } + } + + // + if (desc->Location == DATA_LOC_RAM) + { + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + memcpy((CPU_INT08U*)desc->Data+ofst, &Val, sizeof(CPU_INT32U)); + OS_EXIT_CRITICAL(); + } + else if (desc->Location == DATA_LOC_FRAM) + { + WriteArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val); + } + else return DATA_ERR; + + // + if (desc->OnchangeFunc) desc->OnchangeFunc(); + + // + return DATA_OK; +} + +// +int GetDataMax(const TDataDescStruct* desc, void* buf) +{ + if (desc->RangeValue) + { + TRangeValueULONG* RVal = desc->RangeValue; + memcpy(buf, &RVal->Max, sizeof(CPU_INT32U)); + } + else + { + *(CPU_INT32U*)&buf = 0; + } + return DATA_OK; +} + +// +int GetDataMin(const TDataDescStruct* desc, void* buf) +{ + if (desc->RangeValue) + { + TRangeValueULONG* RVal = desc->RangeValue; + memcpy(buf, &RVal->Min, sizeof(CPU_INT32U)); + } + else + { + *(CPU_INT32U*)&buf = 0; + } + return DATA_OK; +} + +// +int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags) +{ + TVariant32 Val; + GetData(desc, &Val, index, flags); + + if (desc->Type == DATA_TYPE_ULONG) + { + if (desc->IsIndex) + { // + if (desc->RangeValue) + { + TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue; + if ((Val.Val32U >= range->Min) && (Val.Val32U <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]); + else {strcpy((char*)buf, ""); return DATA_ERR;} + } + else if (desc->Desc == DATA_DESC_VIEW) + { + strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]); + } + else + { + strcpy((char*)buf, ""); + } + } + else + { + sprintf((char*)buf, "%d", Val.Val32U); + } + } + else if (desc->Type == DATA_TYPE_SLONG) + { + sprintf((char*)buf, "%d", Val.Val32S); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + sprintf((char*)buf, "%0.3f", Val.ValFloat); + } + else if (desc->Type == DATA_TYPE_TIME) + { + PrintTimeString((char*)buf, Val.Val32U); + } + else if (desc->Type == DATA_TYPE_TIME_COUNT) + { + PrintSecToBigHourMinSec((char*)buf, Val.Val32U); + } + else if (desc->Type == DATA_TYPE_HOUR_MIN) + { + int min_ = Val.Val32U % 60; + int hour_ = Val.Val32U / 60; + sprintf((char*)buf, "%02d:%02d", hour_, min_); + } + else return DATA_ERR; + + return DATA_OK; +} + +// +int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags) +{ + GetDataNameStr(desc, buf); + if (desc->Name) + { + if (desc->IsIndex) strcat((char*)&buf[strlen((char*)buf)], " "); + else strcat((char*)&buf[strlen((char*)buf)], "="); + } + GetDataStr(desc, &buf[strlen((char*)buf)], index, flags); + return DATA_OK; +} + +// +int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf) +{ + if (desc->Name) strcpy((char*)buf, (char const*)desc->Name); + else strcpy((char*)buf, ""); + return DATA_OK; +} + + +// +int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex) +{ + if (!desc->IsIndex) {buf[0]=0;return DATA_ERR;} + + if (desc->Type != DATA_TYPE_ULONG) {buf[0]=0;return DATA_ERR;} + + // + if (desc->RangeValue) + { + TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue; + if ((itemindex >= range->Min) && (itemindex <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[itemindex]); + else return DATA_ERR; + } + else + { + strcpy((char*)buf, ""); + } + + return DATA_OK; +} + +// +int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index) +{ + SetData(desc, (void*)&desc->DefaultValue, index, DATA_FLAG_DIRECT_INDEX); + return DATA_OK; +} + +// +int InitData(const TDataDescStruct* desc) +{ + return DATA_OK; +} + +// +int CheckDataRange(const TDataDescStruct* desc) +{ + TVariant32 ValMin, ValMax, Val; + TRangeValueULONG* RVal = desc->RangeValue; + + if (!desc->RangeValue) return DATA_OK; + + memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U)); + + if (desc->IsArray) + { + for (int i = 0; i < desc->ArraySize; i++) + { + GetData(desc, &Val, i, DATA_FLAG_DIRECT_INDEX); + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, i); + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, i); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, i); + } + else return DATA_ERR; + } + } + else + { + GetData(desc, &Val, 0, DATA_FLAG_DIRECT_INDEX); + if (desc->Type == DATA_TYPE_ULONG) + { + if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, 0); + } + else if (desc->Type == DATA_TYPE_SLONG) + { + if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, 0); + } + else if (desc->Type == DATA_TYPE_FLOAT) + { + if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, 0); + } + else return DATA_ERR; + + } + + + return DATA_OK; +} + +// , +int InitDescByDefault(const TDataDescStruct* desc) +{ + if (desc->IsArray) + { + for (int i = 0; i < desc->ArraySize; i++) InitDataByDefault(desc, i); + } + else + { + InitDataByDefault(desc, 0); + } + + return DATA_OK; +} + +// +int CheckAllData(void) +{ + int i = 0; + while (AllDataArray[i].ptr != NULL) + { + CheckDataRange(AllDataArray[i].ptr); + i++; + } + + return DATA_OK; +} diff --git a/PROJECT/data/data.h b/PROJECT/data/data.h new file mode 100644 index 0000000..1ca3a66 --- /dev/null +++ b/PROJECT/data/data.h @@ -0,0 +1,141 @@ +#ifndef _DATA_H_ +#define _DATA_H_ + +/*! + + + - 32 - float signed long + +*/ + +#include "cpu.h" + +typedef union{ + CPU_INT32U Val32U; + CPU_INT32S Val32S; + CPU_FP32 ValFloat; +}TVariant32; + +// +typedef struct{ + CPU_INT32U Min; + CPU_INT32U Max; +}TRangeValueULONG; + +typedef struct{ + CPU_INT32S Min; + CPU_INT32S Max; +}TRangeValueSLONG; + +typedef struct{ + CPU_FP32 Min; + CPU_FP32 Max; +}TRangeValueFLOAT; + + +// +typedef struct{ + + // + CPU_INT08U Desc; + #define DATA_DESC_EDIT 0 // + #define DATA_DESC_VIEW 1 // + + // + CPU_INT08U Type; + //#define DATA_TYPE_UCHAR 0 + //#define DATA_TYPE_SCHAR 1 + #define DATA_TYPE_ULONG 2 + #define DATA_TYPE_SLONG 3 + #define DATA_TYPE_FLOAT 4 + #define DATA_TYPE_TIME 5 + #define DATA_TYPE_TIME_COUNT 6 + #define DATA_TYPE_HOUR_MIN 7 + + // + CPU_INT08U Location; + #define DATA_LOC_RAM 0 + #define DATA_LOC_FRAM 1 + + // + CPU_INT08U IsArray; + #define DATA_NO_ARRAY 0 + #define DATA_IS_ARRAY 1 + + // + CPU_INT32U ArraySize; + + // + const void* ArrayIndex; //TDataDescStruct* + + // FRAM + void* Data; + + // + void* RangeValue; + + // + void (*OnchangeFunc)(void); + + // + CPU_INT32U ArrayOffset; + + // + const CPU_INT08U* Name; + + // ( ) + CPU_INT08U IsIndex; + #define DATA_NO_INDEX 0 + #define DATA_IS_INDEX 1 + + // + const CPU_INT08U** Items; + + // + CPU_INT08U EnableInit; + #define DATA_INIT_DISABLE 0 + #define DATA_INIT_ENABLE 1 + + // + TVariant32 DefaultValue; + +}TDataDescStruct; + + +// +typedef struct{ + const TDataDescStruct* ptr; +}TDataDescArrayStruct; + +// +#define DATA_FLAG_SYSTEM_INDEX 0 +#define DATA_FLAG_DIRECT_INDEX 1 + +// +#define DATA_OK 0 +#define DATA_ERR -1 + +// + +// +extern int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags); +// +extern int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf); +// +extern int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index); +// +extern int CheckAllData(void); +// +extern int InitData(const TDataDescStruct* desc); +extern int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex); +extern int InitDescByDefault(const TDataDescStruct* desc); +extern int GetDataMin(const TDataDescStruct* desc, void* buf); +extern int GetDataMax(const TDataDescStruct* desc, void* buf); + +#endif //#ifndef _DATA_H_ diff --git a/PROJECT/data/datadesc.c b/PROJECT/data/datadesc.c new file mode 100644 index 0000000..57ad459 --- /dev/null +++ b/PROJECT/data/datadesc.c @@ -0,0 +1,2798 @@ +#include +#include "data.h" +#include "datadesc.h" +#include "menu.h" +#include "menudesc.h" +#include "fram_map.h" +#include +#include +#include +#include +#include "control.h" +#include "fiscal.h" +#include "time.h" +#include "CRC16.h" +#include "modem_task.h" +#include "modem.h" + +extern CPU_INT32U modem_status; + +/************************************* + +*************************************/ +CPU_INT32U ChannelIndex=0; +TRangeValueULONG const ChannelIndexRange = {0, CHANNELS_NUM-1}; +CPU_INT08U const ChannelIndexName[] = " "; +CPU_INT08U const* ChannelItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; + +TDataDescStruct const ChannelIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStIndexName[] = ".."; + +TDataDescStruct const ChannelStIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ChannelStLongIndexName[] = ".."; + +TDataDescStruct const ChannelStLongIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &ChannelIndex, // FRAM + (void*)&ChannelIndexRange, // + NULL, // + 0, // + ChannelStLongIndexName, // + DATA_IS_INDEX, // ( ) + ChannelItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + email +*************************************/ +extern TRangeValueULONG const WorkTimeRange; + +TDataDescStruct const LastEmailSendTime = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, LastEmailTime), // FRAM + (void*)&WorkTimeRange, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableChannelRange = {0, 1}; +CPU_INT08U const EnableChannelName[] = ""; +CPU_INT08U const EnableChannelList_str0[] = "."; +CPU_INT08U const EnableChannelList_str1[] = "."; +CPU_INT08U const *EnableChannelList[] = {EnableChannelList_str0, EnableChannelList_str1}; + + +TDataDescStruct const EnableChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Enable), // FRAM + (void*)&EnableChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableChannelName, // + DATA_IS_INDEX, // ( ) + EnableChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const NameChannelRange = {0, 2}; +CPU_INT08U const NameChannelName[] = ""; +CPU_INT08U const NameChannelList_str0[] = "#"; +CPU_INT08U const NameChannelList_str1[] = ""; +CPU_INT08U const NameChannelList_str2[] = ""; +CPU_INT08U const *NameChannelList[] = {NameChannelList_str0, NameChannelList_str1, NameChannelList_str2}; + + +TDataDescStruct const NameChannelDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Name), // FRAM + (void*)&NameChannelRange, // + NULL, // + sizeof(CPU_INT32U), // + NameChannelName, // + DATA_IS_INDEX, // ( ) + NameChannelList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + ( ) +*************************************/ +TRangeValueULONG const StartButtonNameRange = {0, 1}; +CPU_INT08U const StartButtonNameName[] = ""; +CPU_INT08U const StartButtonNameList_str0[] = ""; +CPU_INT08U const StartButtonNameList_str1[] = ""; +CPU_INT08U const *StartButtonNameList[] = {StartButtonNameList_str0, StartButtonNameList_str1}; + + +TDataDescStruct const StartButtonNameDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, StartButtonName), // FRAM + (void*)&StartButtonNameRange, // + NULL, // + 0, // + StartButtonNameName, // + DATA_IS_INDEX, // ( ) + StartButtonNameList, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EnableValidatorRange = {0, 1}; +CPU_INT08U const EnableValidatorName[] = "-"; +CPU_INT08U const OnOffList_str0[] = "."; +CPU_INT08U const OnOffList_str1[] = "."; +CPU_INT08U const *EnableValidatorList[] = {OnOffList_str0, OnOffList_str1}; + + +TDataDescStruct const EnableValidatorDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableValidator), // FRAM + (void*)&EnableValidatorRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableValidatorName, // + DATA_IS_INDEX, // ( ) + EnableValidatorList, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableModemRange = {0, 1}; +CPU_INT08U const EnableModemName[] = ""; +CPU_INT08U const *EnableModemList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableModem(void) +{ + CPU_INT32U en = 0; + GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX); + + if (en) + { + if (!IsModemConn()) + { + modem_status = 2; + } + else if (!IsModemConf()) + { + modem_status = 1; + } + PostModemTask(MODEM_TASK_RECONNECT); + } +} + +TDataDescStruct const EnableModemDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableModem), // FRAM + (void*)&EnableModemRange, // + OnchangeEnableModem, // + sizeof(CPU_INT32U), // + EnableModemName, // + DATA_IS_INDEX, // ( ) + EnableModemList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +TRangeValueULONG const EnableEmailErrorSendRange = {0, 1}; +CPU_INT08U const EnableEmailErrorSendName[] = ". ."; +CPU_INT08U const *EnableEmailErrorSendList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableEmailErrorSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailErrorSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailErrorSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const ModemStatusName[] = ""; +CPU_INT08U const *ModemStatusList[] = {"", "..", " "}; + +TDataDescStruct const ModemStatusDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + &modem_status, // FRAM + NULL, // + NULL, // + 0, // + ModemStatusName, // + DATA_IS_INDEX, // ( ) + ModemStatusList,// + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const EnableEmailJournalSendName[] = "."; + +TDataDescStruct const EnableEmailJournalSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableEmailJournalSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableEmailJournalSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + e-mail +*************************************/ +CPU_INT08U const ClearJournalAfterSendName[] = "."; + +TDataDescStruct const ClearJournalAfterSendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ClearJournalAfterSend), // FRAM + (void*)&EnableEmailErrorSendRange, // + NULL, // + sizeof(CPU_INT32U), // + ClearJournalAfterSendName, // + DATA_IS_INDEX, // ( ) + EnableEmailErrorSendList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + , : +*************************************/ +TRangeValueULONG const StatSendHourRange = {0, 60*24 - 1}; +CPU_INT08U const StatSendHourName[] = "T."; + +TDataDescStruct const StatSendHourMinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_HOUR_MIN, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.StatSendHourMin), // FRAM + (void*)&StatSendHourRange, // + NULL, // + 0, // + StatSendHourName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 9 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableCoinRange = {0, 1}; +CPU_INT08U const EnableCoinName[] = "-"; +CPU_INT08U const *EnableCoinList[] = {OnOffList_str0, OnOffList_str1}; + +void OnchangeEnableCoin(void) +{ +} + +TDataDescStruct const EnableCoinDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableCoinAcceptor), // FRAM + (void*)&EnableCoinRange, // + OnchangeEnableCoin, // + sizeof(CPU_INT32U), // + EnableCoinName, // + DATA_IS_INDEX, // ( ) + EnableCoinList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const CoinPerPulseRange = {1, 9999}; +CPU_INT08U const CoinPerPulseName[] = "./."; + +TDataDescStruct const CoinPerPulseDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.CoinPerPulse), // FRAM + (void*)&CoinPerPulseRange, // + NULL, // + 0, // + CoinPerPulseName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 1 // +}; + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalRange = {0, 1}; +CPU_INT08U const EnableFiscalName[] = ""; +CPU_INT08U const *EnableFiscalList[] = {OnOffList_str0, OnOffList_str1}; + +TDataDescStruct const EnableFiscalDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscal), // FRAM + (void*)&EnableFiscalRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalName, // + DATA_IS_INDEX, // ( ) + EnableFiscalList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const DisableFiscalErrorsRange = {0, 1}; +CPU_INT08U const DisableFiscalErrorsName[] = ".."; +CPU_INT08U const DisableFiscalErrorsList_str0[] = ""; +CPU_INT08U const DisableFiscalErrorsList_str1[] = ""; +CPU_INT08U const *DisableFiscalErrorsList[] = {DisableFiscalErrorsList_str0, DisableFiscalErrorsList_str1}; + +TDataDescStruct const DisableFiscalErrorsDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DisableFiscalErrors), // FRAM + (void*)&DisableFiscalErrorsRange, // + NULL, // + sizeof(CPU_INT32U), // + DisableFiscalErrorsName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U WorkTime[CHANNELS_NUM]; +TRangeValueULONG const WorkTimeRange = {0, 0xffffffffL}; +CPU_INT08U const WorkTimeName[] = "."; + +TDataDescStruct const WorkTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + &WorkTime, // FRAM + (void*)&WorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + WorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutBeforeRange = {0, 999}; +CPU_INT08U const TimeOutBeforeName[] = " ,."; + +TDataDescStruct const TimeOutBeforeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutBefore), // FRAM + (void*)&TimeOutBeforeRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutBeforeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 30 +}; + +/************************************* + - +*************************************/ +TRangeValueULONG const TimeOutAfterRange = {0, 99}; +CPU_INT08U const TimeOutAfterName[] = " ,."; + +TDataDescStruct const TimeOutAfterDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.TimeOutAfter), // FRAM + (void*)&TimeOutAfterRange, // + NULL, // + sizeof(CPU_INT32U), // + TimeOutAfterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 3 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MaxWorkTimeRange = {1, 999}; +CPU_INT08U const MaxWorkTimeName[] = "Tmax,."; + +TDataDescStruct const MaxWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MaxWorkTime), // FRAM + (void*)&MaxWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MaxWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 20 +}; + +/************************************* + , . +*************************************/ +TRangeValueULONG const MinWorkTimeRange = {1, 999}; +CPU_INT08U const MinWorkTimeName[] = "Tmin,."; + +TDataDescStruct const MinWorkTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.MinWorkTime), // FRAM + (void*)&MinWorkTimeRange, // + NULL, // + sizeof(CPU_INT32U), // + MinWorkTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 5 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const WeekEndRange = {0, 4}; +CPU_INT08U const WeekEndName[] = ":"; +CPU_INT08U const WeekEndList_str0[] = ""; +CPU_INT08U const WeekEndList_str1[] = "-"; +CPU_INT08U const WeekEndList_str2[] = "-"; +CPU_INT08U const WeekEndList_str3[] = "-"; +CPU_INT08U const WeekEndList_str4[] = "-"; +CPU_INT08U const *WeekEndList[] = {WeekEndList_str0, WeekEndList_str1, WeekEndList_str2, WeekEndList_str3, WeekEndList_str4, NULL}; + +TDataDescStruct const WeekEndDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.WeekEnd), // FRAM + (void*)&WeekEndRange, // + NULL, // + sizeof(CPU_INT32U), // + WeekEndName, // + DATA_IS_INDEX, // ( ) + WeekEndList, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const DeferredStartRange = {0, 1}; +CPU_INT08U const DeferredStartName[] = "."; +CPU_INT08U const DeferredStart_str0[] = ""; +CPU_INT08U const DeferredStart_str1[] = ""; +CPU_INT08U const *DeferredStartList[] = {DeferredStart_str0, DeferredStart_str1, NULL}; + +TDataDescStruct const DeferredStartDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelIndexDesc, // + (void*)offsetof(TFramMap, DefferedStartEnabled), // FRAM + (void*)&DeferredStartRange, // + NULL, // + sizeof(CPU_INT32U), // + DeferredStartName, // + DATA_IS_INDEX, // ( ) + DeferredStartList, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PeriodIndexRange = {0, 0xffffffff/*CHANNELS_NUM*PRICE_PERIODS_NUM-1*/}; +CPU_INT08U const PeriodIndexName[] = ""; +CPU_INT08U const *PeriodWeekendIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; + +CPU_INT32U PeriodIndex = 0; + +void OnChangePeriodIndex(void) +{ + if ((PeriodIndex == 0xffffffff) || (PeriodIndex < ChannelIndex*PRICE_PERIODS_NUM)) PeriodIndex = (ChannelIndex+1)*PRICE_PERIODS_NUM-1; + else if (PeriodIndex >= (ChannelIndex+1)*PRICE_PERIODS_NUM) PeriodIndex = (ChannelIndex)*PRICE_PERIODS_NUM; +} + +TDataDescStruct const PeriodWeekendIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekendIndexList, // + DATA_INIT_ENABLE, + 0 +}; + +CPU_INT08U const *PeriodWeekdaysIndexList[] = { + ".1 .1 .", + ".1 .2 .", + ".1 .3 .", + ".1 .4 .", + ".2 .1 .", + ".2 .2 .", + ".2 .3 .", + ".2 .4 .", + ".3 .1 .", + ".3 .2 .", + ".3 .3 .", + ".3 .4 .", + ".4 .1 .", + ".4 .2 .", + ".4 .3 .", + ".4 .4 .", + ".5 .1 .", + ".5 .2 .", + ".5 .3 .", + ".5 .4 .", + ".6 .1 .", + ".6 .2 .", + ".6 .3 .", + ".6 .4 .", + ".7 .1 .", + ".7 .2 .", + ".7 .3 .", + ".7 .4 .", + ".8 .1 .", + ".8 .2 .", + ".8 .3 .", + ".8 .4 .", + ".9 .1 .", + ".9 .2 .", + ".9 .3 .", + ".9 .4 .", + ".10 .1 .", + ".10 .2 .", + ".10 .3 .", + ".10 .4 .", + NULL}; +TDataDescStruct const PeriodWeekdaysIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PeriodIndex, // FRAM + (void*)&PeriodIndexRange, // + OnChangePeriodIndex, // + 0, // + PeriodIndexName, // + DATA_IS_INDEX, // ( ) + PeriodWeekdaysIndexList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekendRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekendName[] = ",."; + +TDataDescStruct const PriceWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekend), // FRAM + (void*)&PriceWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceWeekdaysRange = {1, MAX_PRICE}; +CPU_INT08U const PriceWeekdaysName[] = ",."; + +TDataDescStruct const PriceWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.Price_Weekdays), // FRAM + (void*)&PriceWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 15 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekendRange = {1, 999}; +CPU_INT08U const PriceTimeWeekendName[] = " ,."; + +TDataDescStruct const PriceTimeWeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekend), // FRAM + (void*)&PriceTimeWeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const PriceTimeWeekdaysRange = {1, 999}; +CPU_INT08U const PriceTimeWeekdaysName[] = " ,."; + +TDataDescStruct const PriceTimeWeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekdays), // FRAM + (void*)&PriceTimeWeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + PriceTimeWeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekdaysRange = {0, 24}; +CPU_INT08U const T_Start_WeekdaysName[] = ","; + +TDataDescStruct const T_Start_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekdays), // FRAM + (void*)&T_Start_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekdaysRange = {0, 24}; +CPU_INT08U const T_End_WeekdaysName[] = ","; + +TDataDescStruct const T_End_WeekdaysDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekdaysIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekdays), // FRAM + (void*)&T_End_WeekdaysRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekdaysName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const T_Start_WeekendRange = {0, 24}; +CPU_INT08U const T_Start_WeekendName[] = ","; + +TDataDescStruct const T_Start_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekend), // FRAM + (void*)&T_Start_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_Start_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const T_End_WeekendRange = {0, 24}; +CPU_INT08U const T_End_WeekendName[] = ","; + +TDataDescStruct const T_End_WeekendDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM*PRICE_PERIODS_NUM, // + &PeriodWeekendIndexDesc, // + (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekend), // FRAM + (void*)&T_End_WeekendRange, // + NULL, // + sizeof(CPU_INT32U), // + T_End_WeekendName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 24 +}; + + +/************************************* + +*************************************/ +CPU_INT32U InitByDefault = 0; + +TRangeValueULONG const InitByDefaultRange = {0, 1}; +CPU_INT08U const InitByDefaultName[] = ""; +CPU_INT08U const InitByDefaultList_str0[] = ""; +CPU_INT08U const InitByDefaultList_str1[] = ""; +CPU_INT08U const *InitByDefaultList[] = {InitByDefaultList_str0, InitByDefaultList_str1}; + + +void OnChangeInitByDefault(void) +{ + int i = 0; + if (InitByDefault == 0) return; + while (AllDataArray[i].ptr != NULL) + { + InitDescByDefault(AllDataArray[i].ptr); + i++; + } + InitByDefault = 0; +} + + +TDataDescStruct const InitByDefaultDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&InitByDefault, // FRAM + (void*)&InitByDefaultRange, // + OnChangeInitByDefault, // + 0, // + InitByDefaultName, // + DATA_IS_INDEX, // ( ) + InitByDefaultList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + Z- +*************************************/ +CPU_INT32U PrintZReportCmd = 0; + +CPU_INT08U const PrintZReportName[] = "Z-"; +CPU_INT08U const PrintZReportList_str0[] = ""; +CPU_INT08U const PrintZReportList_str1[] = ""; +CPU_INT08U const *PrintZReportList[] = {PrintZReportList_str0, PrintZReportList_str1}; + + +void OnChangePrintZReportCmd(void) +{ +} + +TDataDescStruct const PrintZReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintZReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintZReportCmd, // + 0, // + PrintZReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + X- +*************************************/ +CPU_INT32U PrintXReportCmd = 0; + +CPU_INT08U const PrintXReportName[] = "X-"; + +void OnChangePrintXReportCmd(void) +{ +} + +TDataDescStruct const PrintXReportDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&PrintXReportCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangePrintXReportCmd, // + 0, // + PrintXReportName, // + DATA_IS_INDEX, // ( ) + PrintZReportList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const ErrorJournalIndexName[] = " #"; +CPU_INT32U ErrorJournalIndex = 0; + +void OnChangeErrorJournalIndex(void) +{ + if (ErrorJournalIndex == 0xffffffff) ErrorJournalIndex = ERROR_RECORDS_NUM-1; + else if (ErrorJournalIndex > ERROR_RECORDS_NUM-1) ErrorJournalIndex = 0; +} + +TDataDescStruct const ErrorJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ErrorJournalIndex, // FRAM + (void*)&ErrorJournalIndexRange, // + OnChangeErrorJournalIndex, // + 0, // + ErrorJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TRangeValueULONG const ErrorNumberRange = {0, ERRORS_NUM-1}; +CPU_INT08U const *ErrorNumberList0[ERRORS_NUM] = {"", + " ", + " ", + "1Ch60h-.", + "1Ch61h-.", + "1Ch64h-.", + "1Ch65h-.", + "1Ch66h-.", + "1Ch67h-.", + "1Ch68h-.", + "1Ch69h-.", + "1Ch6Ch-.", + "/:41h-", + "/:42h-", + "/:43h- ", + "/:44h-", + "/:45h-", + "/:50h-", + "/:51h- .", + "/:52h-", + "/:53h- .", + "/:54h-", + "/:65h-", + "/:66h-", + "/:67h- .", + "", + "", + + ":01h-", + ":02h-", + ":03h-", + ":04h-.-", + ":05h-", + ":06h- ", + ":07h-.-", + ":08h-", + ":09h-.", + ":0Ah- ", + ":0Bh-.", + ":11h- ", + ":12h-", + ":13h- ", + ":14h-", + ":15h-", + ":16h-", + ":17h- ", + ":18h- ", + ":19h- ", + ":1Ah- ", + ":1Bh-", + ":1Ch-", + ":1Dh-", + ":1Fh-", + ":20h-", + ":21h- ", + ":22h- ", + ":23h- ", + ":24h-", + ":25h-", + ":28h- ", + ":33h-", + ":35h-", + ":36h-", + ":37h-", + ":38h- ", + ":39h-", + ":3Ah-", + ":3Ch-:", + ":3Eh-", + ":3Fh-", + ":40h-", + ":41h-", + ":42h-", + ":43h-", + ":44h-", + ":45h-C", + ":46h- ", + ":47h-", + ":48h-", + ":4Ah- ", + ":4Bh- ", + ":4Ch-", + ":4Dh-", + ":4Eh-", + ":4Fh- ", + ":50h- ", + ":51h-", + ":52h-", + ":53h-", + ":54h-", + ":56h- .", + ":57h-:", + ":58h-", + ":59h-", + ":5Bh-", + ":5Ch-", + ":5Dh-", + ":5Eh-", + ":5Fh-.", + ":60h-", + ":61h-", + ":62h-", + ":63h-", + ":64h- ", + ":65h- ", + ":66h-", + ":67h- ", + ":68h- ", + ":69h-", + ":6Ah-", + ":6Bh- ", + ":6Ch- .", + ":6Dh- ", + ":6Eh-", + ":6Fh-", + ":70h-", + ":71h-", + ":72h- ", + ":73h- ", + ":74h- ", + ":75h-", + ":76h-:", + ":77h-:", + ":78h- ", + ":79h- ", + ":7Ah- ", + ":7Bh-", + ":7Ch- ", + ":7Dh-", + ":7Eh-", + ":7Fh-", + ":80h-", + ":81h-", + ":82h-", + ":83h-", + ":84h-", + ":85h-", + ":86h-", + ":87h-", + ":88h-", + ":89h-", + ":8Ah-", + ":8Bh-", + ":8Ch-.", + ":8Dh-", + ":8Eh- ", + ":8Fh- ", + ":90h- .", + ":91h- ", + ":92h-", + ":93h-", + ":94h-", + ":A0h- ", + ":A1h-", + ":A2h-: ", + ":A3h-", + ":A4h- ", + ":A5h- ", + ":A6h-", + ":A7h-", + ":A8h-:", + ":A9h-:", + ":AAh-", + ":B0h-:", + ":B1h-:", + ":B2h-:", + ":C0h-", + ":C1h-:", + ":C2h-", + ":C3h-", + ":C4h-", + //":5h-", + //":C6h-", + //":C7h- ", + //":8h-", + +}; + +TDataDescStruct const JournalErrorNumberDesc0 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList0, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const *ErrorNumberList1[ERRORS_NUM] = {"", + "", + "", + " ", + " .", + " .", + " ", + " ", + " . ", + " ", + " .", + " ", + "", + "", + "", + " ", + "", + " ", + ".", + ".", + "", + "", + "", + ".", + "", + "", + " ", + "1,2 ", + " 1", + " 2", + " ", + " ", + " ", + " ", + " .", + " ", + " BCD", + " ", + "", + " ", + " ", + "", + " ", + " ", + "", + "", + " ", + "", + " ", + ". ", + " ", + " ", + " ", + "", + "", + "", + ".", + "", + "2 ", + " ", + "", + "", + " .", + "", + " ", + " ", + " .", + ". ", + ". ", + " ", + " ", + " 2", + " 3", + " 4", + " ", + " ", + " ", + " ", + " ", + "", + ". ", + ". ", + " 24 ", + "", + ".", + " ", + " 2 ", + " 3 ", + " 4 ", + " ", + " - ", + " ", + " .", + " ", + " 24", + " ", + "", + " ", + " ", + " ", + " -", + " ", + "", + " ", + " ", + " ", + " ", + " ", + "", + "", + "", + " ", + " ", + " ", + "", + "", + ".", + ".", + "", + "", + " ", + " ", + "", + "", + "", + "", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "", + "", + " ", + " ", + "", + " ", + " ", + " ", + "", + ". ", + " ", + "", + " ", + ". ", + "", + " ", + " ", + "", + " -", + " ", + " ", + " ", + " ", + "", + " ", + " ", + //".. ", + //".", + //"", + //"" + +}; + +TDataDescStruct const JournalErrorNumberDesc1 = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberList1, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + - +*************************************/ +CPU_INT08U const *ErrorNumberListEng[ERRORS_NUM] = +{ + "Net oshibki", + "Oshibka svyazi c kupuropriemnikom", + "Kriticheskaya oshibka kupuropriemnika", + "Vybros kupury po mag.datchiku", + "Vybros kupury pri transportirovke", + "Vybros kupury po identifikacii", + "Vybros kupury po verifikacii", + "Vybros kupury po opt.datchiku", + "Vybros kupury po zapretu", + "Vybros kupury po emk.datchiku", + "Vybros kupury po dline", + "Kasseta zapolnena", + "Kasseta otsutstvuet", + "Zamin v kupuropriemnike", + "Zamin v kassete", + "Popytka obmana", + "Oshibka stekernogo motora", + "Oshibka skorosti transp.motora", + "Oshibka transp.motora", + "Oshibka mehanizmavyravnivaniya", + "Kasseta otsutstvuet", + "Oshibka optiki", + "Oshibka magn.datchika", + "Oshibka emk.datchika", + "Nekriticheskaya oshibka kupuropriemnika", + + "Oshibka svyazi s modemom", + "Oshibka svyazi s FR", + "Oshibka FR 0x01", + "Oshibka FR 0x02", + "Oshibka FR 0x03", + "Oshibka FR 0x04", + "Oshibka FR 0x05", + "Oshibka FR 0x06", + "Oshibka FR 0x07", + "Oshibka FR 0x08", + "Oshibka FR 0x09", + "Oshibka FR 0x0A", + "Oshibka FR 0x0B", + "Oshibka FR 0x11", + "Oshibka FR 0x12", + "Oshibka FR 0x13", + "Oshibka FR 0x14", + "Oshibka FR 0x15", + "Oshibka FR 0x16", + "Oshibka FR 0x17", + "Oshibka FR 0x18", + "Oshibka FR 0x19", + "Oshibka FR 0x1A", + "Oshibka FR 0x1B", + "Oshibka FR 0x1C", + "Oshibka FR 0x1D", + "Oshibka FR 0x1F", + "Oshibka FR 0x20", + "Oshibka FR 0x21", + "Oshibka FR 0x22", + "Oshibka FR 0x23", + "Oshibka FR 0x24", + "Oshibka FR 0x25", + "Oshibka FR 0x28", + "Oshibka FR 0x33", + "Oshibka FR 0x35", + "Oshibka FR 0x36", + "Oshibka FR 0x37", + "Oshibka FR 0x38", + "Oshibka FR 0x39", + "Oshibka FR 0x3A", + "Oshibka FR 0x3C", + "Oshibka FR 0x3E", + "Oshibka FR 0x3F", + "Oshibka FR 0x40", + "Oshibka FR 0x41", + "Oshibka FR 0x42", + "Oshibka FR 0x43", + "Oshibka FR 0x44", + "Oshibka FR 0x45", + "Oshibka FR 0x46", + "Oshibka FR 0x47", + "Oshibka FR 0x48", + "Oshibka FR 0x4A", + "Oshibka FR 0x4B", + "Oshibka FR 0x4C", + "Oshibka FR 0x4D", + "Oshibka FR 0x4E", + "Oshibka FR 0x4F", + "Oshibka FR 0x50", + "Oshibka FR 0x51", + "Oshibka FR 0x52", + "Oshibka FR 0x53", + "Oshibka FR 0x54", + "Oshibka FR 0x56", + "Oshibka FR 0x57", + "Oshibka FR 0x58", + "Oshibka FR 0x59", + "Oshibka FR 0x5B", + "Oshibka FR 0x5C", + "Oshibka FR 0x5D", + "Oshibka FR 0x5E", + "Oshibka FR 0x5F", + "Oshibka FR 0x60", + "Oshibka FR 0x61", + "Oshibka FR 0x62", + "Oshibka FR 0x63", + "Oshibka FR 0x64", + "Oshibka FR 0x65", + "Oshibka FR 0x66", + "Oshibka FR 0x67", + "Oshibka FR 0x68", + "Oshibka FR 0x69", + "Oshibka FR 0x6A", + "Oshibka FR 0x6B", + "Oshibka FR 0x6C", + "Oshibka FR 0x6D", + "Oshibka FR 0x6E", + "Oshibka FR 0x6F", + "Oshibka FR 0x70", + "Oshibka FR 0x71", + "Oshibka FR 0x72", + "Oshibka FR 0x73", + "Oshibka FR 0x74", + "Oshibka FR 0x75", + "Oshibka FR 0x76", + "Oshibka FR 0x77", + "Oshibka FR 0x78", + "Oshibka FR 0x79", + "Oshibka FR 0x7A", + "Oshibka FR 0x7B", + "Oshibka FR 0x7C", + "Oshibka FR 0x7D", + "Oshibka FR 0x7E", + "Oshibka FR 0x7F", + "Oshibka FR 0x80", + "Oshibka FR 0x81", + "Oshibka FR 0x82", + "Oshibka FR 0x83", + "Oshibka FR 0x84", + "Oshibka FR 0x85", + "Oshibka FR 0x86", + "Oshibka FR 0x87", + "Oshibka FR 0x88", + "Oshibka FR 0x89", + "Oshibka FR 0x8A", + "Oshibka FR 0x8B", + "Oshibka FR 0x8C", + "Oshibka FR 0x8D", + "Oshibka FR 0x8E", + "Oshibka FR 0x8F", + "Oshibka FR 0x90", + "Oshibka FR 0x91", + "Oshibka FR 0x92", + "Oshibka FR 0x93", + "Oshibka FR 0x94", + "Oshibka FR 0xA0", + "Oshibka FR 0xA1", + "Oshibka FR 0xA2", + "Oshibka FR 0xA3", + "Oshibka FR 0xA4", + "Oshibka FR 0xA5", + "Oshibka FR 0xA6", + "Oshibka FR 0xA7", + "Oshibka FR 0xA8", + "Oshibka FR 0xA9", + "Oshibka FR 0xAA", + "Oshibka FR 0xB0", + "Oshibka FR 0xB1", + "Oshibka FR 0xB2", + "Oshibka FR 0xC0", + "Oshibka FR 0xC1", + "Oshibka FR 0xC2", + "Oshibka FR 0xC3" + "Oshibka FR 0xC4" +}; + +TDataDescStruct const JournalErrorNumberDescEng = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].error), // FRAM + (void*)&ErrorNumberRange, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_IS_INDEX, // ( ) + (void*)ErrorNumberListEng, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalErrorTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &ErrorJournalIndexDesc, // + (void*)offsetof(TFramMap, ErrorRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TErrorRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EventJournalIndexRange = {0, 0xffffffff}; +CPU_INT08U const EventJournalIndexName[] = " #"; +CPU_INT32U EventJournalIndex = 0; + +void OnChangeEventJournalIndex(void) +{ + TEventRecord record; + + if (EventJournalIndex == 0xffffffff) EventJournalIndex = EVENT_RECORDS_NUM-1; + else if (EventJournalIndex > ERROR_RECORDS_NUM-1) EventJournalIndex = 0; + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +TDataDescStruct const EventJournalIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&EventJournalIndex, // FRAM + (void*)&EventJournalIndexRange, // + OnChangeEventJournalIndex, // + 0, // + EventJournalIndexName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const JournalEventTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + ERROR_RECORDS_NUM, // + &EventJournalIndexDesc, // + (void*)offsetof(TFramMap, EventRecords[0].time), // FRAM + NULL, // + NULL, // + sizeof(TEventRecord), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U SystemTime; + +TDataDescStruct const SystemTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +void OnSetTime(void) +{ + TRTC_Data rtc; + Sec2Date(&rtc, SystemTime); + RTC_SetTime(&rtc); +} + +TDataDescStruct const SystemTimeEditDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_TIME, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&SystemTime, // FRAM + NULL, // + OnSetTime, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U ClearJournalCmd = 0; + +CPU_INT08U const ClearJournalCmdName[] = ""; +CPU_INT08U const ClearJournalCmdList_str0[] = ""; +CPU_INT08U const ClearJournalCmdList_str1[] = ""; +CPU_INT08U const *ClearJournalCmdList[] = {ClearJournalCmdList_str0, ClearJournalCmdList_str1}; + +void OnChangeClearJournalCmd(void) +{ + if (ClearJournalCmd) + { + ClearErrorJournal(); + ClearEventJournal(); + ClearJournalCmd = 0; + } +} + +TDataDescStruct const ClearJournalCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearJournalCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearJournalCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT08U const CounterRunName[] = ""; + +TDataDescStruct const CounterRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterRun), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterMoneyName[] = ",."; + +TDataDescStruct const CounterMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterMoney), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const CounterTimeName[] = ".."; + +TDataDescStruct const CounterTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.CounterTime), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterRunLong), // FRAM + NULL, // + NULL, // + 0, // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterMoneyLong), // FRAM + NULL, // + NULL, // + 0, // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterLongTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, CountersLong.CounterTimeLong), // FRAM + NULL, // + NULL, // + 0, // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelRun[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelMoney[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterChannelTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelRunLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelRunLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterRunName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelMoneyLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelMoneyLong[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterMoneyName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const CounterChannelTimeLongDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_TIME_COUNT, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + CHANNELS_NUM, // + &ChannelStIndexDesc, // + (void*)offsetof(TFramMap, CountersLong.CounterChannelTimeLong), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + CounterTimeName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U ClearStatCmd = 0; + +CPU_INT08U const ClearStatCmdName[] = ""; + +void OnChangeClearStatCmd(void) +{ + if (ClearStatCmd) + { + ClearCounters(); + ClearStatCmd = 0; + } +} + +TDataDescStruct const ClearStatCmdDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&ClearStatCmd, // FRAM + (void*)&InitByDefaultRange, // + OnChangeClearStatCmd, // + 0, // + ClearJournalCmdName, // + DATA_IS_INDEX, // ( ) + ClearJournalCmdList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const EnableFiscalDayClearRange = {0, 2}; +CPU_INT08U const EnableFiscalDayClearName[] = "."; +CPU_INT08U const *EnableFiscalDayClearList[] = {".", "", ""}; + +TDataDescStruct const EnableFiscalDayClearDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.EnableFiscalDayClear), // FRAM + (void*)&EnableFiscalDayClearRange, // + NULL, // + sizeof(CPU_INT32U), // + EnableFiscalDayClearName, // + DATA_IS_INDEX, // ( ) + EnableFiscalDayClearList, // + DATA_INIT_ENABLE, + 1 // +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const BillFormatRange = {0, 1}; +CPU_INT08U const BillFormatName[] = ":"; +CPU_INT08U const BillFormatList_str0[] = "-*"; +CPU_INT08U const BillFormatList_str1[] = ""; +CPU_INT08U const *BillFormatList[] = {BillFormatList_str0, BillFormatList_str1}; + +TDataDescStruct const BillFormatDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.BillFormat), // FRAM + (void*)&BillFormatRange, // + NULL, // + sizeof(CPU_INT32U), // + BillFormatName, // + DATA_IS_INDEX, // ( ) + BillFormatList, // + DATA_INIT_DISABLE, + 1 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const ServiceNameRange = {0, 0}; +CPU_INT08U const ServiceNameName[] = ""; +CPU_INT08U const *ServiceNameList[] = {" "}; + +TDataDescStruct const ServiceNameDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.ServiceName), // FRAM + (void*)&ServiceNameRange, // + NULL, // + sizeof(CPU_INT32U), // + ServiceNameName, // + DATA_IS_INDEX, // ( ) + ServiceNameList, // + DATA_INIT_DISABLE, + 0 // +}; + +/************************************* + +*************************************/ +TDataDescStruct const AcceptedMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, FRAM_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + Crc16 +*************************************/ +TDataDescStruct const AcceptedMoneyCRC16Desc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_AcceptedMoney), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + +*************************************/ +TRangeValueULONG const PassRange = {0, 9999}; +CPU_INT08U const PassName[] = " b"; + +void OnChangePass(void) +{ + // CRC + CPU_INT32U pass,crc; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); +} + +TDataDescStruct const PassDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Pass), // FRAM + (void*)&PassRange, // + OnChangePass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + DEFAULT_PASSWORD +}; + +/************************************* + CRC +*************************************/ +TDataDescStruct const PassCRCDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, crc_Pass), // FRAM + NULL, // + NULL, // + 0, // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT32U TempPass = 0; + +void OnChangeTempPass(void) +{ + CPU_INT32U pass; + GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + + if (GetCurrentMenu() == SetPassMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {GoToPreviousMenu(); GoToMenu(SetNewPassMenuPanel);} + } + else if (GetCurrentMenu() == ResetSettingsMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {InitByDefault = 1; OnChangeInitByDefault(); GoToPreviousMenu(); GoToMenu(SettingsIsReset);} + } + else if (GetCurrentMenu() == ClearStatMenu) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearStatCmd = 1; OnChangeClearStatCmd(); GoToPreviousMenu(); GoToMenu(StatIsReset);} + } + else if (GetCurrentMenu() == ClearJournalMenuPanel) + { // + if (pass != TempPass) + { + SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass); + GoToMenu(ErrorPassPanel); + } + else {ClearJournalCmd = 1; OnChangeClearJournalCmd(); GoToPreviousMenu(); GoToMenu(JournalIsReset);} + } + +} + +TDataDescStruct const PassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +CPU_INT08U const PassTempName1[] = " b"; + +TDataDescStruct const PassTempDesc1 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName1, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +TRangeValueULONG const MasterPassRange = {0, 99999999}; +CPU_INT08U const MasterPassTempName[] = "b"; + +void OnChangeMasterPass(void) +{ + CPU_INT32U pass, crc; + + if (TempPass == MASTER_PASSWORD) + { + TempPass = 0; + pass = DEFAULT_PASSWORD; + crc = CRC16((unsigned char*)&pass, sizeof(CPU_INT32U)); + SetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX); + SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX); + + GoToPreviousMenu(); + GoToPreviousMenu(); + GoToMenu(SetNewPassMenuPanel); + } +} + +TDataDescStruct const MasterPassTempDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&MasterPassRange, // + OnChangeMasterPass, // + 0, // + (void*)&MasterPassTempName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +CPU_INT08U const PassTempName2[] = " b"; + +TDataDescStruct const PassTempDesc2 = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)&TempPass, // FRAM + (void*)&PassRange, // + OnChangeTempPass, // + 0, // + (void*)&PassTempName2, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const SendTestEmailName[] = "."; +CPU_INT32U send_test; + +void OnChangeSendTestEmail(void) +{ + if (send_test) + { + PostModemTask(MODEM_TASK_SEND_TEST_MSG); + send_test = 0; + } +} + +TDataDescStruct const SendTestEmailDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)&send_test, // FRAM + (void*)&EnableEmailErrorSendRange, // + OnChangeSendTestEmail, // + sizeof(CPU_INT32U), // + SendTestEmailName, // + DATA_IS_INDEX, // ( ) + DisableFiscalErrorsList, // + DATA_INIT_ENABLE, + 0 +}; + + +/************************************* + +*************************************/ +CPU_INT32U BillnomViewIndex; +TRangeValueULONG const BillnomIndexRange = {0, 23}; +CPU_INT08U const BillnomName[] = " #"; +CPU_INT08U const* BillnomItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}; + +TDataDescStruct const BillnomIndexDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + &BillnomViewIndex, // FRAM + (void*)&BillnomIndexRange, // + NULL, // + 0, // + BillnomName, // + DATA_IS_INDEX, // ( ) + BillnomItems, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +extern CPU_INT32U BillNominals[24]; +CPU_INT08U const BillnomValName[] = ",."; + +TDataDescStruct const BillnomDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_RAM, // + DATA_IS_ARRAY, // + 24, // + (void*)&BillnomIndexDesc, // + (void*)&BillNominals, // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomValName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillnomCountersName[] = "-"; + +TDataDescStruct const BillnomCountersDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_IS_ARRAY, // + 24, // + &BillnomIndexDesc, // + (void*)offsetof(TFramMap, Counters.CounterBillNominals[0]), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + BillnomCountersName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +CPU_INT08U const BillCounterName[] = " "; + +TDataDescStruct const BillCounterDesc = { + DATA_DESC_VIEW, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + NULL, // + (void*)offsetof(TFramMap, Counters.BillsCount), // FRAM + NULL, // + NULL, // + 0, // + BillCounterName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + + +/************************************* + ID +*************************************/ +CPU_INT08U const DeviceIDName[] = "ID -"; +TRangeValueULONG const DeviceIDRange = {0, 9999}; + +TDataDescStruct const DeviceIDDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 0, // + 0, // + (void*)offsetof(TFramMap, DeviceConfig.DeviceId), // FRAM + (void*)&DeviceIDRange, // + NULL, // + 0, // + DeviceIDName, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_ENABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasSendFlagDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasEmailFlag), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasMoneyDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasMoney), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +/************************************* + +*************************************/ +TDataDescStruct const IncasTimeDesc = { + DATA_DESC_EDIT, // + DATA_TYPE_ULONG, // + DATA_LOC_FRAM, // + DATA_NO_ARRAY, // + 1, // + NULL, // + (void*)offsetof(TFramMap, IncasTime), // FRAM + NULL, // + NULL, // + sizeof(CPU_INT32U), // + NULL, // + DATA_NO_INDEX, // ( ) + NULL, // + DATA_INIT_DISABLE, + 0 +}; + +//************************************************** +//************************************************** +//************************************************** +const TDataDescArrayStruct AllDataArray[] = { + &WorkTimeDesc, + &ChannelIndexDesc, + &EnableChannelDesc, + &EnableValidatorDesc, + &EnableModemDesc, + &EnableFiscalDesc, + &EnableCoinDesc, + &TimeOutBeforeDesc, + &TimeOutAfterDesc, + &MaxWorkTimeDesc, + &MinWorkTimeDesc, + &WeekEndDesc, + &PeriodWeekendIndexDesc, + &PeriodWeekdaysIndexDesc, + + &PriceWeekendDesc, + &PriceWeekdaysDesc, + + &PriceTimeWeekendDesc, + &PriceTimeWeekdaysDesc, + &T_Start_WeekdaysDesc, + &T_End_WeekdaysDesc, + &T_Start_WeekendDesc, + &T_End_WeekendDesc, + + &PrintZReportDesc, + &PrintXReportDesc, + &ErrorJournalIndexDesc, + &SystemTimeDesc, + &SystemTimeEditDesc, + &CoinPerPulseDesc, + + &BillFormatDesc, + &NameChannelDesc, + + &PassDesc, + &DeviceIDDesc, + + &EnableEmailErrorSendDesc, + &EnableEmailJournalSendDesc, + &ClearJournalAfterSendDesc, + &StatSendHourMinDesc, + &SendTestEmailDesc, + &BillnomIndexDesc, + + &DeferredStartDesc, + &StartButtonNameDesc, + + NULL +}; + + diff --git a/PROJECT/data/datadesc.h b/PROJECT/data/datadesc.h new file mode 100644 index 0000000..318c379 --- /dev/null +++ b/PROJECT/data/datadesc.h @@ -0,0 +1,189 @@ +#ifndef _DATADESC_H_ +#define _DATADESC_H_ + +#include "data.h" +#include "control.h" + +#define INCAS_SEND_FLAG 0x87654321 + +#define MAX_PRICE 9999 + +#define DEFAULT_PASSWORD 1111 +#define MASTER_PASSWORD 11300045//1234567890L + +// +typedef struct{ + // + CPU_INT32U Enable[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutBefore[CHANNELS_NUM]; + // - , . + CPU_INT32U TimeOutAfter[CHANNELS_NUM]; + // , . + CPU_INT32U MaxWorkTime[CHANNELS_NUM]; + // , . + CPU_INT32U MinWorkTime[CHANNELS_NUM]; + // , + CPU_INT32U WeekEnd[CHANNELS_NUM]; + #define WEEKEND_NO 0 + #define WEEKEND_FRIDAY_SUNDAY 1 + #define WEEKEND_SATURDAY_SUNDAY 2 + #define WEEKEND_FRIDAY_SATURDAY 3 + #define WEEKEND_FRIDAY_MONDAY 4 + // + CPU_INT32U Name[CHANNELS_NUM]; + + // + #define PRICE_PERIODS_NUM 4 + CPU_INT32U T_Start_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_Start_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U T_End_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + // + CPU_INT32U Price_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U Price_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM]; + CPU_INT32U PriceTime_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM]; + + + +}TChannelConfig; + + + +// +typedef struct{ + CPU_INT32U EnableValidator; + CPU_INT32U EnableCoinAcceptor; + CPU_INT32U EnableModem; + CPU_INT32U EnableFiscal; + CPU_INT32U EnableFiscalDayClear; + CPU_INT32U ServiceName; + + CPU_INT32U CoinPerPulse; // + CPU_INT32U BillFormat; + + CPU_INT32U DisableFiscalErrors; // + + CPU_INT32U EnableEmailErrorSend; + CPU_INT32U EnableEmailStatSend; + CPU_INT32U EnableEmailJournalSend; + CPU_INT32U ClearJournalAfterSend; + CPU_INT32U StatSendHourMin; + + CPU_INT32U DeviceId; +}TDeviceConfig; + + +extern CPU_INT32U PeriodIndex; +extern CPU_INT32U ChannelIndex; +extern TDataDescStruct const DeviceIDDesc; + +extern TDataDescStruct const LastEmailSendTime; + +extern TDataDescStruct const ChannelIndexDesc; +extern TDataDescStruct const EnableChannelDesc; +extern TDataDescStruct const TimeOutBeforeDesc; +extern TDataDescStruct const TimeOutAfterDesc; +extern TDataDescStruct const MaxWorkTimeDesc; +extern TDataDescStruct const MinWorkTimeDesc; +extern TDataDescStruct const WeekEndDesc; +extern TDataDescStruct const DeferredStartDesc; + +extern TDataDescStruct const PeriodWeekendIndexDesc; +extern TDataDescStruct const PeriodWeekdaysIndexDesc; +extern TDataDescStruct const ServiceNameDesc; +extern TDataDescStruct const PassDesc; +extern TDataDescStruct const PassCRCDesc; +extern TDataDescStruct const PassTempDesc; +extern CPU_INT32U TempPass; +extern TDataDescStruct const PassTempDesc1; +extern TDataDescStruct const PassTempDesc2; + +extern TDataDescStruct const PriceWeekendDesc; +extern TDataDescStruct const PriceWeekdaysDesc; +extern TDataDescStruct const PriceTimeWeekendDesc; +extern TDataDescStruct const PriceTimeWeekdaysDesc; +extern TDataDescStruct const T_Start_WeekdaysDesc; +extern TDataDescStruct const T_End_WeekdaysDesc; +extern TDataDescStruct const T_Start_WeekendDesc; +extern TDataDescStruct const T_End_WeekendDesc; + +extern TDataDescStruct const EnableFiscalDesc; +extern TDataDescStruct const EnableCoinDesc; +extern TDataDescStruct const EnableModemDesc; +extern TDataDescStruct const EnableValidatorDesc; +extern TDataDescStruct const CoinPerPulseDesc; +extern TDataDescStruct const EnableFiscalDayClearDesc; + +extern TDataDescStruct const InitByDefaultDesc; +extern TDataDescStruct const PrintZReportDesc; +extern TDataDescStruct const PrintXReportDesc; + +extern TDataDescStruct const ErrorJournalIndexDesc; +extern TDataDescStruct const EventJournalIndexDesc; +extern TDataDescStruct const JournalEventTimeDesc; + +extern TDataDescStruct const JournalErrorNumberDesc0; +extern TDataDescStruct const JournalErrorNumberDesc1; +extern TDataDescStruct const JournalErrorTimeDesc; +extern TDataDescStruct const ClearJournalCmdDesc; + + +extern TDataDescStruct const SystemTimeDesc; +extern TDataDescStruct const SystemTimeEditDesc; + +extern const TDataDescArrayStruct AllDataArray[]; + +extern CPU_INT32U ErrorJournalIndex; +extern CPU_INT32U EventJournalIndex; + +extern TDataDescStruct const CounterRunDesc; +extern TDataDescStruct const CounterMoneyDesc; +extern TDataDescStruct const CounterTimeDesc; +extern TDataDescStruct const CounterChannelRunDesc; +extern TDataDescStruct const CounterChannelMoneyDesc; +extern TDataDescStruct const CounterChannelTimeDesc; +extern TDataDescStruct const ChannelStIndexDesc; +extern TDataDescStruct const ClearStatCmdDesc; +extern TDataDescStruct const BillFormatDesc; +extern TDataDescStruct const NameChannelDesc; + +extern TDataDescStruct const AcceptedMoneyDesc; +extern TDataDescStruct const AcceptedMoneyCRC16Desc; + +extern TDataDescStruct const DisableFiscalErrorsDesc; + +extern TDataDescStruct const StartButtonNameDesc; + +extern TDataDescStruct const EnableEmailErrorSendDesc; +extern TDataDescStruct const EnableEmailJournalSendDesc; +extern TDataDescStruct const ClearJournalAfterSendDesc; +extern TDataDescStruct const StatSendPeriodDesc; +extern TDataDescStruct const JournalErrorNumberDescEng; +extern TDataDescStruct const SendTestEmailDesc; +extern TDataDescStruct const ModemStatusDesc; + +extern TDataDescStruct const BillnomIndexDesc; +extern TDataDescStruct const BillnomDesc; +extern TDataDescStruct const BillnomCountersDesc; +extern TDataDescStruct const BillCounterDesc; + +extern TDataDescStruct const CounterLongRunDesc; +extern TDataDescStruct const CounterLongMoneyDesc; +extern TDataDescStruct const CounterLongTimeDesc; + +extern TDataDescStruct const MasterPassTempDesc; + +extern TDataDescStruct const CounterChannelRunLongDesc; +extern TDataDescStruct const CounterChannelMoneyLongDesc; +extern TDataDescStruct const CounterChannelTimeLongDesc; +extern TDataDescStruct const ChannelStLongIndexDesc; + +extern TDataDescStruct const StatSendHourMinDesc; +extern TDataDescStruct const IncasSendFlagDesc; +extern TDataDescStruct const IncasMoneyDesc; +extern TDataDescStruct const IncasTimeDesc; + + +#endif //#ifndef _DATADESC_H_ diff --git a/PROJECT/data/fram_map.h b/PROJECT/data/fram_map.h new file mode 100644 index 0000000..b0d6485 --- /dev/null +++ b/PROJECT/data/fram_map.h @@ -0,0 +1,42 @@ +#include "cpu.h" +#include "datadesc.h" +#include "journal.h" + + +typedef struct{ + + CPU_INT32U SerialNum; + + TChannelConfig ChannelConfig; + + TDeviceConfig DeviceConfig; + + // + TCounters Counters; + + // CRC16 + TCountersLong CountersLong; + + CPU_INT32U FRAM_AcceptedMoney; + CPU_INT32U crc_AcceptedMoney; + + // + TErrorRecord ErrorRecords[ERROR_RECORDS_NUM]; + // + TEventRecord EventRecords[EVENT_RECORDS_NUM]; + + CPU_INT32U Pass; + CPU_INT32U crc_Pass; + + CPU_INT32U LastEmailTime; + + CPU_INT32U IncasEmailFlag; + CPU_INT32U IncasMoney; + CPU_INT32U IncasTime; + + CPU_INT32U StartButtonName; + + CPU_INT32U DefferedStartEnabled[CHANNELS_NUM]; + +}TFramMap; + diff --git a/PROJECT/menu/menu.c b/PROJECT/menu/menu.c new file mode 100644 index 0000000..00177b3 --- /dev/null +++ b/PROJECT/menu/menu.c @@ -0,0 +1,654 @@ +#include +#include "menu.h" +#include "menudesc.h" +#include "data.h" +#include "keyboard.h" +#include "lcd.h" +#include "mode.h" +#include "app_serv.h" +#include "time.h" + +OS_STK MenuTaskStk[MENU_TASK_STK_SIZE]; + +#define STACKPANELSIZE 8 +TMenuStack MenuStack[STACKPANELSIZE]; +CPU_INT08U MenuStackPtr; +CPU_INT08U MenuActiveLine, MenuFirstLine, MenuEditStatus; +TMenuPanel* MenuCurrentPanel; + +CPU_INT08U EditPos, EditStart, EditLen, EditLine; +TVariant32 EditVal, EditMax, EditMin; +TDataDescStruct* EditDesc; +TRTC_Data EditTime; +// +const CPU_INT08U EditTimePos[12] = +{ + 0, 1, + 3, 4, + 6, 7, + 9,10, + 12,13, + 15,16 +}; +CPU_INT08U EditBuf[32]; +#define EDIT_TYPE_NUMBER 0 +#define EDIT_TYPE_ITEMS 1 + +CPU_INT08U refresh_menu = 0; + +void ShowMenuLine(TMenuLine* line_ptr, CPU_INT08U pos) +{ + CPU_INT08U strbuf[32]; + + if (line_ptr->LineType == MENU_LINE_STRING) + { + sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr); + LCD_puts(strbuf, pos); + } + else if (line_ptr->LineType == MENU_LINE_SHOW_DESC) + { + strbuf[0] = ' '; + if ((MenuEditStatus) && (pos == EditLine)) + { + // + if (EditDesc->IsIndex) + { + GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]); + strcat((char*)strbuf, "<"); + strcat((char*)strbuf, (char const*)EditBuf); + strcat((char*)strbuf, ">"); + LCD_puts(strbuf, pos); + } + else + { + GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]); + if (EditDesc->Name) strcat((char*)strbuf, "="); + strcat((char*)strbuf, (char const*)EditBuf); + LCD_puts(strbuf, pos); + } + } + else + { + GetDataFullStr((const TDataDescStruct*)line_ptr->Ptr, &strbuf[1], 0, DATA_FLAG_SYSTEM_INDEX); + LCD_puts(strbuf, pos); + } + } + else if (line_ptr->LineType == MENU_LINE_GOTO_MENU) + { + sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr); + LCD_puts(strbuf, pos); + } + + + +} + +void ClearMenuLine(CPU_INT08U pos) +{ + CPU_INT08U c = 0; + LCD_puts(&c, pos); +} + +void ClearDisplay(void) +{ + LCD_clear(); +} + + +TMenuPanel* GetCurrentMenu(void) +{ + return MenuCurrentPanel; +} + +// +void ShowCurrentMenu(void) +{ + // + CPU_INT08U i, j; + TMenuLine* pLine; + //MenuCurrentPanel->LineNum + + // , 4 + if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC) + { + j=0; + LCD_cursor_off(); + for (i=0; iLineArray[i].pMenuLine; + if (pLine == NULL) break; + ShowMenuLine(pLine, j++); + } + while (jLineArray[0].pMenuLine)->Flags) & MENU_INDEX_LINE) + { + LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0); + } + return; + } + + + // + pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine == NULL) {ClearDisplay(); return;} + ShowMenuLine(pLine, 0); + + // 3 + // MenuFirstLine - + if (MenuActiveLine == 0) MenuFirstLine = 0; + else + { + if (MenuCurrentPanel->LineNum < MENU_LINES_NUMBER) MenuFirstLine = MenuActiveLine-1; + else + { + if (MenuActiveLine < MenuCurrentPanel->LineNum-2) MenuFirstLine = MenuActiveLine-1; + else MenuFirstLine = MenuActiveLine-2; + } + } + + i=MenuFirstLine+1; + j=1; + while((jLineNum)) + { + TMenuLine* pline = (TMenuLine*)MenuCurrentPanel->LineArray[i].pMenuLine; + if (pline == NULL) ClearMenuLine(j); + else ShowMenuLine(pline, j); + i++; + j++; + } + + while(jLineArray[MenuActiveLine+1].pMenuLine)->LineType); + if (linetype == MENU_LINE_STRING) + { + LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1); + } + else if (linetype == MENU_LINE_GOTO_MENU) + { + LCD_putc_embed(SYMB_RIGHT_ARROW, 0, MenuActiveLine-MenuFirstLine+1); + } + else if (linetype == MENU_LINE_SHOW_DESC) + { + TMenuLine* mline = ((TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine); + + if (((const TDataDescStruct*)mline->Ptr)->Desc == DATA_DESC_EDIT) + LCD_putc_embed(SYMB_DESC_MARK, 0, MenuActiveLine-MenuFirstLine+1); + else + LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1); + } + + // + CPU_INT08U lineflags = (((TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine)->Flags); + if (lineflags & MENU_INDEX_LINE) + { + LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0); + } + + // () + if ((MenuEditStatus) && (!EditDesc->IsIndex)) + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + LCD_goto(EditStart+EditPos, MenuActiveLine-MenuFirstLine+1); + } + else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN)) + { + LCD_goto(EditStart+EditTimePos[EditPos], MenuActiveLine-MenuFirstLine+1); + } + LCD_cursor_on(); + } + else + { + LCD_cursor_off(); + } +} + +void RefreshMenu(void) +{ + refresh_menu = 1; +} + +// +CPU_INT08U GetFirstActiveLine(TMenuPanel *menu) +{ + CPU_INT08U line = 0; + CPU_INT08U i = 0; + while (i++ < menu->LineNum) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +// +CPU_INT08U GetNextActiveLine(TMenuPanel *menu, CPU_INT08U recent) +{ + CPU_INT08U line = recent+1; + CPU_INT08U i = recent+1; + while (i++ < menu->LineNum) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +// +CPU_INT08U GetPrevActiveLine(TMenuPanel *menu, CPU_INT08U recent) +{ + CPU_INT08U line = recent+1; + CPU_INT08U i = recent+1; + if (recent == 0) return 0; + while (i--) + { + TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine; + if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC)) + { + line = i; + break; + } + } + return line-1; +} + +void GoToMenu(const TMenuPanel* Menu) +{ + if (MenuStackPtr >= STACKPANELSIZE) return; + MenuStack[MenuStackPtr].PrevMenu = MenuCurrentPanel; + MenuStack[MenuStackPtr].PrevActiveLine = MenuActiveLine; + MenuStackPtr++; + + MenuCurrentPanel = (TMenuPanel*)Menu; + MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel); + if (Menu->InitFunc) Menu->InitFunc(); + refresh_menu = 1; +} + +void SetMenu(const TMenuPanel* Menu) +{ + MenuCurrentPanel = (TMenuPanel*)Menu; + MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel); + if (Menu->InitFunc) Menu->InitFunc(); + refresh_menu = 1; +} + +void GoToPreviousMenu(void) +{ + if (!MenuStackPtr) return; + --MenuStackPtr; + MenuCurrentPanel = (TMenuPanel*)MenuStack[MenuStackPtr].PrevMenu; + MenuActiveLine = MenuStack[MenuStackPtr].PrevActiveLine; + if (MenuCurrentPanel->InitFunc) MenuCurrentPanel->InitFunc(); + refresh_menu = 1; +} + +void GoToNextMenu(void) +{ + if ((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr) + GoToMenu((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr); +} + +void MenuSprintf(CPU_INT08U* str, CPU_INT08U len, CPU_INT32U Val) +{ + if (EditDesc->Type == DATA_TYPE_ULONG) + { + CPU_INT08U format[6]; + format[0]='%'; + format[1]='0'; + format[2]='0'+len/10; + format[3]='0'+len%10; + format[4]='u'; + format[5]=0; + sprintf((char*)str, (char const*)format, Val); + } + else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN)) + { + GetDataStr(EditDesc, str, 0, DATA_FLAG_SYSTEM_INDEX); + } +} + +// +void EnterEdit(void) +{ + // , 0 - + EditPos = 0; + // + EditDesc = (TDataDescStruct*)(MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->Ptr; + // + EditLine = MenuActiveLine+1-MenuFirstLine; + // + GetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX); + // + TRangeValueULONG* RVal = EditDesc->RangeValue; + memcpy(&EditMin, &RVal->Min, sizeof(CPU_INT32U)); + memcpy(&EditMax, &RVal->Max, sizeof(CPU_INT32U)); + + if (EditDesc->IsIndex) + { + GetDataStr((const TDataDescStruct*)EditDesc, EditBuf, 0, DATA_FLAG_SYSTEM_INDEX); + } + else + { + GetDataNameStr((const TDataDescStruct*)EditDesc, EditBuf); + if (EditDesc->Name) strcat((char*)EditBuf, "="); + EditStart = strlen((char const*)EditBuf)+1; + if (EditDesc->Type == DATA_TYPE_ULONG) + { + sprintf((char*)EditBuf, "%u", RVal->Max); + EditLen = strlen((char const*)EditBuf); + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditLen = 12; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditLen = 4; + } + else + { + EditLen = 0; + } + MenuSprintf(EditBuf, EditLen, EditVal.Val32U); + } + + MenuEditStatus = 1; +} + +// +void EscEdit(void) +{ + MenuEditStatus = 0; +} + +// +void SaveEdit(void) +{ + if (EditDesc->Type == DATA_TYPE_ULONG) + { + if (!EditDesc->IsIndex) + { + sscanf((char const*)EditBuf, "%d", &EditVal.Val32U); + } + SetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX); + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + TRTC_Data rtc; + ScanRTCDateTimeStringRus((char*)EditBuf, &rtc); + if (RTCCheckTime(&rtc) == 0) + { // + CPU_INT32U time; + time = GetSec(&rtc); + SetData(EditDesc, &time, 0, DATA_FLAG_SYSTEM_INDEX); + } + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + int hour, min, hour_min; + sscanf((char*)EditBuf, "%02d:%02d", &hour, &min); + hour_min = hour * 60 + min; + SetData(EditDesc, &hour_min, 0, DATA_FLAG_SYSTEM_INDEX); + } + MenuEditStatus = 0; +} + + +void MenuTask(void *p_arg) +{ + int pause = 0; + + SetMenu(START_MENU); + + while (1) + { + int key=0; + if (GetKbrdEvent(&key) || (++pause >= 1000) || ((pause >= 500) && (MenuEditStatus)) || (refresh_menu != 0)) + { + if (refresh_menu) {refresh_menu = 0; ShowCurrentMenu();} + // + if (!MenuEditStatus) + { // + pause = 0; + if (key) + { + switch (key){ + + case KEY_UP: + //if (MenuActiveLine) MenuActiveLine--; + MenuActiveLine = GetPrevActiveLine(MenuCurrentPanel, MenuActiveLine); + ShowCurrentMenu(); + break; + + case KEY_DOWN: + //MenuActiveLine++; + //if (MenuActiveLine+1 >= MenuCurrentPanel->LineNum) MenuActiveLine--; + MenuActiveLine = GetNextActiveLine(MenuCurrentPanel, MenuActiveLine); + ShowCurrentMenu(); + break; + + case KEY_LEFT: + { + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine->Flags & MENU_INDEX_LINE) + {// - + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Type == DATA_TYPE_ULONG) + { + CPU_INT32U i, min, max; + GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + GetDataMin(desc, &min); + GetDataMax(desc, &max); + i--; + if ((i < min) || (i > max)) i = max; + SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + } + ShowCurrentMenu(); + } + } + break; + + case KEY_RIGHT: + { + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine; + if (pLine->Flags & MENU_INDEX_LINE) + {// - + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Type == DATA_TYPE_ULONG) + { + CPU_INT32U i, min, max; + GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + GetDataMin(desc, &min); + GetDataMax(desc, &max); + i++; + if ((i < min) || (i > max)) i = min; + SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX); + } + ShowCurrentMenu(); + } + } + break; + + case KEY_STOP: + // + GoToPreviousMenu(); + break; + + case KEY_START: + { + if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC) {ShowCurrentMenu();break;} + TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine; + if (pLine->LineType == MENU_LINE_SHOW_DESC) + {// , + TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr; + if (desc->Desc == DATA_DESC_EDIT) {EnterEdit(); pause=1000;} + } + else if (pLine->LineType == MENU_LINE_GOTO_MENU) + {// + GoToNextMenu(); + } + } + break; + }//switch (key) + }//if (key) + else + { + ShowCurrentMenu(); + } + } + else//if (!MenuEditStatus) + { // + if (key) + { + switch (key){ + case KEY_UP: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U++; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + EditBuf[EditPos]++; + if (EditBuf[EditPos] > '9') EditBuf[EditPos] = '0'; + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditBuf[EditTimePos[EditPos]]++; + if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0'; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditBuf[EditTimePos[EditPos]]++; + if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0'; + } + } + break; + case KEY_DOWN: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U--; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditDesc->Type == DATA_TYPE_ULONG) + { + EditBuf[EditPos]--; + if (EditBuf[EditPos] < '0') EditBuf[EditPos] = '9'; + } + else if (EditDesc->Type == DATA_TYPE_TIME) + { + EditBuf[EditTimePos[EditPos]]--; + if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9'; + } + else if (EditDesc->Type == DATA_TYPE_HOUR_MIN) + { + EditBuf[EditTimePos[EditPos]]--; + if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9'; + } + } + break; + case KEY_LEFT: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U--; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditPos) EditPos--; + } + break; + case KEY_RIGHT: + if (EditDesc->IsIndex) + { + CPU_INT32U min, max; + GetDataMin(EditDesc, &min); + GetDataMax(EditDesc, &max); + EditVal.Val32U++; + if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min; + GetDataItem(EditDesc, EditBuf, EditVal.Val32U); + } + else + { + if (EditPos < EditLen-1) EditPos++; + } + break; + case KEY_STOP: + EscEdit(); + break; + case KEY_START: + SaveEdit(); + break; + }//switch (key) + + ShowCurrentMenu(); + }//if (key) + else + { + pause = 0; + ShowCurrentMenu(); + } + }//if (!MenuEditStatus) + + } + } +} + + + +void InitMenu(void) +{ + + MenuStackPtr = 0; + MenuActiveLine = 0; + MenuFirstLine = 0; + MenuEditStatus = 0; + MenuCurrentPanel = NULL; + + memset(&MenuStack, 0, sizeof(TMenuStack)*STACKPANELSIZE); + + OSTaskCreate(MenuTask, (void *)0, (OS_STK *)&MenuTaskStk[MENU_TASK_STK_SIZE-1], MENU_TASK_PRIO); +} + + +void ReInitMenu(void) +{ + OSTaskDel(MENU_TASK_PRIO); + ClearDisplay(); + OSTimeDly(100); + InitMenu(); + OSTimeDly(100); + if (GetMode() == MODE_WORK) SetMenu(WORK_MENU); + else SetMenu(SERVICE_MENU); +} + diff --git a/PROJECT/menu/menu.h b/PROJECT/menu/menu.h new file mode 100644 index 0000000..8d95b86 --- /dev/null +++ b/PROJECT/menu/menu.h @@ -0,0 +1,99 @@ +#ifndef _MENU_H_ +#define _MENU_H_ + +#include "cpu.h" + +#define MENU_LINES_NUMBER 4 +#define MENU_SYMB_NUMBER 20 + + +// +#define SYMB_GO_UP 0x87 +#define SYMB_GO_DOWN 0x86 + +#define SYMB_RIGHT_ARROW 0x13 +#define SYMB_DESC_MARK 0x84 +#define SYMB_IND_MARK 0x85 +#define SYMB_POINT_MARK 0xDF + + + +// +typedef struct{ + + // + CPU_INT08U LineType; + #define MENU_LINE_STRING 0 // + #define MENU_LINE_GOTO_MENU 1 // + #define MENU_LINE_SHOW_DESC 2 // + #define MENU_LINE_INDEX 3 // + + // . + CPU_INT08U Flags; + #define MENU_FIXED_LINE 0x01 // + #define MENU_INDEX_LINE 0x02 // + + // + void* Ptr; + + // + void* GoToPtr; + +}TMenuLine; + + +// +typedef struct{ + const TMenuLine* pMenuLine; +}TMenuLineArray; + + +// +typedef struct{ + + // + const TMenuLineArray* LineArray; + + // , + void (*InitFunc)(void); + + // + CPU_INT08U LineNum; + + // + CPU_INT08U PanelType; + #define MENU_PANEL_STANDARD 0 // , + #define MENU_PANEL_STATIC 1 // + +}TMenuPanel; + + +// +typedef struct{ + + // + const TMenuPanel* PrevMenu; + // + CPU_INT08U PrevActiveLine; + +}TMenuStack; + + +/////////////////////////////////// +// +/////////////////////////////////// +// +extern void InitMenu(void); +// +extern void GoToMenu(const TMenuPanel* Menu); +extern void SetMenu(const TMenuPanel* Menu); +// +extern void GoToPreviousMenu(void); +// +extern void ReInitMenu(void); + +extern void MenuSprintf(CPU_INT08U* str, CPU_INT08U len, CPU_INT32U Val); +extern TMenuPanel* GetCurrentMenu(void); +extern void RefreshMenu(void); + +#endif //#ifndef _MENU_H_ diff --git a/PROJECT/menu/menudesc.c b/PROJECT/menu/menudesc.c new file mode 100644 index 0000000..8302ae0 --- /dev/null +++ b/PROJECT/menu/menudesc.c @@ -0,0 +1,1814 @@ +#include +#include "app_serv.h" +#include "menu.h" +#include "menudesc.h" +#include "data.h" +#include "datadesc.h" +#include "control.h" +#include "journal.h" +#include "time.h" +#include "mode.h" +#include "version.h" + +char FlagForPrintReport=0; + +/*********************************** + - +***********************************/ +const CPU_INT08U str_StartMenu_0[] = "-------------------"; +const CPU_INT08U str_StartMenu_1[] = " "; +const CPU_INT08U str_StartMenu_2[] = " !"; +const CPU_INT08U str_StartMenu_3[] = "-------------------"; + +const TMenuLine line_StartMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_0, // + NULL // +}; + +const TMenuLine line_StartMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_1, // + NULL // +}; + +const TMenuLine line_StartMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_2, // + NULL // +}; + +const TMenuLine line_StartMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StartMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_StartMenuArray[] = {&line_StartMenu_0, &line_StartMenu_1, &line_StartMenu_2, &line_StartMenu_3, NULL}; +const TMenuPanel StartMenuPanel[] = {arr_StartMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_IncasMenu_0[] = "-------------------"; +const CPU_INT08U str_IncasMenu_1[] = " "; +const CPU_INT08U str_IncasMenu_2[] = " "; +CPU_INT08U str_IncasMenu_3[32]; + +const TMenuLine line_IncasMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_0, // + NULL // +}; + +const TMenuLine line_IncasMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_1, // + NULL // +}; + +const TMenuLine line_IncasMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_2, // + NULL // +}; + +const TMenuLine line_IncasMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_IncasMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_IncasMenuArray[] = {&line_IncasMenu_0, &line_IncasMenu_1, &line_IncasMenu_2, &line_IncasMenu_3, NULL}; +const TMenuPanel IncasMenuPanel[] = {arr_IncasMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalEmptyMenu_0[] = ""; +const CPU_INT08U str_JournalEmptyMenu_1[] = " "; +const CPU_INT08U str_JournalEmptyMenu_2[] = " "; +const CPU_INT08U str_JournalEmptyMenu_3[] = ""; + +const TMenuLine line_JournalEmptyMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_0, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_1, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_2, // + NULL // +}; + +const TMenuLine line_JournalEmptyMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalEmptyMenu_3, // + NULL // +}; + + +const TMenuLineArray arr_JournalEmptyMenuArray[] = {&line_JournalEmptyMenu_0, &line_JournalEmptyMenu_1, &line_JournalEmptyMenu_2, &line_JournalEmptyMenu_3, NULL}; +const TMenuPanel JournalEmptyMenuPanel[] = {arr_JournalEmptyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_ServiceMenu_0[] = " . "DEVICE_FW_VERSION; +const CPU_INT08U str_ServiceMenu_1[] = ""; +const CPU_INT08U str_ServiceMenu_2[] = ""; +const CPU_INT08U str_ServiceMenu_3[] = ""; +const CPU_INT08U str_ServiceMenu_4[] = ""; + +const TMenuLine line_ServiceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ServiceMenu_0, // + NULL // +}; + +const TMenuLine line_ServiceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_1, // + (void*)&SettingsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_2, // + (void*)&StatisticsMenuPanel // +}; + +const TMenuLine line_ServiceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_3, // + (void*)&SelectJournalMenuPanel // +}; + +const TMenuLine line_ServiceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ServiceMenu_4, // + (void*)&ReportMenuPanel // +}; + +const TMenuLineArray arr_ServiceMenuArray[] = {&line_ServiceMenu_0, &line_ServiceMenu_1, &line_ServiceMenu_2, &line_ServiceMenu_3, &line_ServiceMenu_4, NULL}; +const TMenuPanel ServiceMenuPanel[] = {arr_ServiceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_StatisticsMenu_0[] = " "; +const CPU_INT08U str_StatisticsMenu_1[] = " "; +const CPU_INT08U str_StatisticsMenu_2[] = ""; +const CPU_INT08U str_StatisticsMenu_3[] = " "; +const CPU_INT08U str_StatisticsMenu_4[] = " "; + + +const TMenuLine line_StatisticsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_StatisticsMenu_0, // + NULL // +}; + +const TMenuLine line_StatisticsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_1, // + (void*)ChanStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_2, // + (void*)CommStatMenuPanel // +}; + +const TMenuLine line_StatisticsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_3, // + (void*)BillCountersPanel // +}; + +const TMenuLine line_StatisticsMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_StatisticsMenu_4, // + (void*)ClearStatMenu // +}; + +const TMenuLineArray arr_StatisticsMenuArray[] = {&line_StatisticsMenu_0, &line_StatisticsMenu_1, &line_StatisticsMenu_2, &line_StatisticsMenu_3, &line_StatisticsMenu_4, NULL}; +const TMenuPanel StatisticsMenuPanel[] = {arr_StatisticsMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearStatMenu_0[] = " "; +const char str_ClearStatMenu_1[] = " "; + +void OnEnterPanelClearStat(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_0, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearStatMenu_1, // + NULL // +}; + +const TMenuLine line_ClearStatMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearStatMenuArray[] = {&line_ClearStatMenu_0, &line_ClearStatMenu_1, &line_ClearStatMenu_2, NULL}; +const TMenuPanel ClearStatMenu[] = {arr_ClearStatMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_ClearJournalMenu_0[] = " "; +const char str_ClearJournalMenu_1[] = " "; + +void OnEnterPanelClearJournal(void) +{ + TempPass = 0; +} + +const TMenuLine line_ClearJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_0, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ClearJournalMenu_1, // + NULL // +}; + +const TMenuLine line_ClearJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc2, // + NULL // +}; + +const TMenuLineArray arr_ClearJournalMenuArray[] = {&line_ClearJournalMenu_0, &line_ClearJournalMenu_1, &line_ClearJournalMenu_2, NULL}; +const TMenuPanel ClearJournalMenuPanel[] = {arr_ClearJournalMenuArray, OnEnterPanelClearStat, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersArray[] = {&line_ChannelCountersMenu_0, &line_ChannelCountersMenu_1, &line_ChannelCountersMenu_2, &line_ChannelCountersMenu_3, NULL}; +const TMenuPanel ChannelCountersPanel[] = {arr_ChannelCountersArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_BillCountersMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&BillnomIndexDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillnomCountersDesc, // + NULL // +}; + +const TMenuLine line_BillCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&BillCounterDesc, // + NULL // +}; + +extern CPU_INT32U BillnomViewIndex; + +void OnEnterBillCountersMenu() +{ + BillnomViewIndex = 0; +} + +const TMenuLineArray arr_BillCountersArray[] = {&line_BillCountersMenu_0, &line_BillCountersMenu_1, &line_BillCountersMenu_2, &line_BillCountersMenu_3, NULL}; +const TMenuPanel BillCountersPanel[] = {arr_BillCountersArray, OnEnterBillCountersMenu, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersMenu_0[] = " "; + +const TMenuLine line_CommonCountersMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersArray[] = {&line_CommonCountersMenu_0, &line_CommonCountersMenu_1, &line_CommonCountersMenu_2, &line_CommonCountersMenu_3, NULL}; +const TMenuPanel CommonCountersPanel[] = {arr_CommonCountersArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonCountersLongMenu_0[] = " "; + +const TMenuLine line_CommonCountersLongMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)&str_CommonCountersLongMenu_0, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongRunDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongMoneyDesc, // + NULL // +}; + +const TMenuLine line_CommonCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterLongTimeDesc, // + NULL // +}; + +const TMenuLineArray arr_CommonCountersLongArray[] = {&line_CommonCountersLongMenu_0, &line_CommonCountersLongMenu_1, &line_CommonCountersLongMenu_2, &line_CommonCountersLongMenu_3, NULL}; +const TMenuPanel CommonCountersLongPanel[] = {arr_CommonCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_SettingsMenu_0[] = " "; +const CPU_INT08U str_SettingsMenu_1[] = ""; +const CPU_INT08U str_SettingsMenu_2[] = ""; +const CPU_INT08U str_SettingsMenu_3[] = " "; +const CPU_INT08U str_SettingsMenu_4[] = " "; +const CPU_INT08U str_SettingsMenu_5[] = " "; + +const TMenuLine line_SettingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SettingsMenu_0, // + NULL // +}; + +const TMenuLine line_SettingsMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_1, // + (void*)&ChannelMenuPanel // +}; + +const TMenuLine line_SettingsMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_2, // + (void*)&DeviceMenuPanel // +}; + +const TMenuLine line_SettingsMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_3, // + (void*)&SetPassMenuPanel // +}; + +const TMenuLine line_SettingsMenu_5 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_4, // + (void*)&TimeSetupMenuPanel // +}; + +const TMenuLine line_SettingsMenu_6 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SettingsMenu_5, // + (void*)&ResetSettingsMenuPanel // +}; + +const TMenuLine line_SettingsMenu_7 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&StartButtonNameDesc, // + NULL // +}; + +const TMenuLineArray arr_SettingsMenuArray[] = {&line_SettingsMenu_0, &line_SettingsMenu_1, &line_SettingsMenu_2, &line_SettingsMenu_5, &line_SettingsMenu_3, &line_SettingsMenu_6, &line_SettingsMenu_7, NULL}; +const TMenuPanel SettingsMenuPanel[] = {arr_SettingsMenuArray, NULL, 7, MENU_PANEL_STANDARD}; + + + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&NameChannelDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutBeforeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&TimeOutAfterDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MinWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MaxWorkTimeDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_7 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&WeekEndDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_8 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&DeferredStartDesc, // + NULL // +}; + +const TMenuLine line_ChannelMenu_9 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekdaysMenuPanel // +}; + +const TMenuLine line_ChannelMenu_10 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " ", // + (void*)PriceWeekendMenuPanel // +}; + +const TMenuLineArray arr_ChannelMenuArray[] = {&line_ChannelMenu_0, + &line_ChannelMenu_1, + &line_ChannelMenu_2, + &line_ChannelMenu_3, + &line_ChannelMenu_4, + &line_ChannelMenu_5, + &line_ChannelMenu_6, + &line_ChannelMenu_7, + &line_ChannelMenu_8, + &line_ChannelMenu_9, + &line_ChannelMenu_10, + NULL}; +char flag_enter_periods=0; + +void OnEnterChannelSettingsMenu(void) +{ + if (!flag_enter_periods) + { + ChannelIndex = 0; + } + else + { + flag_enter_periods = 0; + } +} + +const TMenuPanel ChannelMenuPanel[] = {arr_ChannelMenuArray, OnEnterChannelSettingsMenu, 11, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +void OnEnterPanelPrice(void) +{ + PeriodIndex = ChannelIndex*PRICE_PERIODS_NUM; + flag_enter_periods = 1; +} + +const TMenuLine line_PriceMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekdaysIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekdaysDesc, // + NULL // +}; + +const TMenuLine line_PriceMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekdaysDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArray[] = {&line_PriceMenu_0, &line_PriceMenu_1, &line_PriceMenu_2, &line_PriceMenu_3, &line_PriceMenu_4, NULL}; +const TMenuPanel PriceWeekdaysMenuPanel[] = {arr_PriceMenuArray, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const char str_SetPassMenu_0[] = " "; + +void OnEnterPanelSetPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_SetPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc, // + NULL // +}; + +const TMenuLine line_SetPassMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + " -", // + (void*)MasterPassMenuPanel // +}; + +const TMenuLineArray arr_SetPassMenuArray[] = {&line_SetPassMenu_0, &line_SetPassMenu_1, &line_SetPassMenu_2, NULL}; +const TMenuPanel SetPassMenuPanel[] = {arr_SetPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + - +***********************************/ +const char str_MasterPassMenu_0[] = " -"; + +void OnEnterPanelMasterPass(void) +{ + TempPass = 0; +} + +const TMenuLine line_MasterPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_MasterPassMenu_0, // + NULL // +}; + +const TMenuLine line_MasterPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&MasterPassTempDesc, // + NULL // +}; + +const TMenuLineArray arr_MasterPassMenuArray[] = {&line_MasterPassMenu_0, &line_MasterPassMenu_1, NULL}; +const TMenuPanel MasterPassMenuPanel[] = {arr_MasterPassMenuArray, OnEnterPanelSetPass, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_ResetSetingsMenu_0[] = " "; +const char str_ResetSetingsMenu_1[] = " "; + +void OnEnterPanelResetSetings(void) +{ + TempPass = 0; +} + +const TMenuLine line_ResetSetingsMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_0, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ResetSetingsMenu_1, // + NULL // +}; + +const TMenuLine line_ResetSetingsMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassTempDesc1, // + NULL // +}; + +const TMenuLineArray arr_ResetSettingsMenuArray[] = {&line_ResetSetingsMenu_0, &line_ResetSetingsMenu_1, &line_ResetSetingsMenu_2, NULL}; +const TMenuPanel ResetSettingsMenuPanel[] = {arr_ResetSettingsMenuArray, OnEnterPanelResetSetings, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const char str_SetNewPassMenu_0[] = " "; + +const TMenuLine line_SetNewPassMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SetNewPassMenu_0, // + NULL // +}; + +const TMenuLine line_SetNewPassMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PassDesc, // + NULL // +}; + +const TMenuLineArray arr_SetNewPassMenuArray[] = {&line_SetNewPassMenu_0, &line_SetNewPassMenu_1, NULL}; +const TMenuPanel SetNewPassMenuPanel[] = {arr_SetNewPassMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_PriceMenuWend_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&PeriodWeekendIndexDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_Start_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&T_End_WeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceWeekendDesc, // + NULL // +}; + +const TMenuLine line_PriceMenuWend_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&PriceTimeWeekendDesc, // + NULL // +}; + +const TMenuLineArray arr_PriceMenuArrayWend[] = {&line_PriceMenuWend_0, &line_PriceMenuWend_1, &line_PriceMenuWend_2, &line_PriceMenuWend_3, &line_PriceMenuWend_4, NULL}; +const TMenuPanel PriceWeekendMenuPanel[] = {arr_PriceMenuArrayWend, OnEnterPanelPrice, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_DeviceMenu_0[] = " "; +const CPU_INT08U str_DeviceMenu_1[] = ""; +const CPU_INT08U str_DeviceMenu_2[] = ""; +const CPU_INT08U str_DeviceMenu_3[] = ""; + +const TMenuLine line_DeviceMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_DeviceMenu_0, // + NULL // +}; + +const TMenuLine line_DeviceMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_1, // + (void*)&FrMenuPanel // +}; + +const TMenuLine line_DeviceMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableValidatorDesc, // + NULL // +}; + +const TMenuLine line_DeviceMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_2, // + (void*)&CoinSetupPanel // +}; + +const TMenuLine line_DeviceMenu_4 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_DeviceMenu_3, // + (void*)&ModemSetupPanel // +}; + +const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, &line_DeviceMenu_1, &line_DeviceMenu_2, &line_DeviceMenu_3, &line_DeviceMenu_4, NULL}; +const TMenuPanel DeviceMenuPanel[] = {arr_DeviceMenuArray, NULL, 5, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrMenu_0[] = " "; + +const TMenuLine line_FrMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrMenu_0, // + NULL // +}; + +const TMenuLine line_FrMenu_1 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&EnableFiscalDesc, + NULL +}; + +const TMenuLine line_FrMenu_2 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&EnableFiscalDayClearDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_3 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&BillFormatDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_4 = { + MENU_LINE_SHOW_DESC, // ??? ?????? ???? + 0, // ???. ????? + (void*)&ServiceNameDesc, // ????????? ?? ????????? ?????? ??? ?????????? + NULL // ?????? ??? ???????? +}; + +const TMenuLine line_FrMenu_5 = { + MENU_LINE_SHOW_DESC, + 0, + (void*)&DisableFiscalErrorsDesc, + NULL +}; + +const TMenuLineArray arr_FrMenuArray[] = {&line_FrMenu_0, &line_FrMenu_1, &line_FrMenu_2, &line_FrMenu_3, &line_FrMenu_4, &line_FrMenu_5, NULL}; +const TMenuPanel FrMenuPanel[] = {arr_FrMenuArray, NULL, 6, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_CoinMenu_0[] = " ."; + +const TMenuLine line_CoinMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CoinMenu_0, // + NULL // +}; + +const TMenuLine line_CoinMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableCoinDesc, // + NULL // +}; + +const TMenuLine line_CoinMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CoinPerPulseDesc, // + NULL // +}; + +const TMenuLineArray arr_CoinMenuArray[] = {&line_CoinMenu_0, &line_CoinMenu_1, &line_CoinMenu_2, NULL}; +const TMenuPanel CoinSetupPanel[] = {arr_CoinMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ModemMenu_0[] = " "; + +const TMenuLine line_ModemMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ModemMenu_0, // + NULL // +}; + +const TMenuLine line_ModemMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableModemDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&ModemStatusDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&StatSendHourMinDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_4 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&EnableEmailJournalSendDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_5 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&DeviceIDDesc, // + NULL // +}; + +const TMenuLine line_ModemMenu_6 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SendTestEmailDesc, // + NULL // +}; + + +const TMenuLineArray arr_ModemMenuArray[] = {&line_ModemMenu_0, &line_ModemMenu_1, &line_ModemMenu_2, &line_ModemMenu_3, &line_ModemMenu_4, &line_ModemMenu_5, &line_ModemMenu_6, NULL}; +const TMenuPanel ModemSetupPanel[] = {arr_ModemMenuArray, NULL, 7, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ + +char str_UserMenu_0[22] = ""; +char str_UserMenu_1[22] = ""; +char str_UserMenu_2[22] = ""; +char str_UserMenu_3[22] = ""; + +char str_buf[22]; + + +void PrintUserMenuStr(char* str, CPU_INT08U n) +{ + char *strptr; + char *instr; + // + + switch (n) + { + case 0: + strptr = str_UserMenu_0; + break; + case 1: + strptr = str_UserMenu_1; + break; + case 2: + strptr = str_UserMenu_2; + break; + case 3: + strptr = str_UserMenu_3; + break; + default: + return; + } + + // , + instr = str; + while (*instr==0x20) instr++; + + memset(strptr, 0x20, 20); + + int len = strlen(instr); + if ((len >= 20) || ((10-len/2-1) < 0)) {strcpy(strptr, instr); return;} + + strcpy(&strptr[10-len/2-1], instr); +} + +const TMenuLine line_FirstMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_0, // + NULL // +}; + +const TMenuLine line_FirstMenu_1 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_1, // + NULL // +}; + +const TMenuLine line_FirstMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_2, // + NULL // +}; + +const TMenuLine line_FirstMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_UserMenu_3, // + NULL // +}; + + +const TMenuLineArray FirstMenuArray[] = {&line_FirstMenu_0, &line_FirstMenu_1, &line_FirstMenu_2, &line_FirstMenu_3, NULL}; +const TMenuPanel FirstMenuPanel[] = {FirstMenuArray, InitUserMenu, 4, MENU_PANEL_STATIC}; + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_ErrPass_0[] = " "; +const CPU_INT08U str_ErrPass_1[] = " "; +const CPU_INT08U str_ErrPass_2[] = ""; + +const TMenuLine line_ErrPassMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_0, // + NULL // +}; + +const TMenuLine line_ErrPassMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_1, // + NULL // +}; +const TMenuLine line_ErrPassMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_ErrPass_2, // + NULL // +}; + +const TMenuLineArray ErrPassMenuArray[] = {&line_ErrPassMenu_2, &line_ErrPassMenu_0, &line_ErrPassMenu_1, &line_ErrPassMenu_2, NULL}; +const TMenuPanel ErrorPassPanel[] = {ErrPassMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_SettingsIsResetPass_0[] = " "; +const CPU_INT08U str_SettingsIsResetPass_1[] = " "; +const CPU_INT08U str_SettingsIsResetPass_2[] = " "; +const CPU_INT08U str_SettingsIsResetPass_3[] = " "; + +const TMenuLine line__SettingsIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_0, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_1, // + NULL // +}; +const TMenuLine line__SettingsIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_2, // + NULL // +}; + +const TMenuLine line__SettingsIsResetMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_SettingsIsResetPass_3, // + NULL // +}; + +const TMenuLineArray SettingsIsResetMenuArray[] = {&line__SettingsIsResetMenu_0, &line__SettingsIsResetMenu_1, &line__SettingsIsResetMenu_2, &line__SettingsIsResetMenu_3, NULL}; +const TMenuPanel SettingsIsReset[] = {SettingsIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_StatIsResetPass_0[] = " "; +const CPU_INT08U str_StatIsResetPass_1[] = " "; +const CPU_INT08U str_StatIsResetPass_2[] = ""; + +const TMenuLine line__StatIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_0, // + NULL // +}; + +const TMenuLine line__StatIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_1, // + NULL // +}; +const TMenuLine line__StatIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_StatIsResetPass_2, // + NULL // +}; + +const TMenuLineArray StatIsResetMenuArray[] = {&line__StatIsResetMenu_2, &line__StatIsResetMenu_0, &line__StatIsResetMenu_1, &line__StatIsResetMenu_2, NULL}; +const TMenuPanel StatIsReset[] = {StatIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + " " +***********************************/ +const CPU_INT08U str_JournalIsResetPass_0[] = " "; +const CPU_INT08U str_JournalIsResetPass_1[] = " "; +const CPU_INT08U str_JournalIsResetPass_2[] = ""; + +const TMenuLine line__JournalIsResetMenu_0 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_0, // + NULL // +}; + +const TMenuLine line__JournalIsResetMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_1, // + NULL // +}; +const TMenuLine line__JournalIsResetMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_JournalIsResetPass_2, // + NULL // +}; + +const TMenuLineArray JournalIsResetMenuArray[] = {&line__JournalIsResetMenu_2, &line__JournalIsResetMenu_0, &line__JournalIsResetMenu_1, &line__JournalIsResetMenu_2, NULL}; +const TMenuPanel JournalIsReset[] = {JournalIsResetMenuArray, NULL, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ + +const CPU_INT08U str_GetMoney_0[] = " "; + +const TMenuLine line_GetMoneyMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_1 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE, // . + (void*)&AcceptedMoneyDesc, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_2 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + +const TMenuLine line_GetMoneyMenu_3 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_GetMoney_0, // + NULL // +}; + + +const TMenuLineArray GetMoneyMenuArray[] = {&line_GetMoneyMenu_0, &line_GetMoneyMenu_1, &line_GetMoneyMenu_2, &line_GetMoneyMenu_3, NULL}; +const TMenuPanel GetMoneyMenuPanel[] = {GetMoneyMenuArray, NULL, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_SelectJournalMenu_0[] = " "; +const CPU_INT08U str_SelectJournalMenu_1[] = " "; +const CPU_INT08U str_SelectJournalMenu_2[] = " "; +const CPU_INT08U str_SelectJournalMenu_3[] = " "; + +const TMenuLine line_SelectJournalMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_SelectJournalMenu_0, // + NULL // +}; + +const TMenuLine line_SelectJournalMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_1, // + (void*)&ErrorJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_2, // + (void*)&EventJournalMenuPanel // +}; + +const TMenuLine line_SelectJournalMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_SelectJournalMenu_3, // + (void*)&ClearJournalMenuPanel // +}; + +const TMenuLineArray arr_SelectJournalMenuArray[] = {&line_SelectJournalMenu_0, &line_SelectJournalMenu_1, &line_SelectJournalMenu_2, &line_SelectJournalMenu_3, NULL}; +const TMenuPanel SelectJournalMenuPanel[] = {arr_SelectJournalMenuArray, NULL, 4, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_ReportMenu_0[] = " "; +const CPU_INT08U str_ReportMenu_1[] = "X-"; +const CPU_INT08U str_ReportMenu_2[] = "Z-"; +const CPU_INT08U str_ReportMenu_3[] = "Z- "; + +const TMenuLine line_ReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ReportMenu_0, // + NULL // +}; + +const TMenuLine line_ReportMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_1, // + (void*)&xReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_2, // + (void*)&zReportMenuPanel // +}; + +const TMenuLine line_ReportMenu_3 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_ReportMenu_3, // + (void*)&bufReportMenuPanel // +}; + + +void OnEnterReportsPanel(void) +{ + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (!enable) + { + GoToPreviousMenu(); + GoToMenu(FrIsOffMenuPanel); + } + FlagForPrintReport = 0; +} + +const TMenuLineArray arr_ReportMenuArray[] = {&line_ReportMenu_0, &line_ReportMenu_1, &line_ReportMenu_2, &line_ReportMenu_3, NULL}; +const TMenuPanel ReportMenuPanel[] = {arr_ReportMenuArray, OnEnterReportsPanel, 4, MENU_PANEL_STANDARD}; + +/*********************************** + X- +***********************************/ +const CPU_INT08U str_xReportMenu_0[] = " X-"; +const CPU_INT08U str_xReportMenu_1[] = " "; +const CPU_INT08U str_xReportMenu_2[] = " ?"; +const CPU_INT08U str_xReportMenu_3[] = "-START STOP-"; + +const TMenuLine line_xReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_xReportMenu_0, // + NULL // +}; + +const TMenuLine line_xReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_1, // + NULL // +}; + +const TMenuLine line_xReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_2, // + NULL // +}; + +const TMenuLine line_xReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +void OnEnterZXReportPanel(void) +{ + OSTimeDly(20); + FlagForPrintReport = 1; +} + +const TMenuLineArray arr_xReportMenuArray[] = {&line_xReportMenu_0, &line_xReportMenu_1, &line_xReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel xReportMenuPanel[] = {arr_xReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_zReportMenu_0[] = " Z-"; +const CPU_INT08U str_zReportMenu_1[] = " "; +const CPU_INT08U str_zReportMenu_2[] = " ?"; + +const TMenuLine line_zReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_zReportMenu_0, // + NULL // +}; + +const TMenuLine line_zReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_1, // + NULL // +}; + +const TMenuLine line_zReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_zReportMenu_2, // + NULL // +}; + +const TMenuLine line_zReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_zReportMenuArray[] = {&line_zReportMenu_0, &line_zReportMenu_1, &line_zReportMenu_2, &line_zReportMenu_3, NULL}; +const TMenuPanel zReportMenuPanel[] = {arr_zReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + + +/*********************************** + Z- +***********************************/ +const CPU_INT08U str_bufReportMenu_0[] = " Z- "; +const CPU_INT08U str_bufReportMenu_1[] = " "; +const CPU_INT08U str_bufReportMenu_2[] = " ?"; + +const TMenuLine line_bufReportMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_bufReportMenu_0, // + NULL // +}; + +const TMenuLine line_bufReportMenu_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_1, // + NULL // +}; + +const TMenuLine line_bufReportMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_bufReportMenu_2, // + NULL // +}; + +const TMenuLine line_bufReportMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_xReportMenu_3, // + NULL // +}; + +const TMenuLineArray arr_bufReportMenuArray[] = {&line_bufReportMenu_0, &line_bufReportMenu_1, &line_bufReportMenu_2, &line_xReportMenu_3, NULL}; +const TMenuPanel bufReportMenuPanel[] = {arr_bufReportMenuArray, OnEnterZXReportPanel, 4, MENU_PANEL_STATIC}; + +/*********************************** + +***********************************/ +const CPU_INT08U str_FrIsOff_0[] = ""; +const CPU_INT08U str_FrIsOff_1[] = " "; +const CPU_INT08U str_FrIsOff_2[] = " "; + +const TMenuLine line_FrIsOff_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_FrIsOff_0, // + NULL // +}; + +const TMenuLine line_FrIsOff_1 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_1, // + NULL // +}; + +const TMenuLine line_FrIsOff_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_FrIsOff_2, // + NULL // +}; + +const TMenuLineArray arr_FrIsOffMenuArray[] = {&line_FrIsOff_0, &line_FrIsOff_1, &line_FrIsOff_2, NULL}; +const TMenuPanel FrIsOffMenuPanel[] = {arr_FrIsOffMenuArray, NULL, 3, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +const TMenuLine line_ErrorJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ErrorJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc0, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorNumberDesc1, // + NULL // +}; + +const TMenuLine line_ErrorJournalMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalErrorTimeDesc, // + NULL // +}; + +void OnEnterErrorJournal(void) +{ + TErrorRecord record; + ErrorJournalIndex = 0; + CPU_INT32U last = 0; + CPU_INT32U i; + + for (i=0; i= last) + { + last = record.time; + ErrorJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} +} + +const TMenuLineArray arr_ErrorJournalMenuArray[] = {&line_ErrorJournalMenu_0, &line_ErrorJournalMenu_1, &line_ErrorJournalMenu_2, &line_ErrorJournalMenu_3, NULL}; +const TMenuPanel ErrorJournalMenuPanel[] = {arr_ErrorJournalMenuArray, OnEnterErrorJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ +char str_EventNumber[24]; +char str_EventData[24]; + +const TMenuLine line_EventJournalMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&EventJournalIndexDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&JournalEventTimeDesc, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_2 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventNumber, // + NULL // +}; + +const TMenuLine line_EventJournalMenu_3 = { + MENU_LINE_STRING, // + 0, // . + (void*)str_EventData, // + NULL // +}; + + +void PrintEventJournalRecord(TEventRecord *record) +{ + if (record->event) + { // + GetEventStr(str_EventNumber, record->event); + if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN)) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, "%d .", record->data); + } + else if (record->event == JOURNAL_EVENT_START_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + PrintSecToHourMinSec(str_EventData, record->data); + } + else if (record->event == JOURNAL_EVENT_END_SESSION) + { + sprintf(&str_EventNumber[strlen(str_EventNumber)], ".%d", record->channel+1); + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_DEVICE_ON) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BILL) + { + sprintf(str_EventData, " %d", record->channel+1); + } + else if (record->event == JOURNAL_EVENT_PRINT_Z) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_X) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_PRINT_BUF) + { + sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_CHANGE_MODE) + { + if (record->data == MODE_WORK) sprintf(str_EventData, ""); + else sprintf(str_EventData, ""); + } + else if (record->event == JOURNAL_EVENT_INCASSATION) + { + sprintf(str_EventData, "%u .", record->data); + } + else if (record->event == JOURNAL_EVENT_PASS_FAIL) + { + sprintf(str_EventData, "%u", record->data); + } + else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL)) + { + sprintf(str_EventData, ""); + } + + } + else + { // + sprintf(str_EventNumber, ""); + sprintf(str_EventData, ""); + } +} + +void OnEnterEventJournal(void) +{ + TEventRecord record; + EventJournalIndex = 0; + CPU_INT32U last = 0; + + for (CPU_INT32U i=0; i= last) + { + last = record.time; + EventJournalIndex = i; + } + } + if (!last) {SetMenu(JournalEmptyMenuPanel); return;} + + GetEventRecord(&record, EventJournalIndex); + PrintEventJournalRecord(&record); +} + +const TMenuLineArray arr_EventJournalMenuArray[] = {&line_EventJournalMenu_0, &line_EventJournalMenu_1, &line_EventJournalMenu_2, &line_EventJournalMenu_3 ,NULL}; +const TMenuPanel EventJournalMenuPanel[] = {arr_EventJournalMenuArray, OnEnterEventJournal, 4, MENU_PANEL_STATIC}; + + +/*********************************** + +***********************************/ + +const CPU_INT08U str_TimeSetupMenu_0[] = " "; + +const TMenuLine line_TimeSetupMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_TimeSetupMenu_0, // + NULL // +}; + +const TMenuLine line_TimeSetupMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&SystemTimeEditDesc, // + NULL // +}; + +const TMenuLineArray arr_TimeSetupMenuArray[] = {&line_TimeSetupMenu_0, &line_TimeSetupMenu_1, NULL}; +const TMenuPanel TimeSetupMenuPanel[] = {arr_TimeSetupMenuArray, NULL, 2, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_CommonStatMenu_0[] = " "; +const CPU_INT08U str_CommonStatMenu_1[] = " "; +const CPU_INT08U str_CommonStatMenu_2[] = " "; + +const TMenuLine line_StatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_CommonStatMenu_0, // + NULL // +}; + +const TMenuLine line_StatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)CommonCountersPanel // +}; + +const TMenuLine line_StatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)CommonCountersLongPanel // +}; + +const TMenuLineArray arr_StatMenuArray[] = {&line_StatMenu_0, &line_StatMenu_1, &line_StatMenu_2, NULL}; +const TMenuPanel CommStatMenuPanel[] = {arr_StatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + + +/*********************************** + +***********************************/ +const CPU_INT08U str_ChanStatMenu_0[] = " - "; + +const TMenuLine line_ChanStatMenu_0 = { + MENU_LINE_STRING, // + MENU_FIXED_LINE, // . + (void*)str_ChanStatMenu_0, // + NULL // +}; + +const TMenuLine line_ChanStatMenu_1 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_1, // + (void*)ChannelCountersPanel // +}; + +const TMenuLine line_ChanStatMenu_2 = { + MENU_LINE_GOTO_MENU, // + 0, // . + (void*)str_CommonStatMenu_2, // + (void*)ChannelCountersLongPanel // +}; + +const TMenuLineArray arr_ChanStatMenuArray[] = {&line_ChanStatMenu_0, &line_ChanStatMenu_1, &line_ChanStatMenu_2, NULL}; +const TMenuPanel ChanStatMenuPanel[] = {arr_ChanStatMenuArray, NULL, 3, MENU_PANEL_STANDARD}; + +/*********************************** + +***********************************/ +const TMenuLine line_ChannelCountersLongMenu_0 = { + MENU_LINE_SHOW_DESC, // + MENU_FIXED_LINE|MENU_INDEX_LINE, // . + (void*)&ChannelStLongIndexDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_1 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelRunLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_2 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelMoneyLongDesc, // + NULL // +}; + +const TMenuLine line_ChannelCountersLongMenu_3 = { + MENU_LINE_SHOW_DESC, // + 0, // . + (void*)&CounterChannelTimeLongDesc, // + NULL // +}; + +const TMenuLineArray arr_ChannelCountersLongArray[] = {&line_ChannelCountersLongMenu_0, &line_ChannelCountersLongMenu_1, &line_ChannelCountersLongMenu_2, &line_ChannelCountersLongMenu_3, NULL}; +const TMenuPanel ChannelCountersLongPanel[] = {arr_ChannelCountersLongArray, NULL, 4, MENU_PANEL_STATIC}; diff --git a/PROJECT/menu/menudesc.h b/PROJECT/menu/menudesc.h new file mode 100644 index 0000000..90fad2f --- /dev/null +++ b/PROJECT/menu/menudesc.h @@ -0,0 +1,62 @@ +#ifndef _MENUDESC_H_ +#define _MENUDESC_H_ + +#include "journal.h" + +#define START_MENU StartMenuPanel +#define WORK_MENU FirstMenuPanel +#define SERVICE_MENU ServiceMenuPanel + +extern char FlagForPrintReport; +extern CPU_INT08U str_IncasMenu_3[32]; + +extern const TMenuPanel ChannelCountersLongPanel[]; +extern const TMenuPanel ChanStatMenuPanel[]; +extern const TMenuPanel CommStatMenuPanel[]; +extern const TMenuPanel MasterPassMenuPanel[]; +extern const TMenuPanel IncasMenuPanel[]; +extern const TMenuPanel CommonCountersLongPanel[]; +extern const TMenuPanel BillCountersPanel[]; +extern const TMenuPanel ModemSetupPanel[]; +extern const TMenuPanel CoinSetupPanel[]; +extern const TMenuPanel JournalIsReset[]; +extern const TMenuPanel ClearJournalMenuPanel[]; +extern const TMenuPanel StatIsReset[]; +extern const TMenuPanel ClearStatMenu[]; +extern const TMenuPanel SettingsIsReset[]; +extern const TMenuPanel ResetSettingsMenuPanel[]; +extern const TMenuPanel ErrorPassPanel[]; +extern const TMenuPanel SetNewPassMenuPanel[]; +extern const TMenuPanel SetPassMenuPanel[]; +extern const TMenuPanel FrMenuPanel[]; +extern const TMenuPanel FrIsOffMenuPanel[]; +extern const TMenuPanel zReportMenuPanel[]; +extern const TMenuPanel xReportMenuPanel[]; +extern const TMenuPanel ReportMenuPanel[]; +extern const TMenuPanel FirstMenuPanel[]; +extern const TMenuPanel ServiceMenuPanel[]; +extern const TMenuPanel StartMenuPanel[]; +extern const TMenuPanel SettingsMenuPanel[]; +extern const TMenuPanel ChannelMenuPanel[]; +extern const TMenuPanel DeviceMenuPanel[]; +extern const TMenuPanel GetMoneyMenuPanel[]; +extern const TMenuPanel PriceWeekdaysMenuPanel[]; +extern const TMenuPanel PriceWeekendMenuPanel[]; +extern const TMenuPanel StatisticsMenuPanel[]; +extern const TMenuPanel ErrorJournalMenuPanel[]; +extern const TMenuPanel SelectJournalMenuPanel[]; +extern const TMenuPanel TimeSetupMenuPanel[]; +extern const TMenuPanel EventJournalMenuPanel[]; +extern const TMenuPanel JournalEmptyMenuPanel[]; +extern const TMenuPanel ChannelCountersPanel[]; +extern const TMenuPanel CommonCountersPanel[]; +extern const TMenuPanel bufReportMenuPanel[]; + +extern void PrintUserMenuStr(char* str, CPU_INT08U n); +extern void PrintEventJournalRecord(TEventRecord *record); + +extern char str_EventNumber[24]; +extern char str_EventData[24]; + + +#endif //#ifndef _MENUDESC_H_ diff --git a/PROJECT/service/coin.c b/PROJECT/service/coin.c new file mode 100644 index 0000000..4f16231 --- /dev/null +++ b/PROJECT/service/coin.c @@ -0,0 +1,160 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include "cpu.h" +#include "app_serv.h" +#include "coin.h" +#include "data.h" +#include "datadesc.h" +#include "modem.h" + + +OS_STK CoinTaskStk[COIN_TASK_STK_SIZE]; + +void InitImpInput(void); + +CPU_INT32U CoinImpCounter; + +void CoinTask(void *p_arg) +{ + + while(1) + { + CPU_INT32U enable_coin; + OSTimeDly(100); + GetData(&EnableCoinDesc, &enable_coin, 0, DATA_FLAG_SYSTEM_INDEX); + if (enable_coin) + { + if (GetCoinCount()) + { + PostUserEvent(EVENT_COIN_INSERTED); + } + } + else + { + CoinDisable(); + GetResetCoinCount(); + } + } + +} + +void CoinDisable(void) +{ + +} + +void CoinEnable(void) +{ + +} + +// +CPU_INT32U GetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +CPU_INT32U GetResetCoinCount(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U ctr = CoinImpCounter; + CoinImpCounter = 0; + OS_EXIT_CRITICAL(); + return ctr; +} + +// +void InitCoin(void) +{ + CoinImpCounter = 0; + InitImpInput(); + + OSTaskCreate(CoinTask, (void *)0, (OS_STK *)&CoinTaskStk[COIN_TASK_STK_SIZE-1], COIN_TASK_PRIO); +} + + +void InputCapture_ISR(void) +{ + CPU_INT08U ir = T3IR; + static CPU_INT32U period = 0; + T3IR = 0xFF; + + if (ir & 0x10) + {// CR0 interrupt + + if (FIO0PIN_bit.P0_23) + {// + CPU_INT32U cr=T3CR0; + if (((cr-period) > COIN_IMP_MIN_LEN) + && ((cr-period) < COIN_IMP_MAX_LEN)) + CoinImpCounter++; + } + else + {// + period = T3CR0; + } + } +} + + +extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk); + +/* +P0.23 MK_P9 IMPULSE OUTPUT ( ) +P0.24 MK_P8 INHIBIT () +*/ +// +// CAP3.0 +void InitImpInput (void) +{ + #define INPUT_CAPTURE_FREQ 100000 // + + CPU_INT32U pclk_freq; + CPU_INT32U rld_cnts; + + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + PCONP_bit.PCTIM3 = 1; + PCLKSEL1_bit.PCLK_TIMER3 = 2; + + PINSEL1_bit.P0_23 = 0x3; + PINMODE1_bit.P0_23 = 0; + FIO0DIR_bit.P0_23 = 0; + FIO0MASK_bit.P0_23 = 0; + + pclk_freq = BSP_CPU_PclkFreq(23); + rld_cnts = pclk_freq / INPUT_CAPTURE_FREQ; + + T3CTCR_bit.CTM = 0; + T3CTCR_bit.CIS = 0; // select CAP3.0 input + T3PR = rld_cnts-1; + T3MCR = 0; + T3CCR = 0x07; + T3EMR = 0; + T3TCR = 0x03; + T3TCR = 0x01; + + VICINTSELECT &= ~(1 << VIC_TIMER3); + VICVECTADDR27 = (CPU_INT32U)InputCapture_ISR; + VICVECTPRIORITY27 = 10; + VICINTENABLE = (1 << VIC_TIMER3); + + T3IR = 0xFF; + + OS_EXIT_CRITICAL(); +} + diff --git a/PROJECT/service/coin.h b/PROJECT/service/coin.h new file mode 100644 index 0000000..0a7d790 --- /dev/null +++ b/PROJECT/service/coin.h @@ -0,0 +1,18 @@ +#ifndef _COIN_H_ +#define _COIN_H_ + + + +#define COIN_IMP_MIN_LEN 2200 // /100 +#define COIN_IMP_MAX_LEN 9000 // /100 + + +extern void InitCoin(void); +extern CPU_INT32U GetCoinCount(void); +extern CPU_INT32U GetResetCoinCount(void); +extern void CoinDisable(void); +extern void CoinEnable(void); + +#endif //#ifndef _COIN_H_ + + diff --git a/PROJECT/service/fr.c b/PROJECT/service/fr.c new file mode 100644 index 0000000..6b8d8f6 --- /dev/null +++ b/PROJECT/service/fr.c @@ -0,0 +1,982 @@ +#include +#include "app_serv.h" +#include "fiscal.h" +#include "fr.h" +#include "uart0.h" +#include "data.h" +#include "datadesc.h" +#include "journal.h" +#include "time.h" + +TFiscDevType FiscDevInfo; +static TFiscFullStatus FiscFullStatus; +CPU_INT08U FiscalConnState = FISCAL_NOCONN; + + +OS_EVENT *FLock = NULL; +//OS_EVENT *FReportLock = NULL; +//OS_STK FiscalTaskStk[FISCAL_TASK_STK_SIZE]; + + +// +int CheckFiscalStatus() +{ + CPU_INT08U err; + int poll; + CPU_INT32U time1, time2; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + if (!enable) return 0; + + time1 = time2 = OSTimeGet(); + + while (labs(time2 - time1) < WAIT_PRINT_TIMEOUT) + { + OSTimeDly(100); + time2 = OSTimeGet(); + // + poll = FiscPollExt(); + if (poll == FISC_UNDEF) + { + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + return -1; + } + else if (poll == FISC_BUSY) + { + continue; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + if (err) SetFiscalErrorByCode(err); + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + } + return -2; + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + + CPU_INT16U flags; + memcpy(&flags, &FiscFullStatus.Flags, sizeof(CPU_INT16U)); + + // : + // (0 , 1 ) + if (!(flags & (1L<<5))) + { + // + SetFiscalErrorByCode(FR_ERROR_CODE_a1); + return -3; + } + else + { + ClrFiscalErrorByCode(FR_ERROR_CODE_a1); + } + + ClrFiscalErrorByCode(FR_ERROR_CODE_6b); + // + switch (FiscFullStatus.SubMode) + { + case 1: + // 1. + // , , + // . + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + return -4; + case 2: + // 2. + // , . 3. + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + return -5; + case 3: + // 3. . + // , . + SetFiscalErrorByCode(FR_ERROR_CODE_6b); + // + FiscPrintContinue(DEFAULT_PASS, &err); + return -6; + case 4: // + case 5: // + continue; + default: + break; + } + + // + switch (FiscFullStatus.Mode) + { + case 0: + // 0. . + // + // OK + ClearFiscalErrors(); + goto check_exit; + case 1: + // 1. . + // OK + ClearFiscalErrors(); + goto check_exit; + case 2: + // 2. , 24 . + // OK + ClearFiscalErrors(); + goto check_exit; + case 3: + // 3. , 24 . + { + CPU_INT32U autoclose; + GetData(&EnableFiscalDayClearDesc, &autoclose, 0, DATA_FLAG_SYSTEM_INDEX); + + if (autoclose==2) + { + // + FiscPrintDayReportToBuf(30, &err); + // , + if (err == FR_ERROR_CODE_4b) + { + SetFiscalErrorByCode(err); + SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec()); + FiscPrintDayReportsFromBuf(30, &err); + if (err) + { + SetFiscalErrorByCode(err); + return -8; + } + } + else if (err) + { + SetFiscalErrorByCode(err); + return -9; + } + } + else if (autoclose==1) + { + // Z- + FiscPrintDayReportClear(30, &err); + SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec()); + if (err) + { + SetFiscalErrorByCode(err); + return -10; + } + } + else if (autoclose==0) + { + // - + SetFiscalErrorByCode(FR_ERROR_CODE_4e); + return -11; + } + } + goto check_exit; + case 4: + // 4. . + ClearFiscalErrors(); + goto check_exit; + case 5: + // 5. . + SetFiscalErrorByCode(FR_ERROR_CODE_4f); + goto check_exit; + case 6: + // 6. . + SetFiscalErrorByCode(FR_ERROR_CODE_c0); + goto check_exit; + case 8: + // 8. : + // 8.0. . + // 8.1. . + // 8.2. . + // 8.3. . + // 8.4. . + { + CPU_INT64U cash = 0; + CPU_INT08U tax[4] = {0,0,0,0}; + FiscCloseBill(DEFAULT_PASS, &cash, &tax[0], " !!!", &err); + if (err) + { + SetFiscalErrorByCode(err); + return -11; + } + } + goto check_exit; + case 12: + // Z- + continue; + default: + goto check_exit; + } + } + +check_exit: + + if (labs(time2 - time1) < WAIT_PRINT_TIMEOUT) + { + // OK + return 0; + } + + return -1; +} + +#define FISCAL_BAUDS_COUNT 7 +static const CPU_INT32U fiscal_bauds[FISCAL_BAUDS_COUNT] = {2400, 4800, 9600, 19200, 38400, 57600, 115200}; + +// +int ConnectFiscal(void) +{ + int i, poll; + CPU_INT08U err; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + FPend(); + if (enable) + { + int j; + // + for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--) + { + Uart0_Init(fiscal_bauds[j]); + i = 10; + do + { + OSTimeDly(100); + poll = FiscPollExt(); + if ((poll == FISC_READY) || (poll == FISC_BUSY)) break; + } while (--i); + // + if (i) + { + break; + } + } + + if (j < 0) + { + SetErrorFlag(ERROR_FR_CONN); + FiscalConnState = FISCAL_NOCONN; + FPost(); + return -1; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + // + if (err) SetFiscalErrorByCode(err); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + FPost(); + return -2; + } + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + FiscalConnState = FISCAL_NOCONN; + ClearFiscalErrors(); + ClrErrorFlag(ERROR_FR_CONN); + FPost(); + return -3; + } + + FPost(); + return 0; +} + +// +int ConnectFiscalFast(void) +{ + int i, poll; + CPU_INT08U err; + CPU_INT32U enable; + GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + FPend(); + if (enable) + { + int j; + // + for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--) + { + Uart0_Init(fiscal_bauds[j]); + i = 2; + do + { + poll = FiscPollExt(); + if ((poll == FISC_READY) || (poll == FISC_BUSY)) break; + } while (--i); + // + if (i) + { + break; + } + } + + if (j < 0) + { + SetErrorFlag(ERROR_FR_CONN); + FiscalConnState = FISCAL_NOCONN; + FPost(); + return -1; + } + + // + if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK) + { + if (err) + { + // - + // + if (err) SetFiscalErrorByCode(err); + } + else + { + // + ClearFiscalErrors(); + FiscalConnState = FISCAL_NOCONN; + SetErrorFlag(ERROR_FR_CONN); + FPost(); + return -2; + } + } + + // + FiscalConnState = FISCAL_CONN; + ClrErrorFlag(ERROR_FR_CONN); + } + else + { + // + FiscalConnState = FISCAL_NOCONN; + ClearFiscalErrors(); + ClrErrorFlag(ERROR_FR_CONN); + FPost(); + return -3; + } + + FPost(); + return 0; +} + +// +void InitFiscal(void) +{ + if (!FLock) + { + FLock = OSSemCreate(1); + //FReportLock = OSSemCreate(1); + //OSTaskCreate(FiscalTask, (void *)0, (OS_STK *)&FiscalTaskStk[FISCAL_TASK_STK_SIZE-1], FISCAL_TASK_PRIO); + } + + if (ConnectFiscal()) return; + + CheckFiscalStatus(); +} + +int IsFiscalConnected(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int retval; + if (FiscalConnState == FISCAL_CONN) retval=1; + else retval=0; + OS_EXIT_CRITICAL(); + return retval; +} + +// +void FPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(FLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// +void FPost(void) +{ + OSTimeDly(200); + OSSemPost(FLock); +} +/* +// +void FReportPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(FReportLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// 2 +int FReportGet(void) +{ + CPU_INT08U err; + OSSemPend(FReportLock, 1, &err); + if (!err) return 1; + return 0; +} + +// +void FReportPost(void) +{ + if (!FReportTest()) OSSemPost(FReportLock); +} + +// +// 0 - +// >0 - +CPU_INT16U FReportTest(void) +{ + return OSSemCheck(FReportLock); +} + +*/ +// +void ClearFiscalErrors(void) +{ + for (unsigned char i=ERROR_FR; i0)) + { + OSTimeDly(5000); + res = PrintFiscalBill(money, time); + i--; + } + return res; +} +*/ + +int TstFiscalErrorByCode(unsigned char code) +{ + for (unsigned char i=0; i +#include "mode.h" +#include "app_serv.h" + +// +CPU_INT08U RecentMode; + + +void InitMode(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + + PINSEL3_bit.P1_22 = 0x0; + PINMODE3_bit.P1_22 = 0; + FIO1DIR_bit.P1_22 = 0; + FIO1MASK_bit.P1_22 = 0; + + OS_EXIT_CRITICAL(); + + OSTimeDly(1); + + OS_ENTER_CRITICAL(); + if (FIO1PIN_bit.P1_22) RecentMode = MODE_WORK; + else RecentMode = MODE_SERVICE; + OS_EXIT_CRITICAL(); +} + + +CPU_INT08U GetMode(void) +{ + CPU_INT08U mode; + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + mode = RecentMode; + OS_EXIT_CRITICAL(); + return mode; +} + + +CPU_INT08U CheckMode(void) +{ + CPU_INT08U newmode; + if (FIO1PIN_bit.P1_22) newmode = MODE_WORK; + else newmode = MODE_SERVICE; + if (newmode != RecentMode) + { + RecentMode = newmode; + PostUserEvent(EVENT_MODE_CHANGE); + return 1; + } + return 0; +} diff --git a/PROJECT/service/mode.h b/PROJECT/service/mode.h new file mode 100644 index 0000000..89cd007 --- /dev/null +++ b/PROJECT/service/mode.h @@ -0,0 +1,17 @@ +#ifndef _MODE_H_ +#define _MODE_H_ + +#include "cpu.h" + +// +#define MODE_WORK 0 +#define MODE_SERVICE 1 + +// +extern CPU_INT08U GetMode(void); +// , +extern CPU_INT08U CheckMode(void); +// +extern void InitMode(void); + +#endif //#ifndef _MODE_H_ diff --git a/PROJECT/service/time.c b/PROJECT/service/time.c new file mode 100644 index 0000000..6c086c1 --- /dev/null +++ b/PROJECT/service/time.c @@ -0,0 +1,322 @@ +#include "iolpc2368.h" +#include "ucos_ii.h" +#include "cpu.h" +#include "app_serv.h" +#include "time.h" +#include +#include +#include + + +void RTC_Isr (void) +{ + CPU_INT32U ilr; + + ilr = ILR & 0x7; + if (ilr & 0x1) PostUserEvent(EVENT_SEC); + + ILR = ilr; +} + + +void RTC_ReadTime(TRTC_Data *rtc) +{ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + rtc->sec = SEC; + rtc->min = MIN; + rtc->hour = HOUR; + rtc->day = DOW; + rtc->date = DOM; + rtc->mon = MONTH; + rtc->year = YEAR-2000; + OS_EXIT_CRITICAL(); +} + +void RTC_SetTime(TRTC_Data *rtc) +{ + #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + SEC = rtc->sec; + MIN = rtc->min; + HOUR = rtc->hour; + DOW = rtc->day; + DOM = rtc->date; + MONTH = rtc->mon; + YEAR = rtc->year+2000; + OS_EXIT_CRITICAL(); +} + + +extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk); + +void InitRTC(void) +{ +#if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; +#endif + + PCONP_bit.PCRTC = 1; + PCLKSEL0_bit.PCLK_RTC = 0; + + OS_ENTER_CRITICAL(); + + CCR = 0x0011; + PREINT = (BSP_CPU_PclkFreq(9) / 32768) - 1; + PREFRAC = BSP_CPU_PclkFreq(9) - ((PREINT + 1) * 32768); + + // If year is corrupt, set reasonable date. + if ((YEAR < 2010) || (HOUR > 23) || (YEAR > 2100)) { + CCR = 0x0000; + YEAR = 2010; + MONTH = 8; + DOM = 8; + HOUR = 7; + MIN = 0; + CCR = 0x0011; + } + + VICVECTADDR13 = (CPU_INT32U)RTC_Isr; + VICINTSELECT &= ~(1 << VIC_RTC); + VICVECTPRIORITY13 = 7; + VICINTENABLE = (1 << VIC_RTC); + + CISS = 0; + AMR = 0xff; + CIIR = 0x1; // sec interrupt + + OS_EXIT_CRITICAL(); +} + + +const char str_sunday[] = "b"; +const char str_monday[] = "b"; +const char str_tuesday[] = ""; +const char str_wednesday[] = ""; +const char str_thirsday[] = ""; +const char str_friday[] = ""; +const char str_saturday[] = ""; +const char* weekday[]={str_sunday, str_monday, str_tuesday, str_wednesday, str_thirsday, str_friday, str_saturday}; + +void GetDayText(char* str, char day) +{ + strcpy(str, weekday[day]); +} + +const char str_jan[] = ""; +const char str_feb[] = ""; +const char str_mar[] = ""; +const char str_apr[] = ""; +const char str_may[] = ""; +const char str_jun[] = ""; +const char str_jul[] = ""; +const char str_aug[] = ""; +const char str_sep[] = ""; +const char str_okt[] = ""; +const char str_nov[] = ""; +const char str_dec[] = ""; +const char* month[]={str_jan, str_feb, str_mar, str_apr, str_may, str_jun, str_jul, str_aug, str_sep, str_okt, str_nov, str_dec}; + + +// 1 1970 +#define JESUS_TO_70 2007437056 +// 1 1970 +#define JESUS_TO_70MIN 1035616320 + +// +CPU_INT16U const mon_add[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334}; +// +CPU_INT08U const mon_len[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; + +void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc) +{ + sprintf(str, "%02d:%02d:%02d %02d/%02d/%02d", rtc->hour, rtc->min, rtc->sec, rtc->date, rtc->mon, rtc->year); +} + +void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc) +{ + int hour, min, sec, date, mon, year; + sscanf(str, "%02d:%02d:%02d %02d/%02d/%02d", &hour, &min, &sec, &date, &mon, &year); + rtc->year = year; + rtc->mon = mon; + rtc->date = date; + rtc->hour = hour; + rtc->min = min; + rtc->sec = sec; +} + +// / +int RTCCheckTime(TRTC_Data *rtc) +{ + if (rtc->hour > 23) return -1; + if (rtc->min > 59) return -2; + if (rtc->sec > 59) return -3; + if ((rtc->mon > 12) || (rtc->mon < 1)) return -5; + if (rtc->year > 99) return -6; + + if ((rtc->year%4 == 0) && (rtc->mon == 2)) + { // + if ((rtc->date == 0) || (rtc->date > 29)) return -4; + } + else + { + if ((rtc->date == 0) || (rtc->date > mon_len[rtc->mon])) return -4; + } + return 0; +} + +void PrintRTCDateTimeString(char *str, TRTC_Data *rtc) +{ + sprintf(str, "20%02d/%02d/%02d %02d:%02d:%02d", rtc->year, rtc->mon, rtc->date, rtc->hour, rtc->min, rtc->sec); +} + +void PrintRTCTimeString(char *str, TRTC_Data *rtc) +{ + sprintf(str, "%02d:%02d:%02d", rtc->hour, rtc->min, rtc->sec); +} + +void PrintTimeString(char *str, CPU_INT32U time) +{ + TRTC_Data rtc_data; + Sec2Date(&rtc_data, time); + PrintRTCDateTimeStringRus(str, &rtc_data); +} + +void PrintSecToMinSec(char *str, int seconds) +{ + int min_ = seconds/60; + int sec_ = seconds%60; + sprintf(str, "%02d:%02d", min_, sec_); +} + +void PrintSecToHourMinSec(char *str, int seconds) +{ + int min_ = (seconds/60)%60; + int sec_ = seconds%60; + int hour_ = seconds/3600; + sprintf(str, "%02d:%02d:%02d", hour_, min_, sec_); +} + +void PrintSecToBigHourMinSec(char *str, int seconds) +{ + int min_ = (seconds/60)%60; + int sec_ = seconds%60; + int hour_ = seconds/3600; + sprintf(str, "%d:%02d:%02d", hour_, min_, sec_); +} + +CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType) +{ // + CPU_INT16U year = (CPU_INT16U)pData->year + ((pData->year >= 70) ? 1900 : 2000); + + // + CPU_INT32U ulIndex = (CPU_INT32U)(((year - 1) * 12) + pData->mon - 1); + + // . + if ( ucType != MONTH_TYPE ) + { // + ulIndex = ((year - 1) * 365L) + ((year - 1)/4) + mon_add[pData->mon] + pData->date; + + // . + if ( (!(year % 4)) && (pData->mon > 2) ) {ulIndex++;} + + // + if ( ucType != DAY_TYPE ) + { // c + ulIndex = ulIndex * 24L + pData->hour; + + if ( ucType != HOUR_TYPE ) + { // . + ulIndex = ulIndex * 60L + pData->min; + + if ( ucType != MIN_TYPE ) + { // . + ulIndex = ulIndex * 60L + pData->sec; + }//if( ) + }//if( ) + }//if( ) + }//if( ) + + return ulIndex; +} + +//------------------------------------------------------------------------ +// 1 1970 , pData +//------------------------------------------------------------------------ +CPU_INT32U GetSec( TRTC_Data *pData) +{ + CPU_INT32U ulIndex = Date2Sec(pData, MIN_TYPE);// . + ulIndex -= JESUS_TO_70MIN; // 1 1970 . + ulIndex *= 60L; // + ulIndex += pData->sec; // . + + return ulIndex; +} + +// e +CPU_INT32U GetTimeSec(void) +{ + TRTC_Data rtc; + RTC_ReadTime(&rtc); + return GetSec(&rtc); +} + + +// +void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec) +{ + pDest->year = 0; + pDest->mon = 0; + pDest->date = 0; + pDest->hour = ulSec/3600L; // + + ulSec %= 3600L; + pDest->min = ulSec/60L; // + + ulSec %= 60L; + pDest->sec = ulSec; // +} + + +// 1 1970 TRTC_Data. +void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec) +{ + CPU_INT32U dl = 0; + + dl = (ulSec)/86400L; + // + pDest->day = (dl+4)%7; + + if ( ulSec >= 946684800L ) + { // 1 2000 + ulSec -= 946684800L; + pDest->year = 0; + }//if( ) + else + { // 1970 1999 + pDest->year = 70; + }//else ( ) + + for ( dl = 365L; + ulSec >= (dl = 86400L * (365L + visocosn(pDest->year))); + ulSec -= dl, pDest->year++ ){;} + + for ( pDest->mon = 1; + ulSec >= ( dl = 86400L * + (mon_len[pDest->mon] + ((pDest->mon == 2) ? + visocosn(pDest->year) : 0))); ulSec -= dl, pDest->mon++){;} + + pDest->date = ulSec / (86400L) + 1; + ulSec %= 86400L; + pDest->hour = ulSec / 3600L; + ulSec %= 3600L; + pDest->min = ulSec / 60L; + ulSec %= 60L; + pDest->sec = ulSec; +} + + diff --git a/PROJECT/service/time.h b/PROJECT/service/time.h new file mode 100644 index 0000000..9815a66 --- /dev/null +++ b/PROJECT/service/time.h @@ -0,0 +1,44 @@ +#ifndef _TIME_H_ +#define _TIME_H_ + + +#define visocosn(year) ((year % 4) ? 0 : 1) + +typedef struct{ + CPU_INT08U sec; + CPU_INT08U min; + CPU_INT08U hour; + CPU_INT08U day; + CPU_INT08U date; + CPU_INT08U mon; + CPU_INT08U year; +}TRTC_Data; + +#define SEC_TYPE 1 +#define MIN_TYPE 2 +#define HOUR_TYPE 3 +#define DAY_TYPE 4 +#define MONTH_TYPE 5 +#define YEAR_TYPE 6 + +extern void InitRTC(void); +extern void RTC_ReadTime(TRTC_Data *rtc); +extern void RTC_SetTime(TRTC_Data *rtc); +extern void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec); +extern void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec); +extern CPU_INT32U GetSec(TRTC_Data *pData); +extern CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType); +extern void PrintSecToMinSec(char *str, int seconds); +extern void PrintRTSTimeString(char *str, TRTC_Data *rtc); +extern void PrintRTCDateTimeString(char *str, TRTC_Data *rtc); +extern void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc); +extern void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc); +extern void GetDayText(char* str, char day); +extern CPU_INT32U GetTimeSec(void); +int RTCCheckTime(TRTC_Data *rtc); +extern void PrintTimeString(char *str, CPU_INT32U time); +extern void PrintSecToHourMinSec(char *str, int seconds); +extern void PrintSecToBigHourMinSec(char *str, int seconds); + + +#endif //#ifndef _TIME_H_ diff --git a/PROJECT/service/validator.c b/PROJECT/service/validator.c new file mode 100644 index 0000000..60f82be --- /dev/null +++ b/PROJECT/service/validator.c @@ -0,0 +1,372 @@ +#include +#include "validator.h" +#include "CCRSProtocol.h" +#include "uart1.h" +#include "app_serv.h" +#include "journal.h" +#include "data.h" +#include "datadesc.h" + + +OS_STK ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE]; +OS_EVENT *VLock = NULL; + +void CC_BusReset(void); +int ValidatorConnect(void); + +// +unsigned char VConnStat = VCONN_STATUS_NOCONN; + +TBillRecord VBillTable[24]; +/// - GUI +CPU_INT32U BillNominals[24]; + +TBillStatus VBillStatus; +/// +CPU_INT32U VBillCount = 0; +/// +CPU_INT32U VLastBillIndex = V_BILLS_NUMBER; + +void ValidatorTask(void *p_arg) +{ + char incas = 0; + // 1. , RESET + // 2. BUS RESET - min 100 ms + // 3. POLL 100-200 , 200 + + VBillCount = 0; + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + + while(1) + { + TPollResults polldata; + OSTimeDly(CC_POLL_TIME_OUT); + + CPU_INT32U enable; + GetData(&EnableValidatorDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX); + + // + if (VConnStat == VCONN_STATUS_NOCONN) + { // + if (!enable) + { // + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + continue; + } + // + if (ValidatorConnect() != 0) {SetErrorFlag(ERROR_VALIDATOR_CONN); continue;} + // + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + VConnStat = VCONN_STATUS_CONN; + } + else + { // + if (!enable) + { // + VConnStat = VCONN_STATUS_NOCONN; + ClrErrorFlag(ERROR_VALIDATOR_CONN); + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + continue; + } + } + + // + if (CC_CmdPoll(ADDR_FL, &polldata)) + {// poll + + if ((incas) && (polldata.Z1 != ST_BOX)) + { + incas = 0; + PostUserEvent(EVENT_INCASSATION_FINISH); + } + + switch (polldata.Z1){ + // States CCNET states and events + case ST_POWER_UP: + case ST_POWER_BILL_ESCROW: + case ST_POWER_BILL_STACKER: + case ST_INITIALIZE: + case ST_IDLING: + case ST_ACCEPTING: + case ST_PACKING: + case ST_RETURNING: + case ST_DISABLED: + case ST_HOLDING: + case ST_BUSY: + ClrValidatorErrors(); + break; + case ST_REJECTING: + ClrErrorFlag(ERROR_VALIDATOR_FAILURE); + switch (polldata.Z2){ + case RJ_INSERTION: //!< Rejection because of insertion problem + case RJ_REMAINING: //!< Rejection because of other bill remaining in the device + SetErrorFlag(ERROR_VALIDATOR_INSERTION); + break; + case RJ_MAGNETIC: //!< Rejection because of invalid magnetic pattern + SetErrorFlag(ERROR_VALIDATOR_MAGNETIC); + break; + case RJ_CONVEYING: //!< Rejection because of conveying + SetErrorFlag(ERROR_VALIDATOR_CONVEYING); + break; + case RJ_IDENT: //!< Rejection because of identification failure + SetErrorFlag(ERROR_VALIDATOR_IDENT); + break; + case RJ_VRFY: //!< Rejection because of verification failure + SetErrorFlag(ERROR_VALIDATOR_VRFY); + break; + case RJ_OPT: //!< Rejection because of optical pattern mismatch + SetErrorFlag(ERROR_VALIDATOR_OPT); + break; + case RJ_INHIBIT: //!< Rejection because the denomination is inhibited + SetErrorFlag(ERROR_VALIDATOR_INHIBIT); + break; + case RJ_CAP: //!< Rejection because of capacity sensor pattern mismatch + SetErrorFlag(ERROR_VALIDATOR_CAP); + break; + case RJ_LNG: //!< Rejection because of invalid bill length + SetErrorFlag(ERROR_VALIDATOR_LNG); + break; + default: + break; + } + break; + case ST_ST_FULL: //!< DROP CASSETTE IS FULL state + SetErrorFlag(ERROR_STACKER_FULL); + break; + case ST_BOX: //!< DROP CASSETTE REMOVED state + //SetErrorFlag(ERROR_STACKER_REMOVED); + if (incas == 0) + { + PostUserEvent(EVENT_INCASSATION); + ClrValidatorErrors(); + incas = 1; + } + break; + case ST_BV_JAMMED: //!< JAM IN VALIDATOR state + SetErrorFlag(ERROR_BV_JAMMED); + break; + case ST_ST_JAMMED: //!< JAM IN STACKER state + SetErrorFlag(ERROR_ST_JAMMED); + break; + case ST_CHEATED: //!< CHEATED event + SetErrorFlag(ERROR_CHEATED); + break; + case ST_FAILURE: + switch (polldata.Z2){ + case FLR_STACKER: //!< Stacking mechanism failure + SetErrorFlag(ERROR_FLR_STACKER); + break; + case FLR_TR_SPEED: //!< Invalid speed of transport mechanism + SetErrorFlag(ERROR_TR_SPEED); + break; + case FLR_TRANSPORT: //!< Transport mechanism failure + SetErrorFlag(ERROR_FLR_TRANSPORT); + break; + case FLR_ALIGNING: //!< Aligning mechanism failure + SetErrorFlag(ERROR_FLR_ALIGNIN); + break; + case FLR_INIT_CAS: //!< Initial cassette status failure + SetErrorFlag(ERROR_FLR_INIT_CAS); + break; + case FLR_OPT: //!< Optical channel failure + SetErrorFlag(ERROR_FLR_OPT); + break; + case FLR_MAG: //!< Inductive channel failure + SetErrorFlag(ERROR_FLR_MAG); + break; + case FLR_CAP: //!< Capacity sensor failure + SetErrorFlag(ERROR_FLR_CAP); + break; + } + // , + SetErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_NOCONN; + break; + // Failure codes + case FLR_STACKER: + case FLR_TR_SPEED: + case FLR_TRANSPORT: + case FLR_ALIGNING: + case FLR_INIT_CAS: + case FLR_OPT: + case FLR_MAG: + case FLR_CAP: + SetErrorFlag(ERROR_VALIDATOR_FAILURE); + break; + // Credit events + case ST_PACKED: + // + // + if (!CC_CmdBillType(0x000000, 0x000000, ADDR_FL)){SetErrorFlag(ERROR_VALIDATOR_CONN);} + // + if (polldata.Z2 < V_BILLS_NUMBER) + { + VBillCount += VBillTable[polldata.Z2].Denomination; + // + VLastBillIndex = polldata.Z2; + } + else + { + VBillCount = 0; + // + VLastBillIndex = V_BILLS_NUMBER; + } + PostUserEvent(EVENT_BILL_STACKED); + ClrValidatorErrors(); + break; + case ESCROW: + if (polldata.Z2 < V_BILLS_NUMBER) + { + VBillCount += VBillTable[polldata.Z2].Denomination; + // + VLastBillIndex = polldata.Z2; + } + else + { + VBillCount = 0; + // + VLastBillIndex = V_BILLS_NUMBER; + } + PostUserEvent(EVENT_BILL_ESCROW); + ClrValidatorErrors(); + break; + case RETURNED: + ClrValidatorErrors(); + break; + default: + ClrValidatorErrors(); + break; + }// switch (polldata.Z1) + ClrErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_CONN; + } + else + { // + SetErrorFlag(ERROR_VALIDATOR_CONN); + VConnStat = VCONN_STATUS_NOCONN; + } + + } + +} + + +int ValidatorConnect(void) +{ + int i; + OSTimeDly(200); + + for (i = 0; i < 24; i++) + { + BillNominals[i] = 0; + } + + CC_BusReset(); + + // + if (!CC_CmdReset(ADDR_FL)) return -1; + + // + if (!CC_CmdGetBillTable(ADDR_FL, VBillTable)) return -2; + + for (i = 0; i < 24; i++) + { + BillNominals[i] = (CPU_INT32U)VBillTable[i].Denomination; + } + + // + if (!CC_CmdBillType(0x00000000, 0x00000000, ADDR_FL)) return -3; + + VConnStat = VCONN_STATUS_CONN; + + return 0; +} + + +int IsValidatorConnected(void) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + int retval; + if (VConnStat == VCONN_STATUS_CONN) retval=1; + else retval=0; + OS_EXIT_CRITICAL(); + return retval; +} + + +// +void StartUpValidator(void) +{ + Uart1_Init(CC_VALIDATOR_SPEED); + + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + + OS_ENTER_CRITICAL(); + + // BUS RESET init + PINSEL4_bit.P2_4 = 0; + PINMODE4_bit.P2_4 = 0; + FIO2DIR_bit.P2_4 = 1; + FIO2MASK_bit.P2_4 = 0; + FIO2CLR_bit.P2_4 = 1; + + OS_EXIT_CRITICAL(); + + if (!VLock) + { + VLock = OSSemCreate(1); + OSTaskCreate(ValidatorTask, (void *)0, (OS_STK *)&ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE-1], VALIDATOR_TASK_PRIO); + } +} + + +void CC_BusReset(void) +{ + VPend(); + FIO2CLR_bit.P2_4 = 1; + OSTimeDly(CC_BUS_RESET_TIME_OUT); + FIO2SET_bit.P2_4 = 1; + VPost(); +} + +// +void VPend(void) +{ + CPU_INT08U err; + do{ + OSSemPend(VLock, 1, &err); + if (!err) break; + OSTimeDly(1); + }while (err); +} + +// +void VPost(void) +{ + OSSemPost(VLock); +} + +// +CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index) +{ + #if OS_CRITICAL_METHOD == 3 + OS_CPU_SR cpu_sr = 0; + #endif + OS_ENTER_CRITICAL(); + CPU_INT32U count = VBillCount; + VBillCount = 0; + *bill_index = VLastBillIndex; + OS_EXIT_CRITICAL(); + return count; +} + diff --git a/PROJECT/service/validator.h b/PROJECT/service/validator.h new file mode 100644 index 0000000..8a82785 --- /dev/null +++ b/PROJECT/service/validator.h @@ -0,0 +1,20 @@ +#ifndef _VALIDATOR_H_ +#define _VALIDATOR_H_ + +#define CC_VALIDATOR_SPEED 9600 +#define CC_POLL_TIME_OUT 150 +#define CC_BUS_RESET_TIME_OUT 100 + +#define VCONN_STATUS_CONN 0 +#define VCONN_STATUS_NOCONN 1 + +// +#define V_BILLS_NUMBER 24 + +extern void StartUpValidator(void); +extern int IsValidatorConnected(void); +extern void VPend(void); +extern void VPost(void); +extern CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index); + +#endif //#define _VALIDATOR_H_ diff --git a/PROJECT/tools/crc16.c b/PROJECT/tools/crc16.c new file mode 100644 index 0000000..ee14e6d --- /dev/null +++ b/PROJECT/tools/crc16.c @@ -0,0 +1,89 @@ +#include +#include "crc16.h" + +#if (CRC16_MODEL_TYPE==CRC16_SMALL) +/* +unsigned short CRC16_small(unsigned char *pBuf, unsigned char ucLength) +{ + register unsigned char Lo, Hi, ucSym; + if (!ucLength) return 1; + + Lo = 0xFF; + Hi = 0xFF; + + do{ + ucSym = *(pBuf++); + ucSym ^= Hi; + Hi = ( ucSym & 0x02 ) ? (Lo - 0x80) : Lo; + if ( ucSym & 0x01 ) + Hi ^= 0xC0; + + Lo = ucSym; + Lo >>= 1; + Lo ^= ucSym; + Lo >>= 1; + ucSym ^= Lo; + + if ( ucSym & 0x08 ) --ucSym; + if ( ucSym & 0x40 ) --ucSym; + + ucSym &= 0x01; + + if (ucSym) Lo ^= 0xC0; + Hi ^= ucSym; + }while(--ucLength); + + return (unsigned short)((((unsigned short)Hi)<<8) | Lo); +} +*/ +#else //(CRC16_MODEL_TYPE==CRC16_LARGE) +unsigned short CRC16_large(unsigned char *pBuf, unsigned char ucLength) +{ + unsigned char ucCRCHi = 0xFF; // high CRC byte initialized + unsigned char ucCRCLo = 0xFF; // low CRC byte initialized + unsigned char table_addr; + +static const unsigned short CRC_Table[8*32]={ +0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011, +0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022, +0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072, +0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041, +0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2, +0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1, +0x00A0,0x80A5,0x80AF,0x00AA,0x80BB,0x00BE,0x00B4,0x80B1, +0x8093,0x0096,0x009C,0x8099,0x0088,0x808D,0x8087,0x0082, +0x8183,0x0186,0x018C,0x8189,0x0198,0x819D,0x8197,0x0192, +0x01B0,0x81B5,0x81BF,0x01BA,0x81AB,0x01AE,0x01A4,0x81A1, +0x01E0,0x81E5,0x81EF,0x01EA,0x81FB,0x01FE,0x01F4,0x81F1, +0x81D3,0x01D6,0x01DC,0x81D9,0x01C8,0x81CD,0x81C7,0x01C2, +0x0140,0x8145,0x814F,0x014A,0x815B,0x015E,0x0154,0x8151, +0x8173,0x0176,0x017C,0x8179,0x0168,0x816D,0x8167,0x0162, +0x8123,0x0126,0x012C,0x8129,0x0138,0x813D,0x8137,0x0132, +0x0110,0x8115,0x811F,0x011A,0x810B,0x010E,0x0104,0x8101, +0x8303,0x0306,0x030C,0x8309,0x0318,0x831D,0x8317,0x0312, +0x0330,0x8335,0x833F,0x033A,0x832B,0x032E,0x0324,0x8321, +0x0360,0x8365,0x836F,0x036A,0x837B,0x037E,0x0374,0x8371, +0x8353,0x0356,0x035C,0x8359,0x0348,0x834D,0x8347,0x0342, +0x03C0,0x83C5,0x83CF,0x03CA,0x83DB,0x03DE,0x03D4,0x83D1, +0x83F3,0x03F6,0x03FC,0x83F9,0x03E8,0x83ED,0x83E7,0x03E2, +0x83A3,0x03A6,0x03AC,0x83A9,0x03B8,0x83BD,0x83B7,0x03B2, +0x0390,0x8395,0x839F,0x039A,0x838B,0x038E,0x0384,0x8381, +0x0280,0x8285,0x828F,0x028A,0x829B,0x029E,0x0294,0x8291, +0x82B3,0x02B6,0x02BC,0x82B9,0x02A8,0x82AD,0x82A7,0x02A2, +0x82E3,0x02E6,0x02EC,0x82E9,0x02F8,0x82FD,0x82F7,0x02F2, +0x02D0,0x82D5,0x82DF,0x02DA,0x82CB,0x02CE,0x02C4,0x82C1, +0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252, +0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261, +0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231, +0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202}; + + while(ucLength--){ + table_addr=(*pBuf++ ^ ucCRCHi); + ucCRCHi=(CRC_Table[table_addr] >> 8) ^ ucCRCLo; + ucCRCLo=(CRC_Table[table_addr] & 0x00FF); + } + + return (unsigned short)((((unsigned short)ucCRCHi)<<8) | (unsigned short)ucCRCLo); +} +#endif + diff --git a/PROJECT/tools/crc16.h b/PROJECT/tools/crc16.h new file mode 100644 index 0000000..7de93e3 --- /dev/null +++ b/PROJECT/tools/crc16.h @@ -0,0 +1,20 @@ +#ifndef __CRC16_H__ +#define __CRC16_H__ + + +#define CRC16_SMALL 0 // +#define CRC16_LARGE 1 // ( ) +#define CRC16_MODEL_TYPE CRC16_LARGE + + +#if (CRC16_MODEL_TYPE==CRC16_LARGE) + extern unsigned short CRC16_large( unsigned char *pBuf, unsigned char ucLength ); + #define CRC16 CRC16_large +#else + extern unsigned short CRC16_small( unsigned char *pBuf, unsigned char ucLength ); + #define CRC16 CRC16_small +#endif + + +#endif // #ifndef __CRC16_H__ + diff --git a/PROJECT/version.h b/PROJECT/version.h new file mode 100644 index 0000000..d1651d8 --- /dev/null +++ b/PROJECT/version.h @@ -0,0 +1,7 @@ +#ifndef _VERSION_H_ +#define _VERSION_H_ + +#define DEVICE_FW_VERSION "03.30" + + +#endif // #ifndef _VERSION_H_ \ No newline at end of file diff --git a/settings/solarium.cspy.bat b/settings/solarium.cspy.bat new file mode 100644 index 0000000..c3eceec --- /dev/null +++ b/settings/solarium.cspy.bat @@ -0,0 +1,15 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM + + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armproc.dll" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armjlink.dll" %1 --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armbat.dll" --flash_loader "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\config\flashloader\NXP\FlashNXPLPC512k2.board" --backend -B "--endian=little" "--cpu=ARM7TDMI-S" "--fpu=None" "-p" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\CONFIG\debugger\NXP\iolpc2368.ddf" "--drv_verify_download" "--semihosting" "--device=LPC2368" "--drv_communication=USB0" "--jlink_speed=adaptive" "--jlink_reset_strategy=0,9" + + diff --git a/settings/solarium.dbgdt b/settings/solarium.dbgdt new file mode 100644 index 0000000..63bee96 --- /dev/null +++ b/settings/solarium.dbgdt @@ -0,0 +1,74 @@ + + + + + + + + + 300Find-in-FilesBreakpoints201222 + + + + + + 2091624461300Debug-LogBreakpointsFind-in-Files + + + + + + + 372272727 + + + + + + 200100Disassembly_I05002000 + + + TRangeValueULONG-Max3TVariant32-Val32U4 + {W}Watch-0:state4{W}Watch-0:ulIndex3 + + + + + + 200139313100100 + 200100100100100ExpressionLocationTypeValue233150100237FiscFullStatusFiscShortStatus300Debug-LogBreakpoints35050601200110$PROJ_DIR$\TermIOInput.txt1030010300Debug-LogFind-in-Files200Locals100100100100200100100100100LocationTypeValueVariable150100181168 + + + + + + + + + TabID-16311-17664 + Workspace + Workspace + + + solariumsolarium/DRIVERSsolarium/DRIVERS/modemsolarium/PROJECTsolarium/PROJECT/appsolarium/PROJECT/datasolarium/PROJECT/menusolarium/PROJECT/service + + + + 0TabID-23366-6968Debug LogDebug-LogTabID-1787-14946BreakpointsBreakpointsTabID-31768-15979Find in FilesFind-in-Files0TabID-4750-16799LocalsLocals1001001001000TabID-25216-28894DisassemblyDisassembly0TabID-6501-5953Quick WatchQuickWatch0 + + + + + + TextEditor$WS_DIR$\OS\app\app.c0059059000100000010000001 + + + + + + + iaridepm.enu1debuggergui.enu1-2-2643467-2-2300278156250283673244271658163-2-2242677-2-22002001041672040823536462489800000-22402002001041672040823536462051020000-2439375368195313375510353646208163-2-22651922-2-219242671002083272449156250272449 + + + + diff --git a/settings/solarium.dni b/settings/solarium.dni new file mode 100644 index 0000000..6a63deb --- /dev/null +++ b/settings/solarium.dni @@ -0,0 +1,93 @@ +[JLinkDriver] +WatchCond=_ 0 +Watch0=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0 +Watch1=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0 +[DebugChecksum] +Checksum=-1172248610 +[DisAssemblyWindow] +NumStates=_ 1 +State 1=_ 1 +[InstructionProfiling] +Enabled=_ 0 +[CodeCoverage] +Enabled=_ 0 +[Profiling] +Enabled=0 +[StackPlugin] +Enabled=1 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnHow=0 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Breakpoints] +Count=0 +[TraceHelper] +Enabled=0 +ShowSource=1 +[InterruptLog] +LogEnabled=0 +SumEnabled=0 +GraphEnabled=0 +ShowTimeLog=1 +ShowTimeSum=1 +SumSortOrder=0 +[Stack] +FillEnabled=0 +OverflowWarningsEnabled=1 +WarningThreshold=90 +SpWarningsEnabled=1 +WarnLogOnly=1 +UseTrigger=1 +TriggerName=main +LimitSize=0 +ByteLimit=50 +[Interrupts] +Enabled=1 +[MemoryMap] +Enabled=0 +Base=0 +UseAuto=0 +TypeViolation=1 +UnspecRange=1 +ActionState=1 +[Trace1] +Enabled=0 +ShowSource=1 +[Exceptions] +StopOnUncaught=_ 0 +StopOnThrow=_ 0 +[CallStack] +ShowArgs=0 +[Disassembly] +MixedMode=1 +[struct_types] +Fmt0=TFiscShortStatus-Mode 4 0 +Fmt1=TFiscShortStatus-OperatorNumber 4 0 +Fmt2=TFiscShortStatus-SubMode 4 0 +[array_types] +Fmt0=CPU_INT32U[8] 4 0 +[Log file] +LoggingEnabled=_ 0 +LogFile=_ "" +Category=_ 0 +[TermIOLog] +LoggingEnabled=_ 0 +LogFile=_ "" +[CallStackLog] +Enabled=0 +[DriverProfiling] +Enabled=0 +Mode=0 +Graph=0 +Symbiont=0 +[Disassemble mode] +mode=0 +[Breakpoints2] +Count=0 +[Aliases] +Count=0 +SuppressDialog=0 diff --git a/settings/solarium.wsdt b/settings/solarium.wsdt new file mode 100644 index 0000000..40ce886 --- /dev/null +++ b/settings/solarium.wsdt @@ -0,0 +1,77 @@ + + + + + + solarium/Flash + + + + + + + + + 163272727 + + + + + + 62962754 + + + + + + 2091624461 + 201222 + + + + + + + TabID-4922-2358 + Workspace + Workspace + + + solariumsolarium/DRIVERSsolarium/DRIVERS/ccnetsolarium/DRIVERS/framsolarium/DRIVERS/keyboardsolarium/PROJECTsolarium/PROJECT/appsolarium/PROJECT/datasolarium/PROJECT/menu + + + + 0 + + + TabID-31733-19868 + Find in Files + Find-in-Files + + + + TabID-17681-20541 + Build + Build + + + TabID-13605-29828Debug LogDebug-LogTabID-31897-1342BreakpointsBreakpoints + + 1 + + + + + + TextEditor$WS_DIR$\PROJECT\version.h00777700100000010000001 + + + + + + + iaridepm.enu1-2-2519254-2-216001171300187408718621-2-21611368-2-2137016310029282248281171300 + + + + diff --git a/settings/solarium_Flash.jlink b/settings/solarium_Flash.jlink new file mode 100644 index 0000000..ecbb0a8 --- /dev/null +++ b/settings/solarium_Flash.jlink @@ -0,0 +1,12 @@ +[FLASH] +SkipProgOnCRCMatch = 1 +VerifyDownload = 1 +AllowCaching = 1 +EnableFlashDL = 2 +Override = 0 +Device="ADUC7020X62" +[BREAKPOINTS] +ShowInfoWin = 1 +EnableFlashBP = 2 +[CPU] +AllowSimulation = 1 diff --git a/solarium.dep b/solarium.dep new file mode 100644 index 0000000..3c94da7 --- /dev/null +++ b/solarium.dep @@ -0,0 +1,1316 @@ + + + + 2 + 898057904 + + Flash + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.h + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + $TOOLKIT_DIR$\inc\DLib_Config_Normal.h + $PROJ_DIR$\Flash\Obj\os_mbox.o + $PROJ_DIR$\Flash\Obj\datadesc.pbi + $TOOLKIT_DIR$\inc\c\xtgmath.h + $TOOLKIT_DIR$\inc\limits.h + $TOOLKIT_DIR$\inc\xtls.h + $TOOLKIT_DIR$\inc\c\wchar.h + $PROJ_DIR$\Flash\Obj\os_mbox.pbi + $TOOLKIT_DIR$\inc\c\yvals.h + $TOOLKIT_DIR$\inc\xencoding_limits.h + $PROJ_DIR$\Flash\Obj\os_mutex.o + $TOOLKIT_DIR$\inc\c\ystdio.h + $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $PROJ_DIR$\Flash\Obj\mode.o + $TOOLKIT_DIR$\inc\c\math.h + $PROJ_DIR$\Flash\Obj\os_cpu_c.o + $PROJ_DIR$\Flash\Obj\os_sem.o + $PROJ_DIR$\Flash\Obj\uart0.o + $PROJ_DIR$\Flash\Obj\os_mem.o + $TOOLKIT_DIR$\inc\c\xlocale_c.h + $PROJ_DIR$\Flash\Obj\time.pbi + $TOOLKIT_DIR$\inc\intrinsics.h + $TOOLKIT_DIR$\inc\c\io_macros.h + $PROJ_DIR$\Flash\Obj\modem_task.pbi + $PROJ_DIR$\Flash\Obj\app_serv.pbi + $PROJ_DIR$\Flash\Obj\validator.pbi + $PROJ_DIR$\Flash\Obj\os_core.o + $PROJ_DIR$\Flash\Obj\lib_mem.o + $TOOLKIT_DIR$\inc\c\stdio.h + $TOOLKIT_DIR$\lib\rt4t_al.a + $PROJ_DIR$\Flash\Obj\os_tmr.o + $PROJ_DIR$\Flash\Obj\os_time.pbi + $PROJ_DIR$\Flash\Obj\cstartup.o + $PROJ_DIR$\PROJECT\data\datadesc.c + $PROJ_DIR$\PROJECT\app\modem_task.h + $PROJ_DIR$\PROJECT\data\fram_map.h + $PROJ_DIR$\PROJECT\data\datadesc.h + $PROJ_DIR$\PROJECT\service\coin.c + $PROJ_DIR$\PROJECT\service\mode.c + $PROJ_DIR$\PROJECT\service\mode.h + $PROJ_DIR$\PROJECT\service\time.c + $PROJ_DIR$\PROJECT\data\data.h + $PROJ_DIR$\PROJECT\tools\crc16.h + $PROJ_DIR$\PROJECT\service\fr.h + $PROJ_DIR$\PROJECT\service\time.h + $PROJ_DIR$\PROJECT\service\coin.h + $PROJ_DIR$\PROJECT\service\fr.c + $PROJ_DIR$\PROJECT\tools\crc16.c + $PROJ_DIR$\Flash\Obj\uart1.o + $PROJ_DIR$\PROJECT\service\validator.c + $PROJ_DIR$\PROJECT\menu\menudesc.c + $PROJ_DIR$\Flash\Obj\data.o + $PROJ_DIR$\PROJECT\data\data.c + $PROJ_DIR$\PROJECT\menu\menudesc.h + $PROJ_DIR$\PROJECT\menu\menu.h + $PROJ_DIR$\Flash\Obj\CCRSProtocol.pbi + $PROJ_DIR$\PROJECT\menu\menu.c + $PROJ_DIR$\PROJECT\service\validator.h + $PROJ_DIR$\PROJECT\version.h + $PROJ_DIR$\Flash\Obj\validator.o + $PROJ_DIR$\Flash\Obj\fram.o + $TOOLKIT_DIR$\lib\m4t_tl.a + $PROJ_DIR$\DRIVERS\modem\uart.c + $PROJ_DIR$\Flash\Obj\modem.pbi + $TOOLKIT_DIR$\inc\io_macros.h + $PROJ_DIR$\DRIVERS\ccnet\Command.h + $PROJ_DIR$\Flash\Obj\keyboard.o + $TOOLKIT_DIR$\inc\xlocaleuse.h + $PROJ_DIR$\Flash\Obj\journal.pbi + $PROJ_DIR$\Flash\Obj\os_flag.pbi + $PROJ_DIR$\Flash\Obj\app.pbi + $TOOLKIT_DIR$\inc\errno.h + $PROJ_DIR$\Flash\Obj\menu.o + $PROJ_DIR$\DRIVERS\lcd.h + $TOOLKIT_DIR$\inc\xmtx.h + $PROJ_DIR$\Flash\Obj\lcd.o + $TOOLKIT_DIR$\inc\c\stddef.h + $TOOLKIT_DIR$\inc\c\xencoding_limits.h + $TOOLKIT_DIR$\inc\c\DLib_Threads.h + $PROJ_DIR$\Flash\Obj\cpu_a.o + $PROJ_DIR$\Flash\Obj\datadesc.o + $TOOLKIT_DIR$\inc\c\errno.h + $PROJ_DIR$\Flash\Obj\lib_mem.pbi + $PROJ_DIR$\Flash\Obj\crc16.pbi + $TOOLKIT_DIR$\inc\c\xmtx.h + $TOOLKIT_DIR$\inc\c\ctype.h + $TOOLKIT_DIR$\inc\string.h + $TOOLKIT_DIR$\inc\c\xlocale.h + $TOOLKIT_DIR$\inc\c\limits.h + $TOOLKIT_DIR$\inc\c\ycheck.h + $PROJ_DIR$\Flash\Obj\os_time.o + $PROJ_DIR$\Flash\Obj\bsp.pbi + $TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h + $TOOLKIT_DIR$\inc\stdarg.h + $PROJ_DIR$\Flash\Obj\coin.o + $PROJ_DIR$\Flash\Obj\modem_task.o + $TOOLKIT_DIR$\lib\shs_l.a + $TOOLKIT_DIR$\inc\DLib_Product_string.h + $PROJ_DIR$\Flash\Obj\os_sem.pbi + $PROJ_DIR$\Flash\Obj\app.o + $PROJ_DIR$\Flash\Exe\solarium.out + $TOOLKIT_DIR$\lib\dl4t_tln.a + $PROJ_DIR$\Flash\Obj\menu.pbi + $PROJ_DIR$\Flash\Obj\uart.pbi + $PROJ_DIR$\Flash\Obj\uart2.pbi + $PROJ_DIR$\Flash\Obj\solarium.pbd + $TOOLKIT_DIR$\inc\ctype.h + $PROJ_DIR$\Flash\Obj\uart.o + $PROJ_DIR$\Flash\Obj\os_mem.pbi + $TOOLKIT_DIR$\inc\xlocale.h + $PROJ_DIR$\Flash\Obj\crc16.o + $TOOLKIT_DIR$\inc\xlocale_c.h + $PROJ_DIR$\Flash\Obj\lib_str.pbi + $TOOLKIT_DIR$\inc\ycheck.h + $PROJ_DIR$\Flash\Obj\data.pbi + $PROJ_DIR$\Flash\Obj\os_flag.o + $PROJ_DIR$\Flash\Obj\os_core.pbi + $PROJ_DIR$\Flash\Obj\os_dbg.o + $TOOLKIT_DIR$\inc\c\DLib_Product_string.h + $PROJ_DIR$\Flash\Obj\menudesc.o + $PROJ_DIR$\Flash\Obj\lcd.pbi + $TOOLKIT_DIR$\inc\wchar.h + $TOOLKIT_DIR$\inc\c\xlocaleuse.h + $PROJ_DIR$\Flash\Obj\os_mutex.pbi + $PROJ_DIR$\DRIVERS\modem\uart.h + $PROJ_DIR$\Flash\Exe\solarium.hex + $TOOLKIT_DIR$\inc\c\ymath.h + $TOOLKIT_DIR$\inc\yvals.h + $PROJ_DIR$\Flash\Obj\Command.pbi + $PROJ_DIR$\Flash\Obj\fiscal.pbi + $PROJ_DIR$\Flash\Obj\lib_str.o + $TOOLKIT_DIR$\inc\DLib_Defaults.h + $PROJ_DIR$\Flash\Obj\control.pbi + $TOOLKIT_DIR$\inc\stdio.h + $PROJ_DIR$\DRIVERS\ccnet\Command.c + $TOOLKIT_DIR$\inc\c\DLib_Product.h + $PROJ_DIR$\Flash\Obj\os_q.o + $PROJ_DIR$\Flash\Obj\uart2.o + $PROJ_DIR$\Flash\Obj\app_serv.o + $PROJ_DIR$\Flash\Obj\fr.pbi + $PROJ_DIR$\Flash\Obj\spi.pbi + $PROJ_DIR$\Flash\Obj\os_cpu_c.pbi + $PROJ_DIR$\Flash\Obj\journal.o + $PROJ_DIR$\Flash\Obj\os_dcc.o + $TOOLKIT_DIR$\inc\ysizet.h + $TOOLKIT_DIR$\inc\c\string.h + $PROJ_DIR$\Flash\Obj\control.o + $TOOLKIT_DIR$\inc\DLib_Threads.h + $PROJ_DIR$\Flash\Obj\fr.o + $PROJ_DIR$\Flash\Obj\spi.o + $TOOLKIT_DIR$\inc\c\stdlib.h + $TOOLKIT_DIR$\inc\c\ysizet.h + $PROJ_DIR$\Flash\Obj\os_task.o + $PROJ_DIR$\Flash\Obj\os_tmr.pbi + $PROJ_DIR$\Flash\Obj\modem.o + $PROJ_DIR$\Flash\Obj\fiscal.o + $PROJ_DIR$\Flash\Obj\bsp.o + $TOOLKIT_DIR$\inc\DLib_Product.h + $PROJ_DIR$\Flash\Obj\os_cpu_a.o + $PROJ_DIR$\Flash\Obj\time.o + $PROJ_DIR$\Flash\Obj\keyboard.pbi + $PROJ_DIR$\Flash\Obj\os_dbg.pbi + $PROJ_DIR$\Flash\Obj\os_dcc.pbi + $PROJ_DIR$\Flash\Obj\mode.pbi + $PROJ_DIR$\Flash\Obj\menudesc.pbi + $PROJ_DIR$\Flash\Obj\os_task.pbi + $PROJ_DIR$\Flash\Obj\coin.pbi + $PROJ_DIR$\Flash\Obj\uart0.pbi + $TOOLKIT_DIR$\inc\c\stdarg.h + $TOOLKIT_DIR$\inc\c\intrinsics.h + $PROJ_DIR$\Flash\Obj\os_q.pbi + $TOOLKIT_DIR$\inc\stdlib.h + $PROJ_DIR$\Flash\Obj\fram.pbi + $PROJ_DIR$\Flash\Obj\uart1.pbi + $TOOLKIT_DIR$\inc\c\xtls.h + $PROJ_DIR$\Flash\Obj\CCRSProtocol.o + $PROJ_DIR$\DRIVERS\lcd.c + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + $PROJ_DIR$\PROJECT\app\journal.c + $PROJ_DIR$\OS\uc\lib\lib_str.c + $PROJ_DIR$\OS\uc\lib\lib_str.h + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + $PROJ_DIR$\OS\uc\lib\lib_def.h + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu.h + $PROJ_DIR$\OS\uc\os_ii\source\ucos_ii.h + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + $PROJ_DIR$\OS\uc\cpu\cpu_def.h + $PROJ_DIR$\OS\uc\lib\lib_mem.c + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + $PROJ_DIR$\PROJECT\app\app_serv.c + $PROJ_DIR$\PROJECT\app\app_serv.h + $PROJ_DIR$\PROJECT\app\control.h + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + $PROJ_DIR$\PROJECT\app\journal.h + $PROJ_DIR$\OS\uc\lib\lib_mem.h + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + $PROJ_DIR$\OS\bsp\LPC2368_Flash.mac + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + $PROJ_DIR$\PROJECT\app\control.c + $PROJ_DIR$\PROJECT\app\modem_task.c + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + $PROJ_DIR$\OS\uc\cpu\cpu.h + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + $PROJ_DIR$\DRIVERS\fiscal\fiscal.h + $PROJ_DIR$\DRIVERS\modem\modem.h + $PROJ_DIR$\DRIVERS\keyboard\keyboard.h + $PROJ_DIR$\DRIVERS\ccnet\VMCConst.h + $PROJ_DIR$\DRIVERS\modem\modem.c + $PROJ_DIR$\DRIVERS\lcd\lcd.c + $PROJ_DIR$\OS\app\app.c + $PROJ_DIR$\DRIVERS\fram\fram.h + $PROJ_DIR$\OS\bsp\bsp.c + $PROJ_DIR$\OS\bsp\bsp.h + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + $PROJ_DIR$\DRIVERS\modem\uart2.c + $PROJ_DIR$\DRIVERS\modem\uart2.h + $PROJ_DIR$\DRIVERS\fram\spi.h + $PROJ_DIR$\OS\app\app_cfg.h + $PROJ_DIR$\OS\app\includes.h + $PROJ_DIR$\OS\app\os_cfg.h + $PROJ_DIR$\DRIVERS\fiscal\uart0.h + $PROJ_DIR$\DRIVERS\fram\spi.c + $PROJ_DIR$\DRIVERS\fram\fram.c + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + $PROJ_DIR$\DRIVERS\lcd\lcd.h + $PROJ_DIR$\OS\bsp\cstartup.s + $PROJ_DIR$\OS\bsp\iolpc2368.h + $PROJ_DIR$\DRIVERS\ccnet\uart1.h + $PROJ_DIR$\OS\bsp\LPC2368_Flash.icf + + + [ROOT_NODE] + + + ILINK + 103 + + + + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + + + BICOMP + 58 + + + ICCARM + 178 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 1 215 60 237 17 129 6 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 1 215 60 237 17 129 6 + + + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + + + BICOMP + 176 + + + ICCARM + 51 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 237 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 237 + + + + + $PROJ_DIR$\PROJECT\data\datadesc.c + + + BICOMP + 5 + + + ICCARM + 83 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 44 39 199 57 56 201 212 38 79 47 45 37 198 213 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 44 39 199 57 56 201 212 38 79 47 45 37 198 213 + + + + + $PROJ_DIR$\PROJECT\service\coin.c + + + BICOMP + 169 + + + ICCARM + 97 + + + + + BICOMP + 236 25 188 227 229 187 210 191 198 48 44 39 199 213 + + + ICCARM + 236 25 188 227 229 187 210 191 198 48 44 39 199 213 + + + + + $PROJ_DIR$\PROJECT\service\mode.c + + + BICOMP + 166 + + + ICCARM + 16 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 42 198 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 42 198 + + + + + $PROJ_DIR$\PROJECT\service\time.c + + + BICOMP + 23 + + + ICCARM + 162 + + + + + BICOMP + 236 25 188 227 229 187 210 191 198 47 153 92 11 15 138 80 81 154 31 14 148 121 + + + ICCARM + 236 25 188 227 229 187 210 191 198 47 153 92 11 15 95 138 80 81 154 31 14 148 121 + + + + + $PROJ_DIR$\PROJECT\service\fr.c + + + BICOMP + 142 + + + ICCARM + 151 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 212 46 230 44 39 199 201 47 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 212 46 230 44 39 199 201 47 + + + + + $PROJ_DIR$\PROJECT\tools\crc16.c + + + BICOMP + 86 + + + ICCARM + 113 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 45 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 45 + + + + + $PROJ_DIR$\PROJECT\service\validator.c + + + BICOMP + 28 + + + ICCARM + 62 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 60 1 237 198 201 199 212 44 39 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 60 1 237 198 201 199 212 44 39 + + + + + $PROJ_DIR$\PROJECT\menu\menudesc.c + + + BICOMP + 167 + + + ICCARM + 122 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 57 56 201 199 212 44 39 47 42 61 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 57 56 201 199 212 44 39 47 42 61 + + + + + $PROJ_DIR$\PROJECT\data\data.c + + + BICOMP + 117 + + + ICCARM + 54 + + + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 44 39 199 219 47 79 + + + + + $PROJ_DIR$\PROJECT\menu\menu.c + + + BICOMP + 105 + + + ICCARM + 75 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 57 56 201 199 212 44 214 234 42 198 47 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 57 56 201 199 212 44 214 234 42 198 47 + + + + + $PROJ_DIR$\DRIVERS\modem\uart.c + + + BICOMP + 106 + + + ICCARM + 110 + + + + + BICOMP + 228 136 116 130 134 160 12 150 147 89 100 109 112 8 77 174 70 114 124 96 236 67 188 227 229 187 210 191 186 202 183 74 7 221 127 + + + ICCARM + 228 136 116 130 134 3 160 12 150 147 89 100 109 112 8 77 174 70 114 124 96 236 67 188 227 229 187 210 191 186 202 183 74 7 221 127 + + + + + $PROJ_DIR$\Flash\Exe\solarium.out + + + OBJCOPY + 128 + + + + + ILINK + 238 178 102 141 159 97 149 82 113 35 54 83 158 151 63 145 69 78 30 133 75 122 16 157 98 29 161 18 120 146 118 4 21 13 139 19 155 93 33 152 162 20 51 140 62 99 32 64 104 + + + + + $PROJ_DIR$\Flash\Obj\solarium.pbd + + + BILINK + 58 73 27 94 169 135 86 117 5 132 142 175 71 163 123 85 115 105 167 166 66 26 119 144 164 165 72 10 111 126 173 101 168 34 156 143 23 170 176 107 28 + + + + + $PROJ_DIR$\DRIVERS\ccnet\Command.c + + + BICOMP + 131 + + + + + BICOMP + 68 136 116 130 134 160 12 150 147 + + + ICCARM + 68 136 116 130 134 3 160 12 150 147 + + + + + $PROJ_DIR$\DRIVERS\lcd.c + + + BICOMP + 123 + + + ICCARM + 78 + + + + + BICOMP + 228 136 116 130 134 160 12 150 147 89 100 109 112 8 77 174 70 114 124 96 236 67 188 227 229 187 210 191 186 202 183 74 7 221 24 76 + + + ICCARM + 228 136 116 130 134 3 160 12 150 147 89 100 109 112 8 77 174 70 114 124 96 236 67 188 227 229 187 210 191 186 202 183 74 7 221 24 76 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + + + BICOMP + 144 + + + ICCARM + 18 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\PROJECT\app\journal.c + + + BICOMP + 71 + + + ICCARM + 145 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 79 201 199 212 219 38 39 44 47 46 45 42 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 79 201 199 212 219 38 39 44 47 46 45 42 + + + + + $PROJ_DIR$\OS\uc\lib\lib_str.c + + + BICOMP + 115 + + + ICCARM + 133 + + + + + BICOMP + 183 210 191 186 227 153 92 11 15 138 80 81 154 88 90 177 87 125 22 9 84 91 31 14 + + + ICCARM + 183 210 191 186 227 153 92 11 15 95 138 80 81 154 88 90 177 87 125 22 9 84 91 31 14 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + + + BICOMP + 119 + + + ICCARM + 29 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + + + BICOMP + 101 + + + ICCARM + 19 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + + + BICOMP + 165 + + + ICCARM + 146 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + + + BICOMP + 111 + + + ICCARM + 21 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\lib\lib_mem.c + + + BICOMP + 85 + + + ICCARM + 30 + + + + + BICOMP + 202 210 191 186 227 + + + ICCARM + 202 210 191 186 227 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + + + AARM + 161 + + + + + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + + + AARM + 82 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + + + BICOMP + 34 + + + ICCARM + 93 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + + + BICOMP + 156 + + + ICCARM + 33 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\PROJECT\app\app_serv.c + + + BICOMP + 27 + + + ICCARM + 141 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 213 60 48 47 212 57 44 42 56 201 199 39 1 46 45 37 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 213 60 48 47 212 57 44 42 56 201 199 39 1 46 45 37 + + + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + + + BICOMP + 164 + + + ICCARM + 120 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + + + BICOMP + 72 + + + ICCARM + 118 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + + + BICOMP + 10 + + + ICCARM + 4 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + + + BICOMP + 126 + + + ICCARM + 13 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\PROJECT\app\control.c + + + BICOMP + 135 + + + ICCARM + 149 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 199 44 39 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 199 44 39 + + + + + $PROJ_DIR$\PROJECT\app\modem_task.c + + + BICOMP + 26 + + + ICCARM + 98 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 201 199 212 213 37 198 44 39 47 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 201 199 212 213 37 198 44 39 47 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + + + BICOMP + 173 + + + ICCARM + 139 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + + + BICOMP + 168 + + + ICCARM + 155 + + + + + BICOMP + 188 227 229 187 + + + ICCARM + 188 227 229 187 + + + + + $PROJ_DIR$\DRIVERS\modem\modem.c + + + BICOMP + 66 + + + ICCARM + 157 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 213 37 198 44 39 199 225 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 213 37 198 44 39 199 225 + + + + + $PROJ_DIR$\DRIVERS\lcd\lcd.c + + + BICOMP + 123 + + + ICCARM + 78 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 172 234 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 172 234 + + + + + $PROJ_DIR$\OS\app\app.c + + + BICOMP + 73 + + + ICCARM + 102 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 234 226 214 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 198 234 226 214 + + + + + $PROJ_DIR$\OS\bsp\bsp.c + + + BICOMP + 94 + + + ICCARM + 159 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 + + + + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + + + BICOMP + 132 + + + ICCARM + 158 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 230 212 46 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 230 212 46 + + + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + + + BICOMP + 170 + + + ICCARM + 20 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 230 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 230 + + + + + $PROJ_DIR$\DRIVERS\modem\uart2.c + + + BICOMP + 107 + + + ICCARM + 140 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 225 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 225 + + + + + $PROJ_DIR$\DRIVERS\fram\spi.c + + + BICOMP + 143 + + + ICCARM + 152 + + + + + BICOMP + 236 25 188 227 229 187 153 92 11 15 138 80 81 154 210 191 226 + + + ICCARM + 236 25 188 227 229 187 153 92 11 15 95 138 80 81 154 210 191 226 + + + + + $PROJ_DIR$\DRIVERS\fram\fram.c + + + BICOMP + 175 + + + ICCARM + 63 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 226 219 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 226 219 + + + + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + + + BICOMP + 163 + + + ICCARM + 69 + + + + + BICOMP + 228 31 92 11 15 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 214 198 + + + ICCARM + 228 31 92 11 15 95 138 80 81 154 14 148 121 88 90 177 87 153 125 22 9 171 236 25 188 227 229 187 210 191 186 202 183 84 91 221 214 198 + + + + + $PROJ_DIR$\OS\bsp\cstartup.s + + + AARM + 35 + + + + + + + diff --git a/solarium.ewd b/solarium.ewd new file mode 100644 index 0000000..8d8bd6e --- /dev/null +++ b/solarium.ewd @@ -0,0 +1,888 @@ + + + + 2 + + Flash + + ARM + + 1 + + C-SPY + 2 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + ANGEL_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IARROM_ID + 2 + + 1 + 1 + 1 + + + + + + + + + JLINK_ID + 2 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + MACRAIGOR_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + PEMICRO_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + + + + + + + RDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + STLINK_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + XDS100_ID + 2 + + 0 + 1 + 1 + + + + + + + $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB6_Plugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin + 1 + + + + + + diff --git a/solarium.ewp b/solarium.ewp new file mode 100644 index 0000000..9a0f15d --- /dev/null +++ b/solarium.ewp @@ -0,0 +1,1239 @@ + + + + 2 + + Flash + + ARM + + 1 + + General + 3 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 28 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 13 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + DRIVERS + + ccnet + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.c + + + $PROJ_DIR$\DRIVERS\ccnet\CCRSProtocol.h + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.c + + + $PROJ_DIR$\DRIVERS\ccnet\uart1.h + + + $PROJ_DIR$\DRIVERS\ccnet\VMCConst.h + + + + fiscal + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.c + + + $PROJ_DIR$\DRIVERS\fiscal\fiscal.h + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.c + + + $PROJ_DIR$\DRIVERS\fiscal\uart0.h + + + + fram + + $PROJ_DIR$\DRIVERS\fram\fram.c + + + $PROJ_DIR$\DRIVERS\fram\fram.h + + + $PROJ_DIR$\DRIVERS\fram\spi.c + + + $PROJ_DIR$\DRIVERS\fram\spi.h + + + + keyboard + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.c + + + $PROJ_DIR$\DRIVERS\keyboard\keyboard.h + + + + lcd + + $PROJ_DIR$\DRIVERS\lcd\lcd.c + + + $PROJ_DIR$\DRIVERS\lcd\lcd.h + + + + modem + + $PROJ_DIR$\DRIVERS\modem\modem.c + + + $PROJ_DIR$\DRIVERS\modem\modem.h + + + $PROJ_DIR$\DRIVERS\modem\uart2.c + + + $PROJ_DIR$\DRIVERS\modem\uart2.h + + + + + OS + + app + + $PROJ_DIR$\OS\app\app.c + + + $PROJ_DIR$\OS\app\app_cfg.h + + + $PROJ_DIR$\OS\app\includes.h + + + $PROJ_DIR$\OS\app\os_cfg.h + + + + bsp + + $PROJ_DIR$\OS\bsp\bsp.c + + + $PROJ_DIR$\OS\bsp\bsp.h + + + $PROJ_DIR$\OS\bsp\cstartup.s + + + $PROJ_DIR$\OS\bsp\iolpc2368.h + + + $PROJ_DIR$\OS\bsp\LPC2368_Flash.icf + + + $PROJ_DIR$\OS\bsp\LPC2368_Flash.mac + + + + uc + + cpu + + $PROJ_DIR$\OS\uc\cpu\cpu.h + + + $PROJ_DIR$\OS\uc\cpu\cpu_a.s + + + $PROJ_DIR$\OS\uc\cpu\cpu_def.h + + + + lib + + $PROJ_DIR$\OS\uc\lib\lib_def.h + + + $PROJ_DIR$\OS\uc\lib\lib_mem.c + + + $PROJ_DIR$\OS\uc\lib\lib_mem.h + + + $PROJ_DIR$\OS\uc\lib\lib_str.c + + + $PROJ_DIR$\OS\uc\lib\lib_str.h + + + + os_ii + + port + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu.h + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_a.asm + + + $PROJ_DIR$\OS\uc\os_ii\port\os_cpu_c.c + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dbg.c + + + $PROJ_DIR$\OS\uc\os_ii\port\os_dcc.c + + + + source + + $PROJ_DIR$\OS\uc\os_ii\source\os_core.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_flag.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mbox.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mem.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_mutex.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_q.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_sem.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_task.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_time.c + + + $PROJ_DIR$\OS\uc\os_ii\source\os_tmr.c + + + $PROJ_DIR$\OS\uc\os_ii\source\ucos_ii.h + + + + + + + PROJECT + + app + + $PROJ_DIR$\PROJECT\app\app_serv.c + + + $PROJ_DIR$\PROJECT\app\app_serv.h + + + $PROJ_DIR$\PROJECT\app\control.c + + + $PROJ_DIR$\PROJECT\app\control.h + + + $PROJ_DIR$\PROJECT\app\journal.c + + + $PROJ_DIR$\PROJECT\app\journal.h + + + $PROJ_DIR$\PROJECT\app\modem_task.c + + + $PROJ_DIR$\PROJECT\app\modem_task.h + + + + data + + $PROJ_DIR$\PROJECT\data\data.c + + + $PROJ_DIR$\PROJECT\data\data.h + + + $PROJ_DIR$\PROJECT\data\datadesc.c + + + $PROJ_DIR$\PROJECT\data\datadesc.h + + + $PROJ_DIR$\PROJECT\data\fram_map.h + + + + menu + + $PROJ_DIR$\PROJECT\menu\menu.c + + + $PROJ_DIR$\PROJECT\menu\menu.h + + + $PROJ_DIR$\PROJECT\menu\menudesc.c + + + $PROJ_DIR$\PROJECT\menu\menudesc.h + + + + service + + $PROJ_DIR$\PROJECT\service\coin.c + + + $PROJ_DIR$\PROJECT\service\coin.h + + + $PROJ_DIR$\PROJECT\service\fr.c + + + $PROJ_DIR$\PROJECT\service\fr.h + + + $PROJ_DIR$\PROJECT\service\mode.c + + + $PROJ_DIR$\PROJECT\service\mode.h + + + $PROJ_DIR$\PROJECT\service\time.c + + + $PROJ_DIR$\PROJECT\service\time.h + + + $PROJ_DIR$\PROJECT\service\validator.c + + + $PROJ_DIR$\PROJECT\service\validator.h + + + + tools + + $PROJ_DIR$\PROJECT\tools\crc16.c + + + $PROJ_DIR$\PROJECT\tools\crc16.h + + + + $PROJ_DIR$\PROJECT\version.h + + + + + diff --git a/solarium.eww b/solarium.eww new file mode 100644 index 0000000..2bd0ca8 --- /dev/null +++ b/solarium.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\solarium.ewp + + + + + diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..2a4e912 --- /dev/null +++ b/todo.txt @@ -0,0 +1,54 @@ + . + ++ 1. e-mail , ( ) (, ). + + : + / + : , 1 , 2 , 4 , 8 , 12 , 24 . + : / + * . + + : + + e-mail + ++ 2. : + // . + - , crc. + ++ 3. . + ++ 4. , . + , .. 2 , . + -> id . id e-mail. + ++ 5. : + . + - , . + ++ 6. + e-mail + + " ", " ". + + . + ++ 7. - . + ++ 8. e-mail. . + +------------------------------------------------------ + ++ 9. . ++ 10. - . ++ 11. - "Test message from modem." ++ 13. , . ++ 14. . + +------------------------------------------------------ + +* 12. . + +------------------------------------------------------ + ++ 15. e-mail , + > 0. ++ 16. . ++ 16. . diff --git a/параметры.txt b/параметры.txt new file mode 100644 index 0000000..b94ae6c --- /dev/null +++ b/параметры.txt @@ -0,0 +1,63 @@ +1. : + +- : / +- - 0-120 . +- - - 0-15 . +- , . 1-120 +- , . 1-120 + + : + +- : "-", "-", "-", "-" +- , : + T1 - , , + T2 - , , + T3 - , , + T4 - , , + 4 +- : + , . 0-9999 + , . + + + +2. - . + + + +3. : + +- , . +- , . +- , . +- , . +- , . +- , . + + - . + + + +4. : + +- + : + - + - + - +- + : + - + - + - +- : , . + : + - + - +- : , . + : + - + - + + +* 1 2, 3 4 * \ No newline at end of file diff --git a/список выводов.xls b/список выводов.xls new file mode 100644 index 0000000000000000000000000000000000000000..6df6774de5dc9cd7dff6d5ca414aadd98acd8c95 GIT binary patch literal 14336 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 literal 0 HcmV?d00001

}kmq#z=IqwHh-VXE7WACxrVIJ~!pu8Po+|$nPKg2ZW1Lb^(t&Dt# zCC&%R`7o}2z5@6g!T6j`6!I5=;@7}zxhzLmv22X|dPz4(x=~V!18O%)6ytRlm81Rr zgdz7e!f5}tq=%^-{Ioj|okDa}e4kBxEx<(2lJ(1oUIYCSUq$the^ zAE0tL{kWvhNcw`LFM~#Q!7ifE|2k2~f0HQW{0}I#$8YR7%>#`f9!iLUf2J&Nk(mC^ z1Zp=*6n@bEfk5<2vi>VXA%DNbV?@FKJEGuwU6#K|6ny^+nw^FIfsdq*{tpA97N~xO z`2RcfZ8#kez7qBj#X_`<_{a{T;Qy+`Pf9#4@#_-f2ZlUhS_cA@V@Q~{sAgts^KJoP<~0Z@t!grLWdMc}&$W&Y&vmoe~R zJDHH?qeSh7Wv7T;%+Kieqvq5T^J6>sY(HqNq?E~z8^O0vRC_-Cel%N*UF+cx!0*Qa z@Qr8S^ZRk@WO3i&XZ4TAJK(eZD3Q#W{0K~8Y=PRLlGpFY;;CXS_v`ihaTt6x8RYr> zu%?N<#4pe9$5!y!e$d&0QYJrkgRdcjUcVm)PRl%Qem^!$hn@`b{C@P+oR}Yvg3tB? zA@Y#MqG*6lQ*bcrMGU)aD5x_wroq^9k9$UdTo`H|{C~Tv{cGdbh{J3L7hu)5y zI=%LS?=q*>&G`9BT272_H~0>?Vw{{`-lDnUF2P}t89(2l6XY9i75C=HlQ#yw6R~gi zyv%Xsw=V~0&rJQd4~D4yJPN);e&c{2#G{@|)}M*9Fv{p$l81*9#nqE|RC$NMS51|^ z^a8Ld?|tx5dy>~Kc?tXV2F`Nz(pi&ICcW2!??m+O1D~yTsSwApU+;eK?MFS?SFZ5+ z{oOF1F-z8~#P9DY_-wr$iafvG-Qc?w^`!S?h0m|oT5w`|7lF^#yIhgy*SidSdr?n% zrzm`Wy|00NC`EfoTN}2TDxJc}8#7Ao_rA&HD+D^>hX7Jg1 z*9&nO^_~U3QPh*(7KP8>&yRrbMCQ@BqW2<2-XDc zJdwSAd0WBPfN~vA8Rrsy`Q`0XzDtvxUg_IRA8@cHG{fX|kPR}7x0onPL1MIMg64xeA%2Jl&^)$!nH&Qm6Nql!GzPbt%Q z>{jIAXvtG1dHWQ3IHEXwe*5+-@^CbA_)hl4=@|G9qm29@eUyk!M;ZP(>BmdNxy~t& W8Tvn2)wn+dzG2jnyrkqIdH)A1p}X1u literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_sem.pbi b/Flash/Obj/os_sem.pbi new file mode 100644 index 0000000..f5f7a42 --- /dev/null +++ b/Flash/Obj/os_sem.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 14s +C:\work\solarium\OS\uc\os_ii\source\os_sem.c +C:\work\solarium\OS\uc\os_ii\source\os_sem.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_task.o b/Flash/Obj/os_task.o new file mode 100644 index 0000000000000000000000000000000000000000..91455073854f90e5e38e4d2cdac664ea7025cbca GIT binary patch literal 29992 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 W6DM;V`Z^)^4*1mWR($9neg6mAnOzzH literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_task.pbi b/Flash/Obj/os_task.pbi new file mode 100644 index 0000000..a30286f --- /dev/null +++ b/Flash/Obj/os_task.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 14s +C:\work\solarium\OS\uc\os_ii\source\os_task.c +C:\work\solarium\OS\uc\os_ii\source\os_task.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_time.o b/Flash/Obj/os_time.o new file mode 100644 index 0000000000000000000000000000000000000000..fd2b2e022a02b1b548d0fc57953a73eca1930c23 GIT binary patch literal 13848 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 literal 0 HcmV?d00001 diff --git a/Flash/Obj/os_time.pbi b/Flash/Obj/os_time.pbi new file mode 100644 index 0000000..72a3d47 --- /dev/null +++ b/Flash/Obj/os_time.pbi @@ -0,0 +1,63 @@ +This is an internal working file generated by the Source Browser. +21:01 14s +C:\work\solarium\OS\uc\os_ii\source\os_time.c +C:\work\solarium\OS\uc\os_ii\source\os_time.c +--diag_suppress +Pa039 +-o +C:\work\solarium\Flash\Obj\ +--no_cse +--no_unroll +--no_inline +--no_code_motion +--no_tbaa +--no_clustering +--no_scheduling +--debug +--endian=little +--cpu=ARM7TDMI-S +-e +--fpu=None +--dlib_config +C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\INC\c\DLib_Config_Normal.h +-I +C:\work\solarium\OS\app\ +-I +C:\work\solarium\OS\bsp\ +-I +C:\work\solarium\OS\uc\cpu\ +-I +C:\work\solarium\OS\uc\lib\ +-I +C:\work\solarium\OS\uc\os_ii\port\ +-I +C:\work\solarium\OS\uc\os_ii\source\ +-I +C:\work\solarium\DRIVERS\lcd\ +-I +C:\work\solarium\DRIVERS\keyboard\ +-I +C:\work\solarium\DRIVERS\fram\ +-I +C:\work\solarium\DRIVERS\ccnet\ +-I +C:\work\solarium\DRIVERS\fiscal\ +-I +C:\work\solarium\DRIVERS\modem\ +-I +C:\work\solarium\PROJECT\ +-I +C:\work\solarium\PROJECT\app\ +-I +C:\work\solarium\PROJECT\service\ +-I +C:\work\solarium\PROJECT\menu\ +-I +C:\work\solarium\PROJECT\data\ +-I +C:\work\solarium\PROJECT\tools\ +--interwork +--cpu_mode +thumb +-On +--use_c++_inline diff --git a/Flash/Obj/os_tmr.o b/Flash/Obj/os_tmr.o new file mode 100644 index 0000000000000000000000000000000000000000..35855961127cf39e1c64252616bead7d85fc9653 GIT binary patch literal 35660 zcmc(I34B$>z5kqZ_nU=4azhB)4FpXH2}wvoK-3_M1d!c5dUKOpNH8QZ3yY#gMWw9^ zKDEVaE7qmf_B~O-VvGNxQpN2Vs#aUIjn%4E|1Pb4wofhZ`CDc*Q`mjb+eL|cxOpx_nP*mL@O(4N;LGWinX@1C9HZ&+sbxU(w$fj(N&%8JsrG9 zZ0*WKtT_>HN_1L+D?8(B(5o}iDz!)k=~vaxTy|PXyt})zrJ<)g(Pi~+ZEv)y@rH)Z z#9CF8@Iff)=xJz!A#`*sIXoe=Cf+EzI3gk>!n!}i6X8({oL=Shb#bhbcc?o4UiR66 z5~m5Z&koGS&y7C8G+2-=Lp9a!;CfUu6x;z^q2SAbvlM(IaE^lS1RkZ}2Z5ssejGSo z!TW&=6#N$OBn5v4T&iG7wXkzl7jC8{(*vb0)L_4eZbe?phEt>j`{)xe}Z~k z!5)l7K*8C-7b>_AIHBMfz*7{w82AzeHvo@Ta1Ze53f>HSs)BC={=0(j2ae&e{C^a6 zpMv+HUaR0&QLj|+yQrV8;J>3jQo&x#?VXCfY+xEA%U%KSg9@Gw{DOiP0za+b^MUs( zxC8hy#ondB$K$Z{UyJ%bmG;|!DF&3&nSx&hrWmdM?*iYT;Lm}F z;;`CHFUC{B8Nj0zJO=n4rT--0FBCi-_(=uN1AbG%X8bCki-PY${Xqpkg!+#a{5a}wDYy^y&lLPe)UT536`c|QxrTO^;rr&7xg)acLo9^{i}d42dMeH<$Tw$^9rPuGrS(=r%j zGhFh=bN|)$1!$in^Nac~cgas;4ZyRN_6uC?W$Ys0UZwp?S9=xr&$?ca{(nO|os*&j z*=;WQ6S#kB`~7I2kNL9XA9l&tuqS}KmGZu+lA{j`Bc{IYER?-Tk$ZK#x8QTcd_rdaDZ)f;YN0k3lC)vyKn~kwF?hpFS&3N zd&`Bh*(WX>VMfsL&clYYAugO?qg{9;D{|pncA^W9Vhdb&B|F=NqimH6k7XNNIFDW9 z!mHRVE&(vOl_TA^XgQi`W4dZeeL5b$lkXkuF@qie0#r zo#4W&S*;6KurpnF3TtuUO1930FJM=>@HBRl3sd(nkYWN*3f z$?OvsUcTDFmo9t;OG{D5<19APg*#cH3)iu! zE_^Plb>Z{anJ(;SO)h*lTdUxqFny(h>6(0lhHusIT^fE^!KCjo4L_&hmo@yhhCkKt zKQ-)0b;gVArD=Gif+?N}3eEto0;bC~?FoiqJwFAw5%pe)7XZJF`u!5016+*jVUENr zf!~6HO%h)Sd>!x#i7x|g!S#Kw#NPsb2K}#)_-0^hyD*HUvO8TE$uVns-MaS93+lSs zTjQNAJ!|R~FR$xqtZVOzwX}fQ)7h9H(7mR!q>;s9xc!ZFZRqMwtm(?n#}k5{)&x8G z73P>h<7JqH2ONdhi03fAsJ&e(v$v;oD)!Lr1fcuU)?mqgBX$`P|&b6B>64$F4aVI^^v=0x+K23up%%y8E7?s%sXp@6p60@@x6 zXnQN5?Wusamjc=z0(K`{qiJ(gb3#V7C^)K7!BOoBj$*pK!?x7yJNXonM95${q}ap7c~v#QZk5Y!m17BG<)l5uJ9U8FsV=)yU3Q%_p7$MKcdElB9fZb}B z-DyVG2jY_;+gR2kN+#mj5kx)&w7x?9>-0W43f z5!*^pUy^8RlC}1(Zq(>HAOz;%og2TdIF}NtEo>2TYdWDy2%xgOWmQ|eRX|d)yjxya zRy0`L7QCP1`cCgkkWFlG&umU4T7^XHG&t7UiEV#85pQUT^|Um#ti`5Z2-+^A6ZW!# zY47|5R9)cPEyvCeJD=iq2|Z z)6vqJ=!~9GRZ?D7QdUw~K6P5fl^**3n=t7dLZt zbJjE@nwk<#(KB&3*pO&zY>rlyl-9*N*VNT6npM|WH+vxz&f*GVi`qNa#9K?6$3=@V z6G`qM;~gCsm*i~?T?cQ&ohRZtXje2NtV1=6`__*3&hEoY$-CR6e$HN2d&Zn)%j;Sj zo02QC1TIKyXlRdj9!82bLx&&b2LgCXjU0EFpYGaF9u~B%1KV;Ltj{+uK{aAX41YhI50SQHZ3+In1pf2 zMFy(|CW(0i4sL9Ycj95a@7M6m_ZM{ay@;CA-qnm#l$inF1O$*mZK)emH?p)lASyy< z`RUZp;1{J88#)rq9M96zAud?6;;pR>aoh%(6?1&5g_qFB zBxbko*$TD-dvgFik?;mvN{08Wm=S%O6xmp^m-D8;wM9i%*}aQJfr@bXw1y&D(t z#MaS;l?8|V#1PKTZRx~Sn}VVj_<}d54PU|FOBTe$GEP~%c;TFxi`eysr#>g6cF~IJ z)2SZk^|Gqd*?$QwpUy7zByutqFORJ_ZCPyA%!Lb2nK^3#yTkBp^$oSyXU>~5 zXCb@8uHt|#FjdmE(%zm8{=KZhX zy1l%9ov_30cMPz9s%HOW#eNCwAJ>-(`;+%Kw;ZSqHP_&Et7W~E74}Err&*A?|GpMh zVD5jv#m|iX`|#6}@wreb%i!7>_vm1rb{xdhQJSY&wx@np<*!OF#fLkd0`oP}ZuC>s zU|pn}x4N{|%5GqO`DE)fThg=-&hhiphwI`MDn0h#oACzw$UT zb|P<^sh5{U`50%2_&A>x82cGUhhz-4uld0IjCvN`ha(sVZ*$EkaC&)d4Ap{+&W^l1 zHtv)aQT~(VJsxLyGwG;jd6(lb;*^1p*B_`2;s|Z7MbDwVyasJUdpl00v8B?nb4%X0 z*nxTET}_^#2j=;}$)``ZqF$Eo%}*UNDfF8rM4A_6d4(%JuFtQ`uWB0g*?SI;Mc=Q7 zk9mgp*?VAKMxKG62WpLaBTCxI7iQOpBQlNcylT5A>fOSko-MsmbIXBw1`f7m^!Nkw zne@oFonroq=VV^glb5%m*k7D(6#Mq~i*qffKAzUU4QH0h@q)w8M6@=~Wn1c7f_Y?@ zZN0p=d2a9KVBWl0@G2+3s++0j4EWa%Z+G1uZZu$4D9N~nG*jSpEdI0 zaN4$=64>A0>|-a^v*K_c*0p$`KicAB{m}YxJu6{-m2p}P^Hz{W(hVzPcJ&Giy*pRW zrN~9jgb;bJok4^c%4a*T*lyhKNbwOy4`d6?Icg%-A?#%D$*IBUdLAj;!nU$zFFw!%u4vd4xo6LxiNiM8Vlenxqun)1ie9D&>sv0gTYWR z983wM2Gb`&)+!CC%*$@Ri;rpEa<^j z=JL$Q#IVOR&hL%gdfI)V@W#o(qJN~BS?hwSrT*d1rg^fyPqnar{B0$jX`1OJ6p2tRHxd~e@uX!&BBl>S=Xml6Qrtw;p8H;0sX!I0p1aliTbkGOH%vf7+H_*eJljy_-b{%It z1xBy~+i_-W7(&kd4hM1_$6#|jN*!eB1)Z6>ag*mN@JFjJ(KUCMBh*nn)HR0 z=;73GR(QmSF+O9(jh;%_kC{vU>I8U}-pcQ^VxoL_M{JAuIf4BAtudNXcmWPxjwDC( ztxllyJp$#Z_bSiT$Wn6|Ux1Z7ZIXG~$XEzTD)N*@P0Lf#d6?{c4%vCSX_^PJjF~w+ zJHO20Yj293o&L)T8^fNmzn-=n`8g?N@_ai#1L5J}QQ z3Lo*Mr;4=3Pm$U9b`-uH%iN|svI@`bKLPRFcAgX)ADSV9)^@8D3>w^wvJnsn_v{$eS^^qy}yeF!q z+zXzlopN3D>Vg?BdQz#o%(x@Vxu|6nbQ2DHFL0T*7igCGw(5U-FK~)!dhg7(_5wf1 z=Bf9M_5!)1)4Y=(q+LP!OKI-CK;;9;oBluV1-|V)=w4tf_5wKMUV!H=U5bz8dP(_U z6`s4#0$I6>C#J@AUiWT*I>^Mm&Z{Tx^q^)Y7)q>-k)yYMOu8(ytD= zZ5nY2EyV!skYwpImS65yphVXJDJ_+V?Ki z_q_{?Qt9{6j?NnWHqZ6YxFq}Dh;R5w5o{MGV7q|DT2_2iPfv~H*k=LX5!2g+V|yM@ z&RK<@2lPvJ@;t!XV&fg{G$46-8oc8jW3S)*uJF&^F|<}MAQ9`fP}~8&>m5V4fV7I! zJtg+f?|H}E4b+Jv*s-#$5og?AyxDXEc@$Znak3bmSBFO?dJO-N!U<{Sv^@+|47zK)h_*>8Xi_%Z`AQeRbqZS-po6%z3J% z4zvabKaa6$@Mkv{GKO1)Z!phOOcpiG;7vJ3rord=hMdSm|EQ5y&sai}Tlur%u*WRj zQTpKYA5ToDiSAmCSEop?qcqQ7(mbco3`aa>P9!%w-)H3WCx_c%^H`qSHLzzDn&;3% z_#x(*e+p$B@C~ur`GkbU6OseI@ifK868t!l`OUYLiQlDA?h7v+a9`LX=e=7z85HNY z7aHu%j>v_B~Gual?ss&;0w0 z|2}C^n#Y$uZU(9Jb(U5Hy%xglU1#A<&fezybZqU|brjW6xu4wTr+qoD9#K559-2kZ z=yE+qW`?iGvu+4l0?0p)k&}y(?@2%2XGE+u=VkbGEOYS+*s}`H#aDquF4AY+%(&Zc z{Ye0kJi!)b{KU^+^V0=}uRdkWxZj^nxw*h%l{4d~f+cP%k0f8CP-2ydsPJnLHtkC@ zFLUoT*2`SQA6d8naw1occ&~wlDq@=9D@GXQB0>L!1oZ|zK7VP|6KSS5_)<|Y)f?nH z4$lPNrT(Sqc;g0pM<;ha;JM??!K;r6=kv6nP291}2^w>&@SM08$jJ%*CBN~p-&vz% zha;I|lC{d!sLagVpxl$y47?}1NY3>J#=ZmjBj0zNWwKeOneyxiBPyo(sS#L*JpSRc zV`1}zrMMkh`p>ZGzc}_9ZlL_3*>x*7p8a$Gx{HT~y=z-f_(lF>p|F3_&RO$|;uBVl zi;Nj@;=6b*bE$u@il1xf6Z9-g{5nR#oLHP<90} zX+fdYBiPZ^(S8BM9t~vf0mhbu1tsejflT`1XcJhxeA66kKyOzLwz*PJ?1^xH#rH%P zXU(BX{Il>q%a_|evL9f54>It4{zU~pT>n5dy17mZLZRJnS zyuLJmmj&jy)fL0@KAHA)X`mz&3b*+$s-pL4NAG#)+dS_)IXu@Q8NRfLFElD5D!yUZ zLivnbdBr-$IY;wk6`pe*JLlxD6&dd-Sx4eB>)s1YpoCH{T7L;-=@+dJ1k06n9|p4a zpr@L49|f|Uv^$cV%Yh=R3_}I?(bpTND)(2H${a(2HKJYQ*b!gTicA(V&9tB78Uc}L z_vG^X=TzEs&Hs>gNa2gqU&4keqnY2w9i8>-#vt887y678ywado^z2ygwP}p4!t;e* zh|4vKe(%h{Qm%pR{64IF8Qz{*dN3!)J`;ujG#PK81fYjM%8~xg`h0 z+{)i7G=8Mat}T8f^ErxZ7eBrY;(B&GGjn|@c;=OIPOo6>55Qth{nXNHL0;2-klY}i z9AAe!s5z!Nl;lz{snu)7gJndZG2gEb9e-BzA@W(%7qABf>*Z zTwIwQPA}PU);#qoF)ac9p7d<%8wWfM_Kv)8!To8@Gve{T!UsV9uBzV`|5utnYh5VZ zNS(yf!=sZ=4^cjOd^x^QYGEY5up}2(o^0RH{D_b4qoTRK$k++Kv{AlLwwWu|lL8Fl zvE1`e4p@cfTp=6~IVbkTk0=>O!hsI)c=nNC9<~qs`HWa%b_KI(&r<`Ye1!98FqEl(_kvIQiQXsbUZVGlI(~{m%7~}w7c5)9BjpMR z{ZyMvIKCu<=rU3F5+yYhw^c|R@id!)<+3SQhqBoVJrpO=D@5H(bd#v#rzm8Tc*|Kvg@$R&~mp z&QNmN+Y6a1xSW#<)Q5PAe-6tY5QpU&5U$IK!z*-qi5@5FIYbL2pXfwU$4{q_c8bNa zg8HZ{z}qDFUZPh^84zA5d5EX@?XYaW9hU94!?Lr&VyRg{MpVDf=lGIQMC(O8=^99} zH{ekGa#*%s4$Jn-VcC9JtV8*gA$$oErR}(y6Xd_(-MAiAyQp!|bqjrhL}|mP_NNZ2 zEct`>9HQSA^(Y804$nEW6kd}qr;QJ(Gni{I1j{vK!sw0l1C`lh7Vt4oaQcuFhD;k$ zn}K(cEbL;0@U^;+)kY9(8mrALPw@n+!5ab)u>f8s)Mnyp2m(1=MLod@!OWBl|1798 zEr^S&k>P)Lk^j9#82hwL!^rdmQ*dvT5Jr0T;eK;yQ%+;;yZ2g-|+X4rM@Up z99Zoj*$c`yiSom6;>(zCa$>&?JTuPN9g_0cfqCqp5aqsokLb->?7+X0?N7>f?i&V- zP8RdKj&Gv~<6!K09KATWZ}fpKFMKXw#F~>k!8IH4w_qjZegSj8K>1u?%zi-aTg5l$ zG=@KynC@{1KO^z)Bz{w3?kALRKfmwznNRIF@Yla_^y1)tIv-ntLxuZ^!L$6`2A-K< z>~2Z9zrfsIP`Jqbxt%C}JS6cW67Q9GpTw_9{JO;4Uj)nj{h{M;l-hA<{@NevQ49AG z6Kwg)#|&G0KE|NjS5WRNs4L&MG4=p-&{#f96!>w8`4|Ip-=K{9_M>FJJ&zu}IQUq? zH++aC3-{?R$2UGctHo~>n4sJ@Q0^P(&FDwI@bSc8|A)kUJb_*L2<)17;18wzCq#i= z=OQqVecBiU zb3c9}{kY%pBTDi(7~74b7l#;A@qq>)3isuwnlJ6r7f|jCDE9@_<;%~+^D-La9nfV0 zb6>FN@%hDoZzMk2qeO9NzQ_*;c!Tie0mm19-r}hy&p}Y`3n=#ml;_@d#^64;!EHY% zZDW!L+9of1aqw}7@t4^^RQNa`X*tC@&uv2?w++f|gL2!T-1ZK6uYvdwIx~TPNfemp z7Vv*c{2SShuFTvieZ&bp(8t#x(ThX)$X{{-QQ^K}(XxExzO9qzCMfq2l=}$EW7s9< z1?6Ldl(XgqQ_4)>$B1HV z_?iIRC-KX&{T+$lm-q{bzm%Ad9hC6g`aez_QEJB_zMSg?6=TO=@(>$^`;JMmVz>=F z^I~}|1LZM*@)$tBN9}vGYZx&8@fh|J1$ar~S0#Q=V!n2u{l6vVYX>lo0RzBec;fIe z$d?AtB7J|-iQ!i8%uD1vfbtkXc?_U@9^fdJ1nx6m|A4s0ZClQwaI#(+ zHbJ>fP#*X5@|;AzZ6_arA0ukzAMlG3^Em{5SK<$({68iBTH-XU=G1>EQOHLn&X<^v z>kBeQocIIJZTecb7uv+Q4mii)kcW9aBYd7ohSyVUdOaoh5Z8+icHXw4ZuZGo_v7!^ z6Fy(IgAO5l6ZVHhF;63iKET)*q8LLiAD8l=Tpp9;l1Gkl`G*-Bul8${{Xls?Ounn1 zr5}43K4+j@?v8`Vt&(z}T<$JS?n&v#uQWea%YLA|-;WQ{5B?lS{@)f zW%~x%4$9jRH@9=KH10dzd*^JA7>J`2bz+Bc_xf@`ae#Ho+W9Mq#crOlynHqjh z31Ivs-9{A0y^_-Z;X(4-CEY<3^1qOD52*Pjp4bsZJpW1jAp8dn_cQie!Xd_9llTqU z-Y;nue5St(o=X&VqC}zpIHHg#APRjYpkbUZ<%Cl(z7o$MjH8C|S&W@SI2F&xiKgM* zA<=Zke@UPI|Ay5h_gg$KAwKNhF6n)e?xOa$@c$qXhTnepL^vCia05};UrBtNM;#J( z6UMmH|2JU1#@J@!LkInz7bLfZDCYNO;=}IuCHBYX+N|KNdw zwTsp)To_q|=oRAmFN0IV3B#!zqHtyeQ8<%J6wZt!3TH+Ug)^gx!WmlA$eFQ3;Y^e$ z4~i;Isc@>UngPVeMsi7RF)_75@$<2i{7sPA1AEk$)-x&;JH@H$n+@gze9%b3DHM-t z=5qvwzg;w-pDgw^`Bm!6EeBd=PzSppQDvTOnupPU@`sN=@!| z$l(+oP`be3=Z0+g2jpnp$$x$>fYLd%35RMoSmgZwT4=J1K5u&Fmr@As=J&wK-tgA`n^f=C%ES?PNqIw+prQ*Gt zE~m#qA4yno@U;XTlEtwZa&!-%7d?)xVBD??0qb$#Z|3qRhq|a9N6wVN#nB2mD~{1p zX|gyrLhc^jD6k$!J{GpY#5Yk-tgw>GRQj!rTyI*63;bULI8RkH$!ePaV$9*>$9#5SdZgc$XRh9wRuSv$L)|?E!$P1 z#}TX-v0@&K%r&wFz=o97r8rlErZ|}Y$uKyDW5Ek8pyRL(Wl3;9dfNn$lahD1=i!(4Y|!pcYzZJ?Qy9jiz5qit3f$PFg1 z-iO>^&hy(B4la&&AZN|T3h808I6jA5!WDr4dK`794et7}7jpL{(Wjput&13g=>bKb zk6n^GcbbZ?gsqZ62U%jI5X4G+C+aX!(E67>vip3*(Hx4zt*~`S=U{Pg~$(1e_-%1`% zZVTit)P;a`yIv&cVC2?A&KfsWt*-Ai$Zb^xWL=l*I9>T8Vv4*jw;OV}qz@>%+*gpx z8Xz?=-VEI64kq4BkefXSefuCcn0V{)e0MN%|A1W0AnaD-;x=gza!ruikwoqR@YMXv z!O8u861m5~Q}5#$p7-^EN2ecuW(7*?!3#K4eSMJ22Tw0=f}!gB9CFm3^z}$#!n)nB zAV((^$?<1kpvmmEp37JiZFqR@+9i_$}B1KNOI|++WRJN<+O#n5o7DCRlyGaTro8J|Xt4BN8Emh=nyE`B^ zm~nnhv3rf8Pmi}>v0JIg>2_;kgR|QNIV;|8EBbW1t&m%Sc8YhpBB$HkJxII#irwoJ zeY)NEAxGyK**#g2)9u#R4=&zKkh9|5qUh7@UJJQ-XeYa~6*=AR%aALO?J9W_K+UVK zAZOXVNeU9y?Rw*4y(hc1ikxoucE}ATul7LBvin^{pKf=bVi#L7UZ|gLx4vO;b~i!J zvU{tdPq%w5Ek@3X>fMyA!m*Aj}(2Mp>9Y_q#1HK3bv}cf4x$U{0m4S z(of3NeBP?q9jeG>XmZ;iSAcfXm!Zh%`t~XMvK2X9UmxUXy(N7SMNZd8H%HdEj8x=w zeL=`Y(N6ku6**mBfufJ(sgQnMU#X&RESC~;y1pffz6pw)uJ0_!S@Gs8a=O0FioS`8 zoUU(+qOVYq)Aj99^i5Xebbb3EM|nl#SE9)2`uY`p6^fj$?|sNoo{+vNikzg6Tbe9(g`OJB7jr|ZjroRu#pDRR1hIgl$rJNb8_BB$%CQS{AH+4nYS@-=kPP)D=iay+u@H4-S`fzK*OEP`C6n(g*vgLGreTqJ8Rc$%lztma|HH2SRdu lJR~iF9RAs5-)d(cZZlD#-y~4i(~ltc5AaFf(^8Q1{tq%@E>WWrH9=vzGJX_Zr&n^$5vX8pDW`FN{&Y3yiNm`~* z+duXzGw=Dm=l8wud#>L(-}hy>v1ePa<2XVej#wuO2-?dzC(tIsNURedpxmbHL^d~* zi;p6;cT!4)6Pd}$HrQ$P9Gr7skSTZe|#*(A6yJP9pR8pr?Q{x%YG@8wdrd)E5 z2+0_6!a84fS+(FHpo%Qz@J#EsxK{Ct-Rfnf59u2-A1x z(DtTyE;o}Joy{fTTIFRDIyo6n$jD?)d~|dsd5vk<%$=Scoq}K3DL7tCC(BJ7J08;I zi{FG&?3VU5H?QGFFu%+;@{8ZjpKE3UzZ^K?N~I&pL?4oE2EGz_r-63^j~Mt3z`G3m zX5cXczZ-bMz#j!p8~7pMX#;-^IA`D=0`D>KuYs>O@E?FT8Mp)mo-^xC^+?z(c^>3>*g@H1IU=uz_y`u0l+7xTw!Nfe+xL@%xbevw=U3^x5is;y(-= zGVo#G?;89cBmH{=Ka2FrL-UuAeFyFNM+^JOmXTj+;dfB>Kj`Qx%u;7Z{arrcN_U{w(vc`!pOhZ!uJ9Djr<2J{3vkE zTuI*lV;24nurTs}WZ_={`;Gi(Ec`#fYmI!r&x@A;2aWvY7G4Xy)W~nN@P)vYMt-M- zw*l+JhyE4y;B&;Nfd%rDz+rs?@RX776Kll{zz5OCSUQ4d}xzTv@J#1B1qz4)aEpD+I4!HptNV%ATm zSmMFWBJ9Bt(c-}^Vv7fF727?yL%ha=+r^{@Zxq*gaF^Kc!7mr@^56@_eIC47e9pj2 zP?RrQ_;CyWz`{p?X}E^*S%UHQH1KMq-vcG#=M=8}`y zwQI4Mo=qpkC6{!^bMfK$Xgb;M0kLKaMl5XSw^;eD7H+e!?XJVh-)P}Y7QVoXE%z-} zxK=b)Fjg#9C{`p^AQVS*I@Pl$F%h5Ios5xV;C}2VIE~tm?M~*R$w?bh4H~&r0)p9O zI+@6IO{AvtC(KTHl)e2sB3;{tgp#pQY+fkc-7j^JdENHT=w+NqiM%%2Gt5dz)(v)T zyDZwXty$=V((V`-gbLph_YZ8}(cKdfgDPQaajw)hYb^{im879#A~|DSG&&gR8jKDJ zohWFBB2qad&t}3bph$0n^HYO@!4%(Ud45VIv;Vnz|uN}=}H zX1=V9@&Pc)$HpjMTZCFX=e2mwYw^U{>hTw1B&%LiRF{5)iV__ z~%&ITOC3qp792sky1WW#a{H8?J0^36E!H!njve%pxJ&*f^Go?~Y|> zr>AF<*=%?)9%;QG+?WY3SYh<0m6?)?+-N+mveL6ymCU53c1xU1OeC>7k(ehX=+QY+@u`c_sa!5iCKJ=M7ok`i zhr74;H%7yaq#K8BAj2NV(y7r{A~Q9f+8thl=m%#qyRjGw_o9}v;dOg9bu^4n9Y*DX zXryOyG&wew91CBGh16(rDlrl6Xo`%)XC_Db2f9WQBi-9zu!{}G1~M~~@pRL~ns6f; zz+Qaqh>pakr%^A9=Z$8Moj02pLAj23DzZ_m<7H>Eu~cegIx~}depWU!JCjH*&eIFX zbYkrIgsYQ#M>Fx6=V9?WbkPdYjuMHfXJ?Z$*QAbBYnp_+*2ic>%^1U~`}mRMGMRK1l*ZH)#s)3#Wv9m&8cT+A6SI?} z;l>>_mS(fbSmONialxn2hPfdYlf4=}b|yZvS5Vi5l840jY&spo^(CH8@-RnF5fPko z5c>~Td>Y@lfgdQxHzbaeF?3#}k<=7M#RwTW&L(GJwi-ZEk zwy^J9WZDqU6Tf@#X@3>xbtlK;v*}#6X+pS9%-!;g|7a=eF=36(CUT^HX8!M=^}mL- z!xOk*j!81v_@bN2#IRzU$*_)@?{~5}YHK?6)+0|o?fZF{q+Ym@AiV_duUns}N`v!!SJxL{#3>HF6||Lo?Hs|ZXe5W>)jCB}C{ z;eU*B+fZ31ew&lZq^A=ttsR@d34E0}51xzZ4yc6DVHYSimK-O|*C_u@4jExeDJy>I z%qF-IKnZ?>D9==jG;UhRTX=rw_`O6%f8y6p9tt!Z+$3(?`*AH!?ViHLBAuDqE&Qbg z1vY^*!U+}>*$En9ZfT&b2KUi!3*qZC^!4xb^;Yco0}s(xGr`x=*G~zSQtF3vMk{^2 zmcBOB;_JS2RMLY1f7P@@3!B*1&f(Zl=XT+~MEKoRT6^hW{|>2Isa1nr zTcu`&*7Ub@HA_`}^|ZqV&d_S>9 zT897>t-PR$N@GE-+1}MJH6=R8eA%O~iejfKb6uT_8!g{L*YGRsoWq6?yey9+>j+qu z-8q}{DP%>EHAV`>I7^$7H8*&rK6N>tic+XE>lsG}Wx&pv42OohI6_C(Eh<)-U8c>- z8pcCPY67Q@&*~gdELqc?1G1u=T6L1YO8Zv4N^Pw|2BF)}kyVTGDhp+t4=h{5kriEN zGN+UYq)?0!?Mhh)C@fpbkkyj?xllR4a)+#tmqlQYMcw`Fupu0yCcR~CEdMd zD-qoPD0Jiq?np7>7Ky}EU*T4W#AI+T*Lft?CYfBvkyyJ#T(OZ@heTYHk=RCwxU)uL zn` zXsWo_fOF|pd7D*ms=&D2#ks1)*k?0TMaBl5p(-Y4f zi~5glV@K7FjM?E4soU65RV5>q!%?@f9F6cU19p~4qpFP^RgJ2R<(LFnR->b8Rkg8G ztIn0x=%`9=Rw0E{uB=8!)wyb1hlepN%W8CV6R4X6BbgATA;i5;X^Hprn{0J^*cYt-5Y>*LB1WpLY8xhCezOf=dfPopdC zcIk<)G0`1r)wNQYSP2u?>Xm(gJgMKt{}$v7rH#Lrcq{UX?=y z+Zuh9j6*Le&w{(Bl|eic>AnIt2)RglMP3g=J8eM7)Q+KkqfkRw!xc(3v{NJUI-Eyl z!FVS_hIV3cW=3z|RjMLZ;eqHZ9AoR1yoO%M!-HI!;QdP;te{DL$sHjU2kJzP95fFrJ`U(EngGr4%R5Ge5&Ii^3W2se9fqPs8$hM`0-49QC%rTfk|8L z0#g?MM+K%)dfJj}Chqu?$=_&Vx8a*M_L?V$_);HL61i57A-OcP&(}PDMoJdX)J)P8 zqNKY6n#<1^h})>S`3IhC_q7IBKBgdYmnO3+Z+ThQ;N`LYf#Jxe%f&vYCbeo=EH<4; zUya8TT=cB?ixWEN_*k8pnx+%8;{E>6yIj_#=-D+-09o;^($Ld}R-OMyS!m8j+-!C_ zF{7x5&kWtQEU#3|_tuBrtCeFj($i1sLm$+-tkV5YeduFamzdVtZ!QmgN^4V-*@Qg* z>E)q=T02H}(xm#piqH{OkMEvNWmHiAy&^PMg4+oPTruBQR#H~&?3(Wr6NgIv{5_JQ zL{tYKt-o~c0HL|nxA~l|`98^+?{~J$g%62f*L;7F&zci+!MW9CB?XRe_5OTrCDOsw zg}exG*uXFDY>GxlHn+OpE%>ofnJ4cy5Bj=+LWr-_h>zmcCEa4A=Zv(hlPyM_I7Y5( zSo0hDppl+O+Tg9`x|ZJ)Vx9lnPI&$gf1Rf|%Fr(Kk}b8GXejwMx6qm)*F_7tyF{4U z?fLTO4!o|{Sxsk>)rnrQN31J(Qu>hSnQxOH+5W^~ulz0$z3)TsDA9XM^S_^;=l75B z&e0Zp=-niG-)VmSuh7q5!tc_8KQHFz={+NQ7m3~t_U$|P<~~Ea$4eO7T=~ger?2Yira=) zzw|oZ4=9i~t?~4eQ(Px%B`$tUq3l~TknggmC5~osl;XI_h~qT0ja;t(k|KG_8gpVh z4RwMo&VN!MH?J`!w$o52yxsW?MRMzD@2?m+f1*fkG3#UI?dVfnZ6nG#Ct)1I+~Ua}VWc|iZoI=8s1s$?K7LQb-HN}xgWl~FA`0o? zBfs4@a8ig@I^z4w9o%6Tfjzb92Ha%8y>Hy_#y=e254)nqb;Yea9e+*G=XZQJ9TCf3 z)|Mz20~eQ-U*GqP*a<_f*i7H{yCBDV1A|^u!@B{Fd^Z4(sPSYP-;OU(9q=tX=Nz{L z0XzzoS}&IV4WHGA$+bFgM^yyLFV?X6_XwS`kh4!SAj9~Sp#Z`uYaso4!ifpM%>?;x z=OFo={1?)e^tTY5b#J`GalgTh8G$XgN3~_Q5FY^sg|zgcwv-Tw=V{PMS3K^xuJg8? zPNTyudK*=YHJgK#k&?3Vs{&IclMVE@pnE97lh{8h(LZV<7j9~3 zZNsO%p=m=?(}vcDhK399d0E?vvjVlN0?t}=TF1EuzE45_q2|&D^`G*0;tTzU-#v9| z=r2g+p@}DTj9;qyMemCnziPw27uSZq z$MS9XCA$q@i>Oa#8-4|U+2?6Q*gswE_-Xj2cJ#dV?DQS0CHtC;mVBY@Nayh!J!D*O zFH`OK3L&mTz8v_}vkP-{elmETiTYw!EOlM~w{|)~IZuC`=jrl>aFzRt|Dsv8yrlZO z0eAc718=PRrz+o?rL5bt^zO3q+1|rqjJ%%2dG~R&w|_}Ppn6rnUlAx<5pd4oIrcvI zIR#^vs#_mC$C6)abM+FuGgz2riCdAJ!Mk-sRdoCMMUPpmiey{&7;U{>we>dqegX1j zyPoj%c&#f+T{rNN}Me_cz3FSrTsiG(De zWF3;rw7#kUDneDEN<37={)+O6TCI~h&keyQ`arGY3!WRStEegIf~Qgq(ciGN`_(|n zuLo-Iz`M?I>U_Zp*sP=^C6=9mDEpVmIPqliOr`g)g}x$mF@`|NdGL<~V-ue(nU_>- zDIw$7hj`WfH9DiB%__f-6#X^YfLr#|0IUbvxdd=S?Sl>A%_MJEYw}?s5`^(PJG)6< zp~nG$07+bp5ALGp?~syS*}Ae|a}GN9Z9>eFT*T%|(&Hoe&SBmrJ;dgNW5Xs=$9NO8 z?p;FAre-mFVbbH{wWsdPv0mAFm1Xnp7i6(^HI~gg zUzklDDBHvZNyo|cdD{t=T|bgH>k|t|ZIjFXmJ^JVZ1U3wqwH4|Y;v4$eF1UOQv@^4 zm}PVS3$RJA1DG~6*O#) z7i``FwfjyX_L5wr9>b)^$1`VgJ@TKLa}LLeNmiHrjnKMp#_v**T*PK!&Lr%cUdlOIg0!c7VBVTJEg_%jMWq%e7OUxzoiNCIS4 zewZXaLL9<}dMo0}-z5XY!Lg+av9a%NCV}JS%vJc7eKyo~gZzVlC`v*xPu76aR-$%SFNR|t6m6D@MzD~(0 zC9hHPS|x8%@>Y@+LcCo`+A~(5aqlIGz3V@atj4HKFYYK-^PSGF)%aaB{wSBs^mpVUVz_9au7$25Kkz15K^2Y#4iY=U7k_$2 zuY?gdZVrj^o3Jw?iT=F?lJw^hMt`Q?T%>Ct9zF4aUEab2*`VR(i@HC7@rbT3L@zcs zBr(p=RfNE}LMZrQMQoZ#VqBo9n2aXk!Gx;D9!!oO{BV-|O-1y7gv5i1#+yKYMp1=8 zKL%9@^fOS|8K~?GLxi1y%FaM#XP}~B`0Xi@a7N>r2I~rvXwS1q!r4la?1U19qpgti zq^Mf;FsBUS?mnd>w^R<(-X5Izd#*f1Qi9?&-K25i3a)%F zZ>`1KkBVsVQW&9Ydh9(49{pCLeW2@kczaNR)7%JNWs8-SG#%;yFqMP* z2_*4uG5l)Yu;M}Rk;a(Pd8E+kF{H_!HZcvJdFVQug|Zl)U0$+xi)m1$ZQgU>?Jt6N zeWW;^9}RSS5%%r^uNc4e=mf>s`!IOL*jwLPoV|lZ^13mQit+n+k-TBdrNxx@D0s#A zo#-fz_bhnD_`QB(arXS1inDhYc#D{B~3{ZEf$2FvHk$&|a=y;A+dAq=)`H99A zE-!op@%=G;OncMdT`99Y-}d}+7(80b*oQri)?O&YA)5qjm*W@U6;qD&Sc~a$tW|aw zE5~N=sBHFOm*Xk$Xw79Gb~(m2%l)6tv&-=p@QNu%Hyr44G$^Bsm17vZV%p<=@OIh3 z0o&!M!~*rRi}37n90ISHas;s^*5znYb{8v0J$S{GV;VfV2H1yPj_-k2OgZ*%DXtt( zf~U)YDUOfD%5fCD8&$q3?0&VYQ{ayf79Msv4ug09LfV4yk=t5aIUWU1mjhD>AB&aa zaqxDjd{fxvSl_ic&o0O9;N5E)Qt5{weOO}XtaaT&^k`tnuOsc5hrk;$@^#YYeFePr zI@6Fg?^*EBWfmMZFM{BT;Z1|LWq~yzYA)63VyK-;bSqsHQ=p7F2%=t21w%Bem8+vOnFDZqw~q$c6{g{Y?pTo zyminM?@WB?AfD~_cJPYv`v7=!KG_?@hYrHF--F<-gPwRx@u7oww%?=R730_6U+^1c zYm57>1W)_rJ=!t+wt-iS-<^ivD~{uLm*F>L@a*#LFVgS*hTm5i_UwB8tl^jDRXP@{ z=bsemm-f!E|6_K#*w;McK_+_@OB}e%G+r0Y`+hHr{hvI z7Pj9bhToeFdke~I_{FUqJ}5rh@0K0K`JDhym-kk~p6z!Uyq(CW@@_PEw%^0x71O>? z8-8yy?Ad;w1Fui{#nzgS#mc)Gi=|@x?gCGj_jbdc?RNq^ny09|r3R1we?(;plbAE? ztuc7*7H>azHOMD>s|}uQ?>&aSml{0V-iN@`@ttSzYEF>Z?#(lyd!W*es#N(-za$aFMkAw@&AR&qe3EX*;@zR5oD7+ylRa6>N}@)cCTq~Y-$x#8=F@2tg3BoX>0QKTiRB(i>cjBy%6ne zZ>;aGM+twUV(q$>O|{KU^^HxPqPDhdLB-tK%JQn3`Bmj5Wdj(sEp07OB2BF9tX~5g zolUJKgS^q5D5+XFwZ6N%vt>n3cT<;`x~j9ir^8dy+TP&puBmU3p32JgD^_$it<&}E zr5!yh+F%~)0{gLevK>gqc8hqbO(+7dJ*Fb8Rnn4I%jb9n}YWOYSksAIx@Lml^TpQS%*IW2v;B8Ni z_uH@A!dC(B-Wil%Z{b^jH)#5Av+zB@>$URj7XChPR4f0Xg?|j3`Oe|PUjOd5@EgEs zTKS(Wd>DAfUxNBsn2U7$Dd0Jp{mB-dspc-SAHsN;W8i9Wj)swGViE8}66P&QEYr$E z;ykeuc%@ei`F5lHLU9G~ceL{Bjq(-ZD;gFe*}^FnPPK5Fh0`sZVc}sG&a`lrg@;>s zgoQ_1c$Bye@m#IuPinurwfI6}l_fvg!ecC)ZQv>Pq6Tb79MZmsD&q3 zc%p?*vT%-g2=Vu8?eRmSJzB*x!27iF14j8;*5@5xsXgCBd9Ir83IEZMU&r~Ym;V#x z4{7oViGDI7|34>21Jf~EZb@RiQNEt-d&gh0Hx1=s9J4(6B18UKwy&4ZNBKleeu*J} zBkT9pkEFjI<#n3;YD4}DtY0su@zbx#Ukdq$HGGXx|5mQAms5Rjy-4=I1o>*ZA6TMttGJ&=D-tN)x){~KIiFMkc?8JH72 zf8R3Xw~4<4pR1L_gujKv{oMZE`jYHt8s#T*xnDt?EG8P|r-+#b{*+i~;Gc+#44fz~ zHgJOIHSk_>qk*T3Ee4(;zG>ju;$Z_9iCqTH75fc*x_HgNdE$_PPZb{+_%xA}97G=y zlf-BP&k{KX&KCs+o+gS7JVh)r@Kmwfzy)Hpfj=#J4Ln&~XW&9{tAS^VyAAw^c)-Bt ziYE-bRO~nKGVz*$9~FlTe1Z7Dz@HUqDSG=X7h?_leUWS6I#FogS~1_i_2OIuKPDOt z+$6dT+$gRy@JjJz11}QaFmQ!<(7=`AM+ROZo;C1d@m~fm75{DE1>)}pt`d<{y*+*) zMi_Xtm}uY@G1I^oi!uY3i7Ern6?FzaTeKPYEOD8E=ZhN+JWp&faJl%Vfs4h%23{z3 z8TcHr-@u;{uNk;R95V2k;sXQE5lM96L2V&%h8S(&{}ed}ZWq%H+$QE3xI-*8@DD|U zfxAVgfxE=D2JR8J8hD4e+rWL|K?C=S-3Go?yky|V#Ty2`LcC+(%S9;Ni=Nh>SBl{V zenLbIe2ti9;H$-418)#Z4E!TeYv7Hd&A``-s|=NS){8e$9fxjZoH1HO&(7-=L3Ha z>)*)=*8<-KeID)uejVlGRQV?0N3gyuR(LCLy@r1Pd=ju%|EItaV9%ddfG0uUjjH}z zz_k3IsPO+#ee9Ph{2}lv?9W#?DGTwTf>%BPcp27rZ>#cCf$18DCqEr{#-9%#MiYn$ zxSmo1OxIUDJRg{@r+9cVFkL_K@G@Y!UgF_eV7fly;g!I2J;cLnfa&^&hkJnOdWVNE z1E%X69=-;cu4j076EI!B@bDI3x?bVoyMXEXgon2S)Aa}sKMG9OA3XdxFkNr(@Uy^l zeZj-O0;cN+9{vk3T|e;f2f(yZ|7W3RTuM@G=oa7{k)m)OQX{Ly7aLIO z&nm;uJT>(zTAT9o#92D3&9`uYg{K?Xl+L$m=hvFG^J}fzwKEKDrgVX&t-#V&U}-C` zwbjlvwbvF}c$S5W3~c&pdOE}MZHDEWX?dn4J=2!9BAIDLGSiA=rWMJ|S~HTFwPqwU zYiH|`8O=~=`c`PVR%m)wXgXGC`ehiI?dfeQsBUVgRcR)H${Gn&r%OO>UV-0Mt7=NQ zinmWSz$mI#p}Jq;JNRr3=ofE?c^d`nzaKCh~zR8&gp@hTS85DSDk)#arEAKpK= zq7>}%MJ00=lnWhbrLc=RU6o4Um7a@&%BqURRTVYo=T9dQlf!c7mzPut`eMYtqZfI< z>`oV=oQT{it_XPIy0>T-$wfNC-nTZUY)ElxLSkmx&rk?~{ z<_F2h@MVT6X?Ql%^vu-a=LYGVX(Hb<+&Gh8duBH zvu==YJG3w+prs?8`t&YA-nmM6sF;Pv+wisd`HQVSw^=}f(9KGj2)5; z8i(r{OxYcl}VLy8~j)&+{cnSAL$Mnub>3V4-1Xmfw3+F_@0nCEp1~ zMz$21q4@2|l7{tJhHJr`!}g4_Lc?C6Y0vkQ8^n)+8zg^V|6u{5#hjn-tLEyygR=U- z_RKdN%g+xgP{#Z1$<+%6S}!oI7ns)lrjykNS}!oI7Z}!qF~QZR541krv_9RiPJ>J) zgRDN#`gGGeW?QcUV%NqXjhq<+t()^*{tVN)KUUcKjDgn82`hhwY2D8=u1-_3HEzv0 zEq|tI-H%LGA86g2So3F^)*-JoUEx6MX3pjZ2~An2O+nOjG!8B23w{4+aO4LQ1Xnk+ zjs~t(eU{npv&`7dteZ8^x;aquXU!6Gt1D|uE0@+*Hnd(mud`{bSX|Axx~jISsjIua zvq|Gr*RN|5mF->KOL3B3zK-q*t*xzZs$bDk+tS#w&Hy-3_i>L=%7}`)Iyzh0x>t&> zu7>(HknYZgjy^$4cRHmJXE$}1)%VrV?WEXM96C9nU3KCjDoF)a|5S_1aQ|o9sw1$g zdb<1)TNp}f+UK^cn%~~jxv-^;Y_M+T$7JeKnl}C1M5yx;rd7E4mE;&yH+A!VH9{ZY zKKTi|d=|qyWZzpMmz0%NVR2boQcI^6Aaqtigia`!;#2~ZP9m5rBf_T+pmfpzLgx!a z_*4Nq-l+jG`J8}v)F}b+_!NMcbOr#TulED2miw~YT+WjaujbdZx7F4+HVUGxO>IQG zo2m0_>pMCn?ODaN5q&`Xl}#%o?QChR@8jLo^=*>&v??m`ntG{Xjgo_MuS#3{Iu>oe zxSMHLeRof%SJ>6mA(=hCe0Ot8XO~yr-P7dnU((drCebBLO&61dyhhc~Fm-D0%$jA3 zaw>b)T!IUS6(v>Cl10@O(b8$9r=1opZC}&T(%RG+J-2XbLH^YIsWS^^&7LuB+4O?w z%J$AEZeNb~qF8jwl*X3&Rkd9`9UYxbU0u=2`n>70qf^?W1FovgYpw5UUcPw6>gA}^ z)?VAt)g*U%+B(}?TjhRB8%>r<0C#uSu4(UXX>XH^?iKa*s;IRGSK(-UN!-=Y+=Q!f z67#GHep4GcI?VW4tTc%~E?d!cdm-qGIK{n1ig82q>%8q?3Rs)}>VtE!i`HZ%?{aB)-LiuU@> zkC38M>cRCiG_*Ax!Dr8xl`WXhTL)J|&k!8Jl6M_AX1reE5j)Nk@U9{css&Fq9HA3E zHI2BA8#@wDqPxAlwF@Fsa2#stq)XZ|=`n^Ho1)##J!@7(r!1zi)YH{e+i==xIBBKP zhU?(9wKA)bv7PmuIPzf!Odb*|k^i-gO-yK9#Rt-c*1RIuf-*h&UWUpny)!s-Hk2nRP)`fzdID(;sRq9BgS`iNDHP~t#(_{T=HK>4*u!H$Yg&}6WT3DQhlYlWsV+yfps%at(kAwqaSmp4WsLFJ zee3F5*%#LQr!ZQvwqYg35!&;QH?B#TfezB~O-@UDYez%D^ui*@gr6dr2T#VF3>0Cs z*9F1|T1lLzsr*`pl(0wwGk)vzG;qg5B=M&t@}~?kOq~Q)60^?kmcK(KKT86;T!zg; z!pWi^zx!kGU<*3~jxb(Mc)hMv4Sij}Lz0ZRJ#AertJ-kDpJ<^KOM3F^C zu$LsVz9aWiMHV>;IqXpo?>WQML>Aqq`v&cecppFDhex(Mv>L8mR#qe2lSJ4((c{!q zEG)0elgx1jGhZ^tdd#IIRW(X5Tjwdc(WBZORz1=ytX#HGl@0e;6$PbAMW)B9uB?!T zGCU4W9V92s<5X8yDorUKs|=U**<6yxDJfH&1dmf%vPf0)8vv{VS@U$GxQt58Re;!O^s&_sU@5dEat`R$VT_#b+S~YaJpw(Ihp2ZOZCjCcx787UfE(! zGM58Sm-b}KQ@BbXkp+mMBxFw@OeGLermLj_*(=qm-<%Mao?ThCutb*2E-GJCE|b=A zr2gu;vKak!HSS0zEnZ$b-jU0hYJ!lCX`92GhB7sB!K-#OmHs+@XF>t5B5fOT8wgE~ZhVj8G3(mn~c<2bM$qt91|c zE;panyNs1j)G=CiQ1@!NL7f|926b&kfyxVX>{ivW-j8YAT;Xx5cX0#8h~Fp)G+$|j z9Kk$dflC%BOi55xQ(dj#399-Ds9u13&B;N`isg%BXV7>rttqXlR_R8yOKWP%6?Q3I z=x4_&)g0dFJ|60JD0LMJ=~@C0M^aa@kS+YbU}k5DJQs0LP|w~ z=SxVL2wjVnF3QA;g?#0KD`%^~vf;@;lqc0o=fV|SykHF>FZM9im1X#qQ)<_%--Mfi zs9kU!#)t&i2nE=T1q>q?##%ItwQzuqcz|OEbg%Nrb0=Y}igqlbeOeWIz8QtTRfWEz z5xvV?EEp(K&ugP_yk96o@Y|1aXO1fL{5SIQv#QV!CT*nhcOAa2*MKFTt9YHULM0X1cECp5#hImvY>bLLTUD z0t%~I?NlowL0=PAJnl&eVhpXJ!r5}cfb`)xW%N|s3d>6f;_&a*FfPW>vP#O*5AWnp zxfJw%foCaNfsvHFzNW6Hk?{E>taAg+v{no1s2}95I+7dIp%tO3V_m1Cigb4|88eH5 z+O*oF+H^IM>3(Jcfds9rr34Ry(Nm>_ymN!2q2)At!dG1>2+LMgBbW7$|ktXeK4)%(Mh?3(QKuGX1B}fck<8kym0UdLT zmeR_(U$~SO&=;S0od4s2_>nvE;%rY~dcjgKhOasCxZ2td{Ls+V)XD>+OY93_ znI2+xds_#Y>JslqvcBRH54Qp0G(a-Hot*WQ$6VLc(B07~`B$fB?PGpRtKw`;&wA=O zs@~b%(9ocmze&&f88aJNS`_P{jI3WPR#%r)wqsb<@0nGUX+?17d z+gMVMi9~Yl&C2>Zb7(e^tf#ZG?qODA`x?plZC2KOigStNTs=JNL8*u?fJ@%jhi5&` zJep!8Ysc`cA2SPAdi~aTWq8(4JSMK$Dc9Z~p7lJqH8`x-;`fkxv1LT|Fr3n4K5}@z zXf94H9u^i+u`|*AnG-$y_kSHeJU?8Qxg%*u_Sr@Bc=yS~iwKg9cF=bnfA{nELH>@e zWj=rB<@K-46;vmGfR1SI;fkcXI{xnG?}Pju?PETF_xF7;;U}Uvn>f0j%tu5HSy?~f z2Bh@i`A!|7!xc_3@55dgK4wjD>XJE%ovFnqk`9RuS0p!Aj9Wi(xVxmZcr5W{?TvGj zUZTD1-0+JYXC!f;=kR=J$9EF%%kM1p9q5HY>@R^Jc-K(96Ea>me&UIfB(VeBU57zb0!M=n2=?9~{?_z(-!MeWmT=&Jg zJ_p}naB>dz_ccN?g8dV*AD%#2Att51fM{})UWoSL(boOZz7umZUJ5}b?I3X?`|BtV zmQU#0IM;oV_~M|5%J%YFB-)D>>2){v_o7Am&?0?zqmJ1kMUPP1+3h7;7FSFV7u{!` z_sBI5ghe`@^lP3+-nGn=Jur(~^*ub!nT|K%%wf;N{$7TdE+&e@6-C^ae`Z;EA35F2 ze)#ZT53h&*KRD``n33N)LZ# z$!CkRC-fC(Ckm3t6J9QakPD$)@zRy!coa+-u|GR{c4>d_S=od`Q&RWO0j^Wnof2Xk z1uhbQQSDCgP>#A2WZxaGD9)ZUVSed^-r{VTHzc8L=yTcI@;meZ&2@PkwTSkw7126; zqL{_J{^{=s_Je$=1J~=-ToLV%Be6s3IR)8RL4BEkeikPrat6JD+49=CVYKR$Y_jAW zoQH2}y9Bhi*Cx(>OveYE=-~-%`SY?5&!1QN2}FzdLe zLt~}B5AD4?L#tVbnssa6e9QBxcpOD1{iAq>7H5an?p~|5B0p){`J?h(>z6oUed(H_ z^*g@!H1Yf!@%0<-z1!na9`lZQmgO(2zNU|KYd7MPtzFN(@YDT!UfA>Oiap}_=bqiO zd(Sf~p56OXvFpX>_7i(0Ak|S@g zKf7z^{@3v=(VkuVcRusF*tc^(*Vy^|{yl)euZz8}J&Qd&BmNq3&>p*f{L%}Mf=4gD z{v_2F;<=y7-DjVZoZWkVx>FTV@sPIh;?v@@qE~!XJc4JO{wlJZJZBLuT#E7I#-E6P z{G~K*0zHb?q{He&LEV_J9@ewAk8>P)JPPYgJl6wqH2uMy26V!3H97Kd&N;p#$G{Id z{kfj}cqnI)@5jcY-yVE(2<1iA_i`5ajsPDMUvScL3;D9s^yL`z51r0^gMm zF897jK5a35y7ic}lX?AD{DK_YH*Sfa(Z^){z!yeeC0BlA9;1%-`10;#{VRMKbB!}X zYnG!v2YPqYCS$!l=33L2qkYVjcl6Rt7h^6>*Ba$$`{CVFJdQkBo926RO#Hw-%@fFv zo@46=-BZne^c`D2=$>x&qdoBBXpdjMw_M&+&aN~Ct{nB_Bl$u%wR5hv1&$nxTwRTu z>QA9u?LO9iv`Ig@j;$YS@N@5J)E*tj+K)bwM}Bk$ejJN2qaLc5Nv_lft{jswLr-<^ znCT51ITmAvo+{x<`3V9n{2DC+`Ojz!LP$p?El zXX^r2#Ifij|H&fmqejh}qraY}obeuRVs};q?i`D@2_CNE8Mh(u=IH0I_jniGW;|w9 zu#(NiSi-MrheN`>ECVn4OB9JtqMH~>3MWO95|R>=l9G~>Qj$^=(~>fxkoC5S*eMxt z#Rm6gXVHi&cbAM1$r*I+i{Fie+l}{C5$zJ96%-~3(dTpck`O!i$>nFqIl^&8q&KT| z65Xdk8w7~_Y=$ecTvxnQ?<6@%p|BHr{tYqe)ZB3?;qzuh5)%^2+SA>MBa_nd5+Z#G zmt?rfDZP`=rDsuGQ9|GLGa!S%qDcsKN4ukLj>kRY1Er z+{qC>Bawtq;m;zMPbf=wNA9Dpo-q21t!FNp^T8SKpYi@#3oHJZ9-7!f{N$9545XcC zA?u%X{}0cIWQ>l4vc}47e8d^+<-ktZJ4!h~UEyt<15W}`4)_n_I-?W(_9p3c+%_bf z(I+kjml7e39wVWIIW8j|xp9ut_HlD#KI;3qQE%l&pUREiPb4>TT-W`RpBulACpVft zbyRX=qL~|$j!kY*S9lxe#!ev04e!}(=ae8dNLZ%EDJKj_jY&po;CJ?qcYHX2dg}P# zuF?(=Ja6DAz{iJ6h4=~NWX^`MXU!XaGJnM6aUBjJt6evA)e0v^&L02d3`tCgOe(_c zar?T_jg$Ntd!q3thwh#m0vdqQ3pAhMnhhI;7=3`bKUTRE1Zx_s{4P9LlTmw zI^FHsB@a5EOSm*+d@XEz;>Vod;+6TKu@R?89%**K#!>25YFcmOekI%53oM+LpleAs z9qVr4w2Y}yN11fG_uOfjkOAx+VusYuH0OBRWbBlTxLmG3N=Ec98F6_@(A#RgiC>#} zKDk|p6_Ed!{e7w{M!Rn0dB4A(;r@O_EO{s0{r*c{hkxtJjPZEh8FoJLKEK96pJR2g z#0}F5b02IRr9P)-_BQVG=YV3rkAz<6;au+oIY4z~4qWe?LP=0b3|@L%?-bGjra`J6 z%CSVx0l5bCbD;CWSUK=Dl>>JOu?FToW)95cWoW{I6;6sA^ZPjmo)k;|?Bzg0RmP-g z7v?>fmx%AgfY;sOE(_)h|(@Tpqer(0L*-2am%{Y+|Y4lVJ80o~oOfJ&snHMmI6XQ-|;7tZi z#2G`Jhqw-&X#wK|Vmw6*ey#W%^a#eI0+}4|1@k zzIiP};3F0Ib9^Lmb|gPHl6XR-cot5p<&1~Fivxd-Qf^bX zdK=Ao8Dtx4X8*;p!nw_fIFvx%Mpfj@cAMibow;x*xuwr-aUI{jp>pi*PvH2L^saw= zdxz(?SFPjQJ^#Mr+cxv~wihjTl=^zW@$DJdj(vO+&US4U3l47Eos-O2Y`Zhvo5eo< z+%gV+`0Lnnf|U)QC*h7UUe|0Dq7HI05kJm4Hp6w3-}n3dZ`|*v(K>eJ$=2ttO=l`{ z$Uo>zqy9dJbq-~`=Wq@ACC^*@walejm&h3$AgnRyvD zj#3T`IG6b^*ybG26W~!T0fIA{N1bt$0KAT&Ys12M)R|1zRO#;#r(u0tOK(&X&SOqG zz3F2$xI>!<1|A14-4MApd|l{zTx+eSx!|d%y$kC+AKa&M<6iuITiBAhG35DRGN0$9 zUfbZM#Z|wd^V(3^s`FmEXl%Os8NMu%oYI%jmNC8oc0TcZ_yO`EacoW`loN3#xoI>n z9D<#rloJDv1%HHX&WUPzZ{kAv!bInBEh&Pdz~jyd{;Ys?DPGBkv!TbGQ)rbyGXt$& zYlZV8xt_g=@qX*9{dFIDE(GHk2V{56f*Ou@!yn3 zd(Au=b&T_fezgno$b4U`voB^U?Q?PlrqVuVij_*w4M?Tu2d2_~J(Y%%Mh~kZGRB@B3FSp1(Q6~qN^spik{FFflJQB6MnWNXqMJyEyrX%{qi*sxn!_^an1|=; z<=cs!15TPlD;sYk@$?RU?jB`PTK4ifxTm3}uLBFA15N?GYJm@U@=D9kos18`;R9Yz zYeidQQ?GD->F{sRALp1C^;`j^C7HVZLRb2|C6PSN{in(;JTE~jFqvEanke1`lS}1c zyBeHCnP5+-1RGa)Al;3)(|$?ExJXxqGr6wdvsf%oK`yU=y-)mD_rH`sqi`8`)Tq%e zy~7fJTMTxN(y@-3+S@o!_5i6jRy!Y9Swg~ImVDrh_p&6-@Ba^F|5KXKHk3Ig$~ENI zXb@cVzuCcw^4TMmMO7SKE7RITroB3>m6CTa8%ugr@3cv5& zW-{s${GvPy3uDR!Sh$d^eA4GiSGhP}9zE7g;I8LuibtvMshPcv`<||>qVM@ki7vrj z>zcC!RiN`A{2bu&DG;41Vf(oKJRf!a-+Ju(37%B_yi@-6BKw)XhtRvYiy-Ug4aj2d z-505MOTRts!u*8k;T7v!o~`-K1=l5~tV_6J()nT~Y5t`9_D1U4vACFj>ZFr#>f_x= zgpiKb_@*ZIHtOS4G;8oycIRd{_*sWUF}m^Md|X*~$9khXy{EOBugAN5F8p!Ec8=!( z=-c?v^{?=?q3dwg>#pV1gLaS6k5#|#!s{j=JM?~UbVax84*y+)Gg0>YuX$=uC|eu3 zY~q&lZ%7HP+CS%l